DEV Community

Cover image for Mastering Conditional Expressions in Terraform
Panchanan Panigrahi
Panchanan Panigrahi

Posted on

Mastering Conditional Expressions in Terraform

In Terraform, conditional expressions are essential for building dynamic infrastructure configurations. They provide the flexibility to control resource creation, modify values, and streamline infrastructure as code workflows, making your Terraform configurations more efficient and adaptable.

This blog will explore how to use conditional expressions effectively in various contexts like the count and for_each parameters, working with modules, and employing them with data blocks.


1. Using Conditional Expressions with count

The count parameter in Terraform allows us to create multiple instances of a resource or conditionally skip its creation. Conditional expressions make count highly adaptable, enabling you to adjust how many resources to create based on specific conditions.

Example: Conditionally Creating EC2 Instances Based on Type

In this scenario, we want to create EC2 instances only if the instance_type is t2.micro. Otherwise, no instances should be created.

variable "instance_names" {
  description = "List of names for each EC2 instance"
  type        = list(string)
  default     = ["ubuntu_server_1", "ubuntu_server_2", "ubuntu_server_3"]
}

variable "instance_type" {
  description = "The type of EC2 instance to create"
  type        = string
  default     = "t2.micro"
}

resource "aws_instance" "ubuntu_instance" {
  count = var.instance_type == "t2.micro" ? length(var.instance_names) : 0
  ami   = "ami-0a0e5d9c7acc336f1"
  instance_type = var.instance_type

  tags = {
    Name = var.instance_names[count.index]
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • count = var.instance_type == "t2.micro" ? length(var.instance_names) : 0: The conditional expression evaluates whether the instance_type is t2.micro. If true, instances are created based on the length of instance_names; otherwise, no instances are created.
  • This approach ensures that resources are only created when necessary, making your configuration more efficient.

2. Using Conditional Expressions with for_each

While count is great for simple scenarios, for_each offers more flexibility when iterating over complex structures like maps or sets. Using conditional expressions with for_each lets you manage resources based on specific criteria.

Example: Creating EC2 Instances Dynamically Based on a List

variable "instance_names" {
  description = "List of names for each EC2 instance"
  type        = list(string)
  default     = ["ubuntu_server_1", "ubuntu_server_2", "ubuntu_server_3"]
}

resource "aws_instance" "ubuntu_instance" {
  for_each = length(var.instance_names) > 0 ? toset(var.instance_names) : {}

  ami           = "ami-0a0e5d9c7acc336f1"
  instance_type = "t2.micro"

  tags = {
    Name = each.value
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • for_each = length(var.instance_names) > 0 ? toset(var.instance_names) : {}: This conditional expression ensures that instances are created only if instance_names is not empty.
  • This method offers greater flexibility in handling resources with varying requirements, making your Terraform configurations more adaptable.

3. Using Conditional Expressions in Modules

Modules help encapsulate Terraform configurations into reusable components. By incorporating conditional expressions, you can create resources within a module based on specific conditions.

Example: Using Modules to Deploy EC2 Instances Conditionally

Child Module (modules/ec2_instance/main.tf):

variable "instance_name" {
  description = "Name of the EC2 instance"
  type        = string
}

resource "aws_instance" "ubuntu_instance" {
  ami           = "ami-0a0e5d9c7acc336f1"
  instance_type = "t2.micro"

  tags = {
    Name = var.instance_name
  }
}
Enter fullscreen mode Exit fullscreen mode

Root Module (main.tf):

variable "deploy_instances" {
  description = "Flag to control EC2 instance creation"
  type        = bool
  default     = true
}

variable "instance_names" {
  description = "List of names for each EC2 instance"
  type        = list(string)
  default     = ["ubuntu_server_1", "ubuntu_server_2", "ubuntu_server_3"]
}

module "ec2_instances" {
  source = "./modules/ec2_instance"
  count  = var.deploy_instances ? length(var.instance_names) : 0

  instance_name = var.instance_names[count.index]
}

output "instance_ids" {
  description = "IDs of the created EC2 instances"
  value       = module.ec2_instances[*].id
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • count = var.deploy_instances ? length(var.instance_names) : 0: This expression controls whether the module creates instances based on the deploy_instances flag.
  • Conditional expressions in modules provide greater control over resource creation, ensuring that unnecessary resources are avoided.

4. Using Conditional Expressions with Data Blocks

Conditional expressions are not limited to just resource blocks; they can also be applied to data blocks to manage the flow of data retrieval based on specific conditions. This ensures that we only retrieve data when certain criteria are met, optimizing resource usage and improving the efficiency of our infrastructure code.

Example: Using Conditional Expressions in a Data Block

In this example, we use a conditional expression to determine whether to fetch AWS instance data based on whether we have a non-empty list of instance names.

variable "instance_names" {
  description = "List of names for each EC2 instance"
  type        = list(string)
  default     = ["ubuntu_server_1", "ubuntu_server_2", "ubuntu_server_3"]
}

data "aws_instances" "ubuntu_instance" {
  count = length(var.instance_names) > 0 ? 1 : 0

  filter {
    name   = "tag:Name"
    values = var.instance_names
  }

  filter {
    name   = "instance-state-name"
    values = ["running"]
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • The count parameter in the data "aws_instances" "ubuntu_instance" block uses a conditional expression:
    • count = length(var.instance_names) > 0 ? 1 : 0
    • This expression evaluates whether var.instance_names contains any elements.
    • If the list is non-empty (length(var.instance_names) > 0), the data block will execute once (count = 1), allowing us to fetch data.
    • If the list is empty, the data block will be skipped entirely (count = 0).

5. Using Conditional Expressions for Assigning Variables

Conditional expressions aren't limited to resource creation; they can also be used to assign variable values based on certain conditions.

Example: Setting Variables Based on Environment

variable "environment" {
  description = "Environment (dev, staging, prod)"
  type        = string
  default     = "dev"
}

locals {
  instance_type = var.environment == "prod" ? "m5.large" : "t2.micro"
}

resource "aws_instance" "example" {
  ami           = "ami-0a0e5d9c7acc336f1"
  instance_type = local.instance_type

  tags = {
    Environment = var.environment
  }
}
Enter fullscreen mode Exit fullscreen mode

Explanation:

  • local.instance_type = var.environment == "prod" ? "m5.large" : "t2.micro": This expression sets the instance_type based on the environment, ensuring the appropriate instance size is used.

Conclusion

Conditional expressions in Terraform are incredibly versatile, allowing you to create adaptable, efficient, and cost-effective configurations. By integrating conditional logic with count, for_each, data blocks, modules, and variable assignments, you can create your infrastructure deployments to meet any requirement.

Now that you've learned how to master conditional expressions, you can make your Terraform configurations smarter and more responsive to changing requirements.Happy Terraforming!

Top comments (0)