github - 动态检索 GitHub Actions 机密
问题描述
我正在尝试在运行时使用 GitHub Actions 动态拉回 GitHub 机密:
假设我有两个 GitHub Secrets:
- SECRET_ORANGES : "这是一个橙色的秘密"
- SECRET_APPLES : "这是苹果的秘密"
在我的 GitHub Action 中,我有另一个 env 变量,它在分支之间会有所不同
env:
FRUIT_NAME: APPLES
本质上,我想找到一种方法来进行某种变量替换以获得正确的秘密。因此,在我的一份子工作中,我想做类似的事情:
env:
FRUIT_SECRET: {{ 'SECRET_' + env.FRUIT_NAME }}
我尝试了以下方法,但没有成功:
secrets['SECRET_$FRUIT_NAME'] }}
我什至尝试了一种没有串联的更简单的方法,只是为了让它工作
secrets['$FRUIT_NAME'] }}
和
{{ secrets.$FRUIT_NAME }}
以上都没有奏效。
抱歉,如果我没有很好地解释这一点。我试图让我的例子尽可能简单。
任何人都知道如何实现这一目标?
或者,我想做的是在每个分支的基础上存储秘密
例如:
在customer1
代码分支中:
SECRET_CREDENTIAL="abc123"
在customer2
代码分支中:
SECRET_CREDENTIAL="def456"
SECRET_CREDENTIAL
然后我可以根据我所在的分支访问正确的值。
谢谢!
更新:我越来越接近我想要实现的目标:
name: Test
env:
CUSTOMER: CUSTOMER1
jobs:
build:
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ env.CUSTOMER }}_AWS_ACCESS_KEY_ID
steps:
- uses: actions/checkout@v2
- run: |
AWS_ACCESS_KEY_ID=${{ secrets[env.AWS_ACCESS_KEY_ID] }}
echo "AWS_ACCESS_KEY_ID = $AWS_ACCESS_KEY_ID"
解决方案
更新 - 2021 年 7 月
我找到了一种更好的方法来在作业中准备动态机密,然后在其他作业中将这些机密用作环境变量。
这是它在GitHub Actions中的样子。
我的假设是每个秘密都应该根据分支名称来获取。我通过这个动作rlespinasse/github-slug-action得到了分支的名字。
浏览内联注释以了解它们如何协同工作。
name: Dynamic Secret Names
# Assumption:
# You've created the following GitHub secrets in your repository:
# AWS_ACCESS_KEY_ID_master
# AWS_SECRET_ACCESS_KEY_master
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
# Sets this step's outputs, that later on will be exported as the job's outputs
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}";
# Sets this job's, that will be consumed by other jobs
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idoutputs
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
# Must wait for `prepare` to complete so it can use `${{ needs.prepare.outputs.{output_name} }}`
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#needs-context
needs:
- prepare
runs-on: ubuntu-20.04
env:
# Get secret names
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:
# Inject secret values to environment variables
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:
### -----------------------
### Available in all steps, change app_name to your app_name
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 object之后,我发现:
作为表达式的一部分,您可以使用两种语法之一访问上下文信息。
索引语法: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
,不好你可以在你的代码中使用上下文表达式,不仅在 in 中
env
,你还可以在 in 中看到SECRET_VALUE=${{ secrets[env.SECRET_NAME] }}
,这很酷
当然 - 这是我测试的工作流程 - https://github.com/unfor19/gha-play/runs/595345435?check_suite_focus=true - 检查Run a multi-line script
步骤
推荐阅读
- c++ - 为什么我不能使用 labmda 作为非类型模板参数?
- java - Java中所有字符大写并在每个字符之间添加空格的递归方法
- reactjs - 仍然没有解决 reactjs sass 安装过程
- java - 我想添加我的实时 firebase 数据库中的值
- c# - 多个 HTTP 请求触发 HTTP Client 超时
- c# - 如何禁用对 DataGrid 的特定(最后)列的重新排序?
- javascript - Firebase 身份验证 onAuthStateChanged 在函数体后响应
- javascript - 为什么我在 console.log 上将下拉值显示为“未定义”?
- python - 如何将 *args 与整数列表一起使用?
- r - 需要帮助使用“Imager”包进行灰度化:灰度错误(im):图像应具有三个颜色通道