terraform-review

PR review checklist for Terraform changes covering structure, state safety, security, naming, modules, variables, providers, and CI/CD. Use when reviewing Terraform PRs or doing pre-merge checks.

c0x12c/ai-toolkit78 installsMITSynced Aug 26

Works with

Claude CodeCursorCodex CLIGitHub CopilotGemini CLI
---
name: terraform-review
description: PR review checklist for Terraform changes covering structure, state safety, security, naming, modules, variables, providers, and CI/CD. Use when reviewing Terraform PRs or doing pre-merge checks.
license: MIT
---

# Terraform Review

Runs an 8-category review checklist on Terraform changes. Produces an Approved / Needs Changes / Blocked verdict.

## When to Use

- Reviewing a Terraform pull request
- Pre-merge validation of infrastructure changes
- Self-review before opening a PR
- Auditing existing Terraform code

## Process

### 1. Structure

- [ ] Files follow standard layout: `live/`, `modules/`, `envs/`
- [ ] One resource per file in modules
- [ ] `terraform.tf` has backend + provider config
- [ ] `variables.tf`, `outputs.tf`, `locals.tf` are separate files
- [ ] No `.terraform/` or `*.tfstate*` in the PR

```
# CORRECT structure
terraform/
  live/terraform.tf        # backend + provider
  live/variables.tf        # inputs
  live/locals.tf           # computed values
  live/outputs.tf          # exports
  modules/{service}/       # one resource per file
  envs/{env}/              # per-environment config

# WRONG — everything in one file
terraform/main.tf          # 500 lines of mixed resources
```

### 2. State Safety

- [ ] No `terraform state` commands in automation
- [ ] State stored in S3 with DynamoDB locking
- [ ] `prevent_destroy` on critical resources (RDS, S3 with data)
- [ ] No resources removed without `terraform state rm` plan documented
- [ ] `create_before_destroy` on security groups and launch configs
- [ ] Import blocks used for adopting existing resources (not `terraform import` CLI)

```hcl
# CORRECT — protect critical resources
resource "aws_db_instance" "main" {
  lifecycle {
    prevent_destroy = true
  }
}

# CORRECT — zero-downtime SG updates
resource "aws_security_group" "app" {
  name_prefix = "${local.name_prefix}-app-"
  lifecycle {
    create_before_destroy = true
  }
}
```

### 3. Security

- [ ] No secrets in `.tf` or `.tfvars` committed to git
- [ ] Sensitive variables marked `sensitive = true`
- [ ] S3 buckets block public access
- [ ] RDS/Redis in private subnets only
- [ ] Security groups follow least privilege (no `0.0.0.0/0` ingress on non-ALB)
- [ ] Encryption enabled (S3 SSE, RDS encryption, Redis transit + at-rest)
- [ ] IAM policies use least privilege, no `*` actions on `*` resources

```hcl
# WRONG — overly permissive
resource "aws_security_group_rule" "bad" {
  cidr_blocks = ["0.0.0.0/0"]
  from_port   = 0
  to_port     = 65535
}

# CORRECT — scoped to specific source
resource "aws_security_group_rule" "good" {
  source_security_group_id = var.alb_security_group_id
  from_port                = 8080
  to_port                  = 8080
}
```

### 4. Naming

- [ ] Resources use `local.name_prefix` (pattern: `{project}-{service}-{env}`)
- [ ] Consistent naming across all resources in the module
- [ ] Tags include: Project, Service, Environment, ManagedBy
- [ ] No hardcoded names or account IDs

```hcl
# CORRECT
locals {
  name_prefix = "${var.project}-${var.service}-${var.env}"
}

# WRONG
resource "aws_s3_bucket" "assets" {
  bucket = "my-bucket-prod"  # hardcoded
}
```

### 5. Modules

- [ ] No provider blocks inside modules
- [ ] Module source uses version pinning (`?ref=vX.Y.Z`)
- [ ] No circular module dependencies
- [ ] Module outputs only expose what consumers need
- [ ] Modules have `versions.tf` with required provider versions

```hcl
# CORRECT — pinned version
module "rds" {
  source = "git::https://github.com/{project}/terraform-modules.git//rds?ref=v1.2.0"
}

# WRONG — no version pin
module "rds" {
  source = "git::https://github.com/{project}/terraform-modules.git//rds"
}
```

### 6. Variables

- [ ] All variables have `description` and `type`
- [ ] Sensitive variables marked `sensitive = true`
- [ ] Validation blocks on critical inputs (CIDR, names, enums)
- [ ] No unused variables
- [ ] Defaults are sensible for dev, overridden per env

```hcl
# CORRECT
variable "instance_class" {
  description = "RDS instance class"
  type        = string
  default     = "db.t3.micro"

  validation {
    condition     = can(regex("^db\\.", var.instance_class))
    error_message = "Must be a valid RDS instance class."
  }
}

# WRONG — no description, no type
variable "instance_class" {}
```

### 7. Providers

- [ ] Provider versions pinned with `~>` (pessimistic constraint)
- [ ] `required_version` for Terraform itself
- [ ] Provider config only in `live/terraform.tf`, never in modules
- [ ] Default tags configured at provider level

### 8. CI/CD

- [ ] `terraform fmt -check` runs in CI
- [ ] `terraform validate` runs in CI
- [ ] Plan output posted as PR comment
- [ ] Apply only runs on merge to main
- [ ] State locking prevents concurrent applies
- [ ] Secrets injected via CI environment, not committed

## Interaction Style

- Reads all changed `.tf` files in the PR
- Checks every category — does not skip sections
- Flags blocking issues (security, state safety) separately from suggestions
- Shows exact file and line for each finding

## Rules

- Blocking issues: secrets in code, no state locking, `0.0.0.0/0` ingress, missing encryption
- Needs Changes: missing descriptions, no version pin, naming inconsistency
- Suggestions: code style, optional validations, documentation

## Output

Produces a structured review:

```
## Terraform Review: {PR title}

### Verdict: Approved | Needs Changes | Blocked

### Findings

#### Blocked (if any)
- [ ] **[Security]** Secrets found in terraform.tfvars — file:line

#### Needs Changes (if any)
- [ ] **[Naming]** Hardcoded bucket name in s3.tf:12
- [ ] **[Modules]** Missing version pin on RDS module

#### Suggestions (if any)
- **[Variables]** Consider adding validation on `instance_class`

### Checklist Summary
| Category  | Status |
|-----------|--------|
| Structure | Pass   |
| State     | Pass   |
| Security  | Fail   |
| Naming    | Warn   |
| Modules   | Warn   |
| Variables | Pass   |
| Providers | Pass   |
| CI/CD     | Pass   |
```

More Code Review skills

pr-to-video

heygen-com/hyperframes

Turn a GitHub pull request (a PR URL, owner/repo#N, or 'this PR' in a checked-out repo) into a code-change explainer video — changelog, feature reveal, fix, or refactor walkthrough built from the diff, commits, and files: the input is a code change, not a website. Not a product promo (/product-launch-video) or a no-PR topic explainer (/faceless-explainer). Unclear → /hyperframes.

178.9k

receiving-code-review

obra/superpowers

Use when receiving code review feedback, before implementing suggestions, especially if feedback seems unclear or technically questionable - requires technical rigor and verification, not performative agreement or blind implementation

178.0k

public-relations

coreyhaines31/marketingskills

When the user wants help with public relations, earned media, press coverage, journalist outreach, or media strategy (not pull requests). Also use when the user mentions 'PR,' 'public relations,' 'press,' 'press release,' 'press coverage,' 'media outreach,' 'pitch a journalist,' 'get featured,' 'media list,' 'media kit,' 'press kit,' 'newsjacking,' 'news hijack,' 'HARO,' 'Qwoted,' 'Featured,' 'Help A Reporter,' 'reporter request,' 'tech press,' 'TechCrunch,' 'earned media,' 'thought leadership placement,' 'op-ed,' 'guest article,' 'press contacts,' 'podcast prep,' 'going on a podcast,' 'podcast guest,' 'prep me for this podcast,' or 'how do I get press.' Use this for earned media work — finding journalists, pitching stories, newsjacking, prepping podcast appearances, and responding to press requests. For startup/SaaS/AI directory submissions, see directory-submissions. For product launches, see launch. For social-media engagement, see social. For cold-email outreach to prospects, see cold-email.

33.1k

← All Code Review skills

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY