Skip to main content

Terraform Module Design

Design reusable, composable Terraform modules with proper input validation, output exposure, documentation, and versioning.

Fill in the placeholders

Edit the values, then copy your finished prompt.

Your Prompt
prompt.txt
Design a reusable Terraform module for a VPC with public/private subnets, NAT gateways, and VPN endpoint on AWS. The module will be used by 5 teams across 4 (dev, staging, production, disaster-recovery) environments. Structure: 1) Module directory layout: main.tf (resource definitions), variables.tf (inputs with descriptions, types, and validation blocks), outputs.tf (useful outputs for consumers), versions.tf (required_providers with version constraints), locals.tf (computed values and naming conventions). 2) Input variables with proper types and validation: vpc_cidr (string, CIDR validation), availability_zones (list), enable_nat_gateway (bool), subnet_configuration (object with public/private CIDR lists) — use object types for complex inputs, optional() for fields with defaults, and validation blocks with condition + error_message for CIDR must be /16 to /24, AZ count must be 2-3, subnet CIDRs must be within VPC CIDR. 3) Resource naming convention using a local that combines project, environment, region, resource_type to produce consistent names across all resources. Tag all resources with Environment, Project, ManagedBy=terraform, Team, CostCenter using a merge of default and user-supplied tags. 4) Conditional resource creation using count or for_each based on NAT gateway (costly, skip in dev), VPN endpoint (only for production), flow logs (configurable destination) — allow consumers to opt-in/out of optional components. 5) Output values: vpc_id, public_subnet_ids, private_subnet_ids, nat_gateway_ips, route_table_ids — include both IDs and ARNs/names for maximum consumer flexibility. Output sensitive values with sensitive=true. 6) Write a comprehensive README.md with usage examples for minimal dev VPC, production VPC with HA NAT, multi-region with VPN, input/output reference tables, and architecture diagram in Mermaid markdown. 7) Add pre-commit hooks: terraform fmt, terraform validate, tflint, and checkov/tfsec for security scanning.

What this prompt does

This prompt designs a reusable Terraform module for [module_purpose] on [cloud_provider], meant to be consumed by [consumer_count] teams across [environment_count] environments. It lays out the standard file structure (main.tf, variables.tf, outputs.tf, versions.tf with required_providers, and locals.tf) and defines input variables for [key_variables] using object types, optional() defaults, and validation blocks enforcing [validation_rules].

It establishes a naming convention built from [naming_components] so every resource is named consistently, tags everything with [required_tags] via a merge of default and user-supplied tags, and uses count or for_each for [conditional_resources] so consumers can opt in or out of costly pieces. Outputs expose [module_outputs] including both IDs and ARNs or names for maximum consumer flexibility, marking secret outputs sensitive=true. Finally it asks for a comprehensive README with usage examples for [usage_scenarios], input and output reference tables, a [diagram_format] architecture diagram, and pre-commit hooks running terraform fmt, validate, tflint, and checkov or tfsec for security scanning. The aim is a module that survives reuse because its inputs are validated, its outputs are documented, and its defaults are sane.

When to use it

  • You're publishing a Terraform module multiple teams will reuse
  • You want strict variable validation so misconfiguration fails at plan time
  • You need consistent resource naming and tagging across environments
  • You want optional components (NAT gateways, VPN) that consumers can toggle
  • You need a README good enough that a teammate uses it without asking you
  • You want security and lint scanning wired in via pre-commit hooks
  • You're standardizing a module library and want one consistent structure across them

Example output

The AI returns the five-file module skeleton, typed variables with validation blocks for [validation_rules], a locals-based naming scheme from [naming_components], a tag-merge pattern, conditional resource definitions using for_each or count, an outputs file with sensitive flags, and a README with usage examples and a [diagram_format] diagram. Expect a pre-commit config too, with the output structured per numbered concern so you can lift the validation or tagging patterns into existing modules.

Pro tips

  • Write validation blocks for every rule in [validation_rules] (CIDR size, AZ count) so bad input fails at plan, not apply
  • Use optional() in object-typed [key_variables] so consumers only set what they need
  • Drive [conditional_resources] with a boolean variable per component so dev can skip the costly NAT gateway
  • Output both IDs and ARNs/names in [module_outputs] to maximize what downstream modules can reference
  • Mark any secret output sensitive=true so it doesn't leak into plan logs
  • Pin provider versions in versions.tf so a consumer's provider upgrade can't silently change behavior
  • Keep [required_tags] in a merged default-plus-override map so consumers can add tags without losing the mandatory ones

Frequently Asked Questions

How does the module stop consumers from passing invalid inputs?
It uses Terraform validation blocks with a condition and error_message for each rule in `[validation_rules]`, so problems like a CIDR outside the /16-/24 range fail during plan with a clear message rather than producing broken infrastructure on apply.
Can consumers skip expensive resources like NAT gateways in dev?
Yes. The module uses count or for_each driven by `[conditional_resources]`, letting consumers opt out of costly components. A common pattern is a boolean variable that skips the NAT gateway in dev while enabling it in production.
Why output both IDs and ARNs?
Different downstream consumers need different references. Exposing both IDs and ARNs or names in `[module_outputs]` gives maximum flexibility, so one module can wire into another using whichever identifier its resources require, without forcing a re-export.
Does it include security scanning?
It asks for pre-commit hooks running terraform fmt, validate, tflint, and checkov or tfsec for security scanning. These catch formatting drift, invalid config, and insecure patterns before the module is committed, though you still review findings rather than trusting them blindly.
Engr Mejba Ahmed

Need this built for real?

Engr Mejba Ahmed

AI Developer · Software Engineer

I'm Mejba — I design and ship production AI systems, automations, and full-stack apps. If you want this turned into a working solution for your team, let's talk.

More in Terraform & Infrastructure as Code Prompts

Engr Mejba Ahmed

Engr Mejba Ahmed

AI assistant · trained on my work

👋

Hey there!

Quick Actions

WhatsApp Direct line to me

Chat on WhatsApp

+880 1723 741224 · Replies within the hour on working days

Popular Questions

Engr Mejba Ahmed is connected
Engr Mejba Ahmed is typing...
Engr Mejba Ahmed avatar

✉ Want me to follow up? Drop your email

Engr Mejba Ahmed avatar

📞 Connect Directly

Choose how you'd like to reach me

WhatsApp

+880 1723 741224

Email

mejba.13@gmail.com

✓ Details sent! I'll get back to you shortly.

Powered by OpenAI

335+

Blog Posts

25

AI Courses

63

Projects

Services & Expertise

Pricing & Process

Learning & Resources

Connect & Support