こんにちは。jedipunkz🚀 です。
Terraform を運用しているとたまに Plan 結果がどうしても出てしまう事があります。また Terraform を GitHub で実行する環境を運用していると Plan 結果をうまく扱って自動化したいモチベーションも湧いてきます。この場合に Plan の差分をうまく処理してくれる GitHub Action があればなと思って作ってみました。
GitHub Actions
作成した GitHub Action は下記のレポジトリで公開しています。
https://github.com/jedipunkz/tf-plan-parser
入力・オプション設定
この GitHub Action では2つの入力オプションが利用可能です:
terraform-plan (必須)
パース対象となる Terraform Plan の出力結果を指定します。通常は前のステップで実行した terraform plan
コマンドの標準出力を渡します。
ignore-resources (オプション)
無視したいリソースタイプや特定のリソースを配列形式で指定します。デフォルトは空の配列 []
です。
指定方法の例:
リソースタイプ全体を無視:
ignore-resources: '["null_resource", "local_file"]'
特定のリソースインスタンスを無視:
ignore-resources: '["null_resource.temporary", "local_file.cache"]'
リソースタイプとインスタンスの混在:
ignore-resources: '["null_resource", "aws_s3_bucket.temp", "local_file"]'
出力される情報
この Action は以下の出力を提供します。また下記は ignore-resources オプションの指定に沿って結果を出力してくれます。
- diff-bool: 変更があるかどうかの真偽値(
true
またはfalse
) - diff-count: 変更されるリソースの数
- diff-resources: 変更されるリソースのアドレス一覧(カンマ区切り)
- diff-raw: 生の差分データ
これらの出力を使って、後続のステップで条件分岐や通知の制御が可能です。
使い方の例
基本的な使い方
- name: Terraform Plan
id: plan
run: terraform plan -no-color
- name: Parse Plan
id: parse
uses: jedipunkz/tf-plan-parser@v1
with:
terraform-plan: ${{ steps.plan.outputs.stdout }}
ignore-resources: '["null_resource", "random_id"]'
- name: Check results
run: |
echo "Changes detected: ${{ steps.parse.outputs.diff-bool }}"
echo "Resource count: ${{ steps.parse.outputs.diff-count }}"
Pull Request への自動コメント
- name: Terraform Plan
id: plan
run: terraform plan -out=tfplan -no-color
- name: Parse Plan
id: parse
uses: jedipunkz/tf-plan-parser@v1
with:
terraform-plan: ${{ steps.plan.outputs.stdout }}
ignore-resources: '["null_resource", "local_file"]'
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const diffBool = '${{ steps.parse.outputs.diff-bool }}';
const diffCount = '${{ steps.parse.outputs.diff-count }}';
const resources = JSON.parse('${{ steps.parse.outputs.diff-resources }}');
const diffRaw = `${{ steps.parse.outputs.diff-raw }}`;
let body = '## Terraform Plan Parser\n\n';
// Summary
if (diffBool === 'true') {
body += `✅ **Changes detected** affecting ${diffCount} resources:\n\n`;
body += '### Changed Resources\n```\n';
for (const resource of resources) {
body += `${resource}\n`;
}
body += '```\n\n';
} else {
body += '✅ **No changes detected**\n\n';
}
// All outputs
body += '### Outputs\n';
body += `- **diff-bool**: \`${diffBool}\`\n`;
body += `- **diff-count**: \`${diffCount}\`\n`;
body += `- **diff-resources**: \`${JSON.stringify(resources)}\`\n\n`;
// Raw plan
if (diffRaw && diffRaw.trim()) {
body += '### Raw Terraform Plan Output\n';
body += '```\n' + diffRaw + '\n```\n\n';
}
body += '---\n*Generated by Terraform Plan Parser*';
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: body
})
条件分岐でのデプロイ制御
- name: Terraform Plan
id: plan
run: terraform plan -out=tfplan -no-color
- name: Parse Plan
id: parse
uses: jedipunkz/tf-plan-parser@v1
with:
terraform-plan: ${{ steps.plan.outputs.stdout }}
ignore-resources: '["null_resource", "random_id", "local_file"]'
- name: Skip deployment if no changes
if: steps.parseoutputs.diff-bool == 'false'
run: echo "No infrastructure changes detected. Skipping deployment."
- name: Proceed with deployment
if: steps.parseoutputs.diff-bool == 'true'
run: |
echo "Infrastructure changes detected: ${{ steps.parseoutputs.diff-count }} resources"
terraform apply -auto-approve tfplan
- name: Notify on major changes
if: steps.parseoutputs.diff-count > 10
run: |
echo "⚠️ Large number of changes detected (${{ steps.parseoutputs.diff-count }} resources)"
echo "Manual review recommended"
まとめ・今後の機能追加について
今回作成したツールにより、Terraform Plan の差分解析が効率化されるかもしれないと思っています。特に下記の点で効果を期待しています。
- 意図しない差分と重要な差分の区別が指定出来るようになった
- Plan 結果差分に反応して通知する仕組み等に応用が効く
- チーム全体で差分の判断基準を統一指定出来る
今後の機能追加として、以下を検討しています:
- 差分の変更の種類(create/update/delete)ごとの分類
- 入力・出力の拡張
ぜひ皆さんの Terraform 運用でも活用してみてください!