1. 概要
- PRにterraform planの結果をコメントで自動投稿する仕組み
- tfcmtを使ったリッチなコメント表示
- github-scriptを使ったシンプルな実装
- 古いコメントを更新(重複を防ぐ)する方法
PRレビュー時にterraform planの結果を自動的にコメント投稿することで、レビュアーがインフラ変更の影響を把握しやすくなります。
2. 最もシンプルな実装(github-script)
# .github/workflows/terraform-plan.yml
name: Terraform Plan
on:
pull_request:
branches: [main]
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "~> 1.9"
- name: Terraform Init
run: terraform init
- name: Terraform Plan
id: plan
run: terraform plan -no-color 2>&1 | tee /tmp/plan.txt
continue-on-error: true
- name: Post Plan Comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
let plan = fs.readFileSync('/tmp/plan.txt', 'utf8');
if (plan.length > 65000) plan = plan.substring(0, 65000) + '\n...(省略)';
const header = '## Terraform Plan 結果';
const body = [
header,
'```',
plan,
'```',
].join('\n');
// 既存コメントを検索して更新(重複防止)
const comments = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const existing = comments.data.find(c =>
c.body.startsWith(header) && c.user.type === 'Bot'
);
if (existing) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: existing.id,
body,
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body,
});
}
3. tfcmtを使ったリッチなコメント(推奨)
tfcmtはterraform planの出力を見やすく整形してGitHubにコメントするCLIツールです。
# .github/workflows/terraform-plan-tfcmt.yml
name: Terraform Plan (tfcmt)
on:
pull_request:
branches: [main]
permissions:
id-token: write
contents: read
pull-requests: write
env:
TFCMT_VERSION: "v4.13.0"
jobs:
plan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: "~> 1.9"
- name: Install tfcmt
run: |
curl -sSL https://github.com/suzuki-shunsuke/tfcmt/releases/download/${{ env.TFCMT_VERSION }}/tfcmt_linux_amd64.tar.gz | tar xz
sudo mv tfcmt /usr/local/bin/
- name: Terraform Init
run: terraform init
- name: Terraform Plan with tfcmt
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
tfcmt plan -patch -- terraform plan -no-color
# -patch: 既存コメントを更新(重複防止)
tfcmtを使うと変更リソースの増減がアイコン付きで分かりやすく表示されます。
4. 複数ディレクトリ(monorepo)での対応
# .github/workflows/terraform-multi-dir.yml
name: Terraform Plan (Multi Dir)
on:
pull_request:
branches: [main]
permissions:
id-token: write
contents: read
pull-requests: write
jobs:
detect-changes:
runs-on: ubuntu-latest
outputs:
dirs: ${{ steps.changed.outputs.dirs }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Detect changed Terraform directories
id: changed
run: |
DIRS=$(git diff --name-only HEAD~1 HEAD | grep '\.tf$' | xargs -I{} dirname {} | sort -u | jq -R -s -c 'split("\n") | map(select(length > 0))')
echo "dirs=$DIRS" >> $GITHUB_OUTPUT
plan:
needs: detect-changes
if: needs.detect-changes.outputs.dirs != '[]'
runs-on: ubuntu-latest
strategy:
matrix:
dir: ${{ fromJson(needs.detect-changes.outputs.dirs) }}
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/GitHubActionsRole
aws-region: ap-northeast-1
- uses: hashicorp/setup-terraform@v3
with:
terraform_version: "~> 1.9"
- name: Terraform Init
run: terraform init
working-directory: ${{ matrix.dir }}
- name: Terraform Plan
run: terraform plan -no-color
working-directory: ${{ matrix.dir }}
5. plan結果コメントのベストプラクティス
| プラクティス | 理由 |
|---|---|
| 既存コメントを更新(-patch) | PRに大量のコメントが積み重なるのを防ぐ |
| 長い出力を切り詰める(65KB制限) | GitHub APIのコメントサイズ制限に対応 |
continue-on-error: true | planが失敗してもコメント投稿ステップを実行する |
| ディレクトリパスをコメントに含める | monorepoでどの環境のplanかを明示 |
6. 関連記事
- GitHub ActionsでTerraformを実行する方法 — 基本ワークフロー
- GitHub Actions: OIDC認証でAWSクレデンシャルを排除する — 認証設定
- GitHub Actions: Matrixで複数環境を並列実行 — 並列実行
- モノレポ vs マルチリポ — リポジトリ設計 — monorepo構成
- Terraform CI/CDのブランチ戦略 — PRベースのapply設計
- Atlantis vs Terraform Cloud — PRベース自動化の比較
7. まとめ
- terraform planの結果をPRコメントに投稿することでレビュアーの負担を減らせる
- シンプルな実装はgithub-script、見た目を重視するならtfcmt
- 既存コメントを更新する(
-patch)ことでPRのコメント欄が溢れるのを防ぐ - monorepoでは変更があったディレクトリのみをplanするようにすると効率的
対象バージョン: Terraform >= 1.9 / GitHub Actions (2024) / tfcmt v4 公式ドキュメント: https://github.com/suzuki-shunsuke/tfcmt