Terraform Loops and Conditionals

Today's focus is on utilizing loops and conditionals in Terraform, two useful strategies for creating dynamic and reusable settings. Using these capabilities allows you to design more scalable and maintainable infrastructure-as-code systems.

Understanding Loops in Terraform

The count Meta-Argument

The count meta-argument enables you to generate numerous instances of a resource from a single block. This is especially beneficial for installing common infrastructure components like instances, subnets, and load balancers.

variable "instance_count" {
  default = 3
}

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

  tags = {
    Name = "web-instance-${count.index}"
# Note: The index starts at 0, so when the count is set to 3, the instances will be indexed as 0, 1, and 2.
  }
}
  • Dynamic Count: Use the count value to define how many instances Terraform should create.

  • Indexing: The count.index property is used to differentiate between instances.

The for_each Meta-Argument

The for_each Meta-argument is particularly useful for iterating over large data structures like maps or lists. Unlike count, it provides more control and allows you to reference elements by key or value.

variable "cidr_blocks" {
  default = {
    subnet_a = "10.0.1.0/24"
    subnet_b = "10.0.2.0/24"
    subnet_c = "10.0.3.0/24"
  }
}

resource "aws_subnet" "example" {
  for_each = var.cidr_blocks

  vpc_id     = var.vpc_id
  cidr_block = each.value

  tags = {
    Name = "subnet-${each.key}"
  }
}
  1. Input Data Structure: The cidr_blocks variable is a map where each key represents a subnet name, and the value is the corresponding CIDR block.

  2. Dynamic Resource Creation: Terraform uses the for_each loop to iterate over cidr_blocks, creating a subnet for each entry in the map.

  3. Dynamic Tags: The each.key is used to dynamically name each subnet, ensuring uniqueness.

Implementing Conditionals in Terraform

Conditionals in Terraform are useful for determining deployment decisions depending on input variables or environmental factors. They simplify settings by removing superfluous resource declarations.

variable "create_instance" {
  default = true
}

resource "aws_instance" "example" {
  count = var.create_instance ? 1 : 0
  ami           = var.ami_id
  instance_type = "t2.micro"
}

Boolean Logic: Use a ternary operator (condition ? true_value : false_value) to toggle resource deployment.

Dynamic Tagging Based on Environment

variable "environment" {
  default = "dev"
}

resource "aws_s3_bucket" "example" {
  bucket = var.bucket_name

  tags = {
    Environment = var.environment == "prod" ? "Production" : "Development"
  }
}

Dynamic Inputs: Use conditionals to adjust resource properties dynamically, ensuring configurations align with your environment.

Tips

  • Plan Before You Code: Plan out your infrastructure requirements and find locations where loops or conditionals might help with configuration.

  • Test Incrementally: After adding loops or conditionals, run terraform plan to verify your changes before applying them.

  • Use Descriptive Variables: Define input variables clearly so that your setup is easy to understand and manage.