Terraform Conditionals, Loops & Built-in Functions Explained

 

Terraform Conditionals, Loops & Built-in Functions Explained

There are some scenario will come to apply the terraform infrastructure based on conditions, functions and loops. On such cases, we can use these feature in terraform codes efficiently. In this post, I will show you how to use terraform conditionals, terraform built-in functions and terraform loops with examples.

In the previous posts, we have covered the topic - "What is Terraform Modules? Explained with Examples".

Let's get started.

Terraform Conditionals:

Terraform conditionals can be used to perform some actions based on some conditions, It is very similar to if else condition that we use in any programming languages.

Terraform conditional expression is as follows:

condition ? true_value : false_value

Where,

condition - It is the expression or condition we need to define, Based on the condition result, further value will be set. it generally return Boolean value ie, true or false.

true_value - This value will be set if the condition is true.

false_value - This value will be set if the condition is false.

Lets take an example that if I want to create one aws ec2 resource with instance type "t2.micro" using terraform for my dev environment as below.

variable "environment" {
  default     = "dev"
}

resource "aws_instance" "web1" {
  ami                         = "ami-0e86e20dae9224db8"
  instance_type               = "t2.micro"
  subnet_id                   = "subnet-0105b1aef1e7755cd"
  key_name                    = "demov2"
  ebs_block_device {
    device_name = "/dev/sda1"
    volume_size = 10
  }
  associate_public_ip_address = "true"
  vpc_security_group_ids      = ["sg-04dd813e22c5a0b2f"]
  tags = {
    Name = "Web Server1"
    Environment = var.environment
  }
}

What if I want to create one more ec2 resources for production environment where I want my AWS EC2 with instance type "t3.medium" or "t3.large". In general, we will copy the resource section and modify the values accordingly for production environment. But with terraform conditionals, we can simplify the code as below.

variable "environment" {

  default     = "dev"
}

resource "aws_instance" "web1" {
  ami                         = "ami-0e86e20dae9224db8"
  instance_type               = var.environment == "prod" ? "t3.large" : "t2.micro"
  subnet_id                   = "subnet-0105b1aef1e7755cd"
  key_name                    = "demov2"
  ebs_block_device {
    device_name = "/dev/sda1"
    volume_size = 10
  }
  associate_public_ip_address = "true"
  vpc_security_group_ids      = ["sg-04dd813e22c5a0b2f"]
  tags = {
    Name = "Web Server1"
    Environment = var.environment
  }
}

Above condition is defined like, if the environment is "prod", "t3.large" value will be set for instance_type. If any other environment except "prod", then "t2.micro" instance_type will be set.

Either, we can modify the variable environment from "dev" to "prod" and apply the terraform or we can use "-var" options along with terraform command to override the environment variable.

terraform apply -var 'environment=prod' 

its not only, you have to use terraform conditionals on instance_type. Wherever you think, the conditional logic can be applied, You can give a try.

Terraform Loops:

In terraform, We can achieve the terraform loops concept using for_each and count method.

Terraform loops are generally used when you have multiple values, but you need to use single resources.

For example, Lets say I need to create 10 AWS ec2 instance. On that case, we need to create 10 aws ec2 resource section. Instead, We can create these values in list and run through terraform loops.

Using for_each:


variable "environment" {
  default     = "dev"
}
variable "ec2_names" {
  default = ["web1", "app1", "db1"]
}

resource "aws_instance" "server" {
  for_each                  = toset(var.ec2_names)
  ami                         = "ami-0e86e20dae9224db8"
  instance_type               = var.environment == "prod" ? "t3.large" : "t2.micro"
  subnet_id                   = "subnet-0105b1aef1e7755cd"
  key_name                    = "demov2"
  ebs_block_device {
    device_name = "/dev/sda1"
    volume_size = 10
  }
  associate_public_ip_address = "true"
  vpc_security_group_ids      = ["sg-04dd813e22c5a0b2f"]
  tags = {
    Name = each.value
    Environment = var.environment
  }
}


This will create each instances through loops based on each values.

Using Count:


variable "environment" {
  default     = "dev"
}
resource "aws_instance" "server" {
  count       = 3
  ami                         = "ami-0e86e20dae9224db8"
  instance_type               = var.environment == "prod" ? "t3.large" : "t2.micro"
  subnet_id                   = "subnet-0105b1aef1e7755cd"
  key_name                    = "demov2"
  ebs_block_device {
    device_name = "/dev/sda1"
    volume_size = 10
  }
  associate_public_ip_address = "true"
  vpc_security_group_ids      = ["sg-04dd813e22c5a0b2f"]
  tags = {
    Name = "ec2-${count.index + 1}"
  }
}


if we define the value in count parameter, accordingly the resources will be looped and created.

Built-in functions:

Terraform built-in functions are pre defined functions that will help us to achieve or perform some actions. Terraform has lot of built-in functions to simply the code. You can find lot of functions from official terraform website  - https://developer.hashicorp.com/terraform/language/functions

List of some Built-in functions:

upper()

lower()

max()

replace()

join()

For example, if I want to change my Aws ec2 names into uppercase. We can use this upper() function to achieve the same as below.


variable "environment" {
  default     = "dev"
}
resource "aws_instance" "server" {
  count       = 3
  ami                         = "ami-0e86e20dae9224db8"
  instance_type               = var.environment == "prod" ? "t3.large" : "t2.micro"
  subnet_id                   = "subnet-0105b1aef1e7755cd"
  key_name                    = "demov2"
  ebs_block_device {
    device_name = "/dev/sda1"
    volume_size = 10
  }
  associate_public_ip_address = "true"
  vpc_security_group_ids      = ["sg-04dd813e22c5a0b2f"]
  tags = {
    Name = upper("ec2-${count.index + 1}")
  }
}

That's it for this post. Keep practicing and have fun. Leave your comments if any.

Post a Comment

0 Comments