← All guides

Claude Code for Terraform: IaC Generation Guide

Use Claude Code to write Terraform modules, generate AWS/GCP/Azure resources, manage remote state, review plans, and enforce IAM least privilege. Full.

Claude Code for Terraform: IaC Generation Guide

Claude Code writes production-ready Terraform HCL from plain English. Describe your target infrastructure — a VPC, an EKS cluster, an S3-backed remote state — and Claude generates the module, variables, outputs, and provider config. A full AWS multi-tier environment that takes a senior engineer 4–6 hours to scaffold manually can be done in under 30 minutes. Claude also reviews terraform plan output, detects drift, generates IAM least-privilege policies, and integrates with Terragrunt DRY patterns.

This guide covers every stage of the Terraform workflow: module scaffolding, cloud resource generation, state management, plan review, drift detection, and security hardening.


Setup: Add Terraform Context to CLAUDE.md

Add your infrastructure conventions once so every subsequent prompt inherits them:

## Terraform Configuration
- Provider: AWS (primary), region: us-east-1
- State backend: S3 bucket `my-org-tfstate`, DynamoDB table `terraform-locks`
- Naming: {project}-{env}-{resource} (e.g., acme-prod-vpc)
- Tagging: Environment, Owner, CostCenter, ManagedBy=terraform (all required)
- Terraform >= 1.7, AWS provider ~> 5.0
- No hardcoded secrets — use aws_secretsmanager_secret_version data sources

See Claude Code Complete Guide for the full CLAUDE.md strategy.


VPC Module Scaffolding

claude "Scaffold a reusable Terraform VPC module.
- 3 public + 3 private subnets across us-east-1a/b/c
- NAT Gateway per AZ, VPC Flow Logs to CloudWatch
- Variables: vpc_cidr, environment, project_name, tags
- Outputs: vpc_id, public_subnet_ids, private_subnet_ids
Apply CLAUDE.md conventions."
# modules/vpc/main.tf
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = merge(var.tags, {
    Name        = "${var.project_name}-${var.environment}-vpc"
    Environment = var.environment
    ManagedBy   = "terraform"
  })
}

resource "aws_subnet" "private" {
  count             = 3
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(var.vpc_cidr, 4, count.index + 3)
  availability_zone = data.aws_availability_zones.available.names[count.index]

  tags = merge(var.tags, {
    Name = "${var.project_name}-${var.environment}-private-${count.index + 1}"
    Tier = "private"
  })
}

EKS Cluster Generation

claude "Generate an EKS 1.30 cluster on private subnets.
- Managed node group: t3.xlarge, min 2 / max 10 / desired 3
- OIDC provider for IRSA, control plane logging: api, audit, authenticator
- Add-ons: vpc-cni, coredns, kube-proxy, aws-ebs-csi-driver"

For Kubernetes manifests alongside these resources, see Claude Code for Kubernetes and DevOps.


Remote State: S3 Backend with DynamoDB Locking

claude "Generate Terraform remote state backend config:
- S3 bucket with versioning, KMS encryption, public access blocked
- DynamoDB table for locking (LockID partition key, PAY_PER_REQUEST)
- Separate bootstrap module to create the backend resources first"
# backend.tf
terraform {
  backend "s3" {
    bucket         = "my-org-tfstate"
    key            = "acme/prod/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-locks"
    kms_key_id     = "alias/terraform-state"
  }
}

# modules/bootstrap/main.tf
resource "aws_dynamodb_table" "tflock" {
  name         = "terraform-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

Terraform Plan Review with Claude Code

Feed terraform plan output directly to Claude for semantic analysis:

terraform plan -out=tfplan.binary
terraform show -json tfplan.binary > tfplan.json
claude "Review this plan. Flag resource deletions, security group rules 
opening public access, IAM policy expansions, and anything causing downtime. 
Explain each risk and suggest safer alternatives." < tfplan.json

Claude returns a structured risk report that catches issues terraform validate and tflint miss because they require understanding of what changes mean operationally — not just syntax.


Drift Detection

claude "Analyze this 'terraform plan' output from a production environment 
that should have zero changes. Identify drifted resources, classify each 
change (config vs. tags vs. permissions), and suggest the safest 
remediation order to avoid downtime."

For automated drift alerts, Claude can write a GitHub Actions workflow that runs terraform plan on a schedule and posts a diff summary to Slack when drift is detected.


Mid-Article CTA

Need 300 tested prompts for Terraform, IaC, and cloud infrastructure? Power Prompts 300 ($29) includes VPC/EKS/RDS module prompts, Terragrunt DRY patterns, IAM policy generators, and CLAUDE.md templates for 5 infrastructure project types.

→ Get Power Prompts 300 — $29


Terragrunt Patterns

claude "Refactor this flat Terraform repo into Terragrunt DRY structure.
- Root terragrunt.hcl with remote_state and generate blocks
- Folders: dev/, staging/, prod/ with account.hcl and region.hcl
- Each module has terragrunt.hcl with dependency blocks
- S3 backend config in exactly one place"

Claude generates the full directory tree with correct dependency and inputs blocks, plus run_cmd hooks for aws-vault credential injection.


Security: IAM Least Privilege and No Hardcoded Secrets

IAM Policy with Conditions

resource "aws_iam_policy" "eks_node" {
  name   = "${var.project_name}-${var.environment}-eks-node"
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "ECRReadOnly"
        Effect = "Allow"
        Action = ["ecr:GetAuthorizationToken", "ecr:BatchGetImage",
                  "ecr:GetDownloadUrlForLayer"]
        Resource = "*"
        Condition = { StringEquals = {
          "aws:ResourceAccount" = var.aws_account_id } }
      },
      {
        Sid      = "SSMParameterStore"
        Effect   = "Allow"
        Action   = ["ssm:GetParameter", "ssm:GetParameters"]
        Resource = "arn:aws:ssm:${var.region}:${var.aws_account_id}:parameter/acme/prod/*"
      }
    ]
  })
}

Generate this with:

claude "Write a least-privilege IAM policy for EKS nodes: ECR read access 
scoped to this account, SSM GetParameter on /acme/prod/* only, 
CloudWatch Logs scoped to this region. Add a Deny statement if the 
request is not from our VPC endpoint."

For secrets and vulnerability scanning across your codebase, see Claude Code Security Scanning.


Greenfield Infrastructure in 30 Minutes

The full Claude Code prompt sequence for a production-ready AWS multi-tier setup:

Step 1 — Bootstrap (2 min)

claude "Create a bootstrap module: S3 state bucket + DynamoDB lock table + 
KMS key. Runs from local state first, then migrates. Include migrate.sh."

Step 2 — Networking (8 min)

claude "VPC 10.0.0.0/16, 3 AZs, public/private/data subnets, 
Route53 private hosted zone. Apply CLAUDE.md naming and tagging."

Step 3 — Compute (10 min)

claude "EKS 1.30 on private subnets. IRSA OIDC provider, 
Karpenter node provisioner, aws-load-balancer-controller IAM role."

Step 4 — Data layer (7 min)

claude "RDS Aurora PostgreSQL 16 on data subnets: writer + reader, 
auto-scaling read replicas up to 5, credentials in Secrets Manager 
with automatic rotation, Performance Insights enabled."

Step 5 — Security review (3 min)

claude "Audit all .tf files: no public S3 buckets, security groups 
follow least privilege, encryption at rest on all storage, no hardcoded 
values, all resources tagged per CLAUDE.md. Output a PASS/FAIL checklist."

Frequently Asked Questions

How does Claude Code work with Terraform vs Pulumi vs CDK?

Claude Code generates HCL for Terraform, TypeScript for CDK, and Python/TypeScript for Pulumi equally well. Specify your tool in CLAUDE.md and Claude applies it consistently. Terraform HCL currently yields the highest-quality output because of training data volume, but CDK and Pulumi are both well-supported. The IaC tool choice is independent of whether you use Claude Code.

Can Claude Code run terraform apply for me?

Yes — if you grant shell execution permissions, Claude can run terraform init, terraform plan, and terraform apply in sequence. The recommended workflow: Claude generates and reviews the plan first, then asks for explicit confirmation before apply. Scope the IAM role Claude uses to only the resources it needs; never give it unrestricted Admin access.

How does Claude handle existing Terraform state?

Provide context before changes: claude "Read all .tf files and describe the current infrastructure before modifying anything." Claude reads your existing resources and avoids generating conflicting configurations. For large codebases, point it to specific modules first.

Does Claude Code work with the Terraform public registry?

Yes. Specify the source in your prompt: "Use terraform-aws-modules/eks/aws version ~> 20.0." Claude generates the correct module block with all required inputs and pins the version. It also knows which module inputs are required vs. optional for the most popular registry modules.

How do I integrate Claude Code Terraform workflows into CI/CD?

claude "Write a GitHub Actions workflow: terraform fmt check and validate 
on PRs, plan output posted as PR comment via tfcmt, manual approval gate 
before apply on main, OIDC for AWS auth (no stored keys), .terraform cache."

Claude generates the complete workflow YAML in one pass. See Claude Code for Kubernetes and DevOps for related pipeline patterns.


Want the complete library of Terraform prompts, Terragrunt templates, and IaC CLAUDE.md configurations? Power Prompts 300 ($29) includes 300 field-tested prompts covering AWS/GCP/Azure generation, state management, drift detection, and security hardening.

→ Get Power Prompts 300 — $29

Tools and references