在部署过程中使用 Azure Key Vault 传递安全参数值

在部署过程中,需要将安全值(例如密码)作为参数传递时,可从 Azure Key Vault 检索值。 通过引用参数文件中的密钥保管库和密钥来检索值。 值永远不会公开,因为仅引用其密钥保管库 ID。 不需要每次部署资源时手动输入机密的值。 密钥保管库与部署到的资源组不需要位于同一订阅中。 引用密钥保管库时,需要包括订阅 ID。

创建密钥保管库时,将 enabledForTemplateDeployment 属性设置为 true。 通过将该值设置为 true,在部署过程中可允许来自资源管理器模板的访问。

部署密钥保管库和机密

若要创建密钥保管库和机密,请使用 Azure CLI 或 PowerShell。 请注意,已为模板部署启用密钥保管库。

对于 Azure CLI,请使用:

vaultname={your-unique-vault-name}
password={password-value}

az group create --name examplegroup --location 'China North'
az keyvault create \
  --name $vaultname \
  --resource-group examplegroup \
  --location 'China North' \
  --enabled-for-template-deployment true
az keyvault secret set --vault-name $vaultname --name examplesecret --value $password

对于 PowerShell,请使用:

$vaultname = "{your-unique-vault-name}"
$password = "{password-value}"

New-AzureRmResourceGroup -Name examplegroup -Location "China North"
New-AzureRmKeyVault `
  -VaultName $vaultname `
  -ResourceGroupName examplegroup `
  -Location "China North" `
  -EnabledForTemplateDeployment
$secretvalue = ConvertTo-SecureString $password -AsPlainText -Force
Set-AzureKeyVaultSecret -VaultName $vaultname -Name "examplesecret" -SecretValue $secretvalue

启用密钥访问权限

无论使用的是新密钥保管库还是现有密钥保管库,请确保部署模板的用户可以访问密钥。 部署引用某个密钥的模板的用户必须具有密钥保管库的 Microsoft.KeyVault/vaults/deploy/action 权限。 所有者参与者角色均授予该访问权限。

通过静态 ID 引用机密

接收 key vault 机密的模板与任何其他模板类似。 这是因为在参数文件(而不是在模板)中引用 key vault。 下图显示了参数文件如何引用机密并将该值传递到模板。

静态 ID

例如,以下模板部署包括管理员密码的 SQL 数据库。 密码参数设置为安全字符串。 但是,此模板未指定该值的来源。

{
  "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminLogin": {
      "type": "string"
    },
    "adminPassword": {
      "type": "securestring"
    },
    "sqlServerName": {
      "type": "string"
    }
  },
  "resources": [
    {
      "name": "[parameters('sqlServerName')]",
      "type": "Microsoft.Sql/servers",
      "apiVersion": "2015-05-01-preview",
      "location": "[resourceGroup().location]",
      "tags": {},
      "properties": {
        "administratorLogin": "[parameters('adminLogin')]",
        "administratorLoginPassword": "[parameters('adminPassword')]",
        "version": "12.0"
      }
    }
  ],
  "outputs": {
  }
}

现在,为上述模板创建参数文件。 在参数文件中,指定与模板中的参数名称匹配的参数。 对于参数值,请从密钥保管库中引用机密。 可以通过传递密钥保管库的资源标识符和机密的名称来引用机密。 在以下参数文件中,Key Vault 机密必须已存在,而且为其资源 ID 提供了静态值。 在本地复制此文件,并设置订阅 ID、保管库名称和 SQL server 名称。

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
        "adminLogin": {
            "value": "exampleadmin"
        },
        "adminPassword": {
            "reference": {
              "keyVault": {
                "id": "/subscriptions/<subscription-id>/resourceGroups/examplegroup/providers/Microsoft.KeyVault/vaults/<vault-name>"
              },
              "secretName": "examplesecret"
            }
        },
        "sqlServerName": {
            "value": "<your-server-name>"
        }
    }
}

现在,部署模板并传入参数文件。 可以使用 GitHub 中的示例模板,但必须使用本地参数文件并将值设置为自己的环境。

Note

必须修改从 GitHub 存储库 sqlserver.json 下载的模板,以适应 Azure 中国云环境。 例如,替换某些终结点(将“blob.core.windows.net”替换为“blob.core.chinacloudapi.cn”,将“cloudapp.azure.com”替换为“chinacloudapp.cn”);更改某些不受支持的 VM 映像;更改某些不受支持的 VM 大小。

对于 Azure CLI,请使用:

az group create --name datagroup --location "China North"
az group deployment create \
    --name exampledeployment \
    --resource-group datagroup \
    --template-file /path/to/sqlserver.json \
    --parameters @sqlserver.parameters.json

对于 PowerShell,请使用:

New-AzureRmResourceGroup -Name datagroup -Location "China North"
New-AzureRmResourceGroupDeployment `
  -Name exampledeployment `
  -ResourceGroupName datagroup `
  -TemplateFile /path/to/sqlserver.json `
  -TemplateParameterFile sqlserver.parameters.json

通过动态 ID 引用机密

上一部分介绍了如何传递密钥保管库机密的静态资源 ID。 但是,在某些情况下,需要引用随当前部署而变的密钥保管库机密。 在这种情况下,不能在参数文件中对资源 ID 进行硬编码。 遗憾的是,不能在参数文件中动态生成资源 ID,因为参数文件中不允许模板表达式。

要动态生成 Key Vault 机密的资源 ID,必须将需要机密的资源迁移到链接模板。 在父模板中添加链接模板,然后传入包含动态生成的资源 ID 的参数。 下图显示链接模板中的参数如何引用机密。

动态 ID

链接模板必须通过外部 URI 提供。 通常,会将模板添加到存储帐户,并通过类似于 https://<storage-name>.blob.core.chinacloudapi.cn/templatecontainer/sqlserver.json 的 URI 访问它。

以下模板动态创建 Key Vault ID 并将其作为参数传递。 它链接到 GitHub 中的示例模板

{
    "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "vaultName": {
        "type": "string"
      },
      "vaultResourceGroup": {
        "type": "string"
      },
      "secretName": {
        "type": "string"
      },
      "adminLogin": {
        "type": "string"
      },
      "sqlServerName": {
        "type": "string"
      }
    },
    "resources": [
    {
      "apiVersion": "2015-01-01",
      "name": "nestedTemplate",
      "type": "Microsoft.Resources/deployments",
      "properties": {
        "mode": "incremental",
        "templateLink": {
          "uri": "https://raw.githubusercontent.com/Azure/azure-docs-json-samples/master/azure-resource-manager/keyvaultparameter/sqlserver.json",
          "contentVersion": "1.0.0.0"
        },
        "parameters": {
          "adminPassword": {
            "reference": {
              "keyVault": {
                "id": "[resourceId(subscription().subscriptionId,  parameters('vaultResourceGroup'), 'Microsoft.KeyVault/vaults', parameters('vaultName'))]"
              },
              "secretName": "[parameters('secretName')]"
            }
          },
          "adminLogin": { "value": "[parameters('adminLogin')]" },
          "sqlServerName": {"value": "[parameters('sqlServerName')]"}
        }
      }
    }],
    "outputs": {}
}

部署前面的模板,并为参数提供值。 可以使用 GitHub 中的示例模板,但必须提供环境的参数值。

Note

必须修改从 GitHub 存储库 sqlserver-dynamic-id.json 下载的模板,以适应 Azure 中国云环境。 例如,替换某些终结点(将“blob.core.windows.net”替换为“blob.core.chinacloudapi.cn”,将“cloudapp.azure.com”替换为“chinacloudapp.cn”);更改某些不受支持的 VM 映像;更改某些不受支持的 VM 大小。

对于 Azure CLI,请使用:

az group create --name datagroup --location "China North"
az group deployment create \
    --name exampledeployment \
    --resource-group datagroup \
    --template-file /path/to/sqlserver-dynamic-id.json \
    --parameters vaultName=<your-vault> vaultResourceGroup=examplegroup secretName=examplesecret adminLogin=exampleadmin sqlServerName=<server-name>

对于 PowerShell,请使用:

New-AzureRmResourceGroup -Name datagroup -Location "China North"
New-AzureRmResourceGroupDeployment `
  -Name exampledeployment `
  -ResourceGroupName datagroup `
  -TemplateFile /path/to/sqlserver-dynamic-id.json `
  -vaultName <your-vault> -vaultResourceGroup examplegroup -secretName examplesecret -adminLogin exampleadmin -sqlServerName <server-name>

后续步骤