[GitHubActions]CDKTFの実行結果に応じてLablesを付与する
はじめに
最近転職したのでPublication経由の投稿ではなくなりました。
自身での投稿第一弾です。
今後は今の会社でも技術ブログの文化を作っていきたいと考えています。
概要
CDKTFの実行をGitHubActionsで行っています。
CDK For Terraformの実行するためのActionsは公式にあります。
- 参考
plan結果をPullRequestにコメントしてくれたり、
設定内容に応じて作業用ディレクトリを指定できたり、
mode
の指定に応じて処理内容変更してくれたりします。
これだけでも便利ではあるのですが、
plan結果に応じてLabelsを付与することで
整理しやすくなると考え、スクリプト自作しました。
ちなみにTerraformで運用している場合は
suzuki-shunsukeさんが作成されているtfcmtが便利なので
こちらがいいかと思います。
- 参考
実装
- add_labels.sh
処理概要: applyが0以外であればapplyラベルを付与し、
0であれば削除する。changeやdestroyも同様です。
#!/bin/bash
# PR番号とplan出力を引数として受け取る
PR_NUMBER="$1"
PLAN_OUTPUT="$2"
if echo "$PLAN_OUTPUT" | grep -q "No changes."; then
gh pr edit "$PR_NUMBER" --add-label "nochange"
# 変更がなければ、apply, change, destroyラベルがあれば削除する
gh pr edit "$PR_NUMBER" --remove-label "apply"
gh pr edit "$PR_NUMBER" --remove-label "change"
gh pr edit "$PR_NUMBER" --remove-label "destroy"
else
# 変更があった場合はnochangeラベルを削除する
gh pr edit $PR_NUMBER --remove-label "nochange"
# add,change,destroyカウントの抽出
if [[ $PLAN_OUTPUT =~ ([0-9]+)[[:space:]]+to[[:space:]]+add ]]; then
ADD_COUNT=${BASH_REMATCH[1]}
else
ADD_COUNT=0
fi
if [[ $PLAN_OUTPUT =~ ([0-9]+)[[:space:]]+to[[:space:]]+change ]]; then
CHANGE_COUNT=${BASH_REMATCH[1]}
else
CHANGE_COUNT=0
fi
if [[ $PLAN_OUTPUT =~ ([0-9]+)[[:space:]]+to[[:space:]]+destroy ]]; then
DESTROY_COUNT=${BASH_REMATCH[1]}
else
DESTROY_COUNT=0
fi
# applyラベル(add)
if [ "$ADD_COUNT" -gt 0 ]; then
gh pr edit "$PR_NUMBER" --add-label "apply"
else
gh pr edit "$PR_NUMBER" --remove-label "apply"
fi
# changeラベル
if [ "$CHANGE_COUNT" -gt 0 ]; then
gh pr edit "$PR_NUMBER" --add-label "change"
else
gh pr edit "$PR_NUMBER" --remove-label "change"
fi
# destroyラベル
if [ "$DESTROY_COUNT" -gt 0 ]; then
gh pr edit "$PR_NUMBER" --add-label "destroy"
else
gh pr edit "$PR_NUMBER" --remove-label "destroy"
fi
fi
- GitHubActions(サンプル)
Cacheなどの設定をカスタマイズしてありますが、Stack名やワーキングディレクトリを
変更することで、他のリポジトリでも流用できると思います。
name: "Sample CDK for Terraform"
on:
pull_request:
branches:
- main
types: [opened, synchronize, reopened, closed]
paths:
workflow_dispatch:
#-------------------------#
# 環境変数
#-------------------------#
env:
CDKTF_VERSION: 0.20.10
TERRAFORM_VERSION: 1.10.5
WORK_DIRECTORY: cdk_for_terraform
STACK_NAME: sample
permissions:
id-token: write
contents: read
pull-requests: write
repository-projects: write
issues: read
jobs:
cdktf:
name: "CDK For Terraform "
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Configure AWS credentials from account
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ap-northeast-1
- name: Cache Node.js modules
id: cache-node-modules
uses: actions/cache@v4
with:
path: ${{ env.WORK_DIRECTORY }}/node_modules
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-node-
- name: Cache .gen directory
id: cache-gen
uses: actions/cache@v4
with:
path: cdk_for_terraform/.gen
key: ${{ runner.os }}-gen-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-gen-
- uses: actions/setup-node@v4
with:
node-version: "22"
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TERRAFORM_VERSION }}
- name: Install dependencies
run: |
cd ${{ env.WORK_DIRECTORY }}
make install
if: steps.cache-node-modules.outputs.cache-hit != 'true'
- name: Generate module and provider bindings
run: |
cd ${{ env.WORK_DIRECTORY }}
npx cdktf-cli@${{ env.CDKTF_VERSION }} get
if: steps.cache-gen.outputs.cache-hit != 'true'
- name: Run Terraform CDK DryRun
id: plan
if: github.event.pull_request.merged != true
uses: hashicorp/terraform-cdk-action@v7
with:
terraformVersion: ${{ env.TERRAFORM_VERSION }}
cdktfVersion: ${{ env.CDKTF_VERSION }}
stackName: ${{ env.STACK_NAME }}
mode: plan-only
githubToken: ${{ secrets.GITHUB_TOKEN }}
workingDirectory: ${{ env.WORK_DIRECTORY }}
suppressOutput: false # プランの出力を抑制フラグ
# ラベル付与
- name: Add labels based on plan
if: github.event.pull_request.merged != true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# PR番号とplan出力を引数として渡す
PR_NUMBER=${{ github.event.pull_request.number }}
LABEL_OUTPUT="${{ steps.plan.outputs.stdout }}"
./.github/scripts/add_labels.sh "$PR_NUMBER" "$LABEL_OUTPUT"
処理イメージ
このような感じでGitHubActionsによってLabelsが付与されます。
まとめ
plan結果を人間の目で確認することも重要ではありますが、
視覚的に識別できるというのも重要と考えています。
本運用を導入することで今までplanが実行されたら必ず注意深くみていたものが
nochange lablesが付与されているものは注意深くみなくてもよくなりました。
今後の構想として特定のファイルの変更のみでトリガーされるようにすることを前提とし、
nochacngeのラベルが付与されたものを自動でマージもしくは
承認なしてもマージしてもいいような運用にしていきたいと考えています。
Discussion