77 lines | 3.2 KB

Terraform — Claude Code rules

Follow the official HashiCorp Terraform Style Guide. These conventions keep configuration readable, reviewable, and safe to apply.

Formatting

  • Run terraform fmt and terraform validate before committing. Use terraform fmt -recursive to format subdirectories.
  • Indent two spaces per nesting level.
  • Align the = signs when consecutive single-line arguments sit at the same level.
  • Use # for both single- and multi-line comments. Avoid // and /* */.
  • Separate top-level blocks with one blank line; group logically related arguments with blank lines.

File & module structure

  • Use the standard file layout so maintainers know where to look:
    • terraform.tfterraform block with required_version and required_providers.
    • providers.tf — provider blocks (default provider first).
    • backend.tf — backend configuration.
    • main.tf — resources and data sources.
    • variables.tfvariable blocks, alphabetical.
    • outputs.tfoutput blocks, alphabetical.
    • locals.tf — local values referenced across files.
  • For larger codebases, split main.tf by logical group (network.tf, compute.tf, storage.tf).
  • Create a module only when it introduces a new abstraction. Don't write thin wrappers around a single resource type. Keep the module tree flat and prefer composition over deep nesting.
  • Name module repositories terraform-<PROVIDER>-<NAME>. Store local modules in ./modules/<name>.

Naming

  • Use descriptive nouns with underscores: snake_case.
  • Do NOT include the resource type in the resource name — the address already has it: resource "aws_instance" "web_api", not "web_api_instance".
  • Order resources for readability. Define data sources before the resources that reference them.

Variables & outputs

  • Define a type and description for every variable and output.
  • Give optional variables a reasonable default.
  • Mark passwords and private keys sensitive = true (note: still stored plaintext in state).
  • Use input variable validation only for uniquely restrictive requirements.
  • Don't hardcode values that vary by environment — use variables or locals.
  • Avoid overusing variables and local values; use locals sparingly.

Resource arguments

  • Recommended argument order inside a resource:
    1. count / for_each meta-argument
    2. non-block parameters
    3. block parameters
    4. lifecycle block (if needed)
    5. depends_on (if needed)
  • Use count for near-identical resources; use for_each when values can't be derived from an integer. Use both in moderation and comment non-obvious effects.

Versions & dependencies

  • Set required_version in the terraform block.
  • Pin providers in required_providers with explicit version constraints.
  • Pin modules to specific major and minor versions.
  • Commit the .terraform.lock.hcl dependency lock file.

Don't

  • Don't commit *.tfstate / *.tfstate.*, .terraform/, .terraform.tfstate.lock.info, saved plan files, or *.tfvars with secrets.
  • Don't store secrets in code — use env vars, Vault, or your CI secret store.
  • Don't include the resource type in resource/output names.
  • Don't use // or /* */ comments.