Terraform Conditional

Terraform Conditional

How to create Terraform Conditional? Like if-statement? Terraform is a declarative language. As we know, infrastructure-as-code in a declarative language gives us a more accurate picture of what’s deployed than in a procedural language, so it’s easier to reason about and makes it more straightforward to preserve the codebase small. However, specific types of tasks become more complex in a declarative language without access to a whole programming language.

Terraform IF Statement Block

Let’s start with the obvious. Wait! What? Terraform IF Statement Block? 

Yeap, it doesn’t exist. There is no such thing as “Terraform Conditional Block.”

Like we saw before. Terraform is a declarative language, so it’s doesn’t have all features of a “real” language. But it’s ok! We still have promising approaches to achieve conditional expression on Terraform.

Terraform Conditional Expression

If you have already worked with any programming language, you may have already heard about Ternary Expression. Le’s see what Ternary’s expression is and how to use Terraform in several ways with examples. Also. it’s worth remembering that it’s possible to use a conditional expression within Terraform Dynamic Block.

Terraform Ternary

The expression below it’s the way we work and represent a ternary expression, and it’s the same way anywhere. It’s not such a thing exclusive from Terraform. But, theoretically, you can use it almost anywhere in your Terraform code.

<CONDITION> ? <TRUE_COND> : <FALSE_COND>

So, if <CONDITION> is true, it returns <TRUE_COND>, but if is not true (false) it returns <FALSE_COND>.

Terraform Conditional Example

Let’s go through one example to see how it works. Suppose that we have the variable below. (See our article about variables type on Terraform)

variable "lb_type" {
	description = "The Type of Load Balance"	 
}

Suppose that we have one scenario that, depending on our environment, sometimes we need to deploy a Network Load Balancer, and sometimes we need to deploy an Application Load Balancer.

Before showing our Terraform Condition Expression, let’s see the pseudo-code.

# if the statement example does not work on Terraform.

if (var.lb_type == 'network') {
  is_network_lb = 1
else
  is_network_lb =0
}

Our Terraform Conditional Expression could be as below:

is_network_lb = var.load_balance_type == 'network' ? 1 : 0

So, with that expression above, we could know if the load balance that we need to deploy is a network or not, according to the value that we receive on the load_balance_type variable. Also, we use conditional string, but we can use another variables types.

Terraform Conditional Resource

It looks pretty straightforward, right? But how can we use that conditional expression to deploy the right Load Balance type according to our variable?

Let’s pseudo-code how we would do in another language.

# The code below doesn’t work on Terraform.

if (var.load_balance_type == 'network'){
	resource "aws_lb" "network_lb" {
  		name = "${var.app_name}-nlb"
  		load_balancer_type = var.load_balance_type
  		subnets         = split(",", var.lb_subnet_ids)
		internal        = var.enable_internal
  		enable_deletion_protection = true
	}
} else {
	resource "aws_lb" "alb" {
 		name = "${var.env_name}-alb"
	  	load_balancer_type = var.load_balance_type
 	 	security_groups = [aws_security_group.sg-alb.id]
  		subnets         = split(",", var.lb_subnet_ids)
  		internal        = true
  	access_logs {
    		bucket         = "${var.bucket_logs}"
    		prefix           = "bitslovers"
    		enabled       = "true"
  	}
}

The code below looks straightforward but doesn’t work that way. If you are learning Terraform, it may be your first thought about how it would be. But let’s see how to do it with a conditional resource on Terraform.

To make it work on Terraform, we use the count keyword to perform conditional on creating or not resources. 

resource "aws_lb" "network_lb" {
       count = var.load_balance_type == "network" ? 1 : 0
	name = "${var.app_name}-nlb"
  	load_balancer_type = var.load_balance_type
  	subnets         = split(",", var.lb_subnet_ids)
	internal        = var.enable_internal
  	enable_deletion_protection = true
}
resource "aws_lb" "alb" {
	count = var.load_balance_type == "network" ? 0 : 1
 	name = "${var.env_name}-alb"
	load_balancer_type = var.load_balance_type
 	security_groups = [aws_security_group.sg-alb.id]
  	subnets         = split(",", var.lb_subnet_ids)
  	internal        = true
  	access_logs {
    		bucket         = "${var.bucket_logs}"
    		prefix           = "bitslovers"
    		enabled       = "true"
  	}
}

If you noticed, we added the count on both resources with revert logic. So, Terraform will not create them at the same time. Therefore, the count is the only approach to accomplishing Terraform Conditional Resource. Check the article “How to use Terraform Count” for more details. 

Terraform Conditional Output

Configuration output on Terraform it’s very useful. The example below shows how to declare conditional output, using the same example above from our Load Balance, where we can deploy different types of Load Balancer according to our conditional expression. 

Conditional variable on output block:

output "dns_name" {
  description = "DNS from Application or Network Load Balancer"
  value           = var.load_balance_type == "network" ? aws_lb.network_lb.dns_name : aws_lb.alb.dns_name 
}

In the example above, the Ternary Expression performs a conditional logic to get the values according to which type of Load Balancer the variable load_balance_type is referencing. Regardless of which Load Balancer type, we will be able to print out the value on the output variable.

Terraform Conditional Module

Another approach that we can use Terraform Conditional with Ternary expression is to define if one specific Terraform Module should be deployed or not. For instance, our previous Load Balancer may have one Module for Network and another for the Application. So, we can use count again inside the Module block.

module "lb_network" {
  count = var.load_balance_type == "network" ? 1 : 0
}

See the documentation for Terraform Modules to learn more.

Conclusion

We have learned a lot! Also, you may have noticed that we apply the ternary operator for creating Terraform conditional variable or expression. Besides, we don’t have a conditional block or a statement that we can use on Terraform, but we can handle any scenario that needs a conditional decision.

We can also use a conditional expression to define values for any attribute on Terraform.

Thanks for reading our article. Please help us share this post on social media, and stay tuned!

Leave a Comment

Your email address will not be published. Required fields are marked *

Free PDF with a useful Mind Map that illustrates everything you should know about AWS VPC in a single view.