Terraformコードレビュースキルを作って Claude Code GitHub Actions で Pull Request を自動レビューしてみた
Claude Code GitHub Actions で Terraform の PR を自動レビューする仕組みを作ってみました。
今回はコードレビューのみを対象にします。
terraform plan の出力を渡した plan レビューは別のブログにします。
Terraform コードレビュースキルを作る
HashiCorp 公式の agent-skills を参考にしました。
レビューに特化したスキルはありませんが、terraform-style-guide が description に "Use when writing, reviewing, or generating" とあり、SECURITY.md を同梱しています。
セキュリティやスタイルのレビュー知識はここをベースにしました。
レビューに必要な知識は自作スキル側に全部入れておきます。
こうするとスキルをリポジトリに同梱でき、ワークフローは actions/checkout だけで動きます。
自作スキルは .claude/skills/terraform-review/ に置きました。SKILL.md にレビューの作業手順・重大度・出力形式を書き、観点の詳細は references/ に分割しています。スキル全体は検証用リポジトリの .claude/skills/terraform-review/ に置いてあります。記事では要点だけ抜き出します。
.claude/skills/terraform-review/
├── SKILL.md
└── references/
├── security.md
├── state-and-lifecycle.md
├── module-and-style.md
└── team-conventions.md
重大度は HIGH/MEDIUM/LOW の3段にして、基準を表で固定しました。
## 重大度
| 重大度 | 基準 |
|---|---|
| HIGH | 本番で実害(情報漏えい・全公開・データ消失・権限過剰)に直結する |
| MEDIUM | セキュリティ/運用のベストプラクティス違反。事故時の影響が大きい |
| LOW | 規約・可読性・保守性。動作はするが直したい |
迷ったら一段下げる。憶測で HIGH を付けない。差分から読み取れる事実だけで判断する。
出力は「1行サマリ → 重大度の高い順」に統一し、修正例は最小の diff で示すよう指示しました。指摘がゼロなら無理に粗探しせず「指摘なし」と書かせます。
ローカルでスキルを検証する
CI に載せる前に、ローカルの Claude Code で観点を確かめます。
claude -p "/terraform-review この変更をレビューしてください。base ブランチは main です。" \
--allowedTools "Bash,Read,Glob,Grep"
スキルを読み込み、references を参照し、git diff で差分を取り、所定のフォーマットで出力します。
検証用コードにはあらかじめ問題を仕込んでおき、検出されるかを見ます。
## Terraform レビュー結果
HIGH: 1 / MEDIUM: 2 / LOW: 4
- 対象: `claude-code-terraform-review/main.tf` の `resource "aws_security_group" "web"`
- 指摘: SSH(22) を `cidr_blocks = ["0.0.0.0/0"]` で開けている。管理ポートの全公開は総当たり攻撃に直結し、チーム規約でも禁止(踏み台/SSM 前提)。
- 提案: 22 の全開放をやめ、SSM Session Manager 経由にする。SSH が必要なら送信元を絞る。
```diff
ingress {
description = "SSH"
from_port = 22
to_port = 22
protocol = "tcp"
- cidr_blocks = ["0.0.0.0/0"]
+ cidr_blocks = [var.admin_cidr] # 管理元IPに限定。可能なら ingress 自体を削除し SSM 経由に
}
```
(HTTP 80 の全開放は公開 Web 用途のため許容と判断、指摘しません)
仕込んだ問題(SSH 全開放、IMDSv2 未強制、ルート EBS 非暗号化、AMI とリージョンのハードコード、Name タグ欠落など)を重大度どおりに検出しました。
スキルの動作に問題ないことを確認してから GitHub Actions に移ります。
GitHub Actions で PR を自動レビューする
ワークフローは以下です。PR の差分をレビューし、指摘を該当行へインラインコメントで、全体サマリをトップレベルコメントで投稿します。
name: terraform-review
on:
pull_request:
types: [opened, synchronize]
paths:
- "claude-code-terraform-review/**"
permissions:
contents: read
pull-requests: write
id-token: write
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
- 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-review この PR の Terraform 差分をレビューしてください。
各指摘は mcp__github_inline_comment__create_inline_comment で該当行にインラインコメントとして投稿してください。
全体サマリ(HIGH/MEDIUM/LOW の件数)は gh pr comment でトップレベルコメントとして投稿してください。
claude_args: |
--allowedTools "Read,Glob,Grep,mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*)"
paths: のフィルタは検証用ディレクトリに絞ったデモ用です。実運用では **/*.tf や対象モジュールのルートに合わせます。
prompt を指定すると、PR へのコメントは自動では作られません。コメント投稿ツールを claude_args で明示的に許可します。
インラインコメントは mcp__github_inline_comment__create_inline_comment、全体サマリのトップレベルコメントは gh pr comment を使います。プロンプトでも投稿方法を指示しておきます。
認証は API キー(anthropic_api_key)でも OAuth(claude_code_oauth_token、サブスクリプション利用)でもどちらでも動きます。今回は OAuth を使いました。
実行すると、PR にトップレベルのサマリが1件と、各指摘が該当行に紐づくインラインコメントとして9件付きました。


model は claude-sonnet-4-6、所要時間は約4分、コストは約 $0.55/run でした。

今回はリポジトリ内スキルを直接置きましたが、GitHub Actions上でプラグイン経由で取得する方法もあります。
自作スキルも marketplace 用リポジトリにまとめれば /plugin で配布・再利用できます。
ただしプラグイン方式を GitHub Actions に載せる場合は、runner 上でプラグインを取得するステップが要る点が、今回のリポジトリ内スキルと異なります。
コメントが出るまでに詰まったところ
run は success になるのに、PR にコメントが付かないところで詰まりました。コメント投稿ツールを許可していなかったためです。
最初は Read,Glob,Grep 程度しか許可しておらず、prompt を指定するとコメントは自動では作られないので、レビュー結果はジョブのログに出るだけで PR には何も出ませんでした。
permission_denials_count に Claude が使おうとしたツールが許可されておらず拒否された回数が出ます。ここの回数が増えていたため、ツールの許可が必要なことが分かりました。

ただし permission_denials_count は回数だけで、どのツールが弾かれたかは出ません。それを見るには action の実行ログ claude-execution-output.json を artifact に保存し、tool_use を確認します。
actions/upload-artifact で ${{ steps.<id>.outputs.execution_file }} を保存します。
- id: claude
uses: anthropics/claude-code-action@v1
with:
# ...省略...
- name: Upload Claude execution log
if: always()
uses: actions/upload-artifact@v7
with:
name: claude-execution-output
path: ${{ steps.claude.outputs.execution_file }}
上記で特定したツールを claude_args で許可することで解消しました。
おわりに
Claude Code GitHub Actionsを使って、Terraformのコードレビューを行いました。
レビュー結果は、指摘ごとに該当行へインラインコメント、件数のサマリをトップレベルコメントとして PR に投稿できました。
コメントの投稿で少し詰まりました。prompt を指定するとコメントは自動では作られないので、ワークフローで投稿ツールを許可する必要があります。
Team / Enterprise なら、マネージドの Code Reviewという選択肢もあります。
今回は個人プランでも試しやすい方法でやってみました。








