Επεξεργασία

Κοινή χρήση μέσω


Use Azure Key Vault to pass a secret from a key vault as a parameter during Bicep deployment

Instead of entering a secure value like a password directly into your Bicep file or parameters file, you can retrieve the value from an Azure Key Vault during a deployment. When a module expects a string parameter with a secure:true modifier, you can use the getSecret function to obtain a key vault secret. The value is never exposed because you only reference its key vault ID.

Important

This article focuses on how to pass a sensitive value as a template parameter. When the secret is passed as a parameter, the key vault can exist in a different subscription than the resource group to which you're deploying.

This article doesn't cover how to set a virtual-machine property to a certificate's URL in a key vault. For a quickstart template of that scenario, see WinRM on a Windows VM.

Deploy key vaults and secrets

To access a key vault during Bicep deployment, set enabledForTemplateDeployment on the key vault to true.

If you already have a key vault, make sure it permits template deployments.

az keyvault update  --name ExampleVault --enabled-for-template-deployment true

To create a new key vault and add a secret, use:

az group create --name ExampleGroup --location centralus
az keyvault create \
  --name ExampleVault \
  --resource-group ExampleGroup \
  --location centralus \
  --enabled-for-template-deployment true
az keyvault secret set --vault-name ExampleVault --name "ExamplePassword" --value "hVFkk965BuUv"

As the owner of the key vault, you automatically have access to create secrets. If the user working with secrets isn't the owner of the key vault, grant access with:

az keyvault set-policy \
  --upn <user-principal-name> \
  --name ExampleVault \
  --secret-permissions set delete get list

For more information about creating key vaults and adding secrets, see:

Grant access to the secrets

The user who deploys the Bicep file must have the Microsoft.KeyVault/vaults/deploy/action permission for the scope of the resource group and key vault. The Owner and Contributor roles both grant this access. If you created the key vault, you're the owner and have the permission.

The following procedure shows how to create a role with the minimum permission and how to assign the user.

  1. Create a custom JSON file with a role definition:

    {
      "Name": "Key Vault Bicep deployment operator",
      "IsCustom": true,
      "Description": "Lets you deploy a Bicep file with the access to the secrets in the Key Vault.",
      "Actions": [
        "Microsoft.KeyVault/vaults/deploy/action"
      ],
      "NotActions": [],
      "DataActions": [],
      "NotDataActions": [],
      "AssignableScopes": [
        "/subscriptions/aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"
      ]
    }
    

    Replace "00000000-0000-0000-0000-000000000000" with the subscription ID.

  2. USe the JSON file to create the new role:

    az role definition create --role-definition "<path-to-role-file>"
    az role assignment create \
      --role "Key Vault Bicep deployment operator" \
      --scope /subscriptions/<Subscription-id>/resourceGroups/<resource-group-name> \
      --assignee <user-principal-name>
    

    The samples assign the custom role to the user on the resource-group level.

When using a key vault with the Bicep file for a Managed Application, you must grant access to the Appliance Resource Provider service principal. For more information, see Access Key Vault secret when deploying Azure Managed Applications.

Retrieve secrets in Bicep file

You can use the getSecret function in Bicep files to obtain a key vault secret. Note that the getSecret function is exclusively applicable to a Microsoft.KeyVault/vaults resource. Additionally, it's restricted to usage within the params section of a module and can only be used with parameters with the @secure() decorator.

Another function called az.getSecret() function can be used in Bicep parameters files to retrieve key vault secrets. For more information, see Retrieve secrets in parameters file.

Since the getSecret function can only be used in the params section of a module, create a sql.bicep file in the same directory as the main.bicep file with the following content:

param sqlServerName string
param location string = resourceGroup().location
param adminLogin string

@secure()
param adminPassword string

resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
  name: sqlServerName
  location: location
  properties: {
    administratorLogin: adminLogin
    administratorLoginPassword: adminPassword
    version: '12.0'
  }
}

The adminPassword parameter has a @secure() decorator in the preceding file.

The following Bicep file consumes sql.bicep as a module. The Bicep file references an existing key vault, calls the getSecret function to retrieve the key vault secret, and then passes the value as a parameter to the module:

param sqlServerName string
param adminLogin string

param subscriptionId string
param kvResourceGroup string
param kvName string

resource kv 'Microsoft.KeyVault/vaults@2023-07-01' existing = {
  name: kvName
  scope: resourceGroup(subscriptionId, kvResourceGroup )
}

module sql './sql.bicep' = {
  name: 'deploySQL'
  params: {
    sqlServerName: sqlServerName
    adminLogin: adminLogin
    adminPassword: kv.getSecret('vmAdminPassword')
  }
}

Retrieve secrets in parameters file

If you don't want to use a module, you can retrieve key vault secrets in a parameters file. However, the approach varies depending on whether you're using a JSON or Bicep parameters file.

The following Bicep file deploys a SQL server that includes an administrator password. While the password parameter is set to a secure string, Bicep doesn't specify the origin of that value:

param sqlServerName string
param location string = resourceGroup().location
param adminLogin string

@secure()
param adminPassword string

resource sqlServer 'Microsoft.Sql/servers@2023-08-01-preview' = {
  name: sqlServerName
  location: location
  properties: {
    administratorLogin: adminLogin
    administratorLoginPassword: adminPassword
    version: '12.0'
  }
}

Next, create a parameters file for the preceding Bicep file.

Bicep parameters file

The az.getSecret function can be used in a .bicepparam file to retrieve the value of a secret from a key vault:

using './main.bicep'

param sqlServerName = '<your-server-name>'
param adminLogin = '<your-admin-login>'
param adminPassword = az.getSecret('<subscription-id>', '<rg-name>', '<key-vault-name>', '<secret-name>', '<secret-version>')

JSON parameters file

In a JSON parameters file, specify a parameter that matches the name of the parameter in the Bicep file. For the parameter value, reference the secret from the key vault; you do this by passing the resource identifier of the key vault and the name of the secret. In the following parameters file, the key vault secret must already exist, and you provide a static value for its resource ID:

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminLogin": {
      "value": "<your-admin-login>"
    },
    "adminPassword": {
      "reference": {
        "keyVault": {
          "id": "/subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.KeyVault/vaults/<key-vault-name>"
        },
        "secretName": "ExamplePassword"
      }
    },
    "sqlServerName": {
      "value": "<your-server-name>"
    }
  }
}

If you need to use a version of the secret other than the current one, include a secretVersion property:

"secretName": "ExamplePassword",
"secretVersion": "cd91b2b7e10e492ebb870a6ee0591b68"

Next steps