「Terraformのコードを書くのに時間がかかる」「既存のインフラをコード化したいけど手が回らない」——SES現場でインフラを担当するエンジニアなら、こんな悩みを抱えたことがあるのではないでしょうか。
**Claude CodeとTerraformを組み合わせると、インフラコードの生成・レビュー・リファクタリングが劇的に効率化されます。**手動で書いていたHCLコードの大部分をAIが自動生成し、plan結果の解析まで自然言語で行えるようになります。
この記事では、Claude CodeでTerraformのIaCワークフローを自動化する具体的な手法を、基礎から応用まで体系的に解説します。

Claude Code × Terraformの相性が良い理由
Claude Codeは、コードベース全体を理解した上でコードを生成する能力に優れたAIコーディングツールです。Terraformとの組み合わせが特に強力な理由は以下の通りです。
HCLコードの構造的特性
Terraformの主要言語であるHCL(HashiCorp Configuration Language)は、以下の特性を持ちます。
- 宣言的構文: リソースの「あるべき状態」を記述するため、AIが意図を理解しやすい
- プロバイダードキュメントが充実: AWSやGCPの全リソースに対する定義が明確
- モジュール化パターン: 再利用可能なパターンが確立されており、AIが学習しやすい
- 型システム: 変数の型定義が明確で、バリデーションが容易
Claude Codeの強み
# プロジェクト全体のコンテキストを理解した上でコードを生成
claude "現在のAWSインフラ構成を分析して、VPC・サブネット・セキュリティグループの
Terraformコードを生成して。既存のmain.tfとの整合性も考慮して。"
Claude Codeはプロジェクト全体のファイルを横断的に読み込むため、既存のTerraformコードとの整合性を保ちながら新しいリソース定義を生成できます。これは、ファイル単位でしかコンテキストを持てない他のAIツールとの大きな違いです。
環境構築:Claude Code × Terraform の開発環境
前提条件
まず、以下のツールがインストールされていることを確認します。
# Terraform のバージョン確認
terraform version
# Terraform v1.9.x 以上を推奨
# Claude Code のバージョン確認
claude --version
# AWS CLI(AWSを使う場合)
aws --version
aws sts get-caller-identity
CLAUDE.md にTerraformルールを追加
プロジェクトルートの CLAUDE.md に、Terraform固有のルールを記載します。
# CLAUDE.md
## Terraform ルール
- HCLコードは HashiCorp Style Guide に準拠する
- リソース名はスネークケース(例: aws_vpc.main)
- 変数は variables.tf に集約、出力は outputs.tf に集約
- 環境ごとの tfvars ファイルを使用(dev.tfvars, staging.tfvars, prod.tfvars)
- モジュールは modules/ ディレクトリに配置
- state は S3 + DynamoDB でリモート管理
- sensitive な値は variables で type = string, sensitive = true を設定
- terraform fmt と terraform validate を commit 前に実行
プロジェクト構成の推奨パターン
infrastructure/
├── CLAUDE.md
├── main.tf # プロバイダー設定・バックエンド
├── variables.tf # 入力変数
├── outputs.tf # 出力値
├── locals.tf # ローカル値
├── terraform.tfvars # デフォルト値
├── environments/
│ ├── dev.tfvars
│ ├── staging.tfvars
│ └── prod.tfvars
├── modules/
│ ├── networking/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── compute/
│ └── database/
└── .github/
└── workflows/
└── terraform.yml
基本操作:Claude CodeでTerraformコードを生成する
新規リソースの生成
最も基本的な使い方は、自然言語でインフラ要件を伝えてHCLコードを生成させることです。
# VPCとサブネットの生成
claude "AWSのVPCを作成して。CIDR 10.0.0.0/16、パブリックサブネット2つ(AZ-a, AZ-c)、
プライベートサブネット2つ(AZ-a, AZ-c)、NATゲートウェイ付き。
modules/networking/ に配置して。"
Claude Codeは以下のようなコードを生成します。
# modules/networking/main.tf
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = merge(var.common_tags, {
Name = "${var.project_name}-vpc"
})
}
resource "aws_subnet" "public" {
count = length(var.public_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
map_public_ip_on_launch = true
tags = merge(var.common_tags, {
Name = "${var.project_name}-public-${count.index + 1}"
Type = "public"
})
}
resource "aws_subnet" "private" {
count = length(var.private_subnet_cidrs)
vpc_id = aws_vpc.main.id
cidr_block = var.private_subnet_cidrs[count.index]
availability_zone = var.availability_zones[count.index]
tags = merge(var.common_tags, {
Name = "${var.project_name}-private-${count.index + 1}"
Type = "private"
})
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = merge(var.common_tags, {
Name = "${var.project_name}-igw"
})
}
resource "aws_eip" "nat" {
domain = "vpc"
tags = merge(var.common_tags, {
Name = "${var.project_name}-nat-eip"
})
}
resource "aws_nat_gateway" "main" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public[0].id
tags = merge(var.common_tags, {
Name = "${var.project_name}-nat"
})
depends_on = [aws_internet_gateway.main]
}
既存インフラのコード化(リバースエンジニアリング)
既に手動で作成されたAWSリソースをTerraformコードに変換する場合も、Claude Codeが強力なサポートを提供します。
# AWS CLIの出力をClaude Codeに渡す
aws ec2 describe-vpcs --output json > /tmp/vpcs.json
aws ec2 describe-subnets --output json > /tmp/subnets.json
aws ec2 describe-security-groups --output json > /tmp/sgs.json
claude "以下のAWSリソース情報をもとに、Terraformコードを生成して。
/tmp/vpcs.json, /tmp/subnets.json, /tmp/sgs.json を読み取って、
再現可能なHCLコードにまとめて。import ブロックも生成して。"
terraform import の自動化
# imports.tf - Claude Codeが生成するimportブロック
import {
to = aws_vpc.main
id = "vpc-0abc123def456789"
}
import {
to = aws_subnet.public[0]
id = "subnet-0abc123def456789"
}
import {
to = aws_subnet.public[1]
id = "subnet-1abc123def456789"
}
# import後にplanで差分確認
terraform plan -generate-config-out=generated.tf
実践テクニック:Terraform開発を加速する7つの方法
1. モジュール設計の自動化
claude "ECS Fargateサービスのモジュールを作成して。
以下を含めて:
- タスク定義(CPU/メモリ可変)
- サービス(デプロイメントサーキットブレーカー付き)
- ALBターゲットグループ
- オートスケーリング(CPU/メモリベース)
- CloudWatchアラーム
- セキュリティグループ
入力変数は最小限に抑えつつ、柔軟性を確保して。"
Claude Codeはベストプラクティスに基づいたモジュールを生成します。以下のような設計原則が自動的に適用されます。
| 設計原則 | Claude Codeの対応 |
|---|---|
| 単一責任 | モジュールごとに1つの論理的リソース群 |
| 疎結合 | 出力値を通じた依存関係の明示 |
| 設定可能性 | デフォルト値付きの変数で柔軟に |
| セキュリティ | 最小権限のIAMポリシー自動生成 |
| コスト最適化 | タグ付けとライフサイクルルール |
2. plan結果の解析
# plan結果をJSON形式で出力
terraform plan -out=plan.tfplan
terraform show -json plan.tfplan > plan.json
# Claude Codeにplan結果を解析させる
claude "plan.json を読んで、変更内容を日本語で要約して。
特に以下に注目して:
1. 破壊的変更(destroy)があるか
2. セキュリティに影響する変更
3. コストに影響する変更
4. ダウンタイムが発生する可能性"
Claude Codeは以下のような分析結果を提供します。
## Plan分析レポート
### ⚠️ 注意が必要な変更
- `aws_db_instance.main`: instance_class変更 → **ダウンタイムが発生**
→ 対策: メンテナンスウィンドウを設定、レプリカでフェイルオーバー
### ✅ 安全な変更
- `aws_s3_bucket_versioning.main`: バージョニング有効化 → 非破壊的
- `aws_cloudwatch_metric_alarm.cpu`: 閾値変更 → 即時適用
### 💰 コスト影響
- RDSインスタンスタイプ変更: 推定 +$50/月
- NATゲートウェイ追加: 推定 +$45/月
3. セキュリティレビューの自動化
claude "infrastructure/ ディレクトリ全体のTerraformコードをセキュリティ観点でレビューして。
以下のチェックリストに基づいて:
- S3バケットのパブリックアクセスブロック
- セキュリティグループのインバウンドルール(0.0.0.0/0の開放)
- IAMポリシーの最小権限原則
- 暗号化(at-rest, in-transit)の設定
- CloudTrailの有効化
- VPCフローログの設定"
4. tfvars ファイルの環境別生成
claude "dev.tfvars を元に、staging.tfvars と prod.tfvars を生成して。
以下のルールに従って:
- staging: devの2倍のスペック、マルチAZ有効
- prod: stagingの2倍のスペック、バックアップ有効、暗号化必須
- 命名規則は環境プレフィックスを付与(dev-xxx, staging-xxx, prod-xxx)"
5. Terraformバージョンアップの支援
claude "現在のTerraformコード(v1.5用)をv1.9に対応させて。
特に以下の変更を適用して:
- removed ブロックの使用
- import ブロック対応
- check ブロックでのアサーション追加
- terraform test の設定ファイル生成"
6. ドリフト検出とレポート
# 現在の状態とコードの差分を検出
terraform plan -detailed-exitcode 2>&1 | tee /tmp/drift.txt
claude "/tmp/drift.txt を分析して、ドリフトが発生しているリソースの一覧と
原因の推測、修正方法を提案して。手動変更を取り込むかコードに合わせるか、
それぞれのメリット・デメリットも教えて。"
7. テストコードの自動生成
claude "modules/networking/ のTerraformモジュールに対して、
terraform test のテストファイルを生成して。以下を検証するテストを書いて:
- VPCのCIDRが正しい
- サブネットが指定数作成される
- NATゲートウェイが稼働している
- プライベートサブネットからインターネットに出られる"
# tests/networking.tftest.hcl
run "vpc_creation" {
command = plan
variables {
project_name = "test"
vpc_cidr = "10.0.0.0/16"
public_subnet_cidrs = ["10.0.1.0/24", "10.0.2.0/24"]
private_subnet_cidrs = ["10.0.10.0/24", "10.0.11.0/24"]
availability_zones = ["ap-northeast-1a", "ap-northeast-1c"]
}
assert {
condition = aws_vpc.main.cidr_block == "10.0.0.0/16"
error_message = "VPC CIDRが期待値と異なる"
}
assert {
condition = length(aws_subnet.public) == 2
error_message = "パブリックサブネットの数が期待値と異なる"
}
assert {
condition = length(aws_subnet.private) == 2
error_message = "プライベートサブネットの数が期待値と異なる"
}
}
CI/CD連携:GitHub ActionsとClaude Code × Terraform
自動planワークフロー
Pull Request作成時にClaude Codeが自動的にplan結果をレビューするワークフローを構築できます。
# .github/workflows/terraform-plan.yml
name: Terraform Plan with AI Review
on:
pull_request:
paths:
- 'infrastructure/**'
jobs:
plan:
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: read
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: 1.9.0
- name: Terraform Init
working-directory: infrastructure
run: terraform init
- name: Terraform Plan
working-directory: infrastructure
run: |
terraform plan -no-color -out=plan.tfplan 2>&1 | tee plan.txt
terraform show -json plan.tfplan > plan.json
- name: AI Review with Claude Code
run: |
claude --print "plan.json を読んで、このPRのインフラ変更を
日本語でレビューして。破壊的変更・セキュリティリスク・
コスト影響・改善提案をMarkdownで出力して。" > review.md
- name: Post Review Comment
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const review = fs.readFileSync('review.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: `## 🤖 AI Infrastructure Review\n\n${review}`
});
自動apply パイプライン
# .github/workflows/terraform-apply.yml
name: Terraform Apply
on:
push:
branches: [main]
paths:
- 'infrastructure/**'
jobs:
apply:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
- name: Terraform Init & Apply
working-directory: infrastructure
run: |
terraform init
terraform apply -auto-approve
実務で使えるCLAUDE.mdテンプレート集
AWS環境向け
# CLAUDE.md - AWS Terraform Project
## プロジェクト概要
- 環境: AWS ap-northeast-1 (東京リージョン)
- Terraform: v1.9+
- State: S3 + DynamoDB
## コーディングルール
- リソース名: {project}-{env}-{resource} 形式
- タグ: Project, Environment, ManagedBy=terraform は必須
- セキュリティグループ: 明示的な deny-all デフォルト
- S3: 暗号化必須、パブリックアクセスブロック必須
- RDS: マルチAZ(prod)、暗号化必須、自動バックアップ7日
## 禁止事項
- ハードコードされたAWSアカウントID
- ワイルドカード(*)のIAMポリシー
- 0.0.0.0/0 のインバウンドルール(ALB以外)
- default VPC の使用
マルチクラウド向け
# CLAUDE.md - Multi-Cloud Terraform
## プロバイダー
- AWS: メインワークロード
- GCP: データ分析・ML
- Cloudflare: CDN・DNS
## 共通ルール
- 各プロバイダーのリソースは別ディレクトリ
- 共有リソース(VPN接続等)は shared/ に配置
- 環境変数でプロバイダー認証(ハードコード禁止)
- terraform workspace は使用しない(tfvarsで環境分離)
SES現場での活用シナリオ
シナリオ1:新規プロジェクトのインフラ構築
SES案件で新規プロジェクトにアサインされた場合、Claude Codeを使えばインフラの初期構築を数時間で完了できます。
# 要件をまとめてClaude Codeに伝える
claude "以下の要件でAWSインフラのTerraformコードを生成して:
- Webアプリケーション(Next.js)
- ECS Fargate + ALB
- RDS PostgreSQL(マルチAZ)
- ElastiCache Redis
- S3(静的ファイル)+ CloudFront
- VPC(パブリック/プライベートサブネット)
- CloudWatch(アラーム・ダッシュボード)
- 環境: dev/staging/prod の3環境
- 予算: 月額10万円以内(dev環境)"
シナリオ2:レガシーインフラのコード化
手動で構築されたインフラをTerraform管理に移行するプロジェクトでは、Claude Codeが特に威力を発揮します。
# 1. 現状のAWSリソースを棚卸し
aws resourcegroupstaggingapi get-resources --output json > resources.json
# 2. Claude Codeにコード化させる
claude "resources.json の全AWSリソースをTerraformコードに変換して。
terraform import 用のコマンドリストも生成して。
既存リソースを壊さないよう、lifecycle { prevent_destroy = true } を付けて。"
シナリオ3:コスト最適化
claude "現在のTerraformコードを分析して、コスト最適化の提案をして。
以下の観点で:
- 過剰スペックのリソース
- リザーブドインスタンスの候補
- 不要なNATゲートウェイ
- S3ライフサイクルポリシー
- 未使用のEIPやEBS
Infracostの形式でコスト比較も出して。"
トラブルシューティング
よくあるエラーと対処法
1. 循環参照エラー
claude "以下のTerraformエラーを解決して:
Error: Cycle: aws_security_group.web, aws_security_group.app
循環参照を避けつつ、WebとAppのセキュリティグループ間の
通信を許可する方法を提案して。"
解決策: aws_security_group_rule を別リソースとして定義する。
resource "aws_security_group" "web" {
name_prefix = "web-"
vpc_id = aws_vpc.main.id
}
resource "aws_security_group" "app" {
name_prefix = "app-"
vpc_id = aws_vpc.main.id
}
# 別リソースでルールを定義(循環参照を回避)
resource "aws_security_group_rule" "web_to_app" {
type = "egress"
from_port = 8080
to_port = 8080
protocol = "tcp"
security_group_id = aws_security_group.web.id
source_security_group_id = aws_security_group.app.id
}
2. State ロックの解消
claude "Terraform state lockが解除されない。DynamoDBのロックテーブルを確認して
安全にロックを解除する手順を教えて。force-unlockのリスクも説明して。"
3. プロバイダーバージョンの非互換
claude "terraform init で以下のエラーが出た:
'Error: Failed to query available provider packages'
.terraform.lock.hcl を更新して解決して。"
ベストプラクティスまとめ
Claude Code × Terraform を最大限活用するための5つのポイント
- CLAUDE.md を充実させる: プロジェクト固有の命名規則・タグルール・セキュリティポリシーを明記
- plan結果を必ずAIレビューする: 人間の見落としをAIがカバー
- モジュール単位で作業する: 小さなスコープで生成→検証のサイクルを回す
- テストを自動生成する: terraform testで変更の安全性を担保
- CI/CDに組み込む: PR時の自動plan・レビューで品質を維持
Claude Codeコマンド チートシート
| ユースケース | コマンド例 |
|---|---|
| リソース生成 | claude "S3バケット+CloudFrontのTerraformコードを生成して" |
| Plan解析 | claude "plan.json を分析して変更点を要約して" |
| セキュリティレビュー | claude "このTerraformコードのセキュリティリスクを指摘して" |
| コスト見積もり | claude "このインフラの月額コストを概算して" |
| リファクタリング | claude "このTerraformコードをモジュール化して" |
| バージョンアップ | claude "Terraform 1.5→1.9の移行対応をして" |
| テスト生成 | claude "このモジュールのtftest.hclを生成して" |
まとめ
Claude Code × Terraformの組み合わせは、SES現場でのインフラ構築・運用を大幅に効率化します。特に以下の場面で威力を発揮します。
- 新規プロジェクト: 要件定義から数時間でインフラコードを生成
- レガシー移行: 既存インフラのコード化を自動化
- 運用フェーズ: plan解析・ドリフト検出・コスト最適化
重要なのは、AIが生成したコードを必ずplan結果で検証すること。Claude Codeは強力なツールですが、最終的な判断は人間が行うべきです。
まずは小さなモジュールから始めて、Claude Code × Terraformの威力を実感してみてください。