diff --git a/Makefile b/Makefile index 24fe76290..1e1334199 100644 --- a/Makefile +++ b/Makefile @@ -28,7 +28,7 @@ FILE_EXT= endif INT_MIXINS = exec kubernetes -EXT_MIXINS = helm azure terraform +EXT_MIXINS = helm arm terraform MIXIN_TAG ?= canary MIXINS_URL = https://cdn.porter.sh/mixins diff --git a/docs/content/wiring.md b/docs/content/wiring.md index 27081a5a5..f7b099cdd 100644 --- a/docs/content/wiring.md +++ b/docs/content/wiring.md @@ -31,8 +31,8 @@ Once a parameter has been declared in the `porter.yaml`, Porter provides a simpl ```yaml install: -- description: "Install MySQL" - helm: +- helm: + description: "Install MySQL" name: porter-ci-mysql chart: stable/mysql version: 0.10.2 @@ -107,9 +107,10 @@ In addition to parameters and credentials, Porter introduces a type called an ou ```yaml install: - - description: "Create Azure MySQL" - azure: - type: mysql + - arm: + description: "Create Azure MySQL" + type: arm + template: "arm/mysql.json" name: demo-mysql-azure-porter-demo-wordpress resourceGroup: "porter-test" parameters: @@ -120,9 +121,9 @@ install: version: "5.7" sslEnforcement: "Disabled" databaseName: "{{ bundle.parameters.database_name }}" - outputs: - - name: "MYSQL_URL" - key: "MYSQL_HOST" + outputs: + - name: "MYSQL_URL" + key: "MYSQL_HOST" ``` In this example, a new output will be created named `MYSQL_URL`. The Azure mixin allows you to specify the key to fetch the output from, in this case it is `MYSQL_HOST`. Each mixin can provide different ways of addressing outputs, so refer to the schema for each mixin. The Porter runtime will keep a map in memory with each of the outputs declared. @@ -136,8 +137,8 @@ Once an output has been declared, it can be referenced in the same way as parame For example, given the install step above, we can use the `MYSQL_URL` with the helm mixin in the following way: ```yaml - - description: "Helm Install Wordpress" - helm: + - helm: + description: "Helm Install Wordpress" name: porter-ci-wordpress chart: stable/wordpress set: @@ -168,8 +169,8 @@ images: These images will be used to build the `bundle.json` images section, but can also be referenced using the same syntax you would use for referencing `parameters`, `credentials`, and `outputs`. ```yaml -- description: "Helm Install Wordpress" - helm: + - helm: + description: "Helm Install Wordpress" name: porter-ci-wordpress chart: stable/wordpress set: @@ -205,22 +206,22 @@ parameters: env: MYSQL_USER install: -- description: "Install MySQL" - helm: +- helm: + description: "Install MySQL" name: porter-ci-mysql chart: stable/mysql - version: 0.10.2 + version: 1.6.2 replace: true set: mysqlDatabase: "{{ bundle.parameters.database-name }}" mysqlUser: "{{ bundle.parameters.mysql-user }}" - outputs: - - name: mysql-root-password - secret: porter-ci-mysql - key: mysql-root-password - - name: mysql-password - secret: porter-ci-mysql - key: mysql-password + outputs: + - name: mysql-root-password + secret: porter-ci-mysql + key: mysql-root-password + - name: mysql-password + secret: porter-ci-mysql + key: mysql-password ``` In this bundle, we see the normal declaration of credentials, parameters and outputs, along with the use of `"{{ bundle.x.y.z }}"` to use these. With this bundle definition, we can build a second bundle to install wordpress and declare a dependency on this bundle. The `porter.yaml` for this might look something like: @@ -251,8 +252,8 @@ parameters: env: WORDPRESS_NAME install: -- description: "Install Wordpress" - helm: +- helm: + description: "Install Wordpress" name: "{{ bundle.parameters.wordpress-name }}" chart: stable/wordpress replace: true @@ -266,8 +267,8 @@ The wordpress bundle declares a dependency on the `mysql` bundle, which we saw a ```yaml install: -- description: "Install Wordpress" - helm: +- helm: + description: "Install Wordpress" name: "{{ bundle.parameters.wordpress-name }}" chart: stable/wordpress replace: true @@ -287,8 +288,8 @@ It is possible to reference multiple parameters, credentials and/or outputs in a ```yaml install: -- description: "Install Java App" - helm: +- helm: + description: "Install Java App" name: "{{ bundle.parameters.cool-app}}" chart: stable/wordpress replace: true diff --git a/examples/aks-spring-music/README.md b/examples/aks-spring-music/README.md index 0a8046552..1bd7f6231 100644 --- a/examples/aks-spring-music/README.md +++ b/examples/aks-spring-music/README.md @@ -2,9 +2,9 @@ This bundle demonstrates advanced use cases for Porter. -The bundle leverages a base Dockerfile (cnab/app/Dockerfile.base) to customize the resulting invocation image for the bundle by first installing the `azure cli` so that it can be used by the `exec` mixin. It then uses 4 mixins to access your Azure subscription and deploy the app. These values need to be updated in the porter.yaml. +The bundle leverages a base Dockerfile (Dockerfile.tmpl) to customize the resulting invocation image for the bundle by first installing the `azure cli` so that it can be used by the `exec` mixin. It then uses 4 mixins to access your Azure subscription and deploy the app. These values need to be updated in the porter.yaml. -* The `azure` mixin is used to create an AKS cluster using ARM. This requires subscription and tenant info. +* The `arm` mixin is used to create an AKS cluster using ARM. This requires subscription and tenant info. * The `exec` mixin uses an Azure Service Principal to access via the CLI and install Helm's Tiller into an AKS cluster. * The `kubernetes` mixin applys RBAC policies for Helm * The `helm` mixin deploys the chart into the AKS cluster. @@ -37,7 +37,7 @@ The bundle will use the service principal created above to interact with Azure. ``` * Update params for your deployment - * change the `invocationImage` Docker repo to match your Docker Hub account (line 4) + * change the `tag` Docker repo to match your Docker Hub account * Cosmos and AKS names must be unique. You can either edit the `porter.yaml` file default values (starting on line 90) or you can supply the with the porter CLI as shown below. * Build the innvocation image @@ -50,5 +50,10 @@ The bundle will use the service principal created above to interact with Azure. ```bash export INSTALL_ID=314 - porter install -c azure --param app-resource-group=spring-music-demo-$INSTALL_ID --param aks-resource-group=spring-music-demo-$INSTALL_ID --param aks-cluster-name=briar-aks-spring-$INSTALL_ID --param cosmosdb-service-name=briarspringmusic$INSTALL_ID --param azure-location=eastus + porter install -c azure \ + --param app-resource-group=spring-music-demo-$INSTALL_ID \ + --param aks-resource-group=spring-music-demo-$INSTALL_ID \ + --param aks-cluster-name=briar-aks-spring-$INSTALL_ID \ + --param cosmosdb-service-name=briarspringmusic$INSTALL_ID \ + --param azure-location=eastus ``` diff --git a/examples/aks-spring-music/arm/aks.json b/examples/aks-spring-music/arm/aks.json new file mode 100644 index 000000000..1382e162f --- /dev/null +++ b/examples/aks-spring-music/arm/aks.json @@ -0,0 +1,113 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "clusterName": { + "type": "string", + "defaultValue": "[concat('cnab-aks-', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "AKS cluster name. Defaults to cnab-aks-xxxxxxxxxxxxx, where xxx... is a unique string based of the hash of your resource group id." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "The location of the Managed Cluster resource." + } + }, + "dnsPrefix": { + "type": "string", + "defaultValue": "[concat('cnab-aks-', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "Optional DNS prefix to use with hosted Kubernetes API server FQDN." + } + }, + "osDiskSizeGB": { + "type": "int", + "defaultValue": 0, + "metadata": { + "description": "Disk size (in GB) to provision for each of the agent pool nodes. This value ranges from 0 to 1023. Specifying 0 will apply the default disk size for that agentVMSize." + }, + "minValue": 0, + "maxValue": 1023 + }, + "agentCount": { + "type": "int", + "defaultValue": 3, + "metadata": { + "description": "The number of nodes for the cluster." + }, + "minValue": 1, + "maxValue": 50 + }, + "agentVMSize": { + "type": "string", + "defaultValue": "Standard_DS2_v2", + "metadata": { + "description": "The size of the Virtual Machine." + } + }, + "servicePrincipalClientId": { + "metadata": { + "description": "Client ID (used by cloudprovider)" + }, + "type": "securestring" + }, + "servicePrincipalClientSecret": { + "metadata": { + "description": "The Service Principal Client Secret." + }, + "type": "securestring" + }, + "osType": { + "type": "string", + "defaultValue": "Linux", + "allowedValues": [ + "Linux" + ], + "metadata": { + "description": "The type of operating system." + } + }, + "kubernetesVersion": { + "type": "string", + "defaultValue": "1.15.7", + "metadata": { + "description": "The version of Kubernetes." + } + } + }, + "resources": [ + { + "apiVersion": "2018-03-31", + "type": "Microsoft.ContainerService/managedClusters", + "location": "[parameters('location')]", + "name": "[parameters('clusterName')]", + "properties": { + "kubernetesVersion": "[parameters('kubernetesVersion')]", + "dnsPrefix": "[parameters('dnsPrefix')]", + "agentPoolProfiles": [ + { + "name": "agentpool", + "osDiskSizeGB": "[parameters('osDiskSizeGB')]", + "count": "[parameters('agentCount')]", + "vmSize": "[parameters('agentVMSize')]", + "osType": "[parameters('osType')]", + "storageProfile": "ManagedDisks" + } + ], + "servicePrincipalProfile": { + "clientId": "[parameters('servicePrincipalClientId')]", + "Secret": "[parameters('servicePrincipalClientSecret')]" + } + } + } + ], + "outputs": { + "controlPlaneFQDN": { + "type": "string", + "value": "[reference(parameters('clusterName')).fqdn]" + } + } +} \ No newline at end of file diff --git a/examples/aks-spring-music/arm/cosmosdb.json b/examples/aks-spring-music/arm/cosmosdb.json new file mode 100644 index 000000000..3289e60a9 --- /dev/null +++ b/examples/aks-spring-music/arm/cosmosdb.json @@ -0,0 +1,94 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "name": { + "type": "string", + "defaultValue": "[concat('cnab-cosmos-', uniqueString(resourceGroup().id))]", + "metadata": { + "description": "Cosmos DB account name. Defaults to cnab-cosmos-xxxxxxxxxxxxx, where xxx... is a unique string based of the hash of your resource group id." + } + }, + "location": { + "type": "string", + "defaultValue": "[resourceGroup().location]", + "metadata": { + "description": "Location for the Cosmos DB account. Defaults to the resource group location." + } + }, + "apiVersion": { + "type": "string", + "defaultValue": "2016-03-31", + "metadata": { + "description": "API Version. Defaults to '2016-03-31'." + } + }, + "kind": { + "type": "string", + "defaultValue": "MongoDB", + "metadata": { + "description": "The type/kind of API for the Cosmos Database. Defaults to MongoDB." + } + }, + "mongoCapabilities": { + "type": "array", + "defaultValue": [ + { + "name": "EnableAggregationPipeline" + }, + { + "name": "MongoDBv3.4" + } + ], + "metadata": { + "description": "MongoDB API capabilities that should be enabled by default." + } + }, + "enableMongoCapabilities": { + "type": "array", + "defaultValue": "[if(equals(parameters('kind'), 'MongoDB'), parameters('mongoCapabilities'), '[]')]", + "metadata": { + "description": "Conditional to enable api specific capabilities if MongoDB is the API chosen." + } + } + }, + "variables": {}, + "resources": [ + { + "apiVersion": "[parameters('apiVersion')]", + "kind": "[parameters('kind')]", + "type": "Microsoft.DocumentDB/databaseAccounts", + "name": "[parameters('name')]", + "location": "[parameters('location')]", + "properties": { + "databaseAccountOfferType": "Standard", + "locations": [ + { + "id": "[concat(parameters('name'), '-', parameters('location'))]", + "failoverPriority": 0, + "locationName": "[parameters('location')]" + } + ], + "enableMultipleWriteLocations": true, + "isVirtualNetworkFilterEnabled": false, + "virtualNetworkRules": [], + "dependsOn": [], + "capabilities": "[parameters('enableMongoCapabilities')]" + } + } + ], + "outputs": { + "HOST": { + "type": "string", + "value": "[reference(parameters('name')).documentEndpoint]" + }, + "primary_key": { + "type": "string", + "value": "[listKeys(resourceId('Microsoft.DocumentDb/databaseAccounts', parameters('name')), parameters('apiVersion')).primaryMasterKey]" + }, + "connection_string": { + "type": "string", + "value": "[listConnectionStrings(resourceId('Microsoft.DocumentDb/databaseAccounts', parameters('name')), parameters('apiVersion')).connectionStrings[0].connectionString]" + } + } +} \ No newline at end of file diff --git a/examples/aks-spring-music/porter.yaml b/examples/aks-spring-music/porter.yaml index ca4dc4f79..0cc585366 100644 --- a/examples/aks-spring-music/porter.yaml +++ b/examples/aks-spring-music/porter.yaml @@ -7,13 +7,14 @@ tag: getporter/aks-spring-music:v0.1.0 mixins: - exec - helm - - azure + - arm - kubernetes install: - - azure: + - arm: description: "Create AKS" - type: aks + type: arm + template: "arm/aks.json" name: "{{ bundle.parameters.aks-cluster-name }}" resourceGroup: "{{ bundle.parameters.aks-resource-group }}" parameters: @@ -35,6 +36,15 @@ install: - "--tenant" - "{{ bundle.credentials.TENANT_ID}}" + - exec: + description: "Azure CLI set subscription" + command: "az" + arguments: + - "account" + - "set" + - "-s" + - "{{ bundle.credentials.SUBSCRIPTION_ID}}" + - exec: description: "Azure CLI AKS get-credentials" command: "az" @@ -61,9 +71,10 @@ install: - "tiller" - "--upgrade" - - azure: + - arm: description: "Create Azure Cosmos DB" - type: cosmosdb + type: arm + template: "arm/cosmosdb.json" name: aks-spring-music-cosmos resourceGroup: "{{ bundle.parameters.app-resource-group }}" parameters: @@ -81,10 +92,10 @@ install: - helm: description: "Helm Install Spring Music Demo App" name: aks-spring-music-helm - chart: /cnab/app/charts/aks-spring-music + chart: /cnab/app/charts/spring-music replace: true set: - deploy.cosmosConnectString: $COSMOSDB_CONNECTION_STRING + deploy.cosmosConnectString: "{{ bundle.outputs.COSMOSDB_CONNECTION_STRING }}" uninstall: - exec: diff --git a/examples/azure-terraform/README.md b/examples/azure-terraform/README.md index 9634c91af..36d7ca012 100644 --- a/examples/azure-terraform/README.md +++ b/examples/azure-terraform/README.md @@ -1,6 +1,6 @@ # Using Porter with Azure and Terraform -This bundle provides an example of how you can use Porter to build Terraform-based bundles. The example provided here will create Azure CosmosDB and Azure EventHubs objects using Terraform configurations and the [porter-terraform](https://github.com/deislabs/porter-terraform/) mixin. This sample also shows how the Terraform mixin can be used with other mixins, in this case the Azure mixin. The Azure mixin is first used to create an Azure storage account that will be used to configure the Terraform `azurerm` backend. It is possible to build bundles using just the [porter-terraform](https://github.com/deislabs/porter-terraform) mixin, but this example shows you how to use outputs between steps as well. +This bundle provides an example of how you can use Porter to build Terraform-based bundles. The example provided here will create Azure CosmosDB and Azure EventHubs objects using Terraform configurations and the [porter-terraform](https://github.com/deislabs/porter-terraform/) mixin. This sample also shows how the Terraform mixin can be used with other mixins, in this case the ARM mixin. The ARM mixin is first used to create an Azure storage account that will be used to configure the Terraform `azurerm` backend. It is possible to build bundles using just the [porter-terraform](https://github.com/deislabs/porter-terraform) mixin, but this example shows you how to use outputs between steps as well. ## Setup @@ -132,20 +132,27 @@ Once this command has finished, you will see some additional resources in your w ```bash $ more Dockerfile -FROM quay.io/deis/lightweight-docker-go:v0.2.0 FROM debian:stretch -COPY --from=0 /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt -COPY . /cnab/app -RUN mv /cnab/app/cnab/app/* /cnab/app && rm -r /cnab/app/cnab +ARG BUNDLE_DIR + +RUN apt-get update && apt-get install -y ca-certificates # exec mixin has no buildtime dependencies -ENV TERRAFORM_VERSION=0.11.11 +ENV TERRAFORM_VERSION=0.12.17 RUN apt-get update && apt-get install -y wget unzip && \ wget https://releases.hashicorp.com/terraform/${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_linux_amd64.zip && \ unzip terraform_${TERRAFORM_VERSION}_linux_amd64.zip -d /usr/bin -WORKDIR /cnab/app +COPY . $BUNDLE_DIR +RUN cd /cnab/app/terraform && terraform init -backend=false + + +COPY . $BUNDLE_DIR +RUN rm -fr $BUNDLE_DIR/.cnab +COPY .cnab /cnab +COPY porter.yaml $BUNDLE_DIR/porter.yaml +WORKDIR $BUNDLE_DIR CMD ["/cnab/app/run"] ``` @@ -190,15 +197,16 @@ Once you have built the bundle and generated a credential set, you're ready to i ```bash $ porter install -c azure-terraform installing azure-terraform... -executing porter install configuration from /cnab/app/porter.yaml +executing install action from azure-terraform (bundle instance: azure-terraform) Create an Azure Storage Account Starting deployment operations... Finished deployment operations... Emit the key in base64 encoded form -Here is a the storage account key (base64 encoded) ==> %%A KEY%% +Here is a the storage account key (base64 encoded) ==> cFNZNExabEg1eGkzSkgrdU5HcFZyek94WmEyYXRRa1Z6WWtFVjZGamg5aU5wcjRVVjROVFBmSXJH +UXNpTVpLQS9FYWVWanF1WkhhMFg5TE9IMERRY2c9PQo= Create Azure CosmosDB and Event Hubs Initializing Terraform... -/usr/bin/terraform terraform init -backend=true -backend-config=access_key=******* -backend-config=container_name=portertf -backend-config=key=porter-terraform.tfstate -backend-config=storage_account_name=porterstorage -reconfigure +/usr/bin/terraform terraform init -backend=true -backend-config=access_key=******* -backend-config=container_name=portertf -backend-config=key=azure-terraform.tfstate -backend-config=storage_account_name=porterstorage -reconfigure Initializing the backend... @@ -206,8 +214,19 @@ Successfully configured the backend "azurerm"! Terraform will automatically use this backend unless the backend configuration changes. Initializing provider plugins... -- Checking for available provider plugins on https://releases.hashicorp.com... -- Downloading plugin for provider "azurerm" (1.31.0)... + +Terraform has been successfully initialized! + +You may now begin working with Terraform. Try running "terraform plan" to see +any changes that are required for your infrastructure. All Terraform commands +should now work. + +If you ever set or change modules or backend configuration for Terraform, +rerun this command to reinitialize your working directory. If you forget, other +commands will detect it and remind you to do so if necessary. +/usr/bin/terraform terraform apply -auto-approve -input=false -var client_id=******* -var client_secret=******* -var database_name=porter-terraform -var resource_group_location=EastUS -var resource_group_name=porter-terraform -var subscription_id=******* -var tenant_id=******* +Acquiring state lock. This may take a few moments... +azurerm_resource_group.rg: Creating... < OUTPUT TRUNCATED> ``` @@ -233,10 +252,10 @@ When you're ready to uninstall the bundle, simply run the `porter uninstall` com ```bash $ porter uninstall -c azure-terraform --param tf_storage_account_key=%%YOUR KEY VALUE%% uninstalling azure-terraform... -executing porter uninstall configuration from /cnab/app/porter.yaml +executing uninstall action from azure-terraform (bundle instance: azure-terraform) Remove Azure CosmosDB and Event Hubs Initializing Terraform... -/usr/bin/terraform terraform init -backend=true -backend-config=access_key= -backend-config=container_name=portertf -backend-config=key=porter-terraform.tfstate -backend-config=storage_account_name=porterstorage -reconfigure +/usr/bin/terraform terraform init -backend=true -backend-config=access_key=******* -backend-config=container_name=portertf -backend-config=key=azure-terraform.tfstate -backend-config=storage_account_name=porterstorage -reconfigure Initializing the backend... @@ -244,8 +263,18 @@ Successfully configured the backend "azurerm"! Terraform will automatically use this backend unless the backend configuration changes. Initializing provider plugins... -- Checking for available provider plugins on https://releases.hashicorp.com... -- Downloading plugin for provider "azurerm" (1.31.0)... + +Terraform has been successfully initialized! + +You may now begin working with Terraform. Try running "terraform plan" to see +any changes that are required for your infrastructure. All Terraform commands +should now work. + +If you ever set or change modules or backend configuration for Terraform, +rerun this command to reinitialize your working directory. If you forget, other +commands will detect it and remind you to do so if necessary. +/usr/bin/terraform terraform destroy -auto-approve -var client_id=******* -var client_secret=******* -var database_name=porter-terraform -var resource_group_location=EastUS -var resource_group_name=porter-terraform -var subscription_id=******* -var tenant_id=******* +Acquiring state lock. This may take a few moments... < OUTPUT TRUNCATED> ``` diff --git a/examples/azure-terraform/arm/storage.json b/examples/azure-terraform/arm/storage.json new file mode 100644 index 000000000..e479f7f1e --- /dev/null +++ b/examples/azure-terraform/arm/storage.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "storageAccountName": { + "type": "string" + }, + "storageContainerName": { + "type": "string" + } + }, + "resources": [ + { + "name": "[parameters('storageAccountName')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2018-07-01", + "sku": { + "name": "Standard_GRS" + }, + "kind": "StorageV2", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "encryption": { + "services": { + "blob": { + "enabled": true + } + }, + "keySource": "Microsoft.Storage" + }, + "supportsHttpsTrafficOnly": true + }, + "resources": [ + { + "name": "[concat(parameters('storageAccountName'), '/default/', parameters('storageContainerName'))]", + "dependsOn": [ + "[parameters('storageAccountName')]" + ], + "type": "Microsoft.Storage/storageAccounts/blobServices/containers", + "apiVersion": "2018-07-01", + "properties": { + "publicAccess": "None" + } + } + ] + } + ], + "outputs": { + "STORAGE_ACCOUNT_KEY": { + "type": "string", + "value": "[first(listKeys(parameters('storageAccountName'), '2018-02-01').keys).value]" + } + } +} \ No newline at end of file diff --git a/examples/azure-terraform/porter.yaml b/examples/azure-terraform/porter.yaml index 9d579854a..8fb6d77e0 100644 --- a/examples/azure-terraform/porter.yaml +++ b/examples/azure-terraform/porter.yaml @@ -1,6 +1,6 @@ ## This section defines which Mixins will be used by the bundle. mixins: - - azure + - arm - exec - terraform @@ -82,9 +82,10 @@ outputs: - install install: - - azure: + - arm: description: "Create an Azure Storage Account" - type: storage + type: arm + template: "arm/storage.json" name: "{{ bundle.parameters.storage_account_name }}" resourceGroup: "{{ bundle.parameters.storage_rg }}" parameters: @@ -156,11 +157,12 @@ uninstall: resource_group_name: "{{bundle.parameters.resource_group_name}}" resource_group_location: "{{bundle.parameters.location}}" - - azure: + - arm: description: "Remove the Azure Storage Account" + type: arm + template: "arm/storage.json" name: "{{ bundle.parameters.storage_account_name }}" resourceGroup: "{{ bundle.parameters.storage_rg }}" - type: storage parameters: location: "{{ bundle.parameters.location }}" storageAccountName: "{{ bundle.parameters.storage_account_name }}" diff --git a/examples/azure-terraform/terraform/cosmos-db.tf b/examples/azure-terraform/terraform/cosmos-db.tf index 45b3e972b..fc875e4ad 100644 --- a/examples/azure-terraform/terraform/cosmos-db.tf +++ b/examples/azure-terraform/terraform/cosmos-db.tf @@ -1,12 +1,12 @@ resource "azurerm_resource_group" "rg" { - name = "${var.resource_group_name}" - location = "${var.resource_group_location}" + name = var.resource_group_name + location = var.resource_group_location } resource "azurerm_cosmosdb_account" "db" { name = "porterform-cosmos-db" - location = "${azurerm_resource_group.rg.location}" - resource_group_name = "${azurerm_resource_group.rg.name}" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name offer_type = "Standard" kind = "MongoDB" @@ -14,19 +14,24 @@ resource "azurerm_cosmosdb_account" "db" { consistency_policy { consistency_level = "BoundedStaleness" - max_interval_in_seconds = 10 - max_staleness_prefix = 200 + max_interval_in_seconds = 301 + max_staleness_prefix = 100001 + } + + geo_location { + location = var.failover_location + failover_priority = 1 } geo_location { prefix = "porterform-${azurerm_resource_group.rg.location}" - location = "${azurerm_resource_group.rg.location}" + location = azurerm_resource_group.rg.location failover_priority = 0 } } resource "azurerm_cosmosdb_mongo_database" "db" { - name = "${var.database_name}" - resource_group_name = "${azurerm_cosmosdb_account.db.resource_group_name}" - account_name = "${azurerm_cosmosdb_account.db.name}" + name = var.database_name + resource_group_name = azurerm_cosmosdb_account.db.resource_group_name + account_name = azurerm_cosmosdb_account.db.name } \ No newline at end of file diff --git a/examples/azure-terraform/terraform/eventhubs.tf b/examples/azure-terraform/terraform/eventhubs.tf index bf1e4be54..e7a5ed6ad 100644 --- a/examples/azure-terraform/terraform/eventhubs.tf +++ b/examples/azure-terraform/terraform/eventhubs.tf @@ -1,10 +1,9 @@ resource "azurerm_eventhub_namespace" "hubs" { name = "porterform-eventhub-ns" - location = "${azurerm_resource_group.rg.location}" - resource_group_name = "${azurerm_resource_group.rg.name}" + location = azurerm_resource_group.rg.location + resource_group_name = azurerm_resource_group.rg.name sku = "Standard" capacity = 1 - kafka_enabled = true tags = { environment = "Production" @@ -13,8 +12,8 @@ resource "azurerm_eventhub_namespace" "hubs" { resource "azurerm_eventhub" "hubs" { name = "porterform-eventhub" - namespace_name = "${azurerm_eventhub_namespace.hubs.name}" - resource_group_name = "${azurerm_resource_group.rg.name}" + namespace_name = azurerm_eventhub_namespace.hubs.name + resource_group_name = azurerm_resource_group.rg.name partition_count = 2 message_retention = 1 } \ No newline at end of file diff --git a/examples/azure-terraform/terraform/main.tf b/examples/azure-terraform/terraform/main.tf index e231ef958..8ea509b72 100644 --- a/examples/azure-terraform/terraform/main.tf +++ b/examples/azure-terraform/terraform/main.tf @@ -1,12 +1,12 @@ provider "azurerm" { - version = "~>1.5" - subscription_id = "${var.subscription_id}" - client_id = "${var.client_id}" - client_secret = "${var.client_secret}" - tenant_id = "${var.tenant_id}" + version = "~>1.41.0" + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id } terraform { - required_version = "~>0.11" + required_version = "~>0.12.17" backend "azurerm" {} } \ No newline at end of file diff --git a/examples/azure-terraform/terraform/outputs.tf b/examples/azure-terraform/terraform/outputs.tf index 6de6eefbd..17375071b 100644 --- a/examples/azure-terraform/terraform/outputs.tf +++ b/examples/azure-terraform/terraform/outputs.tf @@ -1,11 +1,11 @@ output "cosmos-db-uri" { - value = "${azurerm_cosmosdb_account.db.connection_strings[0]}" + value = azurerm_cosmosdb_account.db.connection_strings[0] } output "eventhubs_connection_string" { - value = "${azurerm_eventhub_namespace.hubs.default_primary_connection_string}" + value = azurerm_eventhub_namespace.hubs.default_primary_connection_string } output "eventhubs_topic" { - value = "${azurerm_eventhub.hubs.name}" + value = azurerm_eventhub.hubs.name } \ No newline at end of file diff --git a/examples/azure-wordpress/arm/mysql.json b/examples/azure-wordpress/arm/mysql.json new file mode 100644 index 000000000..b9ec21d57 --- /dev/null +++ b/examples/azure-wordpress/arm/mysql.json @@ -0,0 +1,72 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2014-04-01-preview/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "administratorLogin": { + "type": "string" + }, + "administratorLoginPassword": { + "type": "securestring" + }, + "location": { + "type": "string" + }, + "serverName": { + "type": "string" + }, + "databaseName": { + "type": "string" + }, + "version": { + "type": "string" + }, + "sslEnforcement": { + "type": "string" + } + }, + "resources": [ + { + "apiVersion": "2017-12-01-preview", + "kind": "", + "location": "[parameters('location')]", + "name": "[parameters('serverName')]", + "properties": { + "version": "[parameters('version')]", + "administratorLogin": "[parameters('administratorLogin')]", + "administratorLoginPassword": "[parameters('administratorLoginPassword')]", + "sslEnforcement": "[parameters('sslEnforcement')]", + "storageProfile": { + "storageMB": "102400", + "backupRetentionDays": 7, + "geoRedundantBackup": "Disabled" + } + }, + "sku": { + "name": "GP_Gen5_4", + "tier": "GeneralPurpose", + "capacity": 4, + "size": 102400, + "family": "Gen5" + }, + "type": "Microsoft.DBforMySQL/servers", + "resources": [ + { + "apiVersion": "2017-12-01-preview", + "name": "[parameters('databaseName')]", + "type": "databases", + "location": "[parameters('location')]", + "dependsOn": [ + "[concat('Microsoft.DBforMySQL/servers/', parameters('serverName'))]" + ], + "properties": {} + } + ] + } + ], +"outputs": { + "MYSQL_HOST": { + "type": "string", + "value": "[reference(parameters('serverName')).fullyQualifiedDomainName]" + } +} +} \ No newline at end of file diff --git a/examples/azure-wordpress/params.ini b/examples/azure-wordpress/params.ini index 7d21a77db..432a2abf6 100644 --- a/examples/azure-wordpress/params.ini +++ b/examples/azure-wordpress/params.ini @@ -1,2 +1,2 @@ -mysql_password=ilovecnab -server_name=ilovecnab \ No newline at end of file +mysql_password=iloveporter-127c6!J9$ +server_name=iloveporter \ No newline at end of file diff --git a/examples/azure-wordpress/porter.yaml b/examples/azure-wordpress/porter.yaml index 1fb1ede93..c1266f356 100644 --- a/examples/azure-wordpress/porter.yaml +++ b/examples/azure-wordpress/porter.yaml @@ -1,5 +1,5 @@ mixins: - - azure + - arm - helm name: azure-wordpress @@ -34,12 +34,17 @@ parameters: - name: server_name type: string +- name: resource_group + type: string + default: "porter-test" + install: - - azure: + - arm: description: "Create Azure MySQL" - type: mysql + type: arm + template: "arm/mysql.json" name: mysql-azure-porter-demo-wordpress - resourceGroup: "porter-test" + resourceGroup: "{{ bundle.parameters.resource_group }}" parameters: administratorLogin: "{{ bundle.parameters.mysql_user }}" administratorLoginPassword: "{{ bundle.parameters.mysql_password }}" @@ -67,8 +72,9 @@ install: externalDatabase.database: "{{ bundle.parameters.database_name }}" uninstall: - # TODO: enable once the porter-azure mixin supports this action - # - azure: + # TODO: enable once the porter-arm mixin implements uninstall + # see https://github.com/deislabs/porter-arm/issues/7 + # - arm: # description: "Uninstall Mysql" # name: mysql-azure-porter-demo-wordpress - helm: diff --git a/workshop/porter-tf-aci/azure/README.md b/workshop/porter-tf-aci/azure/README.md index d28ee8c32..0aedf8e7e 100644 --- a/workshop/porter-tf-aci/azure/README.md +++ b/workshop/porter-tf-aci/azure/README.md @@ -1,6 +1,6 @@ # Advanced Azure + Terraform Cloud Native Application Bundle Using Porter -This exercise extends the [porter-tf](https://github.com/deislabs/porter/tree/master/workshop/porter-tf) example in order provide a more complete example of buiding a CNAB that combines both infrastructure and deployment of an application. As in the `porter-tf` example, we will use the `azure` and `terraform` mixins to provision a MySQL database on Azure. We will then use the `azure` mixin with a custom [ARM](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authoring-templates) template to deploy a notional web service as an Azure Container Instance. This part of the bundle could easily be replaced with deployment to Kubernetes or any other container runtime system, but this exercise will use Azure. +This exercise extends the [porter-tf](https://github.com/deislabs/porter/tree/master/workshop/porter-tf) example in order provide a more complete example of buiding a CNAB that combines both infrastructure and deployment of an application. As in the `porter-tf` example, we will use the `arm` and `terraform` mixins to provision a MySQL database on Azure. We will then use the `arm` mixin with a custom [ARM](https://docs.microsoft.com/en-us/azure/azure-resource-manager/resource-group-authoring-templates) template to deploy a notional web service as an Azure Container Instance. This part of the bundle could easily be replaced with deployment to Kubernetes or any other container runtime system, but this exercise will use Azure. ## Prerequisites @@ -24,18 +24,16 @@ Finally, the `porter.yaml` also defines an `imageMap`. In this section, you can ## Update the porter.yaml -Now, update the `porter.yaml` and change the following values: +Now, update the `porter.yaml` and change the following value: ``` -invocationImage: deislabs/porter-workshop-tf-aci:v0.1.0 -tag: deislabs/porter-workshop-tf-bundle-aci:v0.1.0 +tag: getporter/workshop-tf-aci:v0.1.0 ``` -For each of these, change the Docker-like reference to point to your own Docker registry. For example, if my Docker user name is `jeremyrickard`, I'd change that these lines to: +Change the Docker-like reference to point to your own Docker registry. For example, if my Docker user name is `jeremyrickard`, I'd change that these lines to: ``` -invocationImage: jeremyrickard/porter-workshop-tf-aci:v0.1.0 -tag: jeremyrickard/porter-workshop-tf-bundle-aci:v0.1.0 +tag: jeremyrickard/workshop-tf-aci:v0.1.0 ``` ## Build The Bundle! @@ -100,19 +98,21 @@ This command will generate a new `credential set` that maps our environment vari Now, you're ready to install the bundle. Replace `` with a username like `carolynvs`. ``` -porter install -c porter-workshop-tf \ - --param server-name=sql \ - --param backend_storage_account=storage \ - --param database-name=testworkshop +porter install -c workshop-tf-aci \ + --param server_name=sql \ + --param database_name=testworkshop \ + --param backend_storage_account=storagetfaci \ + --param backend_storage_container=-workshop-tf-aci \ + --param backend_storage_resource_group=-workshop-tf-aci ``` ### View The Outputs -Once the bundle has been installed, you can use `porter bundle show` to see the outputs: +Once the bundle has been installed, you can use `porter instance show` to see the outputs: ``` -$ porter bundle show -Name: porter-workshop-tf-aci +$ porter instance show +Name: workshop-tf-aci Created: 2 minutes ago Modified: 4 seconds ago Last Action: install @@ -122,9 +122,13 @@ Outputs: ----------------------------------------------- Name Type Value (Path if sensitive) ----------------------------------------------- - IP_ADDRESS string 20.42.26.66 + IP_ADDRESS string 40.88.49.175 + STORAGE_ACCOUNT_KEY string /cnab/app/outputs/STORAGE_ACCOUNT_KEY ``` +Note that sensitive outputs (`STORAGE_ACCOUNT_KEY` in this example) are replaced by their runtime path +in the default output format (`-o table`), but their values can be seen via `-o json` or `-o yaml`. + This is the IP address of the new ACI container. You can test it out now with `curl`: ``` diff --git a/workshop/porter-tf-aci/azure/bundle/arm/storage.json b/workshop/porter-tf-aci/azure/bundle/arm/storage.json new file mode 100644 index 000000000..e479f7f1e --- /dev/null +++ b/workshop/porter-tf-aci/azure/bundle/arm/storage.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "storageAccountName": { + "type": "string" + }, + "storageContainerName": { + "type": "string" + } + }, + "resources": [ + { + "name": "[parameters('storageAccountName')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2018-07-01", + "sku": { + "name": "Standard_GRS" + }, + "kind": "StorageV2", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "encryption": { + "services": { + "blob": { + "enabled": true + } + }, + "keySource": "Microsoft.Storage" + }, + "supportsHttpsTrafficOnly": true + }, + "resources": [ + { + "name": "[concat(parameters('storageAccountName'), '/default/', parameters('storageContainerName'))]", + "dependsOn": [ + "[parameters('storageAccountName')]" + ], + "type": "Microsoft.Storage/storageAccounts/blobServices/containers", + "apiVersion": "2018-07-01", + "properties": { + "publicAccess": "None" + } + } + ] + } + ], + "outputs": { + "STORAGE_ACCOUNT_KEY": { + "type": "string", + "value": "[first(listKeys(parameters('storageAccountName'), '2018-02-01').keys).value]" + } + } +} \ No newline at end of file diff --git a/workshop/porter-tf-aci/azure/bundle/porter.yaml b/workshop/porter-tf-aci/azure/bundle/porter.yaml index f7c65fb6c..b1eaf7d98 100644 --- a/workshop/porter-tf-aci/azure/bundle/porter.yaml +++ b/workshop/porter-tf-aci/azure/bundle/porter.yaml @@ -1,13 +1,12 @@ mixins: - - azure + - arm - exec - terraform -name: porter-workshop-tf-aci +name: workshop-tf-aci version: 0.1.0 -description: "An example using Porter to build the a TF bundle and use ACI" -invocationImage: porter-workshop-tf-aci:latest -tag: deislabs/porter-workshop-tf-bundle-aci:latest +description: "An example using Porter to build a TF bundle and use ACI" +tag: getporter/workshop-tf-aci:v0.1.0 ## This section defines what credentials are used for the bundle. In this case, we are operating ## against Azure, so we need some Azure Service Principal information. @@ -36,16 +35,14 @@ parameters: - name: backend_storage_container type: string - default: "portertf" - name: backend_storage_resource_group type: string - default: "devops-days-msp" - - name: server-name + - name: server_name type: string - - name: database-name + - name: database_name type: string outputs: @@ -53,6 +50,7 @@ outputs: type: string - name: STORAGE_ACCOUNT_KEY type: string + sensitive: true images: websvc: @@ -62,9 +60,11 @@ images: digest: "sha256:85b1a9b4b60a4cf73a23517dad677e64edf467107fa7d58fce9c50e6a3e4c914" install: - - azure: + # TODO: utilize the workshop-tf bundle as a dependency? + - arm: description: "Create an Azure Storage Account" - type: storage + type: arm + template: "arm/storage.json" name: "{{ bundle.parameters.backend_storage_account }}" resourceGroup: "{{ bundle.parameters.backend_storage_resource_group }}" parameters: @@ -83,23 +83,23 @@ install: container_name: "{{ bundle.parameters.backend_storage_container }}" access_key: "{{ bundle.outputs.STORAGE_ACCOUNT_KEY }}" vars: - backend_storage_account: "{{ bundle.parameters.backend_storage_account }}" + backend_storage_resource_group: "{{ bundle.parameters.backend_storage_resource_group }}" subscription_id: "{{bundle.credentials.subscription_id}}" tenant_id: "{{bundle.credentials.tenant_id}}" client_id: "{{bundle.credentials.client_id}}" client_secret: "{{bundle.credentials.client_secret}}" - server-name: "{{bundle.parameters.server-name}}" - database-name: "{{bundle.parameters.database-name}}" + server_name: "{{bundle.parameters.server_name}}" + database_name: "{{bundle.parameters.database_name}}" outputs: - name: "mysql_fqdn" - - azure: + - arm: description: "Create an ACI Instance" type: arm template: "arm/aci.json" - name: "{{ bundle.parameters.server-name }}-aci" + name: "{{ bundle.parameters.server_name }}-aci" resourceGroup: "{{ bundle.parameters.backend_storage_resource_group }}" parameters: - containerName: "{{ bundle.parameters.server-name }}-aci-go" + containerName: "{{ bundle.parameters.server_name }}-aci-go" location: "{{ bundle.parameters.location }}" imageName: "{{bundle.images.websvc.repository}}@{{bundle.images.websvc.digest}}" mysqlFQDN: "{{bundle.outputs.mysql_fqdn}}" diff --git a/workshop/porter-tf-aci/azure/bundle/terraform/main.tf b/workshop/porter-tf-aci/azure/bundle/terraform/main.tf index eb9afa76e..c4ecda7c3 100644 --- a/workshop/porter-tf-aci/azure/bundle/terraform/main.tf +++ b/workshop/porter-tf-aci/azure/bundle/terraform/main.tf @@ -1,12 +1,12 @@ provider "azurerm" { - version = "~>1.5" - subscription_id = "${var.subscription_id}" - client_id = "${var.client_id}" - client_secret = "${var.client_secret}" - tenant_id = "${var.tenant_id}" + version = "~>1.41.0" + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id } terraform { - required_version = "~>0.11" + required_version = "~>0.12.17" backend "azurerm" {} } diff --git a/workshop/porter-tf-aci/azure/bundle/terraform/mysql.tf b/workshop/porter-tf-aci/azure/bundle/terraform/mysql.tf index 0c019f8c7..bf46cdb03 100644 --- a/workshop/porter-tf-aci/azure/bundle/terraform/mysql.tf +++ b/workshop/porter-tf-aci/azure/bundle/terraform/mysql.tf @@ -1,25 +1,20 @@ resource "random_string" "password" { length = 16 special = true - override_special = "/@\" " + override_special = "/@£$" } resource "random_string" "name" { length = 5 - special = false + special = false } resource "azurerm_mysql_server" "bundle" { - name = "${var.server-name}" - location = "EastUS" - resource_group_name = "devops-days-msp" + name = var.server_name + location = var.location + resource_group_name = var.backend_storage_resource_group - sku { - name = "B_Gen5_2" - capacity = 2 - tier = "Basic" - family = "Gen5" - } + sku_name = "B_Gen5_2" storage_profile { storage_mb = 5120 @@ -27,16 +22,16 @@ resource "azurerm_mysql_server" "bundle" { geo_redundant_backup = "Disabled" } - administrator_login = "${var.mysql-admin}" - administrator_login_password = "${random_string.password.result}" + administrator_login = var.mysql_admin + administrator_login_password = random_string.password.result version = "5.7" ssl_enforcement = "Disabled" } resource "azurerm_mysql_database" "bundle" { - name = "${var.database_name}" - resource_group_name = "devops-days-msp" - server_name = "${azurerm_mysql_server.bundle.name}" + name = var.database_name + resource_group_name = var.backend_storage_resource_group + server_name = azurerm_mysql_server.bundle.name charset = "utf8" collation = "utf8_unicode_ci" } diff --git a/workshop/porter-tf-aci/azure/bundle/terraform/outputs.tf b/workshop/porter-tf-aci/azure/bundle/terraform/outputs.tf index 3bc6541a6..57fc1c306 100644 --- a/workshop/porter-tf-aci/azure/bundle/terraform/outputs.tf +++ b/workshop/porter-tf-aci/azure/bundle/terraform/outputs.tf @@ -1,3 +1,3 @@ output "mysql_fqdn" { - value = "${azurerm_mysql_server.bundle.fqdn}" + value = azurerm_mysql_server.bundle.fqdn } \ No newline at end of file diff --git a/workshop/porter-tf-aci/azure/bundle/terraform/params.tf b/workshop/porter-tf-aci/azure/bundle/terraform/params.tf index f3e18e54d..b34c3443f 100644 --- a/workshop/porter-tf-aci/azure/bundle/terraform/params.tf +++ b/workshop/porter-tf-aci/azure/bundle/terraform/params.tf @@ -7,21 +7,15 @@ variable "location" { default = "EastUS" } -variable "backend_storage_account" {} - variable "backend_storage_resource_group" { default = "devops-days-msp" - -} -variable "backend_storage_container" { - default = "tf-storage" } -variable "server-name" { +variable "server_name" { default = "mysql-bundle" } -variable "mysql-admin" { +variable "mysql_admin" { default = "myadmin" } diff --git a/workshop/porter-tf/azure/README.md b/workshop/porter-tf/azure/README.md index e9af9fbab..2a26ee79a 100644 --- a/workshop/porter-tf/azure/README.md +++ b/workshop/porter-tf/azure/README.md @@ -22,18 +22,16 @@ Review the `porter.yaml` to see what each of these sections looks like. ## Update the porter.yaml -Now, update the `porter.yaml` and change the following values: +Now, update the `porter.yaml` and change the following value: ``` -invocationImage: deislabs/porter-workshop-tf:v0.1.0 -tag: deislabs/porter-workshop-tf-bundle:v0.1.0 +tag: getporter/orkshop-tf:v0.1.0 ``` -For each of these, change the Docker-like reference to point to your own Docker registry. For example, if my Docker user name is `jeremyrickard`, I'd change that these lines to: +Change the Docker-like reference to point to your own Docker registry. For example, if my Docker user name is `jeremyrickard`, I'd change that these lines to: ``` -invocationImage: jeremyrickard/porter-workshop-tf:v0.1.0 -tag: jeremyrickard/porter-workshop-tf-bundle:v0.1.0 +tag: jeremyrickard/workshop-tf:v0.1.0 ``` ## Build The Bundle! @@ -98,16 +96,18 @@ This command will generate a new `credential set` that maps our environment vari Now, you're ready to install the bundle. Replace `` with a username like `carolynvs`. ``` -porter install -c porter-workshop-tf \ - --param server-name=sql \ - --param backend_storage_account=storage \ - --param database-name=testworkshop +porter install -c workshop-tf \ + --param server_name=sql \ + --param database_name=testworkshop \ + --param backend_storage_account=storagetf \ + --param backend_storage_container=-workshop-tf \ + --param backend_storage_resource_group=-workshop-tf ``` ### View the Outputs -Now that you've installed the bundle, you can view any outputs that were created with the `porter bundle` command. +Now that you've installed the bundle, you can view any outputs that were created with the `porter instance show` command. ``` -porter bundle show porter-workshop-tf +porter instance show workshop-tf ``` diff --git a/workshop/porter-tf/azure/arm/storage.json b/workshop/porter-tf/azure/arm/storage.json new file mode 100644 index 000000000..e479f7f1e --- /dev/null +++ b/workshop/porter-tf/azure/arm/storage.json @@ -0,0 +1,60 @@ +{ + "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "location": { + "type": "string" + }, + "storageAccountName": { + "type": "string" + }, + "storageContainerName": { + "type": "string" + } + }, + "resources": [ + { + "name": "[parameters('storageAccountName')]", + "type": "Microsoft.Storage/storageAccounts", + "apiVersion": "2018-07-01", + "sku": { + "name": "Standard_GRS" + }, + "kind": "StorageV2", + "location": "[parameters('location')]", + "identity": { + "type": "SystemAssigned" + }, + "properties": { + "encryption": { + "services": { + "blob": { + "enabled": true + } + }, + "keySource": "Microsoft.Storage" + }, + "supportsHttpsTrafficOnly": true + }, + "resources": [ + { + "name": "[concat(parameters('storageAccountName'), '/default/', parameters('storageContainerName'))]", + "dependsOn": [ + "[parameters('storageAccountName')]" + ], + "type": "Microsoft.Storage/storageAccounts/blobServices/containers", + "apiVersion": "2018-07-01", + "properties": { + "publicAccess": "None" + } + } + ] + } + ], + "outputs": { + "STORAGE_ACCOUNT_KEY": { + "type": "string", + "value": "[first(listKeys(parameters('storageAccountName'), '2018-02-01').keys).value]" + } + } +} \ No newline at end of file diff --git a/workshop/porter-tf/azure/porter.yaml b/workshop/porter-tf/azure/porter.yaml index 9d4868f7b..df3eb0a61 100644 --- a/workshop/porter-tf/azure/porter.yaml +++ b/workshop/porter-tf/azure/porter.yaml @@ -3,11 +3,10 @@ mixins: - exec - terraform -name: porter-workshop-tf +name: workshop-tf version: 0.1.0 description: "An example using Porter to build the from scratch bundle" -invocationImage: deislabs/porter-workshop-tf:v0.1.0 -tag: deislabs/porter-workshop-tf-bundle:v0.1.0 +tag: getporter/workshop-tf:v0.1.0 ## This section defines what credentials are used for the bundle. In this case, we are operating ## against Azure, so we need some Azure Service Principal information. @@ -36,26 +35,26 @@ parameters: - name: backend_storage_container type: string - default: "portertf" - name: backend_storage_resource_group type: string - default: "devops-days-msp" - - name: server-name + - name: server_name type: string - - name: database-name + - name: database_name type: string outputs: - name: STORAGE_ACCOUNT_KEY type: string + sensitive: true install: - - azure: + - arm: description: "Create an Azure Storage Account" - type: storage + type: arm + template: "arm/storage.json" name: "{{ bundle.parameters.backend_storage_account }}" resourceGroup: "{{ bundle.parameters.backend_storage_resource_group }}" parameters: @@ -74,13 +73,13 @@ install: container_name: "{{ bundle.parameters.backend_storage_container }}" access_key: "{{ bundle.outputs.STORAGE_ACCOUNT_KEY }}" vars: - backend_storage_account: "{{ bundle.parameters.backend_storage_account }}" + backend_storage_resource_group: "{{ bundle.parameters.backend_storage_resource_group }}" subscription_id: "{{bundle.credentials.subscription_id}}" tenant_id: "{{bundle.credentials.tenant_id}}" client_id: "{{bundle.credentials.client_id}}" client_secret: "{{bundle.credentials.client_secret}}" - server-name: "{{bundle.parameters.server-name}}" - database-name: "{{bundle.parameters.database-name}}" + server_name: "{{bundle.parameters.server_name}}" + database_name: "{{bundle.parameters.database_name}}" upgrade: - exec: diff --git a/workshop/porter-tf/azure/terraform/main.tf b/workshop/porter-tf/azure/terraform/main.tf index eb9afa76e..c4ecda7c3 100644 --- a/workshop/porter-tf/azure/terraform/main.tf +++ b/workshop/porter-tf/azure/terraform/main.tf @@ -1,12 +1,12 @@ provider "azurerm" { - version = "~>1.5" - subscription_id = "${var.subscription_id}" - client_id = "${var.client_id}" - client_secret = "${var.client_secret}" - tenant_id = "${var.tenant_id}" + version = "~>1.41.0" + subscription_id = var.subscription_id + client_id = var.client_id + client_secret = var.client_secret + tenant_id = var.tenant_id } terraform { - required_version = "~>0.11" + required_version = "~>0.12.17" backend "azurerm" {} } diff --git a/workshop/porter-tf/azure/terraform/mysql.tf b/workshop/porter-tf/azure/terraform/mysql.tf index 0c019f8c7..bf46cdb03 100644 --- a/workshop/porter-tf/azure/terraform/mysql.tf +++ b/workshop/porter-tf/azure/terraform/mysql.tf @@ -1,25 +1,20 @@ resource "random_string" "password" { length = 16 special = true - override_special = "/@\" " + override_special = "/@£$" } resource "random_string" "name" { length = 5 - special = false + special = false } resource "azurerm_mysql_server" "bundle" { - name = "${var.server-name}" - location = "EastUS" - resource_group_name = "devops-days-msp" + name = var.server_name + location = var.location + resource_group_name = var.backend_storage_resource_group - sku { - name = "B_Gen5_2" - capacity = 2 - tier = "Basic" - family = "Gen5" - } + sku_name = "B_Gen5_2" storage_profile { storage_mb = 5120 @@ -27,16 +22,16 @@ resource "azurerm_mysql_server" "bundle" { geo_redundant_backup = "Disabled" } - administrator_login = "${var.mysql-admin}" - administrator_login_password = "${random_string.password.result}" + administrator_login = var.mysql_admin + administrator_login_password = random_string.password.result version = "5.7" ssl_enforcement = "Disabled" } resource "azurerm_mysql_database" "bundle" { - name = "${var.database_name}" - resource_group_name = "devops-days-msp" - server_name = "${azurerm_mysql_server.bundle.name}" + name = var.database_name + resource_group_name = var.backend_storage_resource_group + server_name = azurerm_mysql_server.bundle.name charset = "utf8" collation = "utf8_unicode_ci" } diff --git a/workshop/porter-tf/azure/terraform/outputs.tf b/workshop/porter-tf/azure/terraform/outputs.tf index 3bc6541a6..57fc1c306 100644 --- a/workshop/porter-tf/azure/terraform/outputs.tf +++ b/workshop/porter-tf/azure/terraform/outputs.tf @@ -1,3 +1,3 @@ output "mysql_fqdn" { - value = "${azurerm_mysql_server.bundle.fqdn}" + value = azurerm_mysql_server.bundle.fqdn } \ No newline at end of file diff --git a/workshop/porter-tf/azure/terraform/params.tf b/workshop/porter-tf/azure/terraform/params.tf index f3e18e54d..b34c3443f 100644 --- a/workshop/porter-tf/azure/terraform/params.tf +++ b/workshop/porter-tf/azure/terraform/params.tf @@ -7,21 +7,15 @@ variable "location" { default = "EastUS" } -variable "backend_storage_account" {} - variable "backend_storage_resource_group" { default = "devops-days-msp" - -} -variable "backend_storage_container" { - default = "tf-storage" } -variable "server-name" { +variable "server_name" { default = "mysql-bundle" } -variable "mysql-admin" { +variable "mysql_admin" { default = "myadmin" }