Skip to main content

Command Palette

Search for a command to run...

How Loops and Conditionals Simplify Infrastructure as Code with Terraform

Updated
2 min read
How Loops and Conditionals Simplify Infrastructure as Code with Terraform

Day 10: Mastering Terraform Loops and Conditionals

Introduction

Welcome to Day 10 of our Terraform learning journey. Today, we dive into loops and conditionals, two powerful features that make Terraform configurations more dynamic and scalable. By leveraging count, for_each, and conditional logic, we can refactor our existing infrastructure code to support multiple instances, environment-specific configurations, and more efficient resource management.

Why Use Loops and Conditionals?

Loops and conditionals help:

  • Reduce code duplication by dynamically creating multiple resources.

  • Improve maintainability by making configurations adaptable to different environments.

  • Enable conditional deployments (e.g., only attach an EBS volume in production).

  • Simplify scaling (e.g., deploy 3 instances in production, 2 in staging, and 1 in dev).

Refactoring Our Terraform Code

1. Using count for Multiple EC2 Instances

Instead of hardcoding a single EC2 instance, we can use count to deploy multiple instances based on the environment:

locals {
  instance_count = var.environment == "production" ? 3 : (var.environment == "staging" ? 2 : 1)
}

resource "aws_instance" "web" {
  count         = local.instance_count
  ami           = var.ami_id
  instance_type = var.instance_type

  tags = merge(var.tags, {
    Name = "${var.name_prefix}-instance-${count.index + 1}"
  })
}

2. Using for_each for ALB Target Group Attachments

Instead of manually attaching each instance to the ALB, we can use for_each (or count) to loop through a list of instance IDs:

resource "aws_lb_target_group_attachment" "web" {
  count = length(var.instance_ids)

  target_group_arn = aws_lb_target_group.web.arn
  target_id        = var.instance_ids[count.index]
  port             = 80
}

3. Conditional Logic for Environment-Specific Configs

We can use ternary operators and dynamic blocks to apply different settings based on the environment:

Conditional EBS Volume

dynamic "ebs_block_device" {
  for_each = var.environment == "production" ? [1] : []
  content {
    device_name = "/dev/xvdf"
    volume_size = 50
    volume_type = "gp3"
  }
}

Enable ALB Stickiness

variable "enable_stickiness" {
  type    = bool
  default = false
}

resource "aws_lb_target_group" "web" {
  stickiness {
    enabled = var.enable_stickiness
    type    = "lb_cookie"
  }
}

Updated Module Outputs

Since we now handle multiple instances, outputs must return lists instead of single values:

output "instance_ids" {
  value = aws_instance.web[*].id
}

output "public_ips" {
  value = aws_instance.web[*].public_ip
}

More from this blog

Simi Cloud and DevOps

20 posts