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
}




