🎯 Goal: Replace repetitive or verbose logic with 3 expressive patterns β€” no functions needed.

βœ… You’ll master:


🧠 Why Expressions > Copy-Paste

❌ Without expressions:

βœ… With expressions:

β†’ DRY, readable, and scalable configs β€” before you learn functions.


πŸ“¦ Expression Cheat Sheet

Expression Syntax Use Case When to Use
Conditional cond ? true_val : false_val Toggle values by env/flag One-off decisions (instance size, tags)
Dynamic Block dynamic "block" { for_each = ... } Generate nested blocks (e.g., ingress) Variable-length nested configs
Splat resource[*].attr Extract lists from count resources Feed IDs/IPs to other resources

πŸ’‘ Golden Rule:

β€œIf you’re repeating a block 3+ times β€” dynamic is calling.”


✏️ Hands-On: Expressions in Action

πŸ”Ή Prerequisites (variables.tf)

variable "env" {
  type    = string
  default = "dev"
}

variable "instance_count" {
  type    = number
  default = 2
}

# πŸ”Ή For Dynamic Blocks: list of security rules
variable "ingress_rules" {
  type = list(object({
    from_port   = number
    to_port     = number
    protocol    = string
    cidr_blocks = list(string)
    description = string
  }))
  default = [
    {
      from_port   = 80
      to_port     = 80
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
      description = "HTTP"
    },
    {
      from_port   = 443
      to_port     = 443
      protocol    = "tcp"
      cidr_blocks = ["0.0.0.0/0"]
      description = "HTTPS"
    }
  ]
}


1️⃣ Conditional Expression β€” Environment-Aware EC2

main.tf

resource "aws_instance" "app" {
  count = var.instance_count

  ami           = "ami-0c7217cdde317cfec"  # Amazon Linux 2
  # βœ… Conditional: dev = t2.micro, prod = t3.medium
  instance_type = var.env == "dev" ? "t2.micro" : "t3.medium"

  tags = {
    Name        = "app-${count.index}"
    Environment = var.env
  }
}

βœ… How it works: