使用服务主体向 Azure 进行身份验证

本文介绍如何使用服务主体向 Azure 验证 Terraform。

在本文中,学习如何:

  • 创建服务主体
  • 在环境变量中指定服务主体凭据
  • 在 Terraform 提供程序块中指定服务主体凭据

创建服务主体

如果无权访问服务主体,请继续执行本部分以创建新的服务主体。 如果有可以使用的服务主体,请跳到该部分, 指定服务主体凭据

部署或使用 Azure 服务的自动化工具(例如 Terraform)应始终具有受限权限。 Azure 提供了服务主体,而不是让应用程序以具有完全特权的用户身份登录。

最常见的模式是以交互方式登录 Azure,创建服务主体,测试服务主体,然后将该服务主体用于将来的身份验证(以交互方式或通过脚本)。

  1. 若要创建服务主体,请登录到 Azure。 通过 Microsoft 帐户向 Azure 进行身份验证之后,请返回此处。

  2. 如果通过 Git Bash 创建服务主体,请设置 MSYS_NO_PATHCONV 环境变量。 (如果使用的是 Cloud Shell,则此步骤不是必需的。)

    export MSYS_NO_PATHCONV=1    
    

    要点

    • 可以在全局(为所有终端会话)或本地(只为当前会话)设置 MSYS_NO_PATHCONV 环境变量。 由于创建服务主体不是经常执行的操作,因此示例会为当前会话设置值。 若要在全局设置此环境变量,请将设置添加到 ~/.bashrc 文件。
  3. 若要创建服务主体,请使用 az ad sp create-for-rbac

    az ad sp create-for-rbac --name <service_principal_name> --role Contributor --scopes /subscriptions/<subscription_id>
    

    要点

    • 可以将 <service-principal-name> 替换为适用于环境的自定义名称,也可以完全省略该参数。 如果省略该参数,则基于当前日期和时间生成服务主体名称。
    • 成功完成后,az ad sp create-for-rbac 会显示多个值。 下一步中将使用 appIdpasswordtenant 值。
    • 如果丢失了密码,则无法对其进行检索。 因此,应将密码存储在安全的位置。 如果忘记了密码,则可以重置服务主体凭据
    • 对于本文,会使用一个具有“参与者”角色的服务主体。 有关基于角色的访问控制 (RBAC) 角色的详细信息,请参阅 RBAC:内置角色
    • 创建服务主体的输出包含敏感凭据。 请确保没有将这些凭据包含在代码中,也没有将凭据签入到源代码管理中。
    • 有关使用 Azure CLI 创建服务主体时的选项的详细信息,请参阅使用 Azure CLI 创建 Azure 服务主体一文。

指定服务主体凭据

可通过多种方式指定服务主体凭据。 但是,出于安全原因,我们建议不要将凭据存储在提供程序块中。 仅出于完整性和测试目的,才显示该技术。

在环境变量中指定服务主体凭据

创建服务主体后,可以通过环境变量将其凭据指定给 Terraform。

  1. 通过添加以下环境变量来编辑 ~/.bashrc 文件。

    export ARM_SUBSCRIPTION_ID="<azure_subscription_id>"
    export ARM_TENANT_ID="<azure_subscription_tenant_id>"
    export ARM_CLIENT_ID="<service_principal_appid>"
    export ARM_CLIENT_SECRET="<service_principal_password>"
    
  2. 若要执行 ~/.bashrc 脚本,请运行 source ~/.bashrc(或其缩写等效项 . ~/.bashrc)。 还可以退出并重新打开 Cloud Shell 以便自动运行脚本。

    . ~/.bashrc
    
  3. 设置环境变量后,可以验证其值,如下所示:

    printenv | grep ^ARM*
    

    要点

    • 与任何环境变量一样,若要从 Terraform 脚本中访问 Azure 订阅值,请使用以下语法:${env.<environment_variable>}。 例如,若要访问 ARM_SUBSCRIPTION_ID 值,请指定 ${env.ARM_SUBSCRIPTION_ID}
    • 创建并应用 Terraform 执行计划会对与服务主体关联的 Azure 订阅进行更改。 如果登录一个 Azure 订阅,而环境变量指向另一个 Azure 订阅,这一事实有时可能会令人困惑。 请看以下示例进行说明。 假设有两个 Azure 订阅:SubA 和 SubB。 如果当前 Azure 订阅是 SubA(通过 az account show 确定),而环境变量指向 SubB,则 Terraform 进行的任何更改都在 SubB 上。 因此,需要登录 SubB 订阅运行 Azure CLI 命令或 Azure PowerShell 命令以查看更改。
  4. 跳到该部分, 后续步骤

在 Terraform 提供程序块中指定服务主体凭据

注意

能够在 Terraform 配置文件中指定 Azure 订阅凭据可能会十分方便 - 尤其是在测试时。 但是,不建议将凭据存储在可以由不受信任的个人查看的明文文件中。

Azure 提供程序块定义用于指定 Azure 订阅的身份验证信息的语法。

terraform {
  required_providers {
    azurerm = {
      source = "hashicorp/azurerm"
      version = "~>3.0"
    }
  }
}

provider "azurerm" {
  features {}

  subscription_id   = "<azure_subscription_id>"
  tenant_id         = "<azure_subscription_tenant_id>"
  client_id         = "<service_principal_appid>"
  client_secret     = "<service_principal_password>"
}

# Your code goes here

后续步骤