All skills
Skillintermediate

Terraform Generator

This skill enables the generation of production-ready Terraform configurations following best practices and current standards. Automatically integrates validation and documentation lookup for custom providers and modules.

Claude Code Knowledge Pack7/10/2026

Overview

Terraform Generator

Overview

This skill enables the generation of production-ready Terraform configurations following best practices and current standards. Automatically integrates validation and documentation lookup for custom providers and modules.

Critical Requirements Checklist

STOP: You MUST complete ALL steps in order. Do NOT skip any REQUIRED step.

StepActionRequired
1Understand requirements (providers, resources, modules)✅ REQUIRED
2Check for custom providers/modules and lookup documentation✅ REQUIRED
3Consult reference files before generation✅ REQUIRED
4Generate Terraform files with ALL best practices✅ REQUIRED
5Include data sources for dynamic values (region, account, AMIs)✅ REQUIRED
6Add lifecycle rules on critical resources (KMS, databases)✅ REQUIRED
7Invoke Skill(devops-skills:terraform-validator)✅ REQUIRED
8FIX all validation/security failures and RE-VALIDATE✅ REQUIRED
9Provide usage instructions (files, next steps, security)✅ REQUIRED

IMPORTANT: If validation fails (terraform validate OR security scan), you MUST fix the issues and re-run validation until ALL checks pass. Do NOT proceed to Step 9 with failing checks.

Core Workflow

When generating Terraform configurations, follow this workflow:

Step 1: Understand Requirements

Analyze the user's request to determine:

  • What infrastructure resources need to be created
  • Which Terraform providers are required (AWS, Azure, GCP, custom, etc.)
  • Whether any modules are being used (official, community, or custom)
  • Version constraints for providers and modules
  • Variable inputs and outputs needed
  • State backend configuration (local, S3, remote, etc.)

Step 2: Check for Custom Providers/Modules

Before generating configurations, identify if custom or third-party providers/modules are involved:

Standard providers (no lookup needed):

  • hashicorp/aws
  • hashicorp/azurerm
  • hashicorp/google
  • hashicorp/kubernetes
  • Other official HashiCorp providers

Custom/third-party providers/modules (require documentation lookup):

  • Third-party providers (e.g., datadog/datadog, mongodb/mongodbatlas)
  • Custom modules from Terraform Registry
  • Private or company-specific modules
  • Community modules

When custom providers/modules are detected:

  1. Use WebSearch to find version-specific documentation:

    Search query format: "[provider/module name] terraform [version] documentation [specific resource]"
    Example: "datadog terraform provider v3.30 monitor resource documentation"
    Example: "terraform-aws-modules vpc version 5.0 documentation"
    
  2. Focus searches on:

    • Official documentation (registry.terraform.io, provider websites)
    • Required and optional arguments
    • Attribute references
    • Example usage
    • Version compatibility notes
  3. If Context7 MCP is available and the provider/module is supported, use it as an alternative:

    mcp__context7__resolve-library-id → mcp__context7__query-docs
    

Step 2.5: Consult Reference Files (REQUIRED)

Before generating configuration, you MUST consult reference files using this matrix:

ReferenceRequirementRead When
terraform_best_practices.mdREQUIREDAlways - contains baseline required patterns
provider_examples.mdREQUIREDAny AWS, Azure, GCP, or Kubernetes resource generation
common_patterns.mdOPTIONAL by default, REQUIRED for complex requestsMulti-environment, workspace, composition, DR, or conditional patterns

Open references by path:

devops-skills-plugin/skills/terraform-generator/references/terraform_best_practices.md
devops-skills-plugin/skills/terraform-generator/references/provider_examples.md
devops-skills-plugin/skills/terraform-generator/references/common_patterns.md

Step 3: Generate Terraform Configuration

Generate HCL files following best practices:

File Organization:

terraform-project/
├── main.tf           # Primary resource definitions
├── variables.tf      # Input variable declarations
├── outputs.tf        # Output value declarations
├── versions.tf       # Provider version constraints
├── terraform.tfvars  # Variable values (optional, for examples)
└── backend.tf        # Backend configuration (optional)

Best Practices to Follow:

  1. Provider Configuration:

    terraform {
      required_version = ">= 1.10, < 2.0"
    
      required_providers {
        aws = {
          source  = "hashicorp/aws"
          version = "~> 6.0"  # Major pin; verify exact current version when needed
        }
      }
    }
    
    provider "aws" {
      region = var.aws_region
    }
    
  2. Resource Naming:

    • Use descriptive resource names
    • Follow snake_case convention
    • Include resource type in name when helpful
    resource "aws_instance" "web_server" {
      # ...
    }
    
  3. Variable Declarations:

    variable "instance_type" {
      description = "EC2 instance type for web servers"
      type        = string
      default     = "t3.micro"
    
      validation {
        condition     = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
        error_message = "Instance type must be t3.micro, t3.small, or t3.medium."
      }
    }
    
  4. Output Values:

    output "instance_public_ip" {
      description = "Public IP address of the web server"
      value       = aws_instance.web_server.public_ip
    }
    
  5. Use Data Sources for References:

    data "aws_ami" "ubuntu" {
      most_recent = true
      owners      = ["099720109477"] # Canonical
    
      filter {
        name   = "name"
        values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
      }
    }
    
  6. Module Usage:

    module "vpc" {
      source  = "terraform-aws-modules/vpc/aws"
      version = "5.0.0"
    
      name = "my-vpc"
      cidr = "10.0.0.0/16"
    
      azs             = ["us-east-1a", "us-east-1b"]
      private_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
      public_subnets  = ["10.0.101.0/24", "10.0.102.0/24"]
    }
    
  7. Use locals for Computed Values:

    locals {
      common_tags = {
        Environment = var.environment
        ManagedBy   = "Terraform"
        Project     = var.project_name
      }
    }
    
  8. Lifecycle Rules When Appropriate:

    resource "aws_instance" "example" {
      # ...
    
      lifecycle {
        create_before_destroy = true
        prevent_destroy       = true
        ignore_changes        = [tags]
      }
    }
    
  9. Dynamic Blocks for Repeated Configuration:

    resource "aws_security_group" "example" {
      # ...
    
      dynamic "ingress" {
        for_each = var.ingress_rules
        content {
          from_port   = ingress.value.from_port
          to_port     = ingress.value.to_port
          protocol    = ingress.value.protocol
          cidr_blocks = ingress.value.cidr_blocks
        }
      }
    }
    
  10. Comments and Documentation:

    • Add comments explaining complex logic
    • Document why certain values are used
    • Include examples in variable descriptions

Security Best Practices:

  • Never hardcode sensitive values (use variables)
  • Use data sources for AMIs and other dynamic values
  • Implement least-privilege IAM policies
  • Enable encryption by default
  • Use secure backend configurations

Required: Data Sources for Dynamic Values (Provider-Aware)

You MUST include provider-appropriate data lookups for dynamic infrastructure values. Do NOT hardcode cloud/account/region/image IDs.

ProviderRequired Dynamic ContextTypical Data Sources
AWSRegion/account/AZ/image IDsaws_region, aws_caller_identity, aws_availability_zones, aws_ami
AzureTenant/subscription/client contextazurerm_client_config, azurerm_subscription
GCPProject/client context/zone discoverygoogle_client_config, google_compute_zones, google_compute_image
KubernetesCluster endpoint/auth from trusted sourceUse module outputs or cloud data sources; avoid hardcoded tokens/endpoints
# AWS dynamic context
data "aws_region" "current" {}
data "aws_caller_identity" "current" {}

# Azure dynamic context
data "azurerm_client_config" "current" {}
data "azurerm_subscription" "current" {}

# GCP dynamic context
data "google_client_config" "current" {}

Required: Lifecycle and Deletion Safeguards (Provider-Aware)

You MUST protect stateful and critical resources from accidental destruction/deletion using both Terraform lifecycle and provider-native safeguards.

ProviderCritical Resource ClassesRequired Protection Mechanism
AWSKMS, RDS, S3 data buckets, DynamoDB, ElastiCache, secretslifecycle { prevent_destroy = true } and service-specific deletion protection where supported
AzureKey Vaults, SQL, Storage, stateful computeprevent_destroy where appropriate plus provider feature flags/resource deletion protection
GCPCloud SQL, GKE, storage, stateful computeprevent_destroy and resource-level deletion_protection = true where supported
KubernetesStateful workloads and persistent dataAvoid destructive replacement patterns and protect backing cloud resources
resource "aws_db_instance" "main" {
  # ...
  deletion_protection = true
  lifecycle {
    prevent_destroy = true
  }
}

resource "google_sql_database_instance" "main" {
  # ...
  deletion_protection = true
}

Required: Object Storage Lifecycle Safeguards

When using AWS S3 lifecycle configuration, ALWAYS include a rule to abort incomplete multipart uploads:

resource "aws_s3_bucket_lifecycle_configuration" "main" {
  bucket = aws_s3_bucket.main.id

  # REQUIRED: Abort incomplete multipart uploads to prevent storage costs
  rule {
    id     = "abort-incomplete-uploads"
    status = "Enabled"

    # Filter applies to all objects (empty filter = all objects)
    filter {}

    abort_incomplete_multipart_upload {
      days_after_initiation = 7
    }
  }

  # Other lifecycle rules (e.g., transition to IA)
  rule {
    id     = "transition-to-ia"
    status = "Enabled"

    filter {
      prefix = ""  # Apply to all objects
    }

    transition {
      days          = 90
      storage_class = "STANDARD_IA"
    }

    noncurrent_version_transition {
      noncurrent_days = 30
      storage_class   = "STANDARD_IA"
    }

    noncurrent_version_expiration {
      noncurrent_days = 365
    }
  }
}

Why? Incomplete multipart uploads consume storage and incur costs. Checkov check CKV_AWS_300 enforces this for AWS.

For Azure/GCP object storage, add equivalent lifecycle/retention rules for stale objects and old versions.

Step 4: Validate Generated Configuration (REQUIRED)

After generating Terraform files, ALWAYS validate them using the devops-skills:terraform-validator skill:

Invoke: Skill(devops-skills:terraform-validator)

The devops-skills:terraform-validator skill will:

  1. Check HCL syntax with terraform fmt -check
  2. Initialize the configuration with terraform init
  3. Validate the configuration with terraform validate
  4. Run security scan with Checkov
  5. Perform dry-run testing (if requested) with terraform plan

CRITICAL: Fix-and-Revalidate Loop

If ANY validation or security check fails, you MUST:

  1. Review the error - Understand what failed and why
  2. Fix the issue - Edit the generated file to resolve the problem
  3. Re-run validation - Invoke Skill(devops-skills:terraform-validator) again
  4. Repeat until ALL checks pass - Do NOT proceed with failing checks
┌─────────────────────────────────────────────────────────┐
│  VALIDATION FAILED?                                      │
│                                                          │
│  ┌─────────┐    ┌─────────┐    ┌─────────────────────┐  │
│  │  Fix    │───▶│ Re-run  │───▶│ All checks pass?    │  │
│  │  Issue  │    │ Skill   │    │ YES → Step 5        │  │
│  └─────────┘    └─────────┘    │ NO  → Loop back     │  │
│       ▲                         └─────────────────────┘  │
│       │                                    │             │
│       └────────────────────────────────────┘             │
└─────────────────────────────────────────────────────────┘

Common validation failures to fix:

CheckIssueFix
CKV_AWS_300Missing abort multipart uploadAdd abort_incomplete_multipart_upload rule
CKV_AWS_24SSH open to 0.0.0.0/0Restrict to specific CIDR
CKV_AWS_16RDS encryption disabledAdd storage_encrypted = true
terraform validateInvalid resource argumentCheck provider documentation

If custom providers are detected during validation:

  • The devops-skills:terraform-validator skill will automatically fetch documentation
  • Use the fetched documentation to fix any issues

Step 5: Provide Usage Instructions (REQUIRED)

After successful generation and validation with ALL checks passing, you MUST provide the user with:

Required Output Format:

## Generated Files

| File | Description |
|------|-------------|
| `<actual-file-path>` | What was generated in that file |

Only list files that were actually generated for this request. Do not include placeholder paths or files that do not exist.

## Next Steps

1. Review and customize `terraform.tfvars` with your values
2. Initialize Terraform:
   ```bash
   terraform init
  1. Review the execution plan:
    terraform plan
    
  2. Apply the configuration:
    terraform apply
    

Customization Notes

  • Update variable_name in terraform.tfvars
  • Configure backend in backend.tf for remote state
  • Adjust resource names/tags as needed

Security Reminders

⚠️ Before applying:

  • Review IAM policies and permissions
  • Ensure sensitive values are NOT committed to version control
  • Configure state backend with encryption enabled
  • Set up state locking for team collaboration

> **IMPORTANT:** Do NOT skip Step 5. The user needs actionable guidance on how to use the generated configuration.

## Common Generation Patterns

### Pattern 1: Simple Resource Creation

User request: "Create an AWS S3 bucket with versioning"

Generated files:
- `main.tf` - S3 bucket resource with versioning enabled
- `variables.tf` - Bucket name, tags variables
- `outputs.tf` - Bucket ARN and name outputs
- `versions.tf` - AWS provider version constraints

### Pattern 2: Module-Based Infrastructure

User request: "Set up a VPC u