Monday, May 3, 2021

Secrets in ARM templates

 You may want to use a password in a template (let’s say user password of a VM or admin password of a SQL-server). Putting the password in your template, which is located in your source code repository, is not according to security guidelines.

One option to secure your strings would be to put them in KeyVault as a Secret and refer them from either paramters.json or in your main.json where it refer to a linked template.

First you need to set Azure Resource Manager for template deployment on checked within Access Policies of the keyvault where the template is refering to.

Deploying Templates

You could start a deployment right from the portal by adding a resource of type Template Deployment.

Another option would be using az CLI:

az deployment group create --resource-group newgrp1 --template-file main.json --parameters parameters.json

Or you could deploy it from your CD-pipeline locatedin Azure Devops.

Using Secured Secrets in Parameters.json

The following example refers to a secret called vmpassword within a keyvault called demovault10001 ie. located in newgrp1 resource group:

{ "$schema": "", "contentVersion": "", "parameters": { "adminUsername": { "value": "admin" }, "adminPassword": { "reference": { "keyVault": { "id": "/subscriptions/baaa99b3-1d19-4c5e-90e1-39d55de5fc6e/resourceGroups/newgrp1/providers/Microsoft.KeyVault/vaults/demovault10001" }, "secretName": "vmpassword" } } } }

Using Secured Secrets in main.json

Similar to above example we can refer to a secured password by setting the keyvault id and the secret name. In the following example we use this to pass the adminPassword as a parameter to nested template.

 { "$schema": "", "contentVersion": "", "parameters": { "location": { "type": "string", "defaultValue": "[resourceGroup().location]", "metadata": { "description": "The location where the resources will be deployed." } }, "vaultName": { "type": "string", "defaultValue":"appvault10001" }, "secretName": { "type": "string", "defaultValue":"vmaccountpassword" }, "vaultResourceGroupName": { "type": "string", "defaultValue":"newgrp1" }, "vaultSubscription": { "type": "string", "defaultValue": "[subscription().subscriptionId]", "metadata": { "description": "The name of the subscription that contains the keyvault." } } }, "resources": [ { "type": "Microsoft.Resources/deployments", "apiVersion": "2018-05-01", "name": "dynamicSecret", "properties": { "mode": "Incremental", "expressionEvaluationOptions": { "scope": "inner" }, "template": { "$schema": "", "contentVersion": "", "parameters": { "adminLogin": { "type": "string" }, "adminPassword": { "type": "securestring" }, "location": { "type": "string" } }, "variables": { "sqlServerName": "[concat('sql-', uniqueString(resourceGroup().id, 'sql'))]" }, "resources": [ { "type": "Microsoft.Sql/servers", "apiVersion": "2018-06-01-preview", "name": "[variables('sqlServerName')]", "location": "[parameters('location')]", "properties": { "administratorLogin": "[parameters('adminLogin')]", "administratorLoginPassword": "[parameters('adminPassword')]" } } ], "outputs": { "sqlFQDN": { "type": "string", "value": "[reference(variables('sqlServerName')).fullyQualifiedDomainName]" } } }, "parameters": { "location": { "value": "[parameters('location')]" }, "adminLogin": { "value": "demousr" }, "adminPassword": { "reference": { "keyVault": { "id": "[resourceId(parameters('vaultSubscription'), parameters('vaultResourceGroupName'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]" }, "secretName": "[parameters('secretName')]" } } } } } ], "outputs": { } }