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

GitHub Action中Terraform OIDC认证初始化ARM配置错误求助

问题:Terraform 采用OIDC认证初始化Azure Storage后端失败

错误信息

Initializing the backend...
╷
│ Error: Error building ARM Config: Authenticating using the Azure CLI is only supported as a User (not a Service Principal).
│
│ To authenticate to Azure using a Service Principal, you can use the separate 'Authenticate using a Service Principal'
│ auth method - instructions for which can be found here: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret
│
│ Alternatively you can authenticate using the Azure CLI by using a User Account.

现有配置

工作流.yml文件

name: 'Create Infra with Terraform'

on:
  push:
    branches: [ main ]
    paths: .github/workflows/main.yml
  pull_request:
    branches:  none # [ main ]
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

permissions:
 id-token: write
 contents: read

env:
  STORAGE_ACCOUNT_NAME: terraformstate01923777
  RESOURCE_GROUP_NAME: rg-terraform-state
  CONTAINER_NAME: tfstate
  BLOB_NAME: terraform.tfstate
  
  WORKING_DIRECTORY: .
  
jobs:
  scan-terraform-config:
    runs-on: ubuntu-latest
    name: Scan Terraform with Checov
    steps:
      - name: Checkout repo
        uses: actions/checkout@master

      - name: Run Checkov Scan
        id: checkov
        uses: bridgecrewio/checkov-action@master
        with:
          directory: .
          soft_fail: true # optional: do not return an error code if there are failed checks
          # check: CKV_AWS_1 # optional: run only a specific check_id. can be comma separated list
          # skip_check: CKV_AWS_2 # optional: skip a specific check_id. can be comma separated list
          # quiet: true # optional: display only failed checks
          # framework: terraform # optional: run only on a specific infrastructure {cloudformation,terraform,kubernetes,all}
          # output_format: sarif # optional: the output format, one of: cli, json, junitxml, github_failed_only, or sarif. Default: sarif
          # download_external_modules: true # optional: download external terraform modules from public git repositories and terraform registry
          # log_level: DEBUG # optional: set log level. Default WARNING
          # config_file: path/this_file
          # baseline: cloudformation/.checkov.baseline # optional: Path to a generated baseline file. Will only report results not in the baseline.
          # container_user: 1000 # optional: Define what UID and / or what GID to run the container under to prevent permission issues
 
  deploy-azure-infra-terraform:
    name: Deploy to Azure with Terraform
    runs-on: ubuntu-latest
    # environment: production
    needs: [scan-terraform-config]

    # Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest
    defaults:
      run:
        shell: bash
        working-directory: .
    steps:
    # Checkout the repository to the GitHub Actions runner
    - name: Checkout
      uses: actions/checkout@v4
                
    - name: Login to Azure with OIDC
      uses: Azure/login@v2.3.0
      with:
        client-id: ${{ secrets.AZURE_CLIENT_ID }}
        tenant-id: ${{ secrets.AZURE_TENANT_ID }}  
        subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}

    - name: Create Terraform backend state storage
      uses: Azure/cli@v2.1.0     
      with:
        inlineScript: |
          az version

          # Create resource group
          az group create --name $RESOURCE_GROUP_NAME --location westeurope
          
          # Create storage account with open access
          az storage account create --name $STORAGE_ACCOUNT_NAME \
             --resource-group $RESOURCE_GROUP_NAME \
             --sku Standard_LRS \
             --encryption-services blob \
             --default-action "Allow"
          
          # Create blob container with authentication mode
          az storage container create --name $CONTAINER_NAME \
             --account-name $STORAGE_ACCOUNT_NAME \
             --auth-mode login

    # Install the latest version of Terraform CLI
    - name: Install Terraform
      uses: hashicorp/setup-terraform@v1
      with:
        terraform_version: 1.1.7
    
    - name: Terraform Init
      id: init
      env:
        ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
        ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        ARM_USE_OIDC: true
        ARM_USE_CLI: false
      run: |
        # Initialize Terraform with backend configuration
        terraform init \
          -backend-config="resource_group_name=$RESOURCE_GROUP_NAME" \
          -backend-config="storage_account_name=$STORAGE_ACCOUNT_NAME" \
          -backend-config="container_name=$CONTAINER_NAME" \
          -backend-config="key=$BLOB_NAME" \
          -backend-config="use_azuread_auth=true"
  
    # Checks that all Terraform configuration files adhere to a canonical format
    - name: Terraform Format
      id: format
      run: terraform fmt -check
      continue-on-error: true

    - name: Terraform Plan
      id: plan
      env:
        ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
        ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        ARM_USE_OIDC: true
        ARM_USE_CLI: false
      if: github.event_name == 'pull_request' # 'push' # 
      run: |
        terraform plan -no-color

    - name: Add Terraform Plan Comment
      id: comment
      uses: actions/github-script@v6
      if: github.event_name == 'pull_request' # 'push'
      env:
        PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
      with:
        github-token: ${{ secrets.GITHUB_TOKEN }}
        script: |
          const output = `#### Terraform Format and Style 🖌\`${{ steps.format.outcome }}\`
          #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
          #### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
      
          <details><summary>Show Plan</summary>
          
          \`\`\`${process.env.PLAN}\`\`\`
          
          </details>
          
          *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Working Directory: \`${{ env.WORKING_DIRECTORY }}\`, Workflow: \`${{ github.workflow }}\`*`;
            
          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: output
          })
        
    # On push to main, build or change infrastructure according to Terraform configuration files
    - name: Terraform Apply
      if: github.ref == 'refs/heads/main' && github.event_name == 'push'
      env:
        ARM_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
        ARM_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
        ARM_SUBSCRIPTION_ID: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
        ARM_USE_OIDC: true
        ARM_USE_CLI: false
      run: terraform apply -auto-approve

main.tf文件

terraform {
    required_providers {
        azurerm = {
        source  = "hashicorp/azurerm"
        version = "~> 3.0"
        }
    }
    
    required_version = ">= 1.0.0"
    
    # Backend configuration will be provided via command line
    backend "azurerm" {}
}

provider "azurerm" {
    features {}
    use_cli = false
    use_oidc = true
  
}

resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "West Europe"
}

解决方案

错误根源是Terraform的azurerm后端默认尝试使用Azure CLI认证,但当前会话是通过服务主体(OIDC登录)创建的,不符合CLI认证的用户账户要求。需要明确告诉后端使用OIDC认证并禁用CLI认证:

  1. 修改Terraform Init命令,添加后端配置参数
    在terraform init的命令中加入-backend-config="use_cli=false",确保后端明确禁用CLI认证:

    terraform init \
      -backend-config="resource_group_name=$RESOURCE_GROUP_NAME" \
      -backend-config="storage_account_name=$STORAGE_ACCOUNT_NAME" \
      -backend-config="container_name=$CONTAINER_NAME" \
      -backend-config="key=$BLOB_NAME" \
      -backend-config="use_azuread_auth=true" \
      -backend-config="use_cli=false"
    
  2. 验证环境变量传递
    确保ARM_USE_OIDC=true和ARM_USE_CLI=false环境变量在Init步骤正确生效,这些变量会被azurerm后端读取,优先使用OIDC认证方式。

  3. 版本兼容性检查
    当前使用的Terraform 1.1.7和azurerm provider 3.x版本组合支持OIDC后端认证,但建议确认两者版本匹配:

    • Terraform 1.1+支持OIDC环境变量传递
    • azurerm provider 3.0+支持OIDC认证
  4. 确认服务主体权限
    确保用于OIDC登录的服务主体拥有目标存储账户的Storage Blob Data Contributor权限,避免后续权限问题(虽然当前错误是认证方式问题,但权限配置是后续必要步骤)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 19:55:54