You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过GitHub Actions与Terraform管理多Azure订阅遇认证问题求助

问题根源

你遇到的错误是因为GitHub Actions中使用的**Service Principal(应用注册)**无法通过Azure CLI的用户身份认证方式被Terraform识别。本地环境通过az login用用户账号登录,而CI环境需要明确配置Service Principal的认证参数,让Terraform用服务主体身份完成认证。

解决方案步骤

1. 补充GitHub仓库密钥

在你的GitHub仓库Settings > Secrets and variables > Actions中,新增以下密钥:

  • CLIENT_SECRET:应用注册terraform_runner生成的客户端密码(在Azure门户应用注册的“证书和密码”页创建)

现在你的仓库密钥应包含:CLIENT_ID、CLIENT_SECRET、SUBSCRIPTION_ID、TENANT_ID

2. 调整GitHub Actions Workflow配置

使用Azure官方的azure/loginAction完成Service Principal登录,该Action会自动设置Terraform所需的环境变量,无需手动在Terraform配置中硬编码认证信息。

示例Workflow文件(.github/workflows/terraform.yml):

name: Terraform Multi-Subscription CI/CD

on:
  push:
    branches: [ main ]
  pull_request:
    branches: [ main ]

jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - name: 拉取代码
        uses: actions/checkout@v4

      - name: Azure服务主体登录
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.CLIENT_ID }}
          tenant-id: ${{ secrets.TENANT_ID }}
          subscription-id: ${{ secrets.SUBSCRIPTION_ID }}
          client-secret: ${{ secrets.CLIENT_SECRET }}

      - name: 安装Terraform
        uses: hashicorp/setup-terraform@v3

      - name: Terraform初始化
        run: terraform init

      - name: Terraform格式检查
        run: terraform fmt -check

      - name: Terraform执行计划(仅PR触发)
        run: terraform plan
        if: github.event_name == 'pull_request'

      - name: Terraform应用部署(仅主分支推送触发)
        run: terraform apply -auto-approve
        if: github.event_name == 'push' && github.ref == 'refs/heads/main'

3. 优化Terraform Providers配置

确保多订阅的别名Provider可以复用全局认证信息,只需指定对应订阅ID即可:

示例providers.tf:

terraform {
  backend "azurerm" {
    storage_account_name = "你的状态存储账户名"
    container_name       = "tfstate"
    key                  = "terraform.tfstate"
  }
}

# 主订阅Provider,自动读取环境变量中的认证信息
provider "azurerm" {
  features {}
}

# 其他订阅的别名Provider,仅需指定订阅ID
provider "azurerm" {
  alias           = "sub_dev"
  subscription_id = var.sub_dev_id
  features {}
}

# 可继续添加更多订阅的别名Provider
provider "azurerm" {
  alias           = "sub_prod"
  subscription_id = var.sub_prod_id
  features {}
}

# 定义订阅ID变量(可通过GitHub Secrets或tfvars传入)
variable "sub_dev_id" {
  type        = string
  description = "开发订阅ID"
}

variable "sub_prod_id" {
  type        = string
  description = "生产订阅ID"
}
关键说明
  • azure/loginAction会自动设置ARM_CLIENT_ID、ARM_CLIENT_SECRET、ARM_TENANT_ID、ARM_SUBSCRIPTION_ID等环境变量,Terraform的azurerm Provider会自动读取这些变量完成Service Principal认证。
  • 多订阅场景下,只要Service Principal已被赋予对应订阅的权限,仅需在别名Provider中指定subscription_id即可跨订阅部署资源。
  • 确保状态存储的Azure存储账户已给terraform_runner应用注册分配Blob Contributor或更高权限,避免terraform init阶段无法访问状态文件。

内容的提问来源于stack exchange,提问作者Springsomfan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 09:25:09