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

拆分GitHub Action后TF_API_TOKEN不可用,如何解决Terraform认证失败问题?

解决共享工作流中Terraform认证401未授权问题

我原本有一个代码冗长、重复内容多的GitHub Action,为优化结构,用workflow_call拆分成多个共享工作流。之前能通过仓库里的TF_API_TOKEN Secret(存储Terraform Cloud API密钥)完成Terraform CLI认证,但现在运行共享工作流时,执行terraform -chdir=deploy/environments/dev/bucket init命令出现401未授权错误,无法从app.terraform.io获取模块版本,推测是共享工作流无法访问该Secret,求解决方法。

相关工作流代码如下:

分支工作流:branch-feature.yml

name: Deploy Feature Branch

on:
  pull_request:
    types: [opened, synchronize]
    branches:
      - develop
  workflow_dispatch:

jobs:

  build:
    if: startsWith(github.head_ref, 'feature/') || github.head_ref == 'master'
    uses: ./.github/workflows/step-build.yml

  deploy-to-dev:
    needs: [build]
    uses: ./.github/workflows/step-deploy.yml
    with:
      deploy-env: dev
      deploy-branch: ${{ github.head_ref }}

部署步骤工作流:step-deploy.yml

on:
  workflow_call:
    inputs:
      deploy-env:
        required: true
        description: 'Environment to deploy to'
        type: string
      deploy-branch:
        required: true
        description: 'Branch to deploy'
        type: string
  
jobs:
  get-version:
    uses: ./.github/workflows/step-version.yml

  deploy-infrastructure:
    uses: ./.github/workflows/step-deploy-infrastructure.yml
    with:
      deploy-env: ${{ inputs.deploy-env }}
      deploy-branch: ${{ inputs.deploy-branch }}
      script-directory: bucket

基础设施部署工作流:step-deploy-infrastructure.yml

on:
  workflow_call:
    inputs:
      deploy-env:
        required: true
        description: 'Environment to deploy to'
        type: string
      deploy-branch:
        required: true
        description: 'Branch to deploy'
        type: string
      script-directory:
        required: true
        description: 'Directory to run terraform from'
        type: string
      terraform-args:
        required: false
        description: 'Additional arguments to pass to terraform'
        type: string
        default: ""
    outputs:
      bucket-name:
        description: 'The name of the s3 bucket created'
        value: ${{ jobs.deploy.outputs.bucket-name }}
  
jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ inputs.deploy-env }}
    outputs:
      bucket-name: ${{ steps.bucket_name.outputs.stdout }}
    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ inputs.deploy-branch }}
      - name: Configure Environment based on branches
        run: |
          echo "TF-DIRECTORY=deploy/environments/${{ inputs.deploy-env }}/${{ inputs.script-directory }}" >> $GITHUB_ENV
      - name: Setup terraform
        uses: hashicorp/setup-terraform@v2
        with:
          cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
      - name: Terraform Format
        id: fmt
        run: terraform -chdir=${{ env.TF-DIRECTORY }} fmt -check
      - name: Terraform Init
        id: init
        run: terraform -chdir=${{ env.TF-DIRECTORY }} init
      - name: Terraform Validate
        id: validate
        run: terraform -chdir=${{ env.TF-DIRECTORY }} validate -no-color
      - name: Terraform Plan
        id: plan
        run: terraform -chdir=${{ env.TF-DIRECTORY }} plan -no-color
        continue-on-error: true
      - name: Update Pull Request
        uses: actions/github-script@v6.4.1
        env:
          PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
        with:
          github-token: ${{ secrets.GITHUB_TOKEN }}
          script: |
            const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\`
            #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
            #### Terraform Plan 📖\`${{ steps.plan.outcome }}\`
            #### Terraform Validation 🤖\`${{ steps.validate.outputs.stdout }}\`
  
            <details><summary>Show Plan</summary>
  
            \`\`\`\n
            ${process.env.PLAN}
            \`\`\`
  
            </details>
  
            *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`;
  
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            })
      - name: Terraform Plan Status
        if: steps.plan.outcome == 'failure'
        run: exit 1
      - name: Terraform Apply ${{ inputs.deploy-env }}
        run: terraform -chdir=${{ env.TF-DIRECTORY }} apply -auto-approve ${{ inputs.terraform-args }}
      - name: Get Bucket Name
        id: bucket_name
        run: terraform -chdir=${{ env.TF-DIRECTORY }} output -raw bucket_name

解决方案

GitHub共享工作流不会自动继承调用方的Secrets,必须在每一层工作流中显式定义并传递所需的Secret。按以下步骤修改:

1. 修改step-deploy-infrastructure.yml,添加Secret定义

在on.workflow_call下新增secrets配置,声明需要接收TF_API_TOKEN:

on:
  workflow_call:
    inputs:
      deploy-env:
        required: true
        description: 'Environment to deploy to'
        type: string
      deploy-branch:
        required: true
        description: 'Branch to deploy'
        type: string
      script-directory:
        required: true
        description: 'Directory to run terraform from'
        type: string
      terraform-args:
        required: false
        description: 'Additional arguments to pass to terraform'
        type: string
        default: ""
    secrets:
      TF_API_TOKEN:
        required: true
        description: 'Terraform Cloud API Token'
    outputs:
      bucket-name:
        description: 'The name of the s3 bucket created'
        value: ${{ jobs.deploy.outputs.bucket-name }}

2. 修改step-deploy.yml,添加Secret定义并传递给下层工作流

首先在on.workflow_call中添加Secret声明:

on:
  workflow_call:
    inputs:
      deploy-env:
        required: true
        description: 'Environment to deploy to'
        type: string
      deploy-branch:
        required: true
        description: 'Branch to deploy'
        type: string
    secrets:
      TF_API_TOKEN:
        required: true

然后在调用step-deploy-infrastructure.yml时,显式传递Secret:

deploy-infrastructure:
    uses: ./.github/workflows/step-deploy-infrastructure.yml
    with:
      deploy-env: ${{ inputs.deploy-env }}
      deploy-branch: ${{ inputs.deploy-branch }}
      script-directory: bucket
    secrets:
      TF_API_TOKEN: ${{ secrets.TF_API_TOKEN }}

3. 修改branch-feature.yml,在调用step-deploy.yml时传递Secret

deploy-to-dev:
    needs: [build]
    uses: ./.github/workflows/step-deploy.yml
    with:
      deploy-env: dev
      deploy-branch: ${{ github.head_ref }}
    secrets:
      TF_API_TOKEN: ${{ secrets.TF_API_TOKEN }}

原理说明

共享工作流作为独立的执行单元,默认无法直接访问调用方仓库的Secrets。通过在每一层workflow_call中定义需要的Secrets,并在调用时显式传递,就能让最底层的工作流获取到TF_API_TOKEN,完成Terraform Cloud的认证,解决401错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 02:27:07