When creating new resource in Azure that have secrets like passwords or ssl certificates you can securely save them in the Key Vault and get them from the Key Vault when you deploy. Only the people who need access to the secrets can read and write them to the Key Vault. In a infrastructure as code scenario the secrets are supplied when deploying your templates to Azure. The code it self will be free of secrets.

To accomplish this you need to do following:

  • Deploy a Key Vault
  • Add the secret to the Key Vault
  • Create a ARM template that uses the secret on deployment

Deploy a Key Vault
When you need to access the Key Vault from you deployment, you need to set the enabledForTemplateDeployment to true. The following ARM template will create a Key Vault that is enable for deployments:

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "keyVaultName": {
      "type": "string",
      "metadata": {
        "description": "Name of the vault"
      }
    },
    "tenantId": {
      "type": "string",
      "metadata": {
        "description": "Tenant Id for the subscription and use assigned access to the vault. Available from the Get-AzureRMSubscription PowerShell cmdlet"
      }
    }
  },
  "variables":{
     "skuFamily": "A",
     "skuName": "standard"
  },
  "resources": [
    {
      "type": "Microsoft.KeyVault/vaults",
      "name": "[parameters('keyVaultName')]",
      "apiVersion": "2015-06-01",
      "location": "[resourceGroup().location]",
      "properties": {
        "sku": {
          "name": "[variables('skuName')]",
          "family": "[variables('skuFamily')]"
        },
"accessPolicies": [
],
        "tenantId": "[parameters('tenantId')]",
        "enabledForDeployment": false,
        "enabledForTemplateDeployment": true,
        "enabledForVolumeEncryption": false
      }
    }
  ]
}

Add secret to the Key Vault
Secret can be added to the Key Vault with an ARM template, with Powershell or you can add it in the portal.

     {
            "type": "secrets",
            "name": "[parameters('secretName')]",
            "apiVersion": "2015-06-01",
            "properties": {
                "value": "[parameters('secretValue')]"
            },
            "dependsOn": [
                "[concat('Microsoft.KeyVault/vaults/', parameters('keyVaultName'))]"
            ]
        }

Create a ARM template that uses the secret on deployment
The last step is using the secrets in your arm templates. This can be done by making a reference to your key vault in the parameters:

{
    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "password": {
        "reference": {
          "keyVault": {
            "id": "/subscriptions/{guid}/resourceGroups/{group-name}/providers/Microsoft.KeyVault/vaults/{vault-name}"
          },
          "secretName": "adminPassword"
        }
      },
      "username": {
        "value": "exampleadmin"
      }
    }
}

This way of referencing the password is to static for a infrastructure as code scenario. The next step is to get the secret dynacly from the Key Vault in the environment you are deploying into. This can be done by giving the resourceGroupName, vaultName and secretName as parameters.

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "vaultName": {
        "type": "string"
      },
      "secretName": {
        "type": "string"
      },
      "keyVaultResourceGroup": {
        "type": "string"
      }
    },
    "resources": [
    {
      "apiVersion": "2015-01-01",
      "name": "nestedTemplate",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "incremental",
        "templateLink": {
          "uri": "		<linked template uri>",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "password": {
            "reference": {
              "keyVault": {
                "id": "[concat(subscription().id,'/resourceGroups/',parameters('keyVaultResourceGroup'), '/providers/Microsoft.KeyVault/vaults/', parameters('vaultName'))]"
              },
              "secretName": "[parameters('secretName')]"
            }
          }
        }
      }
    }],
    "outputs": {}
}

This way you are able to get the secrets from the Key Vault in the subscription your are deploying into.

Some extra information can be found at: resource-manager-keyvault-parameter