terraform-module
Generate a Terraform module from a described need, with main.tf, variables.tf, outputs.tf and versions.tf, typed and validated variables, secure defaults (encryption on, public access off, least-privilege IAM), a merged tags variable, a basic usage example and a README with inputs and outputs tables. Use when the user says "write a terraform module for", "create terraform for an S3 bucket / VPC / database", "turn this into a reusable module", or "scaffold infrastructure as code for".
Other ways to install
With the sibling skills it hands off to:
The whole pack it belongs to:
By hand, from a clone of the repo:
In Claude Code, with the infra-as-code plugin installed, invoke it as:
Try it
A realistic prompt from the skill's acceptance evals:
Write a Terraform module for Acme's Postgres database on AWS RDS. The payments team and the orders team will both call it. They need to pick instance class and storage size; everything else should be safe by default.
What a good result looks like
Example output
Worked example: an S3 bucket for access logs · the skill's own worked example, source
"We need a Terraform module for a log bucket on AWS. Our S3 buckets send server access logs there, and we keep them a year. Several teams will call it."
All three inputs are present (need, cloud, callers), so no questions are asked.
Stated defaults and assumptions
- Terraform
>= 1.5.0; AWS provider>= 5.0, < 7.0. - SSE-S3 (AES256) by default, with SSE-KMS as an opt-in through
kms_key_arn, because some AWS log delivery services do not support SSE-KMS on the destination bucket. - Retention 365 days, transition to STANDARD_IA at 30 days (the S3 minimum for that transition).
[assumption]Log sources are in the same account as the bucket. Cross-account delivery needs a wider policy and is left out.
The module is in s3-log-bucket/:
| File | What to look at |
|---|---|
s3-log-bucket/versions.tf | Bounded provider constraint, Terraform floor |
s3-log-bucket/variables.tf | Every input typed and described; validation on the bucket name, day counts, KMS ARN format and source bucket ARNs |
s3-log-bucket/main.tf | Public access block, BucketOwnerEnforced, encryption, versioning, lifecycle, TLS-only policy, log delivery scoped by aws:SourceAccount from data.aws_caller_identity; a precondition checks retention is longer than the transition |
s3-log-bucket/outputs.tf | Name, ARN and regional domain name, each described |
s3-log-bucket/examples/basic/main.tf | A caller with a provider block and placeholder names |
s3-log-bucket/README.md | Inputs and outputs tables matching the code |
How it meets the quality bar:
- Secure by default. A caller who sets only
bucket_namegets a private, encrypted, versioned, TLS-only bucket thatterraform destroywill not empty (force_destroy = false). - Least privilege. The only Allow statement is
s3:PutObjectforlogging.s3.amazonaws.com, limited to this account and, whenaccess_log_source_bucket_arnsis set, to named source buckets. - Nothing hard-coded. The account ID and partition come from data sources; the region comes from the caller's provider.
- One tags variable.
merge(local.default_tags, var.tags)on the bucket. The bucket's sub-resources (public access block, policy, lifecycle and so on) do not take tags in the AWS provider.
Validation status
Run on 2026-10-01 with Terraform 1.16.4, on the module and on its examples/basic caller:
$ terraform fmt -recursive -check
$ terraform init -backend=false && terraform validate
Success! The configuration is valid.
fmt -check printed nothing and exited 0. validate passed with the AWS provider at 6.67.0 (the newest the >= 5.0, < 7.0 range allows), and again with the range pinned to 5.100.0 and to 5.0.0, so both ends of the stated range hold. validate checks syntax, types and references; it does not call AWS. Run terraform plan against a real account before relying on the module.
How it's checked
Measured against plain Claude Code (2026-10-23): it met 92% of its checks, against 77% without it, and a blind judge preferred it. How skills are checked
27 assertions across 4 acceptance evals, and 8 trigger queries. Every skill's checks
What the output must do
When it should and shouldn't activate
Should activate:
- Write a terraform module for a private S3 bucket with encryption
- Create Terraform for an RDS Postgres instance that other teams can reuse
- Turn these copy-pasted resource blocks into a reusable Terraform module with variables and outputs
- Scaffold infrastructure as code for a GCS bucket with a README and inputs table
Should leave to another skill:
- Review my terraform plan output before I apply it
- Review this pull request that changes our Terraform files
- Threat model the payments platform we are deploying to AWS
- Estimate what this infrastructure will cost per month at 10k requests per second
Hands off to
- terraform-plan-review — when the module has been planned from examples/basic or a real caller. Check the plan for destroys, stateful changes and access widening before the first apply.
Related skills
capacity-cost-model, migration-plan, pre-merge-review, threat-model
Source
SKILL.md · the whole folder on GitHub.