GitHub Actions で terraform plan を実行して Claude Code にレビューさせてみた

GitHub Actions で terraform plan を実行して Claude Code にレビューさせてみた

2026.06.28

Claude Code GitHub Actions で terraform plan の結果をレビューする仕組みを作ってみました。

以前コードレビュー(HCL)について記事を書きました。

https://dev.classmethod.jp/articles/terraform-review-skill-claude-code-github-actions/

今回は GitHub Actions 上で terraform plan を実行し、その plan の出力(JSON)をレビュー対象にします。

今回使用したサンプルコード(スキル・ワークフロー・Terraformコード)はGitHubリポジトリ msato0731/terraform-sample に格納しました。

plan レビュー用スキルを作る

検証用にplanレビュー用のスキルを作成しました。

planファイルを読み込んで、リソース変更を確認します。

重大度の目安は以下にしました。

  • 状態を持つリソース(RDS / EBS / S3 / DynamoDB など)の delete・replace → HIGH(データ消失)
  • 想定外の delete(PR の意図にないリソースが消える)→ HIGH
  • ステートレスなリソースの replace(ダウンタイムのみ)→ MEDIUM
  • 1つの変更が多数リソースへ波及する場合 → 件数を明示して注意喚起

出力形式は、先頭に1行サマリ(create / update / delete / replace の件数)を置き、replace と delete を上から列挙します。

各指摘には「対象リソースアドレス・アクション・なぜ危険か・確認すべきこと」を書かせるようにしました。

GitHub Actions で plan を実行する

plan を実行するので、AWS 認証と Terraform のセットアップが要ります。

.github/workflows/terraform-plan-review.yml
name: terraform-plan-review
on:
  pull_request:
    types: [opened, synchronize]
    paths:
      - "claude-code-terraform-plan-review/**"   # このディレクトリの変更でだけ起動する
permissions:
  contents: read
  pull-requests: write
  id-token: write
jobs:
  plan-review:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: claude-code-terraform-plan-review
    steps:
      - uses: actions/checkout@v7
        with:
          fetch-depth: 0
      - uses: aws-actions/configure-aws-credentials@v6
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }}
          aws-region: ap-northeast-1
      - uses: hashicorp/setup-terraform@v4
      - run: terraform init
      - run: terraform plan -out=tfplan
      - run: terraform show -json tfplan > plan.json

サンプルコードを実際に動かす場合は、backend.tf<STATE_BUCKET>の値を環境に合わせて修正してください。

claude-code-terraform-plan-review/backend.tf
terraform {
  backend "s3" {
    bucket       = "<STATE_BUCKET>"
    key          = "claude-code-terraform-plan-review/terraform.tfstate"
    region       = "ap-northeast-1"
    use_lockfile = true
  }
}

plan は -out=tfplan で保存し、レビューにはその保存ファイルを terraform show -json で render した plan.json を渡します。

plan の出力を Claude にレビューさせる

prompt を指定するとコメントは自動作成されないので、投稿に使うツールを claude_args で明示許可します。

.github/workflows/terraform-plan-review.yml
      - id: claude
        uses: anthropics/claude-code-action@v1
        with:
          claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
          github_token: ${{ secrets.GITHUB_TOKEN }}
          prompt: |
            REPO: ${{ github.repository }}
            PR NUMBER: ${{ github.event.pull_request.number }}

            /terraform-plan-review claude-code-terraform-plan-review/plan.json をレビューしてください。
            replace / delete を中心に、適用時のリスクを指摘してください。
            結果は gh pr comment でトップレベルコメントとして投稿してください。
          claude_args: |
            --allowedTools "Read,Bash(jq:*),Bash(gh pr comment:*),Bash(gh pr view:*)"

動作確認

実際に PR を作って動かしてみます。

まずベースライン(Ubuntu AMI)を main に置き、ローカルで一度 terraform init && apply して state を S3 に保存します。

VPC と EC2 がを作成します。

次に EC2の ami_id を変更するPRを作成します。

variables.tf
 variable "ami_id" {
   type    = string
-  default = "ami-0d52744d6551d851e"
+  default = "ami-0a371542ad09d2434"
 }

ami は変更すると再作成が必要な属性なので、plan は replace になります。

Planファイルを見ると # forces replacement 付きで確認できます。

plan.txt(識別子はマスク)
  # aws_instance.web must be replaced
-/+ resource "aws_instance" "web" {
      ~ ami        = "ami-0d52744d6551d851e" -> "ami-0a371542ad09d2434" # forces replacement
      ~ arn        = "<ARN>" -> (known after apply)
      ~ private_ip = "<PRIVATE_IP>" -> (known after apply)
      ~ public_ip  = "<PUBLIC_IP>" -> (known after apply)
      ~ id         = "<INSTANCE_ID>" -> (known after apply)
        # ...省略...
    }

Plan: 1 to add, 0 to change, 1 to destroy.

ワークフローは pull_request で起動し、1分半程度で完了しました。

OIDC 認証 → terraform init(S3 上の既存 state を読む)→ terraform plan -out=tfplanterraform show -jsonclaude-code-action まで、全ステップの成功を確認できました。

Change_EC2_AMI_to_AL2023_·_m…form-review-sandbox_d36afba.png

投稿された PR コメントがこちらです。

## Terraform plan レビュー結果

create: 0 / update: 0 / delete: 0 / **replace: 1**

---

### [HIGH] `aws_instance.web` が replace(破棄→再作成)される

- **アクション**: replace(delete → create)
- **要因**: `ami` 属性の変更(ForceNew フィールドのため、変更すると必ず再作成)
- **リスク**: インスタンスが一度破棄されてからの再作成となる。ルート EBS ボリュームのデータが失われ、再作成完了までダウンタイムが発生する。またプライベート IP アドレスが変わる可能性がある(Elastic IP を使っていない場合)
- **確認事項**:
  - AL2023 への AMI 更新は意図した変更か
  - ルート EBS に保持すべきデータ(アプリケーションデータ・ログ等)がないか。あれば事前スナップショットを取得すること
  - ダウンタイム許容が取れているか(Blue/Green や ASG によるローリング更新が必要でないか)
  - Elastic IP を使っていない場合、IP アドレス変更による影響(DNS・セキュリティグループ・接続先設定)を確認すること

Change_EC2_AMI_to_AL2023_by_…731_terraform-review-sandbox.png

おわりに

GitHub Actions で terraform plan を実行し、その出力を Claude にレビューさせる仕組みを試してみました。

AMI 変更の PR では replace を HIGH として拾い、データ消失とダウンタイムのリスクを PR コメントに出せました。

コードのレビューだと「この書き方で何が起きるか」までしか見えませんが、plan を渡すと「実際に何が消えて何が作り直されるか」を判断材料にできます。

replace や delete の見落としを PR の段階で気づける点が便利でした。

今回作成したスキルは最小限の叩き台です。

drift や output の変更まで広げたり、重大度の基準を調整したりは運用しながら足していけます。


Claudeならクラスメソッドにお任せください

クラスメソッドは、Anthropic社とリセラー契約を締結しています。各種製品ガイドから、業種別の活用法、フェーズごとのお悩み解決などサービス支援ページにまとめております。まずはご覧いただき、お気軽にご相談ください。

サービス詳細を見る

この記事をシェアする

関連記事