# Terraform

> >-

- **Type:** Skill
- **Install:** `agentstack add skill-iliaal-whetstone-terraform`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [iliaal](https://agentstack.voostack.com/s/iliaal)
- **Installs:** 0
- **Category:** [Cloud & Infrastructure](https://agentstack.voostack.com/c/cloud-infrastructure)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [iliaal](https://github.com/iliaal)
- **Source:** https://github.com/iliaal/whetstone/tree/master/distillery/generated-skills/terraform

## Install

```sh
agentstack add skill-iliaal-whetstone-terraform
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# Terraform & OpenTofu

## 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.

## Testing

| Situation | Approach |
|-----------|----------|
| Quick validation | `terraform fmt -check && terraform validate` |
| Pre-commit | + `tflint` + `trivy config .` / `checkov -d .` |
| Logic validation (1.6+) | Native `terraform test` with `command = plan` |
| Cost-free unit tests (1.7+) | Native tests + `mock_provider` |
| Real infra validation | Native tests with `command = apply`, or Terratest (Go) |

**Native test essentials** (`.tftest.hcl` in `tests/`):
- `command = plan` for fast unit tests; `command = apply` for integration (default)
- `assert { condition = expr; error_message = "..." }` — multiple per run block
- `expect_failures = [var.name]` for negative testing (validate rejection of bad input)
- `mock_provider "aws" { mock_resource "..." { defaults = { ... } } }` — plan-mode only, no credentials, fast CI
- `variables {}` at file level (all runs) or within a `run` block (override)
- Reference prior run outputs: `run.setup.vpc_id`
- `parallel = true` on independent runs with separate state — creates sync point at next sequential run
- File naming: `*_unit_test.tftest.hcl` (plan mode) vs `*_integration_test.tftest.hcl` (apply mode)

## Version Pinning

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

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+).

## State & Security

- Remote backend with locking: S3+DynamoDB, Azure Blob, GCS, or Terraform Cloud. Never local state for shared infrastructure.
- Encrypt state at rest. Never commit `.tfstate`, `.terraform/`, or `*.tfplan`. Always commit `.terraform.lock.hcl`.
- `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: `terraform fmt -recursive && terraform validate && trivy config .`

## Dependency Management

Use `locals` with `try()` to control deletion ordering without explicit `depends_on`:

```hcl
locals {
  vpc_id = try(aws_vpc_ipv4_cidr_block_association.this[0].vpc_id, aws_vpc.this.id, "")
}
```

This forces Terraform to destroy subnets before CIDR associations — prevents deletion errors.

## Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [iliaal](https://github.com/iliaal)
- **Source:** [iliaal/whetstone](https://github.com/iliaal/whetstone)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/skill-iliaal-whetstone-terraform
- Seller: https://agentstack.voostack.com/s/iliaal
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
