Usar o Azure Key Vault para passar o valor do parâmetro seguro durante a implantação do Bicep

Em vez de colocar um valor seguro (como uma senha) diretamente em seu arquivo Bicep ou arquivo de parâmetros, você pode recuperar o valor de um Cofre de Chaves do Azure durante uma implantação. Quando um módulo espera um string parâmetro com secure:true modificador, você pode usar a função getSecret para obter um segredo do cofre de chaves. O valor nunca é exposto porque você só faz referência ao ID do cofre da chave.

Importante

Este artigo se concentra em como passar um valor confidencial como um parâmetro de modelo. Quando o segredo é passado como um parâmetro, o cofre de chaves pode existir em uma assinatura diferente do grupo de recursos no qual você está implantando.

Este artigo não aborda como definir uma propriedade de máquina virtual para a URL de um certificado em um cofre de chaves. Para obter um modelo de início rápido desse cenário, consulte Instalar um certificado do Cofre de Chaves do Azure em uma máquina virtual.

Implantar cofres de chaves e segredos

Para acessar um cofre de chaves durante a implantação do Bicep, defina enabledForTemplateDeployment no cofre de chaves como true.

Se você já tiver um cofre de chaves, verifique se ele permite implantações de modelos.

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

Para criar um novo cofre de chaves e adicionar um segredo, 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"

Como proprietário do cofre de chaves, você automaticamente tem acesso para criar segredos. Se o usuário que trabalha com segredos não for o proprietário do cofre de chaves, conceda acesso com:

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

Para obter mais informações sobre como criar cofres de chaves e adicionar segredos, consulte:

Conceder acesso aos segredos

O usuário que implanta o arquivo Bicep deve ter a Microsoft.KeyVault/vaults/deploy/action permissão para o escopo do grupo de recursos e do cofre de chaves. As funções Proprietário e Colaborador concedem esse acesso. Se você criou o cofre de chaves, você é o proprietário e tem a permissão.

O procedimento a seguir mostra como criar uma função com a permissão mínima e como atribuir o usuário.

  1. Crie um arquivo JSON de definição de função personalizada:

    {
      "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"
      ]
    }
    

    Substitua "00000000-0000-0000-0000-0000000000000" pelo ID da assinatura.

  2. Crie a nova função usando o arquivo JSON:

    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>
    

    Os exemplos atribuem a função personalizada ao usuário no nível do grupo de recursos.

Ao usar um cofre de chaves com o arquivo Bicep para um Aplicativo Gerenciado, você deve conceder acesso à entidade de serviço do Provedor de Recursos do Aparelho. Para obter mais informações, consulte Segredo do Cofre da Chave de Acesso ao implantar Aplicativos Gerenciados do Azure.

Recuperar segredos no arquivo Bicep

Você pode usar a função getSecret em arquivos Bicep para obter um segredo do cofre de chaves. Observe que a getSecret função é exclusivamente aplicável a um Microsoft.KeyVault/vaults recurso. Além disso, é restrito ao uso dentro da params seção de um módulo e só pode ser usado com parâmetros com o @secure() decorador.

Outra função chamada az.getSecret() função pode ser usada em arquivos de parâmetros Bicep para recuperar segredos do cofre de chaves. Para obter mais informações, consulte Recuperar segredos no arquivo de parâmetros.

Porque a getSecret função só pode ser usada na params seção de um módulo. Vamos criar um sql.bicep no mesmo diretório que o arquivo main.bicep com o seguinte conteúdo:

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'
  }
}

Observe no arquivo Bicep anterior, o adminPassword parâmetro tem um @secure() decorador.

O seguinte arquivo Bicep consome o sql.bicep como um módulo. O arquivo Bicep faz referência a um cofre de chaves existente e chama a getSecret função para recuperar o segredo do cofre de chaves e, em seguida, passa o valor como um parâmetro para o módulo.

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')
  }
}

Recuperar segredos no arquivo de parâmetros

Se você não quiser usar um módulo, poderá recuperar segredos do cofre de chaves no arquivo de parâmetros. No entanto, a abordagem varia dependendo se você está usando um arquivo de parâmetro JSON ou um arquivo de parâmetro Bicep.

O seguinte arquivo Bicep implanta um servidor SQL que inclui uma senha de administrador. O parâmetro password é definido como uma cadeia de caracteres segura. Mas o Bicep não especifica de onde vem esse valor.

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'
  }
}

Agora, crie um arquivo de parâmetros para o arquivo Bicep anterior.

Arquivo de parâmetro Bicep

az.getSecret função pode ser usada em um .bicepparam arquivo para recuperar o valor de um segredo de um cofre de chaves.

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>')

Arquivo de parâmetro JSON

No arquivo de parâmetros JSON, especifique um parâmetro que corresponda ao nome do parâmetro no arquivo Bicep. Para o valor do parâmetro, faça referência ao segredo do cofre de chaves. Você faz referência ao segredo passando o identificador de recurso do cofre de chaves e o nome do segredo:

No arquivo de parâmetros a seguir, o segredo do cofre de chaves já deve existir e você fornece um valor estático para sua ID de recurso.

{
  "$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>"
    }
  }
}

Se você precisar usar uma versão do segredo diferente da versão atual, inclua a secretVersion propriedade.

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

Próximos passos