Exercise - Manage secrets in your ARM template

Completed

In the previous exercise, you ran a basic Azure Resource Manager (ARM) template that provisions a Linux virtual machine. In this part, you follow a similar process.

This time, instead of passing the password as a parameter, you store the password in Azure Key Vault. To enable the ARM template to access the password, you create a parameter file that references the key vault secret in your subscription.

Deploy Azure Key Vault

Note

Due to limitations with the sandbox, here you create a key vault in Azure Key Vault from the Azure portal. Normally, you would use the New-AzKeyVault cmdlet to create a key vault from Azure PowerShell.

Create a key vault and allow deploy time access. To do so:

  1. Create a PowerShell variable that holds the key vault name:

    $KVNAME="tailwind-secrets" + (Get-Random -Count 1 -Maximum 9999999)
    
  2. Run $KVNAME to print its value:

    $KVNAME
    

    Your output resembles this (the number you see will be different):

    tailwind-secrets5978564
    

    Copy the value somewhere convenient for the next step.

  3. Sign in to the Azure portal by using the same account you activated the sandbox with.

  4. On the Azure portal menu or from the Home page, select Create a resource.

  5. In the search box, enter Key Vault.

  6. Select Key Vault from the list, and select Create to start configuring the key vault.

  7. In the creation pane, specify these values:

    1. Resource group: resource group name.
    2. Key vault name: Your value of $KVNAME, for example, tailwind-secrets5978564.
  8. Select Review + create.

  9. Select Create. This should take a minute or so. When the resource has been created, select Go to resource.

  10. Select Access Configuration under Settings. Enable the option Azure Resource Manager for template deployment and select Apply.

  11. From your PowerShell session, run the ConvertTo-SecureString cmdlet and assign the result to the secretSecureString variable:

    $secretSecureString = ConvertTo-SecureString 'insecurepassword123!' -AsPlainText -Force
    
  12. Run the following Set-AzKeyVaultSecret command to create a secret in the key vault. The secret is named vmPassword, with the value insecurepassword123!:

    $secret = Set-AzKeyVaultSecret -VaultName $KVNAME -Name vmPassword -SecretValue $secretSecureString
    

Create the parameter file

Here, you create a parameter file that contains the VM's name, the administrator username, and a reference to the VM password in the key vault.

You can pass parameters to templates from the command line. Recall that a parameter file is an alternative way to pass parameters to your ARM template during deployment. A parameter file enables you to access key vault secrets from your template.

  1. Run the following Get-AzKeyVault command to print your key vault ID:

    Get-AzKeyVault -VaultName $KVNAME | Select-Object -ExpandProperty ResourceId
    

    The output resembles this:

    /subscriptions/7c7df858-93a0-4f38-8990-304c836a4e8d/resourceGroups/<rgn>[resource group name]</rgn>/providers/Microsoft.KeyVault/vaults/tailwind-secrets3020
    

    Note the output for the next step.

  2. In Visual Studio Code, create a file named azuredeploy.parameters.json in the same directory that contains azuredeploy.json.

  3. Add these contents to azuredeploy.parameters.json:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "adminUsername": {
          "value": "azureuser"
        },
        "vmName": {
          "value": "vm2"
        },
        "adminPasswordOrKey": {
          "reference": {
             "keyVault": {
             "id": ""
             },
             "secretName": "vmPassword"
          }
        }
      }
    }
    
  4. Replace the value of id (the empty string) with the value you copied in the previous step. Then save the file.

Deploy a Linux VM

Here, you deploy the same ARM template that you deployed in the previous exercise. This time, you provide the parameter file that references the VM password in the key vault.

  1. Run the following command New-AzResourceGroupDeployment:

    New-AzResourceGroupDeployment `
      -TemplateFile "./azuredeploy.json" `
      -TemplateParameterFile "./azuredeploy.parameters.json" `
      -dnsLabelPrefix ("vm2-" + (Get-Random -Count 1 -Maximum 9999999))
    

    In the previous exercise, you provided each key-value pair directly from the command line. Here, you specify "./azuredeploy.parameters.json" to provide your parameters file.

    The dnsLabelPrefix is set to vm2- followed by a random number. This is required to ensure that the DNS name differs from the DNS name you used in the previous exercise.

Verify deployment

Verify that the VM is provisioned and is connectable over SSH. To do so:

  1. Run the Invoke-Expression command to connect to the VM via SSH:

    Invoke-Expression (Get-AzResourceGroupDeployment -Name azuredeploy -ResourceGroupName <rgn>your resource group</rgn>).outputs.sshCommand.value
    

    When prompted, enter yes to continue connecting. Then enter the administrator password, insecurepassword123!.

    Important

    In practice, keep passwords safe. You can also use public key authentication, which is typically more secure than using passwords.

  2. From your SSH connection to the VM, run hostname to print the VM's hostname:

    hostname
    

    You see the VM's internal hostname, vm1:

    vm2
    
  3. Run exit to leave your SSH session.

    exit
    

Nice work! You've extended your deployment to include a parameters file that reads secret information from Key Vault.

Deploy Azure Key Vault

In Azure Key Vault, create a key vault and add the VM password as a secure secret. To do so:

  1. Create a Bash variable that holds the key vault name.

    KVNAME=tailwind-secrets$RANDOM
    

    Key vault names must be unique. The $RANDOM part ensures that the key vault name ends in a random series of numbers.

  2. Run the following az keyvault create command to create the key vault:

    az keyvault create \
      --name $KVNAME \
      --enabled-for-template-deployment true
    

    The --enabled-for-template-deployment argument permits the Azure Resource Manager (ARM) template to retrieve secrets from the key vault.

  3. Run the following az keyvault secret set command to create a secret in the key vault. The secret is named vmPassword, with the value insecurepassword123!:

    az keyvault secret set \
      --vault-name $KVNAME \
      --name vmPassword \
      --value 'insecurepassword123!'
    

Create the parameter file

Here, you create a parameter file that contains the VM's name, the administrator username, and a reference to the VM password in the key vault.

You can pass parameters to templates from the command line. Recall that a parameter file is an alternative way to pass parameters to your ARM template during deployment. A parameter file enables you to access key vault secrets from your template.

  1. Run the following az keyvault show command to print your key vault ID:

    az keyvault show \
      --name $KVNAME \
      --query id \
      --output tsv
    

    The output resembles this:

    /subscriptions/7c7df858-93a0-4f38-8990-304c836a4e8d/resourceGroups/<rgn>[resource group name]</rgn>/providers/Microsoft.KeyVault/vaults/tailwind-secrets3020
    

    Note the output for the next step.

  2. In Visual Studio Code, create a file named azuredeploy.parameters.json in the same directory that contains azuredeploy.json.

  3. Add these contents to azuredeploy.parameters.json:

    {
      "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
      "contentVersion": "1.0.0.0",
      "parameters": {
        "adminUsername": {
          "value": "azureuser"
        },
        "vmName": {
          "value": "vm2"
        },
        "adminPasswordOrKey": {
          "reference": {
             "keyVault": {
             "id": ""
             },
             "secretName": "vmPassword"
          }
        }
      }
    }
    
  4. Replace the value of id (the empty string) with the value you copied in the previous step. Then save the file.

Deploy a Linux VM

Here, you deploy the same ARM template that you deployed in the previous exercise. This time, you provide the parameter file that references the VM password in the key vault.

Run the following az deployment group create command to deploy the template:

az deployment group create \
  --template-file azuredeploy.json \
  --parameters @azuredeploy.parameters.json dnsLabelPrefix="vm2-$RANDOM"

In the previous exercise, you provided each key-value pair in the --parameters argument. Here, you specify @azuredeploy.parameters.json to provide your parameters file.

The dnsLabelPrefix is set to vm2- followed by a random number. This is required to ensure that the DNS name differs from the DNS name you used in the previous exercise.

Verify the deployment

As you did in the previous exercise, verify that the VM is provisioned and is connectable over SSH. For brevity, this time you'll skip some of the intermediary steps.

  1. Run the following to connect to your VM over SSH:

    $(az deployment group show \
      --name azuredeploy \
      --query properties.outputs.sshCommand.value \
      --output tsv)
    

    When prompted, enter yes to continue connecting. Then enter the administrator password, insecurepassword123!.

  2. From your SSH connection to the VM, run hostname to print the VM's hostname:

    hostname
    

    You see the VM's internal hostname, vm2:

    vm2
    
  3. Run exit to leave your SSH session.

    exit
    

Nice work! You've extended your deployment to include a parameters file that reads secret information from Key Vault.