更新 - 2021年7月
我找到了一种更好的方法来准备动态密钥,并将这些密钥作为环境变量在其他作业中使用。
以下是在GitHub Actions中的实现方式。
假设每个密钥应根据分支名称获取。 我使用此操作rlespinasse/github-slug-action获取分支名称。
请查看内联注释以了解它们如何共同工作。
name: Dynamic Secret Names
on:
push:
env:
AWS_REGION: "eu-west-1"
jobs:
prepare:
name: Prepare
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v3.x
- name: Prepare Outputs
id: prepare-step
run: |
echo "::set-output name=aws_access_key_id_name::AWS_ACCESS_KEY_ID_${GITHUB_REF_SLUG}";
echo "::set-output name=aws_secret_access_key_name::AWS_SECRET_ACCESS_KEY_${GITHUB_REF_SLUG}";
outputs:
aws_access_key_id_name: ${{ steps.prepare-step.outputs.aws_access_key_id_name }}
aws_secret_access_key_name: ${{ steps.prepare-step.outputs.aws_secret_access_key_name }}
test:
name: Test
needs:
- prepare
runs-on: ubuntu-20.04
env:
AWS_ACCESS_KEY_ID_NAME: ${{ needs.prepare.outputs.aws_access_key_id_name }}
AWS_SECRET_ACCESS_KEY_NAME: ${{ needs.prepare.outputs.aws_secret_access_key_name }}
steps:
- uses: actions/checkout@v2
- name: Test Application
env:
AWS_ACCESS_KEY_ID: ${{ secrets[env.AWS_ACCESS_KEY_ID_NAME] }}
AWS_SECRET_ACCESS_KEY: ${{ secrets[env.AWS_SECRET_ACCESS_KEY_NAME] }}
run: |
printenv | grep AWS_
aws s3 ls
更新 - 2020年8月
通过对这个项目 terraform-monorepo 进行一些实际操作,以下是我如何动态使用秘密名称的示例。
- 秘密名称与环境名称和分支名称相对应 -
development
、staging
和 production
$GITHUB_REF_SLUG
来自于 Slug GitHub Action,该操作获取分支名称
- 执行解析的命令为
- name: set-aws-credentials
run: |
echo "::set-env name=AWS_ACCESS_KEY_ID_SECRET_NAME::AWS_ACCESS_KEY_ID_${GITHUB_REF_SLUG}"
echo "::set-env name=AWS_SECRET_ACCESS_KEY_SECRET_NAME::AWS_SECRET_ACCESS_KEY_${GITHUB_REF_SLUG}"
- name: terraform-apply
run: |
export AWS_ACCESS_KEY_ID=${{ secrets[env.AWS_ACCESS_KEY_ID_SECRET_NAME] }}
export AWS_SECRET_ACCESS_KEY=${{ secrets[env.AWS_SECRET_ACCESS_KEY_SECRET_NAME] }}
完整示例
name: pipeline
on:
push:
branches: [development, staging, production]
paths-ignore:
- "README.md"
jobs:
terraform:
runs-on: ubuntu-latest
env:
TF_VAR_app_name: tfmonorepo
steps:
- uses: actions/checkout@v2
- name: Inject slug/short variables
uses: rlespinasse/github-slug-action@v2.x
- name: prepare-files-folders
run: |
mkdir -p ${GITHUB_REF_SLUG}/
cp live/*.${GITHUB_REF_SLUG} ${GITHUB_REF_SLUG}/
cp live/*.tf ${GITHUB_REF_SLUG}/
cp live/*.tpl ${GITHUB_REF_SLUG}/ 2>/dev/null || true
mv ${GITHUB_REF_SLUG}/backend.tf.${GITHUB_REF_SLUG} ${GITHUB_REF_SLUG}/backend.tf
- name: install-terraform
uses: little-core-labs/install-terraform@v1
with:
version: 0.12.28
- name: set-aws-credentials
run: |
echo "::set-env name=AWS_ACCESS_KEY_ID_SECRET_NAME::AWS_ACCESS_KEY_ID_${GITHUB_REF_SLUG}"
echo "::set-env name=AWS_SECRET_ACCESS_KEY_SECRET_NAME::AWS_SECRET_ACCESS_KEY_${GITHUB_REF_SLUG}"
- name: terraform-apply
run: |
export AWS_ACCESS_KEY_ID=${{ secrets[env.AWS_ACCESS_KEY_ID_SECRET_NAME] }}
export AWS_SECRET_ACCESS_KEY=${{ secrets[env.AWS_SECRET_ACCESS_KEY_SECRET_NAME] }}
cd ${GITHUB_REF_SLUG}/
terraform version
rm -rf .terraform
terraform init -input=false
terraform get
terraform validate
terraform plan -out=plan.tfout -var environment=${GITHUB_REF_SLUG}
terraform apply -auto-approve plan.tfout
rm -rf .terraform
阅读完GitHub Actions中上下文和表达式语法,特别关注env对象后,我发现:
在表达式的一部分中,您可以使用以下两种语法之一访问上下文信息:
索引语法:github['sha']
属性引用语法:github.sha
因此,对于secrets
也适用相同的语法,您可以执行secrets[secret_name]
,因此您可以执行以下操作:
- name: Run a multi-line script
env:
SECRET_NAME: A_FRUIT_NAME
run: |
echo "SECRET_NAME = $SECRET_NAME"
echo "SECRET_NAME = ${{ env.SECRET_NAME }}"
SECRET_VALUE=${{ secrets[env.SECRET_NAME] }}
echo "SECRET_VALUE = $SECRET_VALUE"
导致的结果是
SECRET_NAME = A_FRUIT_NAME
SECRET_NAME = A_FRUIT_NAME
SECRET_VALUE = ***
由于SECRET_VALUE已被删除,我们可以假设真正的秘密已经被获取。
我学到的东西 -
您无法从另一个env
引用env
,因此这不起作用
env:
SECRET_PREFIX: A
SECRET_NAME: ${{ env.SECRET_PREFIX }}_FRUIT_NAME
SECRET_NAME 的结果是 _FRUIT_NAME
,不太好
您可以在代码中使用上下文表达式,不仅限于 env
,您可以看到在 SECRET_VALUE=${{ secrets[env.SECRET_NAME] }}
中,这很酷
当然 - 这是我测试过的工作流程 - https://github.com/unfor19/gha-play/runs/595345435?check_suite_focus=true - 请检查 Run a multi-line script
步骤
{{ secrets.SECRET_NAME }}
,也许你可以尝试:{{ secrets['$FRUIT_NAME'] }}
或者{{ secrets.$FRUIT_NAME }}
。如果两者都不起作用,我建议你编辑你的问题并提到你已经尝试了这两种方法。 - Meir Gabay{{ secrets[$FRUIT_NAME] }}
是什么意思? - Meir GabayUnexpected symbol: '$FRUIT_NAME'。该符号位于表达式中第9个位置:secrets[$FRUIT_NAME]
。 - Mark McKim