# infrastructure > Infrastructure as Code generation for Terraform, CloudFormation, and Pulumi - Author: Manas Talukdar - Repository: manastalukdar/claude-devstudio - Version: 20260127222652 - Stars: 1 - Forks: 0 - Last Updated: 2026-02-07 - Source: https://github.com/manastalukdar/claude-devstudio - Web: https://mule.run/skillshub/@@manastalukdar/claude-devstudio~infrastructure:20260127222652 --- --- name: infrastructure description: Infrastructure as Code generation for Terraform, CloudFormation, and Pulumi disable-model-invocation: false --- # 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 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 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 " ;; 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