通过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
相关产品推荐
相关产品推荐

