williamzujkowski

Terraform Module Best Practices

3
0
# Install this skill:
npx skills add williamzujkowski/cognitive-toolworks --skill "Terraform Module Best Practices"

Install specific skill from multi-skill repository

# Description

Usage examples and documentation

# SKILL.md


name: "Terraform Module Best Practices"
slug: "terraform-module-patterns"
description: "Design reusable Terraform modules with variable validation, output schemas, module composition, and testing (Terratest)."
capabilities:
- "module structure design with validated variables"
- "output schema definition and documentation"
- "module composition and registry publishing"
- "Terratest test generation and CI/CD integration"
inputs:
- name: "module_type"
type: "string"
required: true
enum: ["network", "compute", "database", "composite"]
- name: "cloud_provider"
type: "string"
required: true
enum: ["aws", "azure", "gcp", "multi-cloud"]
- name: "testing_required"
type: "boolean"
required: false
default: true
outputs:
- name: "module_structure"
type: "object"
description: "Directory layout with recommended files"
- name: "variables_tf"
type: "string"
description: "Input variables with validation rules"
- name: "outputs_tf"
type: "string"
description: "Output values with descriptions"
- name: "test_code"
type: "string"
description: "Terratest Go tests"
- name: "examples"
type: "string"
description: "Usage examples and documentation"
keywords: ["terraform", "modules", "iac", "validation", "terratest", "composition"]
version: "1.0.0"
owner: "cognitive-toolworks"
license: "Apache-2.0"
security:
pii: "none"
secrets: "never hardcode; use variable injection + secrets manager"
audit: "include module versioning and change documentation"
links:
docs:
- "https://developer.hashicorp.com/terraform/language/modules/develop"
- "https://developer.hashicorp.com/terraform/registry/modules/publish"
- "https://terratest.gruntwork.io/docs/"


Purpose & When-To-Use

Use when designing reusable Terraform modules that require:
- Input validation and type constraints
- Clear output contracts for module consumers
- Composition patterns for complex infrastructure
- Automated testing with Terratest
- Registry publishing and versioning

Trigger conditions:
- "Create a Terraform module for [infrastructure component]"
- "Add validation to Terraform variables"
- "Write Terratest tests for [module]"
- "Publish module to Terraform Registry"

Pre-Checks

  • Authoritative time: Set NOW_ET to ISO 8601 in America/New_York using NIST/time.gov semantics: 2025-10-26T02:31:29-0400
  • Module type validation: Ensure module_type is one of: network, compute, database, composite
  • Cloud provider support: Verify provider-specific features and resource availability
  • Terraform version: Check compatibility with >= 1.0 for validation features
  • Source freshness: Validate against current Terraform language spec and provider docs

Procedure

Tier 1 โ€” Basic Module Structure (T1โ‰ค2000 tokens)

  1. Define module layout:
    terraform-<name>/ main.tf # Primary resources variables.tf # Input variables with validation outputs.tf # Output values with descriptions versions.tf # Provider version constraints README.md # Usage documentation examples/ # Usage examples basic/ tests/ # Terratest tests

  2. Create variables.tf with validation:

  3. Use type constraints (string, number, bool, list, map, object, set, tuple, any)
  4. Add validation blocks for business logic constraints
  5. Include description and default where appropriate
  6. Use sensitive = true for secrets

  7. Define outputs.tf with clear contracts:

  8. Document output purpose and format
  9. Use description for all outputs
  10. Mark sensitive outputs with sensitive = true
  11. Group related outputs logically

  12. Establish versioning in versions.tf:

  13. Pin Terraform version: required_version = ">= 1.5"
  14. Pin provider versions with ~> for minor updates
  15. Document version rationale in comments

Tier 2 โ€” Module Composition & Publishing (T2โ‰ค6000 tokens)

  1. Implement composition patterns:
  2. Child modules: Extract repeated resources into sub-modules
  3. Dependency injection: Pass outputs from one module as inputs to another
  4. Data-only modules: Use data sources for discovery/lookups
  5. For-each patterns: Use for_each with maps for dynamic resources

  6. Add comprehensive examples:

  7. Basic example: Minimal required inputs
  8. Complete example: All features enabled
  9. Composition example: Integration with other modules
  10. Each example should be self-contained and runnable

  11. Prepare for Registry publishing:

  12. Follow naming convention: terraform-<PROVIDER>-<NAME>
  13. Create Git tags matching semantic versioning: v1.0.0
  14. Write comprehensive README.md with inputs/outputs tables
  15. Add LICENSE file (Apache-2.0, MIT, etc.)
  16. Include module registry metadata in repository

  17. Document module contracts:

  18. Input variable requirements and defaults
  19. Output value structures and types
  20. Provider configuration requirements
  21. Resource naming conventions

Tier 3 โ€” Testing & CI/CD Integration (T3โ‰ค12000 tokens)

  1. Create Terratest tests:
  2. Install Terratest: go get github.com/gruntwork-io/terratest/modules/terraform
  3. Write test structure:
    • Setup: Configure test inputs
    • Deploy: terraform.InitAndApply(t, terraformOptions)
    • Validate: Assert expected outputs and resource state
    • Teardown: defer terraform.Destroy(t, terraformOptions)
  4. Test different scenarios: minimal, complete, error cases

  5. Implement validation tests:

  6. Test variable validation rules trigger correctly
  7. Verify output schemas match documentation
  8. Check resource dependencies and ordering
  9. Validate provider authentication patterns

  10. Set up CI/CD pipeline:

  11. Lint stage: terraform fmt -check, terraform validate
  12. Security stage: tfsec, checkov, terrascan
  13. Test stage: Run Terratest suite in isolated environment
  14. Docs stage: Auto-generate docs with terraform-docs
  15. Release stage: Tag and publish to registry

  16. Add pre-commit hooks:

  17. Format code: terraform fmt -recursive
  18. Validate syntax: terraform validate
  19. Update docs: terraform-docs markdown table --output-file README.md
  20. Security scan: tfsec .

Decision Rules

  • If module_type == "composite" โ†’ require Tier 2 composition patterns
  • If testing_required == true โ†’ require Tier 3 Terratest implementation
  • If publishing to registry โ†’ require semantic versioning and comprehensive README
  • If variable validation fails in tests โ†’ emit specific validation error message
  • If module has >5 required variables โ†’ recommend using object type for grouping
  • If module creates >10 resources โ†’ recommend breaking into child modules
  • Abort conditions:
  • Missing provider configuration
  • Circular module dependencies
  • Hardcoded secrets or credentials
  • Missing required variable descriptions

Output Contract

module_structure:

{
  "root": ["main.tf", "variables.tf", "outputs.tf", "versions.tf", "README.md"],
  "examples": ["basic", "complete"],
  "tests": ["<module_name>_test.go"],
  "docs": ["README.md", "CHANGELOG.md"]
}

variables_tf: String containing Terraform variable definitions with:
- type constraint
- description field
- validation blocks where applicable
- default values for optional inputs
- sensitive flag for secrets

outputs_tf: String containing output definitions with:
- description for each output
- sensitive flag where needed
- Logical grouping (e.g., network_ids, instance_details)

test_code: Go test file using Terratest framework with:
- Setup and teardown logic
- Terraform init/apply/destroy
- Output validation assertions
- Resource state checks

examples: Directory structure with runnable examples:
- examples/basic/main.tf โ€” minimal configuration
- examples/complete/main.tf โ€” all features enabled
- Each with README.md explaining usage

Examples

Example (โ‰ค30 lines): AWS VPC Module with Validation

# variables.tf
variable "vpc_cidr" {
  type        = string
  description = "CIDR block for VPC"
  validation {
    condition     = can(cidrhost(var.vpc_cidr, 0))
    error_message = "Must be valid IPv4 CIDR block."
  }
}

variable "subnet_count" {
  type        = number
  description = "Number of subnets to create"
  validation {
    condition     = var.subnet_count >= 2 && var.subnet_count <= 16
    error_message = "Subnet count must be between 2 and 16."
  }
}

# outputs.tf
output "vpc_id" {
  description = "ID of the created VPC"
  value       = aws_vpc.main.id
}

output "subnet_ids" {
  description = "List of subnet IDs"
  value       = aws_subnet.main[*].id
}

Quality Gates

  • Token budgets: T1โ‰ค2k (basic module structure), T2โ‰ค6k (composition + docs), T3โ‰ค12k (testing + CI/CD)
  • Example size: โ‰ค30 lines in SKILL.md; full examples in examples/ directory
  • Variable validation: All required variables must have description; validation rules for business logic
  • Output documentation: All outputs must have description field
  • Testing coverage: Minimum 3 test scenarios (basic, complete, error handling)
  • Security: No hardcoded secrets; use sensitive flag; scan with tfsec
  • Versioning: Semantic versioning for releases; provider version constraints in versions.tf
  • Formatting: All code must pass terraform fmt
  • Documentation: Auto-generated docs match actual inputs/outputs

Resources

  • Terraform Module Development (accessed 2025-10-26): https://developer.hashicorp.com/terraform/language/modules/develop
  • Terraform Module Publishing (accessed 2025-10-26): https://developer.hashicorp.com/terraform/registry/modules/publish
  • Terraform Variable Validation (accessed 2025-10-26): https://developer.hashicorp.com/terraform/language/values/variables#custom-validation-rules
  • Terratest Documentation (accessed 2025-10-26): https://terratest.gruntwork.io/docs/
  • Terratest Terraform Module (accessed 2025-10-26): https://terratest.gruntwork.io/docs/getting-started/quick-start/#example-2-terraform
  • HashiCorp Module Standards (accessed 2025-10-26): https://developer.hashicorp.com/terraform/language/modules/develop/structure
  • Terraform Testing Best Practices (accessed 2025-10-26): https://developer.hashicorp.com/terraform/language/modules/testing-experiment

# Supported AI Coding Agents

This skill is compatible with the SKILL.md standard and works with all major AI coding agents:

Learn more about the SKILL.md standard and how to use these skills with your preferred AI coding agent.