Skip to content
Development
Skill

/ia-terraform

Terraform and OpenTofu configuration, modules, testing, state management, and HCL review. Use when working with Terraform, OpenTofu, HCL, tfvars, tftest, state migration, or IaC patterns.

From plugin
whetstone
3630 skills18 agents31 commands1 MCP

Claude Code

$ npx -y skills add iliaal/whetstone --skill ia-terraform --agent claude-code

SKILL.md

ia-terraform.SKILL.md
name: ia-terraform
class: language
description: >-
  Terraform and OpenTofu configuration, modules, testing, state management, and
  HCL review. Use when working with Terraform, OpenTofu, HCL, tfvars, tftest,
  state migration, or IaC patterns.
paths:
  - "**/*.tf"
  - "**/*.tfvars"

Terraform & OpenTofu

Working rules

  • Preserve state and resource addresses during refactoring; inspect the plan for unintended replacement.
  • Separate tests with verified local or mocked effects from tests that access real services or create billable infrastructure. Plan mode can still read real data sources; mocked apply can run without infrastructure creation.

File Organization & Naming

| File | Purpose | |------|---------| | `terraform.tf` | Terraform + provider version requirements | | `providers.tf` | Provider configurations | | `main.tf` | Primary resources and data sources | | `variables.tf` | Input variables (alphabetical) | | `outputs.tf` | Output values (alphabetical) | | `locals.tf` | Local values |

  • Lowercase with underscores: `web_api`, not `webAPI` or `web-api`
  • Descriptive nouns excluding resource type: `aws_instance.web_api` not `aws_instance.web_api_instance`
  • Singular, not plural
  • `this` for singleton resources (one of that type per module)
  • Contextual variable prefixes: `vpc_cidr_block` not `cidr`

Block Ordering

**Resources:** `count`/`for_each` (blank line after) → arguments → nested blocks → `tags` → `depends_on` → `lifecycle` (last)

**Variables:** `description` → `type` → `default` → `validation` → `nullable`

Every variable needs `type` + `description`. Every output needs `description`. Mark secrets `sensitive = true`.

Module Structure

| Type | Scope | Example | |------|-------|---------| | Resource Module | Single logical group | VPC + subnets, SG + rules | | Infrastructure Module | Collection of resource modules | Networking + compute for one region | | Composition | Complete infrastructure | Spans regions/accounts |

module-name/
├── main.tf, variables.tf, outputs.tf, versions.tf
├── examples/
│   ├── minimal/
│   └── complete/
└── tests/
    └── defaults.tftest.hcl

Keep modules small (single responsibility). `examples/` double as documentation and integration test fixtures. Semantic versioning for all published modules.

count vs for_each

| Scenario | Use | |----------|-----| | Boolean toggle (create or skip) | `count = condition ? 1 : 0` | | Named/keyed items that may reorder | `for_each = toset(list)` or `map` | | Fixed identical replicas | `count = N` |

Default to `for_each`: removing a middle item from a `count` list recreates all subsequent resources. Use `count` only for boolean conditionals or truly identical replicas.

Version Pinning

| Component | Strategy | Example | |-----------|----------|---------| | Terraform | Pin minor | `required_version = "~> 1.9.0"` | | Providers | Pin major | `version = "~> 5.0"` | | Modules (prod) | Pin exact | `version = "5.1.2"` | | Modules (dev) | Allow patch | `version = "~> 5.1.0"` |

Key modern features: `moved` blocks (1.1+), `optional()` with defaults (1.3+), native testing (1.6+), mock providers (1.7+), cross-variable validation (1.9+), write-only arguments (1.11+). Stacks (HCP; check current release status): orchestrates multiple configs as a single deployment unit. Evaluate for multi-environment patterns.

State & Security

  • Remote backend with locking: S3 with `use_lockfile = true` (1.10+), Azure Blob, GCS, or Terraform Cloud. Never local state for shared infrastructure. DynamoDB-based S3 locking (`dynamodb_table`) is deprecated and slated for removal; prefer `use_lockfile`. Both may be set at once while migrating an existing table off.
  • OpenTofu-only: `terraform { encryption { key_provider "pbkdf2" "k" {...} method "aes_gcm" "m" { keys = key_provider.pbkdf2.k } state { method = method.aes_gcm.m } plan { method = method.aes_gcm.m } } }` encrypts state and plan files client-side (or via `TF_ENCRYPTION`). Roll out with a `fallback { method = method.unencrypted.x }` so existing plaintext state still loads, and never rename a key provider or method without a `fallback` block. OpenTofu also accepts `var.*`/`local.*` in `backend {}` arguments and in module `source`/`version` (resolved at `init`; no state or provider-function references); the same HCL is a hard error in Terraform ("A backend block cannot refer to named values").
  • Encrypt state at rest. Never commit `.tfstate`, `.terraform/`, or `*.tfplan`. Always commit `.terraform.lock.hcl`.
  • `sensitive = true` redacts CLI output (plan, apply, `terraform output`) only; the value is still stored in plaintext state. Keep secrets out of state in this order: provider-managed secrets (for example `manage_master_user_password = true`), then an `ephemeral` resource (1.10+) feeding a write-only `*_wo` argument (1.11+). Write-only values never enter plan or state, so changing one produces no diff: increment its `*_wo_version` companion argument (a provider convention, not enforced by core) to push a rotation.
  • `default_tags` on provider for consistent resource tagging.
  • Encryption at rest on all storage. Private networking by default; public access is opt-in.
  • Least-privilege security groups. No `0.0.0.0/0` ingress without explicit justification.
  • Never hardcode credentials; use assume_role, OIDC, or secrets managers.
  • Pre-commit: auto-format first (`terraform fmt -recursive` rewrites files), then verify (`terraform validate && tflint && trivy config .`)
  • Use `moved` blocks with `from` and `to` addresses for refactoring resource names/modules without destroy-recreate. Retain historical moves for downstream upgrades; remove only after every affected state has migrated, or as an explicitly breaking module release.
  • `lifecycle { ignore_changes = [attr] }` suppresses **updates only**, and it substitutes the prior state value at plan time, on the *first* plan after the config change, with no "first apply" exception. Two conseq
Read more
@iliaal
Ships withwhetstone

A Claude Code plugin that makes AI coding agents follow engineering discipline. Plan before coding. Verify before claiming done. Find root cause before patching. Review before merge. Skills activate based on file type and task signals, not manual toggling.

3630 skills18 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
36
Star history of iliaal/whetstone on GitHub, a chart by star-history.com

Other skills on whetstone.

skill-distiller

skill-distiller

Fetches top-rated skills from skills.sh, analyzes them, and synthesizes one token-efficient skill combining the best elements.…

@iliaal@iliaalInstall Skill
ia-brainstorming

ia-brainstorming

Pre-implementation exploration: deep interview, approach comparison, design doc. Use when exploring a vague feature idea,…

@iliaal@iliaalInstall Skill
ia-c-systems

ia-c-systems

C patterns for systems code, libraries, and native extensions: module layout, function decomposition, status-enum errors, memory…

@iliaal@iliaalInstall Skill
ia-code-review

ia-code-review

Structured code reviews with severity-ranked findings and deep multi-agent mode. Use when performing a code review, auditing code…

@iliaal@iliaalInstall Skill
ia-cpp-systems

ia-cpp-systems

Modern C++ patterns: RAII and ownership, rule of zero/five, exceptions and error handling, API and ABI boundaries, templates, and…

@iliaal@iliaalInstall Skill

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about ia-terraform.

Which coding agents can use ia-terraform?
ia-terraform installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.