通过从 Azure Key Vault 读取来管理 ARM 模板中的机密

已完成

基础结构即代码 (IaC) 是指将基础结构要求描述为用户可读的文本文件。 Azure 资源管理器 (ARM) 模板是 IaC 的一种形式。

与应用程序代码一样,你可以在版本控制系统(如 Git)中管理基础结构代码。 这样做可以与他人协作,并随着不断变化而跟踪对基础结构要求所做的更改。

与应用程序代码一样,不应将敏感信息(如密码和 API 密钥)硬编码到 ARM 模板中。 否则,对存储库拥有读取权限的任何人都可以访问此机密信息。

尽管只有组织中的授权人员才能访问敏感信息,但 ARM 模板也需要此信息。 Azure Key Vault 是一种帮助保护敏感信息的方法。

Azure Key Vault 帮助保护敏感信息

Azure Key Vault 是一项云服务,用作机密的安全存储。 可以通过 Key Vault 创建多个安全的称为保管库的容器。 这些保管库受硬件安全模块 (HSM) 的支持。 保管库可以集中存储应用程序机密,降低安全信息意外丢失的可能性。 Key Vault 还控制并记录外界对其所存储内容的访问。

Key Vault 能够同时存储密钥和机密。 其众多功能不仅可用于管理机密,而且还可用于部署过程。

  • 基于角色的访问控制。 可以使用各种角色管理密钥保管库,以便可以确保它可供应用和不同级别的管理员使用。

  • 允许用户和应用。 可以配置密钥保管库,以便特定用户和应用可以访问密钥保管库。 对于应用,可以创建服务主体。 事实上,可以配置密钥保管库,以便只有服务主体可以访问它。

    注意

    服务主体是创建用于应用程序、托管服务和自动化工具以访问 Azure 资源的标识。 通过仅向主体分配具有有限访问权限的角色或部分角色来限制对资源的访问。 通过此方法可以更精细地控制可访问资源的对象和数量。

  • 可以与 ARM 模板进行交互。 在部署 ARM 模板的过程中,可以从密钥保管库中读取。 要使其正常工作,需要进行一些配置。 下一部分将提供更多详细信息。

配置权限

你已选择 Key Vault 作为存储凭据的服务。 例如,你希望能够在部署期间读取机密,以便可以设置虚拟机的密码。

需要执行几个配置步骤来设置 Key Vault,以便可以在部署期间从中读取。 步骤如下:

  1. 启用用于部署的 Key Vault。 需要允许 Key Vault 才能在部署期间从中读取。 可以在创建时传递此设置,也可以稍后修改它。

  2. 用户需要对资源组拥有部署权限。 这与其他部署没有什么不同。 但是,如果尚未创建资源组,则可以分配角色以确保可对其进行部署。

  3. 用户需要具有访问密钥保管库的适当权限。 在部署期间从密钥保管库读取时,必须确保具有访问密钥保管库的适当权限。 创建密钥保管库时,将创建访问策略,该策略向用户提供管理所有机密、密钥和证书的权限。

配置用于部署的 Key Vault

配置 Key Vault 的实例,以便可以在部署 ARM 模板的过程中从该实例读取凭据。

若要启用用于部署的 Key Vault,可以在创建 Key Vault 实例的过程中传递一项设置,也可以在以后修改它。 在 PowerShell 中,它是称为 -EnabledForTemplateDeployment 的开关。 在 Azure CLI 中,它是称为 --enabled-for-template-deployment 的参数,也需要传递值 true

注意

此外,Azure CLI 还需要传递值为 true 的布尔值。

用户需要对 Key Vault 和资源组拥有部署权限

在尝试从密钥保管库部署和读取机密之前,必须确保具有部署权限。 两个角色均提供此权限:

  • Owner:如果创建了密钥保管库,你将自动具有此角色。
  • Contributor:该角色授予你管理所有机密的访问权限。 如果未创建密钥保管库,最简单的方法是为你自己提供 Contributor 角色。

还可以创建和分配自定义角色,并确保角色包含 Microsoft.KeyVault/vaults/deploy/action 权限。

配置部署参数文件

可以使用参数文件,而不是在部署期间将每个参数和相应值指定为键值对。

在该参数文件中,指定感兴趣的密钥保管库和其中的机密。 可以通过修改参数,然后更新部署模板以使用此参数来执行此操作。

注意

该模板没有任何关于密钥保管库或其机密的概念。 需要在参数文件中进行配置。

为参数配置密钥保管库和机密

在参数文件中,对于特定参数,指向对其具有部署权限的密钥保管库。 接下来,指定你感兴趣的机密。 按名称指出机密。 在部署期间,此配置将解析为机密值。 下面是一个名为 myPassword 的参数,该参数配置为使用特定密钥保管库并使用名为 databaseSecret 的机密。

"myPassword" : {
  "reference": {
    "keyVault": {
      "id": "/subscriptions/<subscription-id>/resourceGroups/<rg-name>/providers/Microsoft.KeyVault/vaults/<vault-name>",
      "secretName": "databaseSecret"
    }
  }
}

在上述 JSON 中,指定密钥保管库的完整 ID,并继续询问机密 databaseSecret。 然后提取此机密的值并将其分配给 myPassword 参数。

将参数分配给资源的密码

此步骤与密钥保管库无关。 此步骤是为了确保预期资源使用配置为从密钥保管库读取机密值的参数。 下面是模板文件中 VM 的一个缩短片段,其中显示了从参数 myPassword 读取的 adminPassword 元素。 此机密值将在部署时从密钥保管库进行读取并分配给元素 adminPassword

{
  "osProfile": {
    "adminPassword": "[parameters('myPassword')]"
  }
}