Advanced Terraform Functions and Expressions: Dynamic Infrastructure Patterns

Master complex Terraform functions, expressions, and dynamic blocks for sophisticated infrastructure automation

Featured image



Overview

As infrastructure complexity grows, Terraform’s advanced functions and expressions become essential for creating sophisticated, maintainable, and scalable Infrastructure as Code solutions.

This comprehensive guide explores the powerful capabilities that distinguish basic Terraform usage from enterprise-grade implementations.

Advanced Terraform programming involves mastering built-in functions, conditional logic, iterative constructs, and dynamic resource generation.

These features enable data transformation, conditional resource creation, and complex infrastructure patterns that adapt to varying requirements and environments.

This guide covers nine categories of Terraform functions, advanced expression patterns, dynamic block construction, and real-world implementation strategies.

We’ll explore how to leverage conditional expressions, for loops, type conversions, and collection manipulations to build flexible, reusable infrastructure modules.

Understanding these advanced concepts enables infrastructure engineers to create self-adapting configurations, reduce code duplication, and implement sophisticated deployment patterns that scale across multiple environments and use cases.



Terraform Functions Overview

Terraform provides over 100 built-in functions organized into nine categories, each serving specific data manipulation and transformation needs in infrastructure configurations.


Function Categories:

# 1. Numeric Functions
abs(-5)                    # Returns: 5
ceil(4.3)                  # Returns: 5
floor(4.7)                 # Returns: 4
max(5, 12, 9)             # Returns: 12
min(5, 12, 9)             # Returns: 5

# 2. String Functions
upper("hello")             # Returns: "HELLO"
lower("WORLD")             # Returns: "world"
title("hello world")       # Returns: "Hello World"
trim("  hello  ", " ")     # Returns: "hello"
replace("hello", "l", "x") # Returns: "hexxo"

# 3. Collection Functions
length([1, 2, 3])          # Returns: 3
concat([1, 2], [3, 4])     # Returns: [1, 2, 3, 4]
distinct([1, 2, 2, 3])     # Returns: [1, 2, 3]
sort(["c", "a", "b"])      # Returns: ["a", "b", "c"]

# 4. Encoding Functions
base64encode("hello")      # Returns: "aGVsbG8="
base64decode("aGVsbG8=")   # Returns: "hello"
jsonencode({a = "b"})      # Returns: "{\"a\":\"b\"}"

# 5. Filesystem Functions
file("path/to/file.txt")   # Returns: file contents
filebase64("image.png")    # Returns: base64 encoded file
dirname("/path/to/file")   # Returns: "/path/to"
basename("/path/to/file")  # Returns: "file"

# 6. Date and Time Functions
timestamp()                # Returns: current timestamp
formatdate("YYYY-MM-DD", timestamp())
timeadd(timestamp(), "24h")

# 7. Hash and Crypto Functions
md5("hello")              # Returns: MD5 hash
sha256("hello")           # Returns: SHA256 hash
uuid()                    # Returns: random UUID

# 8. IP Network Functions
cidrhost("10.0.0.0/8", 2) # Returns: "10.0.0.2"
cidrnetmask("10.0.0.0/8") # Returns: "255.0.0.0"
cidrsubnet("10.0.0.0/8", 8, 2) # Returns: "10.2.0.0/16"

# 9. Type Conversion Functions
tostring(42)              # Returns: "42"
tonumber("42")            # Returns: 42
tolist(toset([1, 2, 2]))  # Returns: [1, 2]



Advanced Collection Functions


1. coalesce - Null Value Handling

The coalesce function returns the first non-null, non-empty value from a sequence of arguments, making it essential for providing fallback values and handling optional configurations.

# Advanced coalesce patterns
locals {
  # Environment-based resource naming with fallbacks
  environment = coalesce(var.environment, "development")
  
  # Multi-level fallback for database configuration
  db_instance_class = coalesce(
    var.db_instance_class,
    local.environment_defaults[var.environment],
    "db.t3.micro"
  )
  
  # Complex subnet group naming with multiple fallbacks
  db_subnet_group_name = coalesce(
    var.db_subnet_group_name,
    format("%s-%s-db-subnet-group", var.project_name, local.environment),
    "default-db-subnet-group"
  )
  
  # API endpoint configuration with environment-specific defaults
  api_endpoint = coalesce(
    var.custom_api_endpoint,
    local.environment_config[local.environment].api_endpoint,
    "https://api.${var.domain_name}"
  )
}

# Usage in resource configuration
resource "aws_db_subnet_group" "main" {
  name       = local.db_subnet_group_name
  subnet_ids = var.subnet_ids

  tags = {
    Name        = local.db_subnet_group_name
    Environment = local.environment
    ManagedBy   = "terraform"
  }
}


2. merge - Complex Object Composition

The merge function combines multiple maps or objects, with later arguments taking precedence over earlier ones for duplicate keys.

# Advanced merge patterns for tag management
locals {
  # Base tags applied to all resources
  base_tags = {
    Project     = var.project_name
    Environment = var.environment
    ManagedBy   = "terraform"
    CreatedAt   = formatdate("YYYY-MM-DD", timestamp())
  }
  
  # Environment-specific tags
  environment_tags = {
    development = {
      AutoShutdown = "true"
      CostCenter   = "development"
      Backup       = "weekly"
    }
    staging = {
      AutoShutdown = "false"
      CostCenter   = "qa"
      Backup       = "daily"
    }
    production = {
      AutoShutdown = "false"
      CostCenter   = "operations"
      Backup       = "hourly"
      Compliance   = "required"
    }
  }
  
  # Compliance tags for sensitive resources
  compliance_tags = var.enable_compliance ? {
    DataClassification = "sensitive"
    ComplianceScope    = "SOC2"
    BackupRequired     = "true"
    EncryptionRequired = "true"
  } : {}
  
  # Final tag composition with precedence
  resource_tags = merge(
    local.base_tags,
    lookup(local.environment_tags, var.environment, {}),
    local.compliance_tags,
    var.additional_tags
  )
  
  # Database-specific tag merging
  database_tags = merge(
    local.resource_tags,
    {
      ResourceType = "database"
      BackupWindow = "03:00-04:00"
      MaintenanceWindow = "Mon:04:00-Mon:05:00"
    }
  )
}

# Advanced configuration merging
locals {
  # Default monitoring configuration
  default_monitoring = {
    enabled                = true
    detailed_monitoring    = false
    cpu_alarm_threshold    = 80
    memory_alarm_threshold = 85
    disk_alarm_threshold   = 90
  }
  
  # Environment-specific monitoring overrides
  environment_monitoring = {
    production = {
      detailed_monitoring    = true
      cpu_alarm_threshold    = 70
      memory_alarm_threshold = 75
      enable_custom_metrics  = true
    }
    staging = {
      cpu_alarm_threshold = 85
      enable_testing_metrics = true
    }
  }
  
  # Final monitoring configuration
  monitoring_config = merge(
    local.default_monitoring,
    lookup(local.environment_monitoring, var.environment, {}),
    var.custom_monitoring_config
  )
}


3. lookup and element - Advanced Data Access

# Advanced lookup patterns with complex defaults
locals {
  # Instance type mapping with environment-based defaults
  instance_types = {
    development = "t3.micro"
    staging     = "t3.small"
    production  = "c5.large"
  }
  
  # Complex lookup with computed defaults
  instance_type = lookup(
    local.instance_types,
    var.environment,
    var.high_performance ? "c5.xlarge" : "t3.medium"
  )
  
  # Multi-level configuration lookup
  availability_zones = lookup(
    var.region_config,
    var.aws_region,
    {
      azs = data.aws_availability_zones.available.names
      preferred_azs = slice(data.aws_availability_zones.available.names, 0, 2)
    }
  ).preferred_azs
  
  # Advanced element usage with modulo for round-robin distribution
  subnet_distribution = [
    for i, instance in var.instances : {
      instance_id = instance.id
      subnet_id   = element(var.subnet_ids, i % length(var.subnet_ids))
      az         = element(local.availability_zones, i % length(local.availability_zones))
    }
  ]
}

# Complex lookup for security group rules
locals {
  # Security group rule templates
  security_rules = {
    web = [
      {
        type        = "ingress"
        from_port   = 80
        to_port     = 80
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      },
      {
        type        = "ingress"
        from_port   = 443
        to_port     = 443
        protocol    = "tcp"
        cidr_blocks = ["0.0.0.0/0"]
      }
    ]
    api = [
      {
        type        = "ingress"
        from_port   = 8080
        to_port     = 8080
        protocol    = "tcp"
        cidr_blocks = var.api_allowed_cidrs
      }
    ]
    database = [
      {
        type                     = "ingress"
        from_port               = 5432
        to_port                 = 5432
        protocol                = "tcp"
        source_security_group_id = aws_security_group.app.id
      }
    ]
  }
  
  # Dynamic rule selection based on service type
  selected_rules = lookup(local.security_rules, var.service_type, [])
}



Advanced String Functions


1. format - Dynamic String Construction

# Advanced format patterns for resource naming
locals {
  # Hierarchical naming convention
  resource_name_template = "%s-%s-%s-%s"
  
  # Generate consistent resource names
  vpc_name = format(
    local.resource_name_template,
    var.organization,
    var.environment,
    var.project_name,
    "vpc"
  )
  
  subnet_names = [
    for i, az in local.availability_zones : format(
      "%s-%s-%s-subnet-%s",
      var.organization,
      var.environment,
      var.project_name,
      substr(az, -1, 1)  # Use last character of AZ
    )
  ]
  
  # Complex formatting with conditional elements
  instance_name = format(
    "%s-%s%s",
    local.base_name,
    var.instance_role,
    var.enable_high_availability ? "-ha" : ""
  )
  
  # URL construction with multiple variables
  database_connection_string = format(
    "postgresql://%s:%s@%s:%d/%s?sslmode=%s",
    var.db_username,
    var.db_password,
    aws_db_instance.main.endpoint,
    aws_db_instance.main.port,
    var.db_name,
    var.enable_ssl ? "require" : "disable"
  )
}

# Advanced format usage in outputs
output "service_endpoints" {
  value = {
    for service, config in var.services : service => {
      internal_url = format(
        "https://%s.%s.local:%d",
        service,
        var.environment,
        config.port
      )
      external_url = format(
        "https://%s.%s.%s",
        service,
        var.environment,
        var.domain_name
      )
      health_check = format(
        "%s/health",
        format(
          "https://%s.%s.%s",
          service,
          var.environment,
          var.domain_name
        )
      )
    }
  }
}


2. substr and String Manipulation

# Advanced string manipulation patterns
locals {
  # Extract components from complex identifiers
  account_id = substr(data.aws_caller_identity.current.arn, 13, 12)
  
  # Create short identifiers for resource naming
  short_project = substr(replace(lower(var.project_name), "-", ""), 0, 8)
  short_env     = substr(var.environment, 0, 3)
  
  # Generate unique identifiers with length constraints
  unique_suffix = substr(uuid(), 0, 8)
  bucket_name = format(
    "%s-%s-%s",
    local.short_project,
    local.short_env,
    local.unique_suffix
  )
  
  # Extract and validate AMI ID format
  is_valid_ami = length(var.ami_id) > 4 && substr(var.ami_id, 0, 4) == "ami-"
  
  # Process and clean input strings
  sanitized_name = replace(
    replace(
      lower(var.user_input),
      "/[^a-z0-9-]/", 
      "-"
    ),
    "/--+/",
    "-"
  )
  
  # Extract domain components
  domain_parts = split(".", var.domain_name)
  subdomain    = length(local.domain_parts) > 2 ? local.domain_parts[0] : ""
  root_domain  = join(".", slice(local.domain_parts, -2, length(local.domain_parts)))
}

# Advanced validation using string functions
variable "ami_id" {
  type        = string
  description = "The AMI ID to use for instances"
  
  validation {
    condition = (
      length(var.ami_id) > 4 && 
      substr(var.ami_id, 0, 4) == "ami-" &&
      can(regex("^ami-[0-9a-f]{8}([0-9a-f]{9})?$", var.ami_id))
    )
    error_message = "AMI ID must be a valid format (ami-xxxxxxxx or ami-xxxxxxxxxxxxxxxxx)."
  }
}

variable "instance_name" {
  type        = string
  description = "Name for the instance"
  
  validation {
    condition = (
      length(var.instance_name) >= 3 &&
      length(var.instance_name) <= 63 &&
      can(regex("^[a-z][a-z0-9-]*[a-z0-9]$", var.instance_name))
    )
    error_message = "Instance name must be 3-63 characters, start with a letter, and contain only lowercase letters, numbers, and hyphens."
  }
}



Types and Values - Advanced Patterns


1. Complex Type Definitions

# Advanced type constraints and validations
variable "application_config" {
  type = object({
    name         = string
    version      = string
    port         = number
    health_check = object({
      enabled  = bool
      path     = string
      interval = number
      timeout  = number
    })
    scaling = object({
      min_instances = number
      max_instances = number
      target_cpu    = number
    })
    environment_variables = map(string)
    secrets              = map(string)
    dependencies         = list(string)
    feature_flags        = map(bool)
  })
  
  description = "Complete application configuration"
  
  validation {
    condition     = var.application_config.port > 1024 && var.application_config.port < 65536
    error_message = "Application port must be between 1024 and 65535."
  }
  
  validation {
    condition = (
      var.application_config.scaling.min_instances <= var.application_config.scaling.max_instances &&
      var.application_config.scaling.min_instances >= 1
    )
    error_message = "Min instances must be at least 1 and not exceed max instances."
  }
}

# Complex tuple definitions for multi-environment configurations
variable "environments" {
  type = list(object({
    name = string
    config = object({
      instance_type    = string
      instance_count   = number
      auto_scaling     = bool
      backup_retention = number
    })
    networking = object({
      vpc_cidr           = string
      availability_zones = list(string)
      enable_nat_gateway = bool
    })
    monitoring = object({
      detailed_monitoring = bool
      custom_metrics     = bool
      log_retention_days = number
    })
  }))
  
  description = "Multi-environment configuration"
  
  validation {
    condition     = length(var.environments) > 0
    error_message = "At least one environment must be defined."
  }
  
  validation {
    condition = alltrue([
      for env in var.environments : can(cidrhost(env.networking.vpc_cidr, 0))
    ])
    error_message = "All VPC CIDR blocks must be valid."
  }
}

# Dynamic type handling with any
variable "resource_configs" {
  type        = map(any)
  description = "Flexible resource configurations"
  
  validation {
    condition = alltrue([
      for k, v in var.resource_configs : contains(["string", "number", "bool", "list", "map"], type(v))
    ])
    error_message = "Resource configs must contain basic types only."
  }
}


2. Advanced List and Map Operations

# Complex list and map transformations
locals {
  # Flatten nested structures
  all_subnets = flatten([
    for env_name, env_config in var.environments : [
      for az_index, az in env_config.networking.availability_zones : {
        environment = env_name
        az          = az
        cidr        = cidrsubnet(env_config.networking.vpc_cidr, 8, az_index)
        type        = az_index < 2 ? "public" : "private"
      }
    ]
  ])
  
  # Group subnets by type
  subnets_by_type = {
    for subnet in local.all_subnets : subnet.type => subnet...
  }
  
  # Create complex mappings
  instance_configs = {
    for env in var.environments : env.name => {
      instances = [
        for i in range(env.config.instance_count) : {
          name      = format("%s-%s-%02d", var.project_name, env.name, i + 1)
          subnet_id = local.subnets_by_type.private[i % length(local.subnets_by_type.private)].cidr
          az        = local.subnets_by_type.private[i % length(local.subnets_by_type.private)].az
        }
      ]
      total_cost_estimate = env.config.instance_count * lookup(local.instance_costs, env.config.instance_type, 100)
    }
  }
  
  # Advanced filtering and transformation
  production_instances = [
    for env_name, env_config in local.instance_configs : env_config.instances...
    if env_name == "production"
  ]
  
  # Conditional list construction
  monitoring_targets = concat(
    [for inst in local.production_instances : inst.name],
    var.enable_staging_monitoring ? [
      for env_name, env_config in local.instance_configs : env_config.instances[*].name...
      if env_name == "staging"
    ] : []
  )
}



Conditional Expressions - Advanced Patterns


1. Complex Conditional Logic

# Multi-level conditional expressions
locals {
  # Environment-based configuration selection
  instance_type = (
    var.environment == "production" ? (
      var.high_performance ? "c5.2xlarge" : "m5.xlarge"
    ) : var.environment == "staging" ? (
      var.enable_testing ? "m5.large" : "t3.medium"
    ) : "t3.micro"
  )
  
  # Complex backup configuration
  backup_config = var.enable_backups ? {
    retention_period = var.environment == "production" ? 30 : 7
    backup_window   = var.environment == "production" ? "03:00-04:00" : "02:00-03:00"
    copy_tags_to_snapshot = true
    delete_automated_backups = var.environment != "production"
  } : null
  
  # Conditional resource creation parameters
  create_monitoring = var.enable_monitoring && (
    var.environment == "production" || 
    (var.environment == "staging" && var.enable_staging_monitoring)
  )
  
  # Network configuration based on environment
  network_config = {
    enable_nat_gateway = var.environment == "production" ? true : var.cost_optimization ? false : true
    enable_vpn_gateway = var.environment == "production" && var.enable_hybrid_connectivity
    flow_logs_enabled  = var.environment != "development" && var.enable_compliance
    
    # Conditional CIDR allocation
    vpc_cidr = (
      var.custom_vpc_cidr != null ? var.custom_vpc_cidr : 
      var.environment == "production" ? "10.0.0.0/16" :
      var.environment == "staging" ? "10.1.0.0/16" : "10.2.0.0/16"
    )
  }
}

# Advanced conditional resource configuration
resource "aws_instance" "web" {
  count = var.enable_web_tier ? var.web_instance_count : 0
  
  ami           = local.is_valid_ami ? var.ami_id : data.aws_ami.default.id
  instance_type = local.instance_type
  
  # Conditional block inclusion
  dynamic "ebs_block_device" {
    for_each = var.enable_additional_storage ? [1] : []
    
    content {
      device_name = "/dev/sdf"
      volume_size = var.environment == "production" ? 100 : 50
      volume_type = var.environment == "production" ? "gp3" : "gp2"
      encrypted   = var.environment != "development"
    }
  }
  
  user_data = var.custom_user_data != null ? var.custom_user_data : (
    var.enable_automatic_updates ? 
    file("${path.module}/scripts/auto-update.sh") : 
    file("${path.module}/scripts/basic-setup.sh")
  )
  
  tags = merge(
    local.base_tags,
    var.enable_cost_tracking ? {
      CostCenter = var.cost_center
      BillingProject = var.billing_project
    } : {},
    var.enable_compliance ? {
      ComplianceScope = "SOC2"
      DataClassification = "internal"
    } : {}
  )
}


2. Validation with Conditional Logic

# Advanced validation using conditional expressions
variable "database_config" {
  type = object({
    engine         = string
    engine_version = string
    instance_class = string
    allocated_storage = number
    multi_az       = bool
    backup_retention_period = number
  })
  
  validation {
    condition = contains(["mysql", "postgres", "mariadb"], var.database_config.engine)
    error_message = "Database engine must be one of: mysql, postgres, mariadb."
  }
  
  validation {
    condition = (
      var.database_config.engine == "mysql" ? 
      can(regex("^[0-9]+\\.[0-9]+$", var.database_config.engine_version)) :
      var.database_config.engine == "postgres" ?
      tonumber(split(".", var.database_config.engine_version)[0]) >= 12 :
      true
    )
    error_message = "Engine version must be valid for the selected database engine."
  }
  
  validation {
    condition = (
      var.database_config.backup_retention_period >= 0 &&
      var.database_config.backup_retention_period <= (
        var.database_config.multi_az ? 35 : 7
      )
    )
    error_message = "Backup retention period must be 0-35 days for Multi-AZ, 0-7 days for single-AZ."
  }
}

# Complex environment-based validation
variable "scaling_config" {
  type = object({
    min_size         = number
    max_size         = number
    desired_capacity = number
    environment      = string
  })
  
  validation {
    condition = (
      var.scaling_config.min_size <= var.scaling_config.desired_capacity &&
      var.scaling_config.desired_capacity <= var.scaling_config.max_size
    )
    error_message = "Scaling configuration must satisfy: min_size ≤ desired_capacity ≤ max_size."
  }
  
  validation {
    condition = (
      var.scaling_config.environment == "production" ?
      var.scaling_config.min_size >= 2 && var.scaling_config.max_size <= 20 :
      var.scaling_config.environment == "staging" ?
      var.scaling_config.min_size >= 1 && var.scaling_config.max_size <= 10 :
      var.scaling_config.max_size <= 5
    )
    error_message = "Scaling limits must be appropriate for the environment."
  }
}



for Expressions - Advanced Iteration


1. Complex Data Transformations

# Advanced for expression patterns
locals {
  # Transform and filter collections simultaneously
  production_databases = {
    for db_name, db_config in var.databases : db_name => {
      instance_class = db_config.performance_tier == "high" ? "db.r5.xlarge" : "db.t3.medium"
      allocated_storage = db_config.storage_requirements * 2  # Production gets 2x storage
      backup_retention = 30
      multi_az = true
      encrypted = true
      
      # Conditional parameter groups
      parameter_group = db_config.engine == "postgres" ? 
        aws_db_parameter_group.postgres_prod.name : 
        aws_db_parameter_group.mysql_prod.name
        
      # Environment-specific networking
      subnet_group_name = aws_db_subnet_group.production.name
      vpc_security_group_ids = [
        aws_security_group.db_production.id,
        aws_security_group.app_to_db.id
      ]
    }
    if db_config.enabled && db_config.environment == "production"
  }
  
  # Create complex nested structures
  service_mesh_config = {
    for service_name, service_config in var.microservices : service_name => {
      # Service discovery configuration
      service_discovery = {
        namespace = aws_service_discovery_http_namespace.main.name
        service_name = format("%s-%s", service_name, var.environment)
        health_check_grace_period = service_config.startup_time
      }
      
      # Load balancer target groups
      target_groups = [
        for port in service_config.ports : {
          name = format("%s-%s-%d", service_name, var.environment, port)
          port = port
          protocol = service_config.protocol
          health_check_path = service_config.health_check_path
          health_check_interval = service_config.health_check_interval
        }
      ]
      
      # Service dependencies and routing
      dependencies = [
        for dep in service_config.dependencies : {
          service_name = dep
          endpoint = format("http://%s.%s.local:%d", 
            dep, 
            var.environment, 
            var.microservices[dep].ports[0]
          )
          timeout = var.microservices[dep].timeout
        }
        if contains(keys(var.microservices), dep)
      ]
      
      # Auto-scaling configuration
      scaling_policies = service_config.auto_scaling ? [
        {
          name = "cpu-scaling"
          target_value = 70
          metric_type = "CPUUtilization"
        },
        {
          name = "memory-scaling"
          target_value = 80
          metric_type = "MemoryUtilization"
        }
      ] : []
    }
  }
  
  # Multi-dimensional data processing
  cross_region_backups = {
    for region in var.backup_regions : region => {
      for db_name, db_config in local.production_databases : db_name => {
        source_db_arn = format(
          "arn:aws:rds:%s:%s:db:%s",
          var.primary_region,
          data.aws_caller_identity.current.account_id,
          db_name
        )
        backup_schedule = format("%d %d * * %s", 
          (index(var.backup_regions, region) * 2),  # Stagger backup times
          3,  # 3 AM
          join(",", range(7))  # Daily
        )
        retention_days = 14
        encrypted = true
      }
      if db_config.cross_region_backup
    }
  }
}


2. Advanced Filtering and Aggregation

# Complex filtering with multiple conditions
locals {
  # Filter and transform with complex conditions
  eligible_instances = [
    for instance in var.instances : {
      id = instance.id
      name = instance.name
      enhanced_config = {
        monitoring_enabled = true
        backup_enabled = true
        security_group_ids = concat(
          instance.security_group_ids,
          [aws_security_group.enhanced_monitoring.id]
        )
      }
      cost_optimization = {
        rightsizing_recommendation = (
          instance.cpu_utilization < 20 ? "downsize" :
          instance.cpu_utilization > 80 ? "upsize" : "maintain"
        )
        estimated_monthly_cost = lookup(local.instance_costs, instance.type, 0) * 24 * 30
      }
    }
    if (
      instance.environment == "production" &&
      instance.cpu_utilization != null &&
      instance.memory_utilization != null &&
      !instance.marked_for_termination
    )
  ]
  
  # Aggregate data across multiple dimensions
  cost_summary = {
    by_environment = {
      for env in distinct([for inst in var.instances : inst.environment]) : env => {
        total_instances = length([for inst in var.instances : inst if inst.environment == env])
        total_cost = sum([
          for inst in var.instances : lookup(local.instance_costs, inst.type, 0)
          if inst.environment == env
        ])
        average_utilization = sum([
          for inst in var.instances : inst.cpu_utilization
          if inst.environment == env && inst.cpu_utilization != null
        ]) / length([
          for inst in var.instances : inst
          if inst.environment == env && inst.cpu_utilization != null
        ])
      }
    }
    
    by_instance_type = {
      for type in distinct([for inst in var.instances : inst.type]) : type => {
        count = length([for inst in var.instances : inst if inst.type == type])
        total_cost = length([for inst in var.instances : inst if inst.type == type]) * 
                    lookup(local.instance_costs, type, 0)
        environments = distinct([
          for inst in var.instances : inst.environment if inst.type == type
        ])
      }
    }
  }
  
  # Create security group rules from service definitions
  security_group_rules = flatten([
    for service_name, service_config in var.services : [
      for rule in service_config.security_rules : {
        service_name = service_name
        rule_type = rule.type
        from_port = rule.from_port
        to_port = rule.to_port
        protocol = rule.protocol
        
        # Dynamic source configuration
        cidr_blocks = lookup(rule, "cidr_blocks", null)
        source_security_group_id = lookup(rule, "source_service", null) != null ? 
          lookup(local.service_security_groups, rule.source_service, null) : null
        
        # Rule description with context
        description = format(
          "%s - %s traffic for %s service",
          title(rule.type),
          rule.protocol,
          service_name
        )
      }
    ]
  ])
}



Dynamic Blocks - Advanced Resource Generation


1. Complex Dynamic Block Patterns

# Advanced dynamic block with conditional logic
resource "aws_security_group" "application" {
  name_prefix = format("%s-%s-", var.application_name, var.environment)
  vpc_id      = var.vpc_id

  # Dynamic ingress rules with complex conditions
  dynamic "ingress" {
    for_each = {
      for rule in var.security_rules : "${rule.name}-${rule.protocol}-${rule.port}" => rule
      if rule.type == "ingress" && (
        var.environment == "production" ? rule.production_approved : true
      )
    }
    
    content {
      description = ingress.value.description
      from_port   = ingress.value.port
      to_port     = ingress.value.port_range != null ? ingress.value.port_range : ingress.value.port
      protocol    = ingress.value.protocol
      
      # Conditional source configuration
      cidr_blocks = ingress.value.source_type == "cidr" ? ingress.value.sources : null
      
      source_security_group_id = (
        ingress.value.source_type == "security_group" ? 
        lookup(local.security_group_map, ingress.value.sources[0], null) : null
      )
      
      # Self-referencing for internal communication
      self = ingress.value.source_type == "self" ? true : null
      
      # Prefix list support for AWS services
      prefix_list_ids = (
        ingress.value.source_type == "prefix_list" ? ingress.value.sources : null
      )
    }
  }

  # Dynamic egress rules with environment-specific filtering
  dynamic "egress" {
    for_each = {
      for rule in var.security_rules : "${rule.name}-${rule.protocol}-${rule.port}" => rule
      if rule.type == "egress" && (
        var.restrict_egress ? 
        contains(var.allowed_egress_destinations, rule.destination) : true
      )
    }
    
    content {
      description = egress.value.description
      from_port   = egress.value.port
      to_port     = egress.value.port_range != null ? egress.value.port_range : egress.value.port
      protocol    = egress.value.protocol
      cidr_blocks = egress.value.destinations
    }
  }

  tags = merge(local.common_tags, {
    Name = format("%s-%s-sg", var.application_name, var.environment)
  })
}

# Complex ALB listener rules with dynamic blocks
resource "aws_lb_listener" "application" {
  load_balancer_arn = aws_lb.application.arn
  port              = "443"
  protocol          = "HTTPS"
  ssl_policy        = var.ssl_policy
  certificate_arn   = var.certificate_arn

  # Default action
  default_action {
    type             = "forward"
    target_group_arn = aws_lb_target_group.default.arn
  }

  # Dynamic listener rules for path-based routing
  dynamic "default_action" {
    for_each = var.enable_advanced_routing ? [1] : []
    
    content {
      type = "forward"
      
      forward {
        dynamic "target_group" {
          for_each = var.target_groups
          
          content {
            arn    = target_group.value.arn
            weight = target_group.value.weight
          }
        }
        
        stickiness {
          enabled  = var.enable_stickiness
          duration = var.stickiness_duration
        }
      }
    }
  }
}

# Dynamic configuration blocks in ECS service
resource "aws_ecs_service" "application" {
  name            = var.service_name
  cluster         = var.cluster_id
  task_definition = aws_ecs_task_definition.application.arn
  desired_count   = var.desired_count

  # Dynamic load balancer configuration
  dynamic "load_balancer" {
    for_each = var.load_balancers
    
    content {
      target_group_arn = load_balancer.value.target_group_arn
      container_name   = load_balancer.value.container_name
      container_port   = load_balancer.value.container_port
    }
  }

  # Dynamic network configuration
  dynamic "network_configuration" {
    for_each = var.network_mode == "awsvpc" ? [1] : []
    
    content {
      subnets          = var.subnet_ids
      security_groups  = var.security_group_ids
      assign_public_ip = var.assign_public_ip
    }
  }

  # Dynamic service registries for service discovery
  dynamic "service_registries" {
    for_each = var.enable_service_discovery ? [var.service_discovery_config] : []
    
    content {
      registry_arn = service_registries.value.registry_arn
      port         = lookup(service_registries.value, "port", null)
      
      dynamic "container_name" {
        for_each = lookup(service_registries.value, "container_name", null) != null ? [1] : []
        
        content {
          container_name = service_registries.value.container_name
        }
      }
    }
  }

  # Dynamic deployment configuration
  dynamic "deployment_configuration" {
    for_each = var.deployment_config != null ? [var.deployment_config] : []
    
    content {
      maximum_percent         = deployment_configuration.value.maximum_percent
      minimum_healthy_percent = deployment_configuration.value.minimum_healthy_percent
      
      dynamic "deployment_circuit_breaker" {
        for_each = lookup(deployment_configuration.value, "circuit_breaker", null) != null ? [1] : []
        
        content {
          enable   = deployment_configuration.value.circuit_breaker.enable
          rollback = deployment_configuration.value.circuit_breaker.rollback
        }
      }
    }
  }
}


2. Nested Dynamic Blocks with Complex Logic

# Advanced ECS task definition with nested dynamic blocks
resource "aws_ecs_task_definition" "application" {
  family                   = var.task_family
  requires_compatibilities = ["FARGATE"]
  network_mode            = "awsvpc"
  cpu                     = var.cpu
  memory                  = var.memory
  execution_role_arn      = var.execution_role_arn
  task_role_arn           = var.task_role_arn

  container_definitions = jsonencode([
    for container in var.containers : {
      name  = container.name
      image = container.image
      
      # Dynamic port mappings
      portMappings = [
        for port_config in lookup(container, "ports", []) : {
          containerPort = port_config.container_port
          hostPort      = lookup(port_config, "host_port", port_config.container_port)
          protocol      = lookup(port_config, "protocol", "tcp")
        }
      ]
      
      # Dynamic environment variables with secrets handling
      environment = [
        for env_name, env_value in lookup(container, "environment", {}) : {
          name  = env_name
          value = env_value
        }
      ]
      
      secrets = [
        for secret_name, secret_arn in lookup(container, "secrets", {}) : {
          name      = secret_name
          valueFrom = secret_arn
        }
      ]
      
      # Dynamic log configuration
      logConfiguration = lookup(container, "logging", null) != null ? {
        logDriver = container.logging.driver
        options = merge(
          {
            "awslogs-group"         = aws_cloudwatch_log_group.application.name
            "awslogs-region"        = var.aws_region
            "awslogs-stream-prefix" = container.name
          },
          lookup(container.logging, "options", {})
        )
      } : null
      
      # Dynamic health check
      healthCheck = lookup(container, "health_check", null) != null ? {
        command = [
          "CMD-SHELL",
          container.health_check.command
        ]
        interval = lookup(container.health_check, "interval", 30)
        timeout  = lookup(container.health_check, "timeout", 5)
        retries  = lookup(container.health_check, "retries", 3)
        startPeriod = lookup(container.health_check, "start_period", 60)
      } : null
      
      # Dynamic mount points
      mountPoints = [
        for mount in lookup(container, "mounts", []) : {
          sourceVolume  = mount.source_volume
          containerPath = mount.container_path
          readOnly      = lookup(mount, "read_only", false)
        }
      ]
    }
  ])

  # Dynamic volume definitions
  dynamic "volume" {
    for_each = var.volumes
    
    content {
      name = volume.value.name
      
      dynamic "host" {
        for_each = lookup(volume.value, "host_path", null) != null ? [1] : []
        
        content {
          source_path = volume.value.host_path
        }
      }
      
      dynamic "efs_volume_configuration" {
        for_each = lookup(volume.value, "efs_config", null) != null ? [1] : []
        
        content {
          file_system_id     = volume.value.efs_config.file_system_id
          root_directory     = lookup(volume.value.efs_config, "root_directory", "/")
          transit_encryption = lookup(volume.value.efs_config, "transit_encryption", "ENABLED")
          
          dynamic "authorization_config" {
            for_each = lookup(volume.value.efs_config, "access_point_id", null) != null ? [1] : []
            
            content {
              access_point_id = volume.value.efs_config.access_point_id
              iam            = lookup(volume.value.efs_config, "use_iam", "ENABLED")
            }
          }
        }
      }
    }
  }

  tags = local.common_tags
}

# CloudFront distribution with complex dynamic behaviors
resource "aws_cloudfront_distribution" "application" {
  enabled             = true
  is_ipv6_enabled     = true
  default_root_object = var.default_root_object
  aliases             = var.aliases
  web_acl_id          = var.web_acl_id

  # Dynamic origins with complex configurations
  dynamic "origin" {
    for_each = var.origins
    
    content {
      domain_name = origin.value.domain_name
      origin_id   = origin.value.origin_id
      origin_path = lookup(origin.value, "origin_path", "")
      
      dynamic "custom_origin_config" {
        for_each = lookup(origin.value, "custom_origin_config", null) != null ? [1] : []
        
        content {
          http_port              = lookup(origin.value.custom_origin_config, "http_port", 80)
          https_port             = lookup(origin.value.custom_origin_config, "https_port", 443)
          origin_protocol_policy = lookup(origin.value.custom_origin_config, "origin_protocol_policy", "https-only")
          origin_ssl_protocols   = lookup(origin.value.custom_origin_config, "origin_ssl_protocols", ["TLSv1.2"])
          
          origin_read_timeout    = lookup(origin.value.custom_origin_config, "origin_read_timeout", 30)
          origin_keepalive_timeout = lookup(origin.value.custom_origin_config, "origin_keepalive_timeout", 5)
        }
      }
      
      dynamic "s3_origin_config" {
        for_each = lookup(origin.value, "s3_origin_config", null) != null ? [1] : []
        
        content {
          origin_access_identity = origin.value.s3_origin_config.origin_access_identity
        }
      }
      
      dynamic "custom_header" {
        for_each = lookup(origin.value, "custom_headers", {})
        
        content {
          name  = custom_header.key
          value = custom_header.value
        }
      }
    }
  }

  # Dynamic cache behaviors
  dynamic "ordered_cache_behavior" {
    for_each = var.cache_behaviors
    
    content {
      path_pattern           = ordered_cache_behavior.value.path_pattern
      allowed_methods        = ordered_cache_behavior.value.allowed_methods
      cached_methods         = ordered_cache_behavior.value.cached_methods
      target_origin_id       = ordered_cache_behavior.value.target_origin_id
      compress               = lookup(ordered_cache_behavior.value, "compress", true)
      viewer_protocol_policy = lookup(ordered_cache_behavior.value, "viewer_protocol_policy", "redirect-to-https")
      
      # Dynamic forwarded values
      dynamic "forwarded_values" {
        for_each = lookup(ordered_cache_behavior.value, "forwarded_values", null) != null ? [1] : []
        
        content {
          query_string = lookup(ordered_cache_behavior.value.forwarded_values, "query_string", false)
          headers      = lookup(ordered_cache_behavior.value.forwarded_values, "headers", [])
          
          dynamic "cookies" {
            for_each = lookup(ordered_cache_behavior.value.forwarded_values, "cookies", null) != null ? [1] : []
            
            content {
              forward           = ordered_cache_behavior.value.forwarded_values.cookies.forward
              whitelisted_names = lookup(ordered_cache_behavior.value.forwarded_values.cookies, "whitelisted_names", [])
            }
          }
        }
      }
      
      # Dynamic Lambda@Edge functions
      dynamic "lambda_function_association" {
        for_each = lookup(ordered_cache_behavior.value, "lambda_function_associations", [])
        
        content {
          event_type   = lambda_function_association.value.event_type
          lambda_arn   = lambda_function_association.value.lambda_arn
          include_body = lookup(lambda_function_association.value, "include_body", false)
        }
      }
    }
  }

  tags = local.common_tags
}



Real-World Implementation Examples


1. Multi-Environment Infrastructure Module

# Complete multi-environment infrastructure module
# modules/multi-env-infrastructure/main.tf

locals {
  # Environment-specific configuration matrix
  environment_config = {
    for env in var.environments : env.name => {
      # Compute configuration
      instance_type = lookup(env.compute, "instance_type", "t3.micro")
      min_instances = lookup(env.compute, "min_instances", 1)
      max_instances = lookup(env.compute, "max_instances", 3)
      
      # Network configuration with automatic CIDR calculation
      vpc_cidr = coalesce(
        lookup(env.networking, "vpc_cidr", null),
        format("10.%d.0.0/16", index(var.environments, env) + 10)
      )
      
      # Storage configuration with environment-based defaults
      storage = merge(
        {
          type = "gp3"
          size = 20
          encrypted = true
        },
        lookup(env, "storage", {})
      )
      
      # Monitoring configuration
      monitoring = merge(
        {
          enabled = env.name != "development"
          detailed = env.name == "production"
          retention_days = env.name == "production" ? 30 : 7
        },
        lookup(env, "monitoring", {})
      )
      
      # Security configuration
      security = merge(
        {
          enable_waf = env.name == "production"
          enable_shield = env.name == "production"
          ssl_policy = env.name == "production" ? "ELBSecurityPolicy-TLS-1-2-2017-01" : "ELBSecurityPolicy-2016-08"
        },
        lookup(env, "security", {})
      )
    }
  }
  
  # Generate all infrastructure components
  infrastructure_components = {
    for env_name, env_config in local.environment_config : env_name => {
      # VPC and networking
      vpc = {
        cidr_block = env_config.vpc_cidr
        availability_zones = slice(data.aws_availability_zones.available.names, 0, 3)
        
        # Dynamic subnet allocation
        public_subnets = [
          for i, az in slice(data.aws_availability_zones.available.names, 0, 3) :
          cidrsubnet(env_config.vpc_cidr, 8, i)
        ]
        
        private_subnets = [
          for i, az in slice(data.aws_availability_zones.available.names, 0, 3) :
          cidrsubnet(env_config.vpc_cidr, 8, i + 10)
        ]
        
        database_subnets = [
          for i, az in slice(data.aws_availability_zones.available.names, 0, 3) :
          cidrsubnet(env_config.vpc_cidr, 8, i + 20)
        ]
      }
      
      # Application Load Balancer configuration
      load_balancer = {
        internal = env_name == "development"
        type = "application"
        
        # Dynamic target groups based on services
        target_groups = {
          for service_name, service_config in var.services : service_name => {
            port = service_config.port
            protocol = "HTTP"
            health_check = {
              enabled = true
              path = service_config.health_check_path
              matcher = "200"
              interval = 30
              timeout = 5
              healthy_threshold = 2
              unhealthy_threshold = 3
            }
          }
        }
      }
      
      # Auto Scaling Group configuration
      auto_scaling = {
        min_size = env_config.min_instances
        max_size = env_config.max_instances
        desired_capacity = env_config.min_instances
        
        # Dynamic scaling policies
        policies = env_config.monitoring.enabled ? [
          {
            name = "cpu-scale-up"
            scaling_adjustment = 1
            adjustment_type = "ChangeInCapacity"
            cooldown = 300
            
            alarm = {
              comparison_operator = "GreaterThanThreshold"
              evaluation_periods = 2
              metric_name = "CPUUtilization"
              threshold = env_name == "production" ? 70 : 80
            }
          },
          {
            name = "cpu-scale-down"
            scaling_adjustment = -1
            adjustment_type = "ChangeInCapacity"
            cooldown = 300
            
            alarm = {
              comparison_operator = "LessThanThreshold"
              evaluation_periods = 3
              metric_name = "CPUUtilization"
              threshold = env_name == "production" ? 30 : 40
            }
          }
        ] : []
      }
      
      # Database configuration
      database = {
        for db_name, db_config in var.databases : db_name => {
          instance_class = coalesce(
            lookup(db_config, "instance_class", null),
            env_name == "production" ? "db.r5.large" : "db.t3.micro"
          )
          
          allocated_storage = coalesce(
            lookup(db_config, "allocated_storage", null),
            env_name == "production" ? 100 : 20
          )
          
          backup_retention_period = env_name == "production" ? 30 : 7
          multi_az = env_name == "production"
          
          # Performance Insights for production
          performance_insights_enabled = env_name == "production"
          performance_insights_retention_period = env_name == "production" ? 7 : null
          
          # Encryption settings
          storage_encrypted = env_config.storage.encrypted
          kms_key_id = env_config.storage.encrypted ? var.kms_key_id : null
          
          # Monitoring and maintenance
          monitoring_interval = env_config.monitoring.detailed ? 60 : 0
          monitoring_role_arn = env_config.monitoring.detailed ? var.rds_monitoring_role_arn : null
          
          # Environment-specific parameter groups
          parameter_group_name = format("%s-%s-%s-params", var.project_name, env_name, db_config.engine)
          
          # Maintenance and backup windows
          maintenance_window = env_name == "production" ? "sun:03:00-sun:04:00" : "sun:02:00-sun:03:00"
          backup_window = env_name == "production" ? "02:00-03:00" : "01:00-02:00"
        }
        if lookup(db_config, "enabled", true)
      }
    }
  }
}

# Generate VPCs for each environment
resource "aws_vpc" "environment" {
  for_each = local.environment_config
  
  cidr_block           = each.value.vpc_cidr
  enable_dns_hostnames = true
  enable_dns_support   = true
  
  tags = merge(
    local.common_tags,
    {
      Name = format("%s-%s-vpc", var.project_name, each.key)
      Environment = each.key
    }
  )
}

# Generate subnets dynamically
resource "aws_subnet" "public" {
  for_each = {
    for combo in flatten([
      for env_name, env_config in local.infrastructure_components : [
        for i, subnet_cidr in env_config.vpc.public_subnets : {
          key = format("%s-public-%d", env_name, i)
          env_name = env_name
          cidr_block = subnet_cidr
          availability_zone = env_config.vpc.availability_zones[i]
        }
      ]
    ]) : combo.key => combo
  }
  
  vpc_id                  = aws_vpc.environment[each.value.env_name].id
  cidr_block              = each.value.cidr_block
  availability_zone       = each.value.availability_zone
  map_public_ip_on_launch = true
  
  tags = merge(
    local.common_tags,
    {
      Name = format("%s-%s", var.project_name, each.key)
      Type = "public"
      Environment = each.value.env_name
    }
  )
}

# Auto Scaling Groups with complex configuration
resource "aws_autoscaling_group" "application" {
  for_each = local.environment_config
  
  name                = format("%s-%s-asg", var.project_name, each.key)
  vpc_zone_identifier = values(aws_subnet.private)[*].id
  
  min_size         = each.value.min_instances
  max_size         = each.value.max_instances
  desired_capacity = each.value.min_instances
  
  health_check_type         = "ELB"
  health_check_grace_period = 300
  
  # Dynamic launch template configuration
  launch_template {
    id      = aws_launch_template.application[each.key].id
    version = "$Latest"
  }
  
  # Dynamic target group attachments
  dynamic "target_group_arns" {
    for_each = aws_lb_target_group.application
    content {
      target_group_arns = [target_group_arns.value.arn]
    }
  }
  
  tag {
    key                 = "Name"
    value               = format("%s-%s-instance", var.project_name, each.key)
    propagate_at_launch = true
  }
  
  tag {
    key                 = "Environment"
    value               = each.key
    propagate_at_launch = true
  }
  
  # Instance refresh configuration
  instance_refresh {
    strategy = "Rolling"
    preferences {
      min_healthy_percentage = each.key == "production" ? 75 : 50
      instance_warmup       = 300
    }
  }
}


2. Advanced Output Processing

# Complex output generation with data transformation
output "environment_summary" {
  description = "Complete summary of all environment configurations"
  value = {
    environments = {
      for env_name, env_config in local.environment_config : env_name => {
        # Network information
        networking = {
          vpc_id = aws_vpc.environment[env_name].id
          vpc_cidr = aws_vpc.environment[env_name].cidr_block
          
          # Subnet information grouped by type
          subnets = {
            public = {
              for subnet in aws_subnet.public : subnet.tags.Name => {
                id = subnet.id
                cidr_block = subnet.cidr_block
                availability_zone = subnet.availability_zone
              }
              if subnet.tags.Environment == env_name
            }
            
            private = {
              for subnet in aws_subnet.private : subnet.tags.Name => {
                id = subnet.id
                cidr_block = subnet.cidr_block
                availability_zone = subnet.availability_zone
              }
              if subnet.tags.Environment == env_name
            }
          }
          
          # Gateway information
          internet_gateway = try(aws_internet_gateway.environment[env_name].id, null)
          nat_gateways = {
            for nat in aws_nat_gateway.environment : nat.tags.Name => {
              id = nat.id
              public_ip = nat.public_ip
              subnet_id = nat.subnet_id
            }
            if nat.tags.Environment == env_name
          }
        }
        
        # Compute resources
        compute = {
          auto_scaling_group = {
            name = aws_autoscaling_group.application[env_name].name
            arn = aws_autoscaling_group.application[env_name].arn
            min_size = aws_autoscaling_group.application[env_name].min_size
            max_size = aws_autoscaling_group.application[env_name].max_size
            desired_capacity = aws_autoscaling_group.application[env_name].desired_capacity
          }
          
          launch_template = {
            id = aws_launch_template.application[env_name].id
            latest_version = aws_launch_template.application[env_name].latest_version
          }
        }
        
        # Load balancer information
        load_balancing = {
          for lb in aws_lb.application : lb.name => {
            arn = lb.arn
            dns_name = lb.dns_name
            zone_id = lb.zone_id
            
            # Target groups for this load balancer
            target_groups = {
              for tg in aws_lb_target_group.application : tg.name => {
                arn = tg.arn
                port = tg.port
                protocol = tg.protocol
                health_check = {
                  enabled = tg.health_check[0].enabled
                  path = tg.health_check[0].path
                  port = tg.health_check[0].port
                }
              }
              if tg.tags.Environment == env_name
            }
          }
          if lb.tags.Environment == env_name
        }
        
        # Database information
        databases = {
          for db in aws_db_instance.application : db.identifier => {
            id = db.id
            arn = db.arn
            endpoint = db.endpoint
            port = db.port
            engine = db.engine
            engine_version = db.engine_version
            instance_class = db.instance_class
            allocated_storage = db.allocated_storage
            
            # Connection information
            connection_info = {
              jdbc_url = format("jdbc:postgresql://%s:%s/%s", db.endpoint, db.port, db.db_name)
              psql_command = format("psql -h %s -p %s -U %s -d %s", db.endpoint, db.port, db.username, db.db_name)
            }
            
            # Backup and maintenance windows
            maintenance = {
              backup_window = db.backup_window
              maintenance_window = db.maintenance_window
              backup_retention_period = db.backup_retention_period
            }
          }
          if db.tags.Environment == env_name
        }
        
        # Cost estimation
        cost_estimation = {
          monthly_estimate = {
            compute = length(aws_autoscaling_group.application[env_name].desired_capacity) * 
                     lookup(local.instance_costs, env_config.instance_type, 100) * 24 * 30
            
            storage = sum([
              for db in values(aws_db_instance.application) : db.allocated_storage * 0.115
              if db.tags.Environment == env_name
            ])
            
            data_transfer = env_name == "production" ? 50 : 10  # Estimated monthly data transfer cost
          }
          
          optimization_recommendations = {
            rightsizing = env_config.instance_type == "t3.micro" && env_name == "production" ? 
                         "Consider upgrading to a larger instance type for production workloads" : null
            
            reserved_instances = env_name == "production" ? 
                               "Consider purchasing Reserved Instances for cost savings" : null
            
            spot_instances = env_name != "production" ? 
                           "Consider using Spot Instances for development/testing" : null
          }
        }
      }
    }
    
    # Global summary
    summary = {
      total_environments = length(local.environment_config)
      total_vpcs = length(aws_vpc.environment)
      total_subnets = length(aws_subnet.public) + length(aws_subnet.private)
      total_instances_capacity = sum([
        for asg in aws_autoscaling_group.application : asg.desired_capacity
      ])
      
      # Security summary
      security_groups = length(aws_security_group.application)
      
      # Cost summary
      estimated_monthly_cost = sum([
        for env in values(local.environment_config) : (
          env.min_instances * lookup(local.instance_costs, env.instance_type, 100) * 24 * 30
        )
      ])
    }
  }
}

# Service-specific outputs
output "service_endpoints" {
  description = "Service endpoints for each environment"
  value = {
    for env_name, env_config in local.environment_config : env_name => {
      for service_name, service_config in var.services : service_name => {
        internal_endpoint = format(
          "http://%s.%s.internal:%d",
          service_name,
          env_name,
          service_config.port
        )
        
        external_endpoint = env_config.load_balancer.internal ? null : format(
          "https://%s.%s.%s",
          service_name,
          env_name,
          var.domain_name
        )
        
        load_balancer_dns = try(
          aws_lb.application[format("%s-%s", env_name, service_name)].dns_name,
          null
        )
        
        health_check_url = format(
          "http://%s%s",
          try(aws_lb.application[format("%s-%s", env_name, service_name)].dns_name, "localhost"),
          service_config.health_check_path
        )
      }
    }
  }
}

# Secrets and configuration outputs
output "configuration_templates" {
  description = "Configuration templates for applications"
  sensitive   = true
  value = {
    for env_name, env_config in local.environment_config : env_name => {
      database_configs = {
        for db_name, db in aws_db_instance.application : db_name => {
          host = db.endpoint
          port = db.port
          database = db.db_name
          username = db.username
          # Note: Password would be retrieved from AWS Secrets Manager
          password_secret_arn = aws_secretsmanager_secret.db_password[db_name].arn
          
          # Connection pool settings
          connection_pool = {
            min_connections = env_name == "production" ? 5 : 2
            max_connections = env_name == "production" ? 20 : 10
            idle_timeout = 300
            max_lifetime = 1800
          }
          
          # SSL configuration
          ssl_mode = env_name == "production" ? "require" : "prefer"
          ssl_cert_path = "/opt/certs/rds-ca-2019-root.pem"
        }
        if db.tags.Environment == env_name
      }
      
      # Environment variables for applications
      environment_variables = {
        AWS_REGION = data.aws_region.current.name
        ENVIRONMENT = env_name
        PROJECT_NAME = var.project_name
        
        # Service discovery endpoints
        SERVICE_DISCOVERY_NAMESPACE = try(
          aws_service_discovery_http_namespace.environment[env_name].name,
          null
        )
        
        # Monitoring and logging
        CLOUDWATCH_LOG_GROUP = try(
          aws_cloudwatch_log_group.application[env_name].name,
          null
        )
        
        # Feature flags based on environment
        ENABLE_DEBUG_LOGGING = env_name != "production" ? "true" : "false"
        ENABLE_PERFORMANCE_MONITORING = env_name == "production" ? "true" : "false"
        CACHE_TTL = env_name == "production" ? "3600" : "300"
      }
    }
  }
}



Conclusion

Advanced Terraform functions and expressions represent the cornerstone of sophisticated Infrastructure as Code implementations.

Mastering these concepts enables infrastructure engineers to build self-adapting, maintainable, and scalable infrastructure solutions that respond dynamically to changing requirements and environments.


Key Mastery Areas:

  1. Function Composition: Combining multiple functions for complex data transformations
  2. Conditional Logic: Building intelligent infrastructure that adapts to context
  3. Dynamic Generation: Creating resources programmatically based on input data
  4. Type Safety: Leveraging Terraform’s type system for robust configurations
  5. Performance Optimization: Efficient data processing and resource creation patterns


Operational Excellence:

Advanced Implementation Strategies:


The combination of advanced functions, sophisticated expressions, and dynamic blocks elevates Terraform from a basic provisioning tool to a comprehensive infrastructure programming platform. These capabilities enable the creation of intelligent, adaptive infrastructure that scales with organizational needs while maintaining consistency and reliability.

“Advanced Terraform mastery transforms infrastructure management from reactive maintenance to proactive, intelligent automation that anticipates and adapts to changing requirements.”



References