Mar*_*Kim 11 github github-actions
我正在尝试在运行时使用 GitHub Actions 动态拉回 GitHub 机密:
假设我有两个 GitHub Secrets:
在我的 GitHub Action 中,我有另一个 env 变量,它在分支之间会有所不同
env:
FRUIT_NAME: APPLES
Run Code Online (Sandbox Code Playgroud)
本质上,我想找到一种方法来进行某种变量替换以获得正确的秘密。因此,在我的一项儿童工作中,我想做以下事情:
env:
FRUIT_SECRET: {{ 'SECRET_' + env.FRUIT_NAME }}
Run Code Online (Sandbox Code Playgroud)
我尝试了以下方法但没有运气:
secrets['SECRET_$FRUIT_NAME'] }}
Run Code Online (Sandbox Code Playgroud)
我什至尝试了一种没有串联的更简单的方法,只是为了尝试让它工作
secrets['$FRUIT_NAME'] }}
Run Code Online (Sandbox Code Playgroud)
和
{{ secrets.$FRUIT_NAME }}
Run Code Online (Sandbox Code Playgroud)
以上都没有奏效。
如果我没有很好地解释这一点,请道歉。我试图让我的例子尽可能简单。
任何人都知道如何实现这一目标?
或者,我想做的是在每个分支的基础上存储秘密
例如:
在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"
Run Code Online (Sandbox Code Playgroud)
Mei*_*bay 10
我找到了一种更好的方法来在作业中准备动态机密,然后在其他作业中将这些机密作为环境变量使用。
下面是它在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
Run Code Online (Sandbox Code Playgroud)
在对这个项目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] }}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
阅读本文后 - 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"
Run Code Online (Sandbox Code Playgroud)
这导致
SECRET_NAME = A_FRUIT_NAME
SECRET_NAME = A_FRUIT_NAME
SECRET_VALUE = ***
Run Code Online (Sandbox Code Playgroud)
由于 SECRET_VALUE 被编辑,我们可以假设获取了真正的秘密。
我学到的东西——
你不能env从另一个引用env,所以这行不通
env:
SECRET_PREFIX: A
SECRET_NAME: ${{ env.SECRET_PREFIX }}_FRUIT_NAME
Run Code Online (Sandbox Code Playgroud)
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步骤
使用format函数有一个更简洁的选项来实现这一点。
给定设置机密 DEV_A 和 TEST_A,以下两个作业将使用这两个机密:
name: Secrets
on: [push]
jobs:
dev:
name: dev
runs-on: ubuntu-18.04
env:
ENVIRONMENT: DEV
steps:
- run: echo ${{ secrets[format('{0}_A', env.ENVIRONMENT)] }}
test:
name: test
runs-on: ubuntu-18.04
env:
ENVIRONMENT: TEST
steps:
- run: echo ${{ secrets[format('{0}_A', env.ENVIRONMENT)] }}
Run Code Online (Sandbox Code Playgroud)
这也适用于通过手动工作流(workflow_dispatch事件)提供的输入:
name: Secrets
on:
workflow_dispatch:
inputs:
env:
description: "Environment to deploy to"
required: true
jobs:
secrets:
name: secrets
runs-on: ubuntu-18.04
steps:
- run: echo ${{ secrets[format('{0}_A', github.event.inputs.env)] }}
Run Code Online (Sandbox Code Playgroud)
如果这有帮助,在阅读了真正有帮助的上述答案后,我决定使用的策略包括按如下方式存储我的秘密:
其中 MASTER 是 prod 环境的 master 分支,TEST 是测试环境的 test 分支。
然后,使用该线程中建议的解决方案,关键是动态生成secrets变量的键。这些密钥是通过中间步骤(vars在下面的示例中称为)使用以下方法生成的outputs:
name: Pulumi up
on:
push:
branches:
- master
- test
jobs:
up:
name: Update
runs-on: ubuntu-latest
steps:
- name: Create variables
id: vars
run: |
branch=${GITHUB_REF##*/}
echo "::set-output name=DB_USER::DB_USER_${branch^^}"
echo "::set-output name=DB_PASSWORD::DB_PASSWORD_${branch^^}"
- uses: actions/checkout@v2
with:
fetch-depth: 1
- uses: docker://pulumi/actions
with:
args: up -s ${GITHUB_REF##*/} -y
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }}
DB_USER: ${{ secrets[steps.vars.outputs.DB_USER] }}
DB_PASSWORD: ${{ secrets[steps.vars.outputs.DB_PASSWORD] }}
Run Code Online (Sandbox Code Playgroud)
注意获取大写分支的技巧:
${branch^^}。这是必需的,因为 GitHub 强制机密为大写。
我能够使用工作流程名称作为分支特定变量来实现此目的。
对于我创建的每个分支,我只需更新 YML 文件顶部的单个值,然后添加 GitHub Secrets 以匹配工作流程名称:
name: CUSTOMER1
jobs:
build:
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ github.workflow }}_AWS_ACCESS_KEY_ID
steps:
- uses: actions/checkout@v2
- run: echo "::set-env name=AWS_ACCESS_KEY_ID::${{ secrets[env.AWS_ACCESS_KEY_ID] }}"
- run: echo $AWS_ACCESS_KEY_ID
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4242 次 |
| 最近记录: |