英文:
TF_API_TOKEN secret not shared with shared GitHub Action
问题
I had a GitHub Action that had got quite long and had a lot of repeated code. So I decomposed it to use shared actions via workflow_call
. Prior to doing this, I could authenticate with the terraform
CLI by the fact that I had a secret defined in the GitHub repository called TF_API_TOKEN
that contained my Terraform Cloud API key.
现在,当我运行共享工作流时,代码出错:
terraform -chdir=deploy/environments/dev/bucket init
Initializing Terraform Cloud...
Initializing modules...
╷
│ Error: Error accessing remote module registry
│
│ on main.tf line 25:
│ 25: module "app_bucket" {
│
│ Failed to retrieve available versions for module "app_bucket" (main.tf:25)
│ from app.terraform.io: error looking up module versions: 401 Unauthorized.
我认为这是由于无法从共享操作中访问密钥导致的。我该如何解决这个问题?
代码
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
英文:
I had a GitHub Action that had got quite long and had a lot of repeated code. So I decomposed it to use shared actions via workflow_call
. Prior to doing this, I could authenticate with the terraform
CLI by the fact that I had a secret defined in the GitHub repository called TF_API_TOKEN
that contained my Terraform Cloud API key.
Now when I run the shared workflow the code errors:
terraform -chdir=deploy/environments/dev/bucket init
Initializing Terraform Cloud...
Initializing modules...
╷
│ Error: Error accessing remote module registry
│
│ on main.tf line 25:
│ 25: module "app_bucket" {
│
│ Failed to retrieve available versions for module "app_bucket" (main.tf:25)
│ from app.terraform.io: error looking up module versions: 401 Unauthorized.
I believe this is due to the secret not being accessible from the shared action. How can I get around this?
Code
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
答案1
得分: 2
根据官方文档的说明,调用可重用工作流时需要继承密钥。
因此,不要使用以下方式:
deploy-infrastructure:
uses: ./.github/workflows/step-deploy-infrastructure.yml
with:
deploy-env: ${{ inputs.deploy-env }}
deploy-branch: ${{ inputs.deploy-branch }}
script-directory: bucket
在调用可重用工作流时,请传递密钥:
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 }}
为了实现这一点,您需要将密钥添加到 step-deploy-infrastruture.yaml
文件中的 workflow_call
配置中:
on:
workflow_call:
inputs:
[ ... ]
secrets:
TF_API_TOKEN:
required: true
另请注意:
> 在同一组织或企业中调用可重用工作流的工作流可以使用 inherit
关键字隐式传递密钥。
在这种情况下,您可以使用以下方式:
deploy-infrastructure:
uses: ./.github/workflows/step-deploy-infrastructure.yml
with:
deploy-env: ${{ inputs.deploy-env }}
deploy-branch: ${{ inputs.deploy-branch }}
script-directory: bucket
secrets: inherit
英文:
As stated on the official documentation, you need to inherit secrets when calling a reusable worklow.
So instead of using:
deploy-infrastructure:
uses: ./.github/workflows/step-deploy-infrastructure.yml
with:
deploy-env: ${{ inputs.deploy-env }}
deploy-branch: ${{ inputs.deploy-branch }}
script-directory: bucket
You should inform the secret when calling the reusable workflow:
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 }}
To enable this, you need to add the secret to the workflow_call
configuration in the step-deploy-infrastruture.yaml
file:
on:
workflow_call:
inputs:
[ ... ]
secrets:
TF_API_TOKEN:
required: true
Also note that:
> Workflows that call reusable workflows in the same organization or enterprise can use the inherit keyword to implicitly pass the secrets.
In that case, you could use:
deploy-infrastructure:
uses: ./.github/workflows/step-deploy-infrastructure.yml
with:
deploy-env: ${{ inputs.deploy-env }}
deploy-branch: ${{ inputs.deploy-branch }}
script-directory: bucket
secrets: inherit
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论