# Infrastructure

> Infrastructure as Code generation for Terraform, CloudFormation, and Pulumi Use when this capability is needed.

- Skill: `tomevault-io/infrastructure-5` (Agent Skill, multi-file: 2 files)
- Install (CLI): `npx skillmds@latest add tomevault-io/infrastructure-5`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tomevault-io/infrastructure-5/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: tomevault-io (https://skillmd.com/u/tomevault-io)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tomevault-io/infrastructure-5

---


# Infrastructure as Code (IaC) Management

I'll help you create, validate, and manage Infrastructure as Code templates for cloud deployments.

**Supported IaC Tools:**
- **Terraform**: HashiCorp's industry-standard IaC tool
- **AWS CloudFormation**: Native AWS infrastructure management
- **Pulumi**: Modern IaC with programming language support

Arguments: `$ARGUMENTS` - IaC tool preference, resource type, or cloud provider

---

## Token Optimization

This skill uses efficient patterns to minimize token consumption during Infrastructure as Code generation and management.

### Optimization Strategies

#### 1. IaC Tool Detection Caching (Saves 800 tokens per invocation)

Cache detected IaC tool, provider, and configuration:

```bash
CACHE_FILE=".claude/cache/infrastructure/setup.json"
CACHE_TTL=86400  # 24 hours

mkdir -p .claude/cache/infrastructure

if [ -f "$CACHE_FILE" ]; then
    CACHE_AGE=$(($(date +%s) - $(stat -c %Y "$CACHE_FILE" 2>/dev/null || stat -f %m "$CACHE_FILE" 2>/dev/null)))

    if [ $CACHE_AGE -lt $CACHE_TTL ]; then
        IAC_TOOL=$(jq -r '.iac_tool' "$CACHE_FILE")
        CLOUD_PROVIDER=$(jq -r '.cloud_provider' "$CACHE_FILE")
        REGIONS=$(jq -r '.regions[]' "$CACHE_FILE" 2>/dev/null)

        echo "Using cached infrastructure config: $IAC_TOOL ($CLOUD_PROVIDER)"
        SKIP_DETECTION="true"
    fi
fi

# First run: detect and cache
if [ "$SKIP_DETECTION" != "true" ]; then
    detect_iac_tools  # Expensive: grep, find, CLI checks

    # Cache results
    jq -n \
        --arg tool "$IAC_TOOL" \
        --arg provider "$CLOUD_PROVIDER" \
        --argjson regions "$(echo $REGIONS | jq -R -s -c 'split(" ")')" \
        '{iac_tool: $tool, cloud_provider: $provider, regions: $regions}' \
        > "$CACHE_FILE"
fi
```

**Savings:** 800 tokens (no repeated grep, no CLI version checks, no file searches)

#### 2. Template Library (Saves 85%)

Use pre-built templates instead of generating from scratch:

```bash
# Efficient: Template-based generation (not custom creation)
generate_infrastructure_template() {
    local resource_type="$1"
    local provider="$2"

    TEMPLATE_DIR=".claude/infrastructure-templates"
    TEMPLATE="$TEMPLATE_DIR/${provider}-${resource_type}.tf"

    if [ -f "$TEMPLATE" ]; then
        # Use existing template (instant)
        cp "$TEMPLATE" "${resource_type}.tf"
        echo "✓ Generated from template: ${resource_type}.tf"
    else
        # Generate basic template
        cat > "${resource_type}.tf" << EOF
resource "${provider}_${resource_type}" "main" {
  # Configure ${resource_type} settings
  # See: https://registry.terraform.io/providers/${provider}/latest/docs/resources/${resource_type}
}
EOF
        echo "✓ Generated basic template: ${resource_type}.tf"
    fi
}
```

**Savings:** 85% (template copy vs full generation: 3,000 → 450 tokens)

#### 3. Early Exit for Existing Infrastructure (Saves 90%)

Quick check for existing IaC setup:

```bash
# Quick validation
if [ -f "main.tf" ] && [ -d ".terraform" ]; then
    echo "✓ Infrastructure code already exists"
    echo ""
    echo "Existing files:"
    ls -1 *.tf 2>/dev/null | head -5
    echo ""
    echo "Use --new to create additional resources"
    echo "Use --validate to check existing infrastructure"
    exit 0
fi
```

**Savings:** 90% when infrastructure exists (skip generation: 5,000 → 500 tokens)

#### 4. Grep-Based Provider Detection (Saves 90%)

Use Grep for provider identification (no full file reads):

```bash
# Efficient: Boolean provider checks
detect_cloud_provider() {
    local provider=""

    # AWS check (single grep)
    if grep -q "provider \"aws\"" *.tf 2>/dev/null || \
       grep -q "AWS::" *.yaml 2>/dev/null; then
        provider="aws"
    fi

    # Azure check
    if grep -q "provider \"azurerm\"" *.tf 2>/dev/null; then
        provider="${provider:+$provider,}azure"
    fi

    # GCP check
    if grep -q "provider \"google\"" *.tf 2>/dev/null; then
        provider="${provider:+$provider,}gcp"
    fi

    echo "$provider"
}

CLOUD_PROVIDER=$(detect_cloud_provider)
```

**Savings:** 90% vs full file parsing (grep boolean vs complete reads: 2,000 → 200 tokens)

#### 5. Incremental Resource Generation (Saves 70%)

Generate only requested resources:

```bash
RESOURCES="${RESOURCES:-vpc}"  # Default: VPC only

IFS=',' read -ra RESOURCE_LIST <<< "$RESOURCES"

for resource in "${RESOURCE_LIST[@]}"; do
    case "$resource" in
        vpc)
            generate_vpc_template      # 400 tokens
            ;;
        compute)
            generate_compute_template  # 500 tokens
            ;;
        database)
            generate_database_template # 600 tokens
            ;;
        storage)
            generate_storage_template  # 400 tokens
            ;;
    esac
done

# Example usage:
# /infrastructure vpc              # Only VPC (400 tokens)
# /infrastructure vpc,compute      # VPC + compute (900 tokens)
# /infrastructure --all            # All resources (2,500 tokens)
```

**Savings:** 70% for single resource (400 vs 2,500 tokens)

#### 6. Bash-Based Validation (Saves 75%)

Use terraform/aws CLI for validation (no full analysis):

```bash
# Efficient: CLI-based validation
validate_infrastructure() {
    local tool="$1"

    echo "Validating infrastructure..."

    case "$tool" in
        terraform)
            # Quick syntax check (no plan)
            terraform fmt -check
            terraform validate
            echo "✓ Terraform validation passed"
            ;;
        cloudformation)
            # Quick template validation
            aws cloudformation validate-template --template-body file://template.yaml
            echo "✓ CloudFormation template valid"
            ;;
    esac
}
```

**Savings:** 75% vs full analysis (CLI validation vs detailed review: 2,000 → 500 tokens)

#### 7. Progressive Infrastructure Setup (Saves 60%)

Three levels of infrastructure generation:

```bash
SETUP_LEVEL="${SETUP_LEVEL:-basic}"

case "$SETUP_LEVEL" in
    basic)
        # Minimal infrastructure (800 tokens)
        generate_vpc
        generate_security_groups
        echo "Basic infrastructure generated"
        ;;

    standard)
        # Production-ready (1,800 tokens)
        generate_vpc
        generate_security_groups
        generate_compute
        generate_database
        setup_monitoring
        ;;

    complete)
        # Full stack (3,000 tokens)
        generate_all_resources
        setup_networking
        configure_security
        setup_monitoring
        setup_backup
        setup_disaster_recovery
        ;;
esac
```

**Savings:** 60% for basic setup (800 vs 3,000 tokens)

### Cache Invalidation

Caches are invalidated when:
- IaC files modified (*.tf, *.yaml, Pulumi.yaml)
- 24 hours elapsed (time-based)
- User runs `--clear-cache` flag
- Provider configuration changes

### Real-World Token Usage

**Typical infrastructure workflow:**

1. **Quick setup (cached):** 600-1,200 tokens
   - Cached tool detection: 100 tokens
   - Template generation (1 resource): 400 tokens
   - Basic validation: 300 tokens
   - Summary: 200 tokens

2. **First-time setup:** 1,800-2,800 tokens
   - Tool detection: 600 tokens
   - Provider detection: 300 tokens
   - Template generation (3 resources): 1,200 tokens
   - Validation: 400 tokens
   - Summary: 300 tokens

3. **Existing infrastructure:** 400-700 tokens
   - Early exit after validation (90% savings)
   - Show existing resources
   - Suggest additions

4. **Single resource addition:** 500-900 tokens
   - Cached detection: 100 tokens
   - Resource template: 400 tokens
   - Integration: 300 tokens

5. **Complete infrastructure:** 2,800-3,500 tokens
   - Only when explicitly requested with --complete

**Average usage distribution:**
- 50% of runs: Cached resource addition (600-1,200 tokens) ✅ Most common
- 25% of runs: Existing infrastructure check (400-700 tokens)
- 15% of runs: First-time setup (1,800-2,800 tokens)
- 10% of runs: Complete infrastructure (2,800-3,500 tokens)

**Expected token range:** 600-2,800 tokens (60% reduction from 1,500-7,000 baseline)

### Progressive Disclosure

Three setup levels:

1. **Default (basic):** Minimal infrastructure
   ```bash
   claude "/infrastructure aws vpc"
   # Generates: VPC + security groups
   # Tokens: 800-1,200
   ```

2. **Standard (production-ready):** Complete application stack
   ```bash
   claude "/infrastructure aws --standard"
   # Generates: networking, compute, database, monitoring
   # Tokens: 1,800-2,200
   ```

3. **Complete (enterprise):** Full infrastructure
   ```bash
   claude "/infrastructure aws --complete"
   # Generates: all resources + DR + compliance
   # Tokens: 2,800-3,500
   ```

### Implementation Notes

**Key patterns applied:**
- ✅ IaC tool detection caching (800 token savings)
- ✅ Template library approach (85% savings)
- ✅ Early exit for existing infrastructure (90% savings)
- ✅ Grep-based provider detection (90% savings)
- ✅ Incremental resource generation (70% savings)
- ✅ Bash-based validation (75% savings)
- ✅ Progressive infrastructure setup (60% savings)

**Cache locations:**
- `.claude/cache/infrastructure/setup.json` - IaC tool and provider (24 hour TTL)
- `.claude/infrastructure-templates/` - Pre-built resource templates

**Flags:**
- `--new` - Create additional resources for existing infrastructure
- `--validate` - Validate existing infrastructure only
- `--standard` - Production-ready infrastructure
- `--complete` - Complete enterprise infrastructure
- `--clear-cache` - Force cache invalidation

**Supported providers:**
- AWS (Terraform, CloudFormation, Pulumi)
- Azure (Terraform, ARM templates, Pulumi)
- Google Cloud (Terraform, Deployment Manager, Pulumi)
- Multi-cloud (Terraform, Pulumi)

**Common resources:**
- VPC/Virtual Networks
- Compute (EC2, VMs, GCE)
- Databases (RDS, Azure SQL, Cloud SQL)
- Storage (S3, Blob Storage, Cloud Storage)
- Kubernetes clusters (EKS, AKS, GKE)
- Load balancers
- Monitoring and logging

---

## Phase 1: Detect Existing Infrastructure

First, let me analyze your current infrastructure setup:

```bash
# Detect IaC tools and existing infrastructure
detect_iac_tools() {
    local iac_tool=""
    local cloud_provider=""

    echo "=== Detecting Infrastructure Setup ==="
    echo ""

    # Check for Terraform
    if [ -f "main.tf" ] || [ -f "terraform.tfvars" ] || [ -d ".terraform" ]; then
        iac_tool="terraform"
        echo "✓ Terraform detected"

        # Check Terraform version
        if command -v terraform &> /dev/null; then
            terraform_version=$(terraform version | head -1)
            echo "  Version: $terraform_version"
        else
            echo "  ⚠ Terraform CLI not installed"
            echo "  Install: https://www.terraform.io/downloads"
        fi
    fi

    # Check for CloudFormation
    if find . -name "*.yaml" -o -name "*.yml" | xargs grep -l "AWSTemplateFormatVersion" 2>/dev/null | head -1 > /dev/null; then
        iac_tool="${iac_tool:+$iac_tool,}cloudformation"
        echo "✓ CloudFormation templates detected"

        # Check AWS CLI
        if command -v aws &> /dev/null; then
            aws_version=$(aws --version 2>&1)
            echo "  AWS CLI: $aws_version"
        else
            echo "  ⚠ AWS CLI not installed"
            echo "  Install: https://aws.amazon.com/cli/"
        fi
    fi

    # Check for Pulumi
    if [ -f "Pulumi.yaml" ] || [ -d ".pulumi" ]; then
        iac_tool="${iac_tool:+$iac_tool,}pulumi"
        echo "✓ Pulumi detected"

        # Check Pulumi version
        if command -v pulumi &> /dev/null; then
            pulumi_version=$(pulumi version)
            echo "  Version: $pulumi_version"
        else
            echo "  ⚠ Pulumi CLI not installed"
            echo "  Install: https://www.pulumi.com/docs/get-started/install/"
        fi
    fi

    # Detect cloud provider from existing files
    if [ -n "$iac_tool" ]; then
        echo ""
        echo "Detecting cloud provider..."

        if grep -r "provider \"aws\"" . 2>/dev/null | head -1 > /dev/null || \
           grep -r "AWS::" . 2>/dev/null | head -1 > /dev/null; then
            cloud_provider="aws"
            echo "  Provider: AWS"
        fi

        if grep -r "provider \"azurerm\"" . 2>/dev/null | head -1 > /dev/null; then
            cloud_provider="${cloud_provider:+$cloud_provider,}azure"
            echo "  Provider: Azure"
        fi

        if grep -r "provider \"google\"" . 2>/dev/null | head -1 > /dev/null; then
            cloud_provider="${cloud_provider:+$cloud_provider,}gcp"
            echo "  Provider: Google Cloud"
        fi
    fi

    if [ -z "$iac_tool" ]; then
        echo "ℹ No existing infrastructure code detected"
        echo ""
        echo "I can help you set up:"
        echo "  - Terraform (recommended for multi-cloud)"
        echo "  - CloudFormation (AWS-specific)"
        echo "  - Pulumi (code-first approach)"
    fi

    echo "$iac_tool|$cloud_provider"
}

IaC_INFO=$(detect_iac_tools)
IaC_TOOL=$(echo "$IaC_INFO" | cut -d'|' -f1)
CLOUD_PROVIDER=$(echo "$IaC_INFO" | cut -d'|' -f2)

echo ""
```

## Phase 2: IaC Tool Selection and Setup

<think>
For IaC tool selection, I need to consider:
- Existing tooling and team expertise
- Cloud provider preferences (single vs multi-cloud)
- Programming language preferences (Pulumi)
- State management requirements
- CI/CD integration needs
- Cost and licensing considerations

If no existing tools are detected, I'll recommend based on:
- AWS-only → CloudFormation or Terraform
- Multi-cloud → Terraform
- Developer preference for code → Pulumi
- Enterprise requirements → Terraform + Terraform Cloud
</think>

If no IaC tool is detected, I'll help you choose and set up one:

```bash
setup_iac_tool() {
    echo "=== IaC Tool Setup ==="
    echo ""

    # If tool specified in arguments, use it
    if [[ "$ARGUMENTS" =~ terraform|cloudformation|pulumi ]]; then
        SELECTED_TOOL=$(echo "$ARGUMENTS" | grep -oE "terraform|cloudformation|pulumi" | head -1)
        echo "Using specified tool: $SELECTED_TOOL"
    else
        echo "Select Infrastructure as Code tool:"
        echo "  1. Terraform (recommended for most projects)"
        echo "  2. AWS CloudFormation (AWS-specific projects)"
        echo "  3. Pulumi (TypeScript/Python developers)"
        echo ""
        read -p "Enter choice (1-3): " tool_choice

        case $tool_choice in
            1) SELECTED_TOOL="terraform" ;;
            2) SELECTED_TOOL="cloudformation" ;;
            3) SELECTED_TOOL="pulumi" ;;
            *) echo "Invalid choice"; exit 1 ;;
        esac
    fi

    case $SELECTED_TOOL in
        terraform)
            echo ""
            echo "Setting up Terraform..."

            # Check if Terraform is installed
            if ! command -v terraform &> /dev/null; then
                echo ""
                echo "Terraform not found. Install from:"
                echo "  https://www.terraform.io/downloads"
                echo ""
                echo "Quick install (Linux/Mac):"
                echo "  brew install terraform"
                echo "  # or"
                echo "  curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo apt-key add -"
                exit 1
            fi

            # Create basic Terraform structure
            echo "Creating Terraform project structure..."

            mkdir -p terraform/{modules,environments/{dev,staging,prod}}

            # Create main.tf
            cat > terraform/main.tf << 'EOF'
# Main Terraform configuration
terraform {
  required_version = ">= 1.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  # Uncomment for remote state
  # backend "s3" {
  #   bucket = "your-terraform-state-bucket"
  #   key    = "terraform.tfstate"
  #   region = "us-east-1"
  # }
}

provider "aws" {
  region = var.aws_region
}
EOF

            # Create variables.tf
            cat > terraform/variables.tf << 'EOF'
variable "aws_region" {
  description = "AWS region for resources"
  type        = string
  default     = "us-east-1"
}

variable "environment" {
  description = "Environment name (dev, staging, prod)"
  type        = string
}

variable "project_name" {
  description = "Project name for resource naming"
  type        = string
}
EOF

            # Create outputs.tf
            cat > terraform/outputs.tf << 'EOF'
# Output values for use by other modules or reference
# output "example_output" {
#   description = "Description of output"
#   value       = resource.example.id
# }
EOF

            # Create .gitignore
            cat > terraform/.gitignore << 'EOF'
# Local .terraform directories
**/.terraform/*

# .tfstate files
*.tfstate
*.tfstate.*

# Crash log files
crash.log
crash.*.log

# Exclude all .tfvars files
*.tfvars
*.tfvars.json

# Ignore CLI configuration files
.terraformrc
terraform.rc
EOF

            echo "✓ Terraform project structure created"
            echo ""
            echo "Next steps:"
            echo "  1. cd terraform"
            echo "  2. terraform init"
            echo "  3. terraform plan"
            ;;

        cloudformation)
            echo ""
            echo "Setting up CloudFormation..."

            # Check if AWS CLI is installed
            if ! command -v aws &> /dev/null; then
                echo ""
                echo "AWS CLI not found. Install from:"
                echo "  https://aws.amazon.com/cli/"
                exit 1
            fi

            mkdir -p cloudformation/{templates,parameters}

            # Create example template
            cat > cloudformation/templates/main.yaml << 'EOF'
AWSTemplateFormatVersion: '2010-09-09'
Description: Main infrastructure stack

Parameters:
  Environment:
    Type: String
    AllowedValues: [dev, staging, prod]
    Default: dev
    Description: Environment name

  ProjectName:
    Type: String
    Description: Project name for resource naming

Resources:
  # Add your AWS resources here
  # Example:
  # MyS3Bucket:
  #   Type: AWS::S3::Bucket
  #   Properties:
  #     BucketName: !Sub '${ProjectName}-${Environment}-bucket'

Outputs:
  StackName:
    Description: Name of the CloudFormation stack
    Value: !Ref AWS::StackName
    Export:
      Name: !Sub '${AWS::StackName}-StackName'
EOF

            # Create parameters file
            cat > cloudformation/parameters/dev.json << 'EOF'
[
  {
    "ParameterKey": "Environment",
    "ParameterValue": "dev"
  },
  {
    "ParameterKey": "ProjectName",
    "ParameterValue": "my-project"
  }
]
EOF

            echo "✓ CloudFormation project structure created"
            echo ""
            echo "Next steps:"
            echo "  1. Edit cloudformation/templates/main.yaml"
            echo "  2. aws cloudformation validate-template --template-body file://cloudformation/templates/main.yaml"
            echo "  3. aws cloudformation create-stack --stack-name my-stack --template-body file://cloudformation/templates/main.yaml --parameters file://cloudformation/parameters/dev.json"
            ;;

        pulumi)
            echo ""
            echo "Setting up Pulumi..."

            # Check if Pulumi is installed
            if ! command -v pulumi &> /dev/null; then
                echo ""
                echo "Pulumi not found. Install from:"
                echo "  https://www.pulumi.com/docs/get-started/install/"
                exit 1
            fi

            echo ""
            echo "Select Pulumi language:"
            echo "  1. TypeScript"
            echo "  2. Python"
            echo "  3. Go"
            echo ""
            read -p "Enter choice (1-3): " lang_choice

            case $lang_choice in
                1) PULUMI_LANG="typescript" ;;
                2) PULUMI_LANG="python" ;;
                3) PULUMI_LANG="go" ;;
                *) PULUMI_LANG="typescript" ;;
            esac

            echo ""
            echo "Initializing Pulumi project..."
            pulumi new aws-$PULUMI_LANG -y

            echo "✓ Pulumi project created"
            echo ""
            echo "Next steps:"
            echo "  1. pulumi config set aws:region us-east-1"
            echo "  2. pulumi up"
            ;;
    esac

    echo "$SELECTED_TOOL"
}

# Set up IaC tool if needed
if [ -z "$IaC_TOOL" ]; then
    IaC_TOOL=$(setup_iac_tool)
fi
```

## Phase 3: Generate Infrastructure Templates

I'll help you generate infrastructure templates for common patterns:

```bash
generate_infrastructure() {
    local tool=$1
    local resource_type=$2

    echo ""
    echo "=== Infrastructure Template Generation ==="
    echo ""

    case $tool in
        terraform)
            generate_terraform_resources "$resource_type"
            ;;
        cloudformation)
            generate_cloudformation_resources "$resource_type"
            ;;
        pulumi)
            generate_pulumi_resources "$resource_type"
            ;;
    esac
}

generate_terraform_resources() {
    local resource_type=$1

    echo "Generating Terraform resources..."
    echo ""

    # Common infrastructure patterns
    case $resource_type in
        vpc|network)
            cat > terraform/modules/vpc/main.tf << 'EOF'
# VPC Module
resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = {
    Name        = "${var.project_name}-${var.environment}-vpc"
    Environment = var.environment
  }
}

resource "aws_subnet" "public" {
  count             = length(var.availability_zones)
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(var.vpc_cidr, 8, count.index)
  availability_zone = element(var.availability_zones, count.index)

  map_public_ip_on_launch = true

  tags = {
    Name        = "${var.project_name}-${var.environment}-public-${count.index + 1}"
    Environment = var.environment
    Tier        = "Public"
  }
}

resource "aws_subnet" "private" {
  count             = length(var.availability_zones)
  vpc_id            = aws_vpc.main.id
  cidr_block        = cidrsubnet(var.vpc_cidr, 8, count.index + length(var.availability_zones))
  availability_zone = element(var.availability_zones, count.index)

  tags = {
    Name        = "${var.project_name}-${var.environment}-private-${count.index + 1}"
    Environment = var.environment
    Tier        = "Private"
  }
}

resource "aws_internet_gateway" "main" {
  vpc_id = aws_vpc.main.id

  tags = {
    Name        = "${var.project_name}-${var.environment}-igw"
    Environment = var.environment
  }
}

resource "aws_route_table" "public" {
  vpc_id = aws_vpc.main.id

  route {
    cidr_block = "0.0.0.0/0"
    gateway_id = aws_internet_gateway.main.id
  }

  tags = {
    Name        = "${var.project_name}-${var.environment}-public-rt"
    Environment = var.environment
  }
}

resource "aws_route_table_association" "public" {
  count          = length(aws_subnet.public)
  subnet_id      = aws_subnet.public[count.index].id
  route_table_id = aws_route_table.public.id
}
EOF

            cat > terraform/modules/vpc/variables.tf << 'EOF'
variable "project_name" {
  type = string
}

variable "environment" {
  type = string
}

variable "vpc_cidr" {
  type    = string
  default = "10.0.0.0/16"
}

variable "availability_zones" {
  type    = list(string)
  default = ["us-east-1a", "us-east-1b"]
}
EOF

            cat > terraform/modules/vpc/outputs.tf << 'EOF'
output "vpc_id" {
  value = aws_vpc.main.id
}

output "public_subnet_ids" {
  value = aws_subnet.public[*].id
}

output "private_subnet_ids" {
  value = aws_subnet.private[*].id
}
EOF

            echo "✓ VPC/Network module generated"
            ;;

        ecs|container)
            cat > terraform/modules/ecs/main.tf << 'EOF'
# ECS Cluster
resource "aws_ecs_cluster" "main" {
  name = "${var.project_name}-${var.environment}"

  setting {
    name  = "containerInsights"
    value = "enabled"
  }

  tags = {
    Name        = "${var.project_name}-${var.environment}"
    Environment = var.environment
  }
}

# ECS Task Definition
resource "aws_ecs_task_definition" "app" {
  family                   = "${var.project_name}-${var.environment}"
  network_mode             = "awsvpc"
  requires_compatibilities = ["FARGATE"]
  cpu                      = var.task_cpu
  memory                   = var.task_memory
  execution_role_arn       = aws_iam_role.ecs_execution.arn
  task_role_arn            = aws_iam_role.ecs_task.arn

  container_definitions = jsonencode([
    {
      name  = var.container_name
      image = var.container_image
      portMappings = [
        {
          containerPort = var.container_port
          protocol      = "tcp"
        }
      ]
      logConfiguration = {
        logDriver = "awslogs"
        options = {
          "awslogs-group"         = aws_cloudwatch_log_group.app.name
          "awslogs-region"        = var.aws_region
          "awslogs-stream-prefix" = "ecs"
        }
      }
      environment = var.environment_variables
    }
  ])
}

# CloudWatch Log Group
resource "aws_cloudwatch_log_group" "app" {
  name              = "/ecs/${var.project_name}-${var.environment}"
  retention_in_days = 30
}

# ECS Service
resource "aws_ecs_service" "app" {
  name            = "${var.project_name}-${var.environment}"
  cluster         = aws_ecs_cluster.main.id
  task_definition = aws_ecs_task_definition.app.arn
  desired_count   = var.desired_count
  launch_type     = "FARGATE"

  network_configuration {
    subnets          = var.subnet_ids
    security_groups  = [aws_security_group.ecs_tasks.id]
    assign_public_ip = false
  }

  load_balancer {
    target_group_arn = aws_lb_target_group.app.arn
    container_name   = var.container_name
    container_port   = var.container_port
  }

  depends_on = [aws_lb_listener.app]
}
EOF

            echo "✓ ECS/Container module generated"
            ;;

        rds|database)
            cat > terraform/modules/rds/main.tf << 'EOF'
# RDS Subnet Group
resource "aws_db_subnet_group" "main" {
  name       = "${var.project_name}-${var.environment}"
  subnet_ids = var.subnet_ids

  tags = {
    Name        = "${var.project_name}-${var.environment}"
    Environment = var.environment
  }
}

# Security Group for RDS
resource "aws_security_group" "rds" {
  name        = "${var.project_name}-${var.environment}-rds"
  description = "Security group for RDS instance"
  vpc_id      = var.vpc_id

  ingress {
    from_port       = var.db_port
    to_port         = var.db_port
    protocol        = "tcp"
    security_groups = var.allowed_security_groups
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name        = "${var.project_name}-${var.environment}-rds"
    Environment = var.environment
  }
}

# RDS Instance
resource "aws_db_instance" "main" {
  identifier             = "${var.project_name}-${var.environment}"
  engine                 = var.engine
  engine_version         = var.engine_version
  instance_class         = var.instance_class
  allocated_storage      = var.allocated_storage
  storage_type           = "gp3"
  storage_encrypted      = true

  db_name  = var.database_name
  username = var.master_username
  password = var.master_password

  db_subnet_group_name   = aws_db_subnet_group.main.name
  vpc_security_group_ids = [aws_security_group.rds.id]

  backup_retention_period = var.backup_retention_period
  backup_window           = var.backup_window
  maintenance_window      = var.maintenance_window

  skip_final_snapshot = var.environment == "dev"
  final_snapshot_identifier = var.environment != "dev" ? "${var.project_name}-${var.environment}-final" : null

  enabled_cloudwatch_logs_exports = ["error", "general", "slowquery"]

  tags = {
    Name        = "${var.project_name}-${var.environment}"
    Environment = var.environment
  }
}
EOF

            echo "✓ RDS/Database module generated"
            ;;

        s3|storage)
            cat > terraform/modules/s3/main.tf << 'EOF'
# S3 Bucket
resource "aws_s3_bucket" "main" {
  bucket = "${var.project_name}-${var.environment}-${var.bucket_suffix}"

  tags = {
    Name        = "${var.project_name}-${var.environment}-${var.bucket_suffix}"
    Environment = var.environment
  }
}

# Bucket Versioning
resource "aws_s3_bucket_versioning" "main" {
  bucket = aws_s3_bucket.main.id

  versioning_configuration {
    status = var.enable_versioning ? "Enabled" : "Disabled"
  }
}

# Bucket Encryption
resource "aws_s3_bucket_server_side_encryption_configuration" "main" {
  bucket = aws_s3_bucket.main.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

# Block Public Access
resource "aws_s3_bucket_public_access_block" "main" {
  bucket = aws_s3_bucket.main.id

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

# Lifecycle Policy
resource "aws_s3_bucket_lifecycle_configuration" "main" {
  count  = var.enable_lifecycle ? 1 : 0
  bucket = aws_s3_bucket.main.id

  rule {
    id     = "transition-to-ia"
    status = "Enabled"

    transition {
      days          = 30
      storage_class = "STANDARD_IA"
    }

    transition {
      days          = 90
      storage_class = "GLACIER"
    }

    expiration {
      days = 365
    }
  }
}
EOF

            echo "✓ S3/Storage module generated"
            ;;

        *)
            echo "Available resource types:"
            echo "  - vpc/network: VPC with public/private subnets"
            echo "  - ecs/container: ECS Fargate cluster and service"
            echo "  - rds/database: RDS database instance"
            echo "  - s3/storage: S3 bucket with security defaults"
            echo ""
            echo "Usage: /infrastructure <resource_type>"
            ;;
    esac
}

# Generate infrastructure based on arguments
RESOURCE_TYPE=$(echo "$ARGUMENTS" | grep -oE "vpc|network|ecs|container|rds|database|s3|storage" | head -1)

if [ -n "$RESOURCE_TYPE" ]; then
    generate_infrastructure "$IaC_TOOL" "$RESOURCE_TYPE"
fi
```

## Phase 4: Best Practices Validation

I'll validate your infrastructure code against best practices:

```bash
validate_iac_best_practices() {
    local tool=$1

    echo ""
    echo "=== Best Practices Validation ==="
    echo ""

    case $tool in
        terraform)
            echo "Running Terraform validation checks..."
            echo ""

            # Format check
            if command -v terraform &> /dev/null; then
                echo "1. Format check..."
                terraform fmt -check -recursive || {
                    echo "  ⚠ Code not formatted. Run: terraform fmt -recursive"
                }

                # Validation
                echo "2. Configuration validation..."
                terraform init -backend=false > /dev/null 2>&1
                terraform validate || {
                    echo "  ❌ Configuration errors found"
                }

                # Security scanning with tfsec (if available)
                if command -v tfsec &> /dev/null; then
                    echo "3. Security scanning with tfsec..."
                    tfsec .
                else
                    echo "3. Security scanning: tfsec not installed"
                    echo "  Install: brew install tfsec"
                fi

                # Cost estimation with infracost (if available)
                if command -v infracost &> /dev/null; then
                    echo "4. Cost estimation..."
                    infracost breakdown --path .
                else
                    echo "4. Cost estimation: infracost not installed"
                    echo "  Install: https://www.infracost.io/docs/"
                fi
            fi
            ;;

        cloudformation)
            echo "Running CloudFormation validation..."
            echo ""

            # Validate templates
            for template in cloudformation/templates/*.yaml cloudformation/templates/*.yml; do
                if [ -f "$template" ]; then
                    echo "Validating: $template"
                    aws cloudformation validate-template \
                        --template-body file://"$template" || {
                        echo "  ❌ Template validation failed"
                    }
                fi
            done

            # Lint with cfn-lint (if available)
            if command -v cfn-lint &> /dev/null; then
                echo ""
                echo "Running cfn-lint..."
                cfn-lint cloudformation/templates/*.yaml cloudformation/templates/*.yml
            else
                echo ""
                echo "cfn-lint not installed"
                echo "  Install: pip install cfn-lint"
            fi
            ;;

        pulumi)
            echo "Running Pulumi validation..."
            echo ""

            if command -v pulumi &> /dev/null; then
                echo "Preview changes..."
                pulumi preview
            fi
            ;;
    esac

    echo ""
    echo "=== Best Practices Checklist ==="
    echo ""
    cat << 'EOF'
✓ Security:
  - Secrets stored in parameter stores/vaults
  - Encryption enabled for data at rest
  - Security groups follow least privilege
  - Public access restricted where appropriate

✓ Cost Optimization:
  - Right-sized instances
  - Auto-scaling configured
  - S3 lifecycle policies for cost savings
  - Reserved instances for predictable workloads

✓ High Availability:
  - Multi-AZ deployments
  - Load balancing configured
  - Health checks enabled
  - Backup and recovery procedures

✓ Maintainability:
  - Consistent naming conventions
  - Proper tagging strategy
  - Modular code structure
  - Documentation and comments

✓ State Management:
  - Remote state backend configured
  - State locking enabled
  - State backup strategy
EOF
}

validate_iac_best_practices "$IaC_TOOL"
```

## Phase 5: State Management Guidance

I'll provide guidance on infrastructure state management:

```bash
setup_state_management() {
    echo ""
    echo "=== State Management Setup ==="
    echo ""

    case $IaC_TOOL in
        terraform)
            cat << 'EOF'
**Terraform State Management:**

For team collaboration, use remote state backend:

1. S3 Backend (Recommended for AWS):

```hcl
terraform {
  backend "s3" {
    bucket         = "your-terraform-state"
    key            = "project/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
  }
}
```

2. Create S3 bucket for state:

```bash
aws s3 mb s3://your-terraform-state
aws s3api put-bucket-versioning \
  --bucket your-terraform-state \
  --versioning-configuration Status=Enabled
```

3. Create DynamoDB table for locking:

```bash
aws dynamodb create-table \
  --table-name terraform-state-lock \
  --attribute-definitions AttributeName=LockID,AttributeType=S \
  --key-schema AttributeName=LockID,KeyType=HASH \
  --billing-mode PAY_PER_REQUEST
```

4. Initialize backend:

```bash
terraform init -migrate-state
```

**State Security:**
- Never commit terraform.tfstate to git
- Enable state file encryption
- Use IAM policies to restrict access
- Enable versioning for state recovery
EOF
            ;;

        cloudformation)
            cat << 'EOF'
**CloudFormation State Management:**

CloudFormation manages state automatically, but you should:

1. Stack Policy (prevent accidental updates):

```json
{
  "Statement": [
    {
      "Effect": "Deny",
      "Principal": "*",
      "Action": "Update:*",
      "Resource": "LogicalResourceId/ProductionDatabase"
    }
  ]
}
```

2. Change Sets (preview changes):

```bash
aws cloudformation create-change-set \
  --stack-name my-stack \
  --change-set-name my-changes \
  --template-body file://template.yaml

aws cloudformation describe-change-set \
  --change-set-name my-changes \
  --stack-name my-stack
```

3. Stack Protection:

```bash
aws cloudformation update-termination-protection \
  --enable-termination-protection \
  --stack-name my-stack
```
EOF
            ;;

        pulumi)
            cat << 'EOF'
**Pulumi State Management:**

Pulumi stores state in Pulumi Service by default or self-managed backend:

1. Pulumi Service (Easiest):

```bash
pulumi login
pulumi stack init production
```

2. S3 Backend (Self-managed):

```bash
pulumi login s3://your-pulumi-state
```

3. State Export/Import:

```bash
pulumi stack export --file state.json
pulumi stack import --file state.json
```

**State Security:**
- Use secret configuration for sensitive values
- Enable encryption for state backend
- Implement RBAC for team access
EOF
            ;;
    esac
}

setup_state_management
```

## Phase 6: Cost Optimization Suggestions

I'll analyze infrastructure and provide cost optimization recommendations:

```bash
echo ""
echo "=== Cost Optimization Recommendations ==="
echo ""

cat << 'EOF'
**Immediate Cost Savings:**

1. Right-Size Resources:
   - Review instance types and downsize overprovisioned resources
   - Use AWS Compute Optimizer or similar tools
   - Implement auto-scaling to match demand

2. Storage Optimization:
   - S3 lifecycle policies (move to IA/Glacier)
   - EBS volume type optimization (gp3 vs gp2)
   - Delete unused snapshots and AMIs

3. Reserved Instances/Savings Plans:
   - For predictable workloads, commit to 1-3 year terms
   - Potential savings: 30-70%
   - Start with convertible RIs for flexibility

4. Spot Instances:
   - For fault-tolerant workloads
   - Potential savings: 50-90%
   - Use with auto-scaling groups

5. Network Optimization:
   - Reduce data transfer costs
   - Use VPC endpoints for AWS services
   - Enable CloudFront caching

**Cost Monitoring:**
- Set up billing alerts
- Tag all resources for cost allocation
- Use cost explorer for analysis
- Review costs weekly/monthly
EOF
```

## Integration Points

This skill works well with:
- `/deploy-validate` - Pre-deployment infrastructure validation
- `/security-scan` - Security analysis of IaC templates
- `/commit` - Version control for infrastructure changes

## Safety Guarantees

**Protection Measures:**
- Plan before apply (preview changes)
- State backup before modifications
- Incremental infrastructure changes
- Rollback procedures documented

**Important:** I will NEVER:
- Apply infrastructure changes without confirmation
- Delete stateful resources without explicit approval
- Expose secrets in code or commits
- Add AI attribution to infrastructure templates

## Example Workflows

```bash
# Create new infrastructure
/infrastructure vpc
/infrastructure ecs
/infrastructure rds

# Validate before deployment
/infrastructure validate
/deploy-validate

# Apply changes
terraform plan
terraform apply

# Cost analysis
/infrastructure cost

# Commit infrastructure changes
/commit
```

## Troubleshooting

**Issue: Terraform state locked**
- Solution: Check for stuck processes
- Solution: Force unlock if necessary (use cautiously)

**Issue: CloudFormation stack stuck**
- Solution: Check stack events for errors
- Solution: May need to manually fix resource

**Issue: Resource already exists**
- Solution: Import existing resources into state
- Solution: Use terraform import or pulumi import

**Credits:**
- Terraform best practices from [HashiCorp documentation](https://www.terraform.io/docs)
- AWS CloudFormation patterns from [AWS documentation](https://docs.aws.amazon.com/cloudformation/)
- Pulumi examples from [Pulumi documentation](https://www.pulumi.com/docs/)
- Infrastructure patterns from SKILLS_EXPANSION_PLAN.md Tier 3 DevOps practices

---
> Converted and distributed by [TomeVault](https://tomevault.io/claim/manastalukdar) — claim your Tome and manage your conversions.
<!-- tomevault:4.0:skill_md:2026-04-13 -->

