1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GitHub Actions - environment と Deployment protection rules

Last updated at Posted at 2024-07-15

environment

以下のようにjobを実行する環境を指定する

[!IMPORTANT]
環境上の variables、secrets を使用する場合のみ environment を指定する

jobs:
  deployment:
    runs-on: ubuntu-latest
    environment: dev  # 環境指定
    env:
      account: ${{ vars.ACCOUNT_ID }}  # Environment variablesの使用
      role_name: ${{ secrets.ACTIONS_ASSUME_ROLE_NAME }}  # Environment secretsの使用
    steps:
      - name: deploy

environmentは、GitHub上に作成し、environmentごとにsecretsとvariablesを登録できる

2024-07-15-15-55-59.png

2024-07-15-16-12-57.png

用途

よく使われるパターンとして、
以下のようにpull request のマージ先によって環境を切り替える

on_pr.yml
on:
  pull_request:

jobs:
  develop:
    name: Deploy Develop
    if: ${{ github.base_ref == 'develop' }}  # pull requestのマージ先で条件分岐
    uses: ./.github/workflows/reuse_deploy_develop.yml
    secrets: inherit
    with:
      environment_name: dev  # 環境指定
workflows/reuse_deploy_develop.yml
on:
  workflow_call:
    inputs:
      environment_name:  # 使用する環境名を引数でもらう
        required: true
        type: string
jobs:
  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    environment:
      name: ${{ inputs.environment_name }}  # 環境指定
    env:
      account: ${{ vars.ACCOUNT_ID }}  # Environment variablesの使用
      role_name: ${{ secrets.ACTIONS_ASSUME_ROLE_NAME }}  # Environment secretsの使用
    steps:
      - name: deploy

Deployment protection rules

Deployment protection rules を環境に対して設定しておくことで、
環境を使用するjob実行時に指定したレビュアーの承認が必要になり、承認されるまでWaiting状態となる

2024-07-15-16-45-54.png

environment指定の集約

environmentはjobに対して指定するが、
可読性向上目的や runs-on の使い分け、matrixを使う場合等、
どうしてもworkflowが複数job構成となることが多い

Deployment protection rulesを設定したenvironmentを以下のように3つのjobで指定すると、
各jobごとに承認待ちとなり、計3回の承認操作が必要になる

jobs:
  job-1:
    runs-on: ubuntu-latest
    environment: dev
    env:
      account: ${{ vars.ACCOUNT_ID }}
    steps:
      - name: step-1

  job-2:
    runs-on: ubuntu-latest
    environment: dev
    env:
      account: ${{ vars.ACCOUNT_ID }}
    steps:
      - name: step-1

  job-3:
    runs-on: ubuntu-latest
    environment: dev
    env:
      account: ${{ vars.ACCOUNT_ID }}
    steps:
      - name: step-1

variables

承認操作を何回も行うのは面倒なので、
以下のようにenvironmentを指定したjobのoutputsを使用することで、
以降のjobでは承認操作が不要になる

jobs:
  output_environment:
    name: Output Environment
    runs-on: ubuntu-latest
    environment: dev  # 環境指定
    outputs:
      accountId: ${{ vars.ACCOUNT_ID }}  # Environment variablesを出力する
    steps:
      - name: Checkout
        uses: actions/checkout@v4

  job-1:  # environmentは指定しない
    name: Job 1
    needs: [output_environment]
    runs-on: ubuntu-latest
    env:
      account: ${{ needs.output_environment.outputs.accountId }}   # Environment variablesの代わりにjobのoutputsを使用する
    steps:
      - name: step-1

secrets

secretsをoutputするとマスクされた文字列***が出力され後続jobで使用できない
これを解決するためにsecretsは暗号化してoutput、後続jobで復号化する
暗号化にはbase64とGPGを組み合わせたものを使用(base64だけでは上手くいかず)

ただしsecretsを暗号化/復号化を行うと全く別文字列扱いとなり、
ログ等にマスクされていないsecretsが出力されてしまう
そのため、復号化時に::add-mask::を使ってマスクする

以下、暗号化/復号化の実装例

.github/actions/encrypt-secret/action.yml
name: Encrypt secret

inputs:
  secret:  # 暗号化したいsecrets
    required: true
    type: string

outputs:
  enc_secret:  # 暗号化したsecrets
    value: ${{ steps.encrypt_secret.outputs.enc_secret }}

runs:
  using: 'composite'
  steps:
    - name: encrypt secret
      id: encrypt_secret
      shell: bash
      run: |
        enc_secret=$(gpg --symmetric --batch --passphrase "SECRET" --output - <(echo "${{ inputs.secret }}") | base64 -w0)
        echo "enc_secret=${enc_secret}" >> $GITHUB_OUTPUT
.github/actions/decrypt-secret/action.yml
name: Decrypt secret

inputs:
  enc_secret:  # 暗号化されたsecrets
    required: true
    type: string

outputs:
  dec_secret:  # 復号化したsecrets
    value: ${{ steps.decrypt_secret.outputs.dec_secret }}

runs:
  using: 'composite'
  steps:
    - name: decrypt secret
      id: decrypt_secret
      shell: bash
      run: |
        dec_secret=$(gpg --decrypt --quiet --batch --passphrase "SECRET" --output - <(echo "${{ inputs.enc_secret }}" | base64 --decode))
        echo "::add-mask::$dec_secret"
        echo "dec_secret=${dec_secret}" >> $GITHUB_OUTPUT

以下secretsを出力した例

jobs:
  output_environment:
    name: Output Environment
    runs-on: ubuntu-latest
    environment: dev  # 環境指定
    outputs:
      accountId: ${{ vars.ACCOUNT_ID }}
      enc_roleName: ${{ steps.encrypt_roleName.outputs.enc_secret }} # 暗号化したsecretsを出力
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: encrypt roleName
        id: encrypt_roleName
        uses: ./.github/actions/encrypt-secret
        with:
          secret: ${{ secrets.ACTIONS_ASSUME_ROLE_NAME }}

  job-1:  # environmentは指定しない
    name: Job 1
    needs: [output_environment]
    runs-on: ubuntu-latest
    env:
      account: ${{ needs.output_environment.outputs.accountId }}
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: decrypt roleName
        id: decrypt_roleName
        uses: ./.github/actions/decrypt-secret
        with:
          enc_secret: ${{ needs.output_environment.outputs.enc_roleName }}

参考

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?