DevOps | Scripts | Automation

Terraform

How to use terraform if-else condition?

Description

Like other programming languages, Terraform also supports conditional operators. We can add the condition at the resource, properties, and block levels. A conditional statement in Terraform is required in case you want to deploy resources or specific properties on a conditional basis.

For example, For a Non-Prod environment, you want to deploy a Storage Account with higher attribute settings for Prod and for the nonprod some lower attribute settings.

The basic syntax for the condition is,

Condition ? <true>: <fale>

For example,

var.Environment == "Prod" ? "GRS" : "LRS"

The above example indicates that if the environment is “Prod,” the GRS value is applicable; otherwise, LRS would be applied.

Following the above syntax and example, we will explore the different levels of conditions that can be applied in Terraform. We will use the example of creating a storage account on Azure Cloud.


Resource block level condition

When you apply the condition at the resource block level then you have to store the output of the condition to the reserved count variable to evaluate if the condition is true or false. The same has been shown in the example.

Let’s say you want to create a storage account on Azure Cloud with different settings for Prod and NonProd. For Prod, you need higher level settings and for Non-Prod you need some lightweight settings to incur less cost on testing Infra.

This can be achieved on a conditional basis. Someone may argue that we can use the tfvars file as well to differentiate both Infra. That is also absolutely right but to cover different scenarios for the conditional operators we are taking this example.

So, here is the resource block for Storage. tf would look like,

resource "azurerm_storage_account" "ProdStorageAccount" {
  count = var.environment == "Prod" ? 1 : 0
  name                     = "ProdStrgAccount"
  resource_group_name      = "PrdResourceGrp"
  location                 = "EastUS2"
  account_tier             = "Premium"
  account_replication_type = "GRS"

  tags = {
    environment = "Prod"
  }
}

resource "azurerm_storage_account" "NonProdStrgAccount" {
  count = var.environment == "NonProd" ? 1 : 0
  name                     = "ProdStrgAccount"
  resource_group_name      = "PrdResourceGrp"
  location                 = "EastUS"
  account_tier             = "Standard"
  account_replication_type = "LRS"

  tags = {
    environment = "NonProd"
  }
}

When terraform runs the main.tf file for the storage account module and if the environment variable value is provided Prod then the first block would be executed. If the environment variable value is set to NonProd, the second block will be executed.

In the condition, 1 means true and 0 means false. Terraform can run a block on a conditional basis only when the value is true which means there is no else block. You need to make the value of the condition true anyhow.

You can also write the above for the non-prod environment.

  count = var.environment != "Prod" ? 1 : 0

There are other several operators you can use for comparison.


Attribute level condition

Now assume, you just want to deploy specific resource attributes on a conditional basis. We will take the above example. We need to use the standard tier for NonProd and the Premium tier for the Prod environment, keeping other properties the same.

See below how we can apply conditions for that.

resource "azurerm_storage_account" "ProdStorageAccount" {
  name                     = "ProdStrgAccount"
  resource_group_name      = "PrdResourceGrp"
  location                 = "EastUS2"
  account_tier             = var.environment == "Prod" ? "Premium":"Standard"
  account_replication_type = "GRS"
}

So, the account_tier attribute verifies if the environment is Prod then sets the Premium otherwise Standard. You can also write a condition as below.

account_tier             = (
 var.environment == "Prod" ? "Premium":"Standard"
)

You can add one or more conditions based on different attributes.


Nested-Block conditions

If you need the nested block level condition then it is also possible through terraform. For example, for the prod region, you need to set the custom domain but not for the NonProd.

Here would be the custom domain properties mentioned in Terraform storage account properties.

custom_domain {
   name = prodDomain.xyz
   use_subdomain = "true" 
}

We need to make the above block conditional so it would only apply to the Prod region. We can achieve this through dynamic block. Taking the reference of the above attribute level example,

resource "azurerm_storage_account" "ProdStorageAccount" {
  name                     = "ProdStrgAccount"
  resource_group_name      = "PrdResourceGrp"
  location                 = "EastUS2"
  account_tier             = var.environment == "Prod" ? "Premium":"Standard"
  account_replication_type = "GRS"

  dynamic "custom_domain" {
    for_each = var.environment == "Prod" ? [1] : []
    content {
       name = prodDomain.xyz
       use_subdomain = "true"          
    }
  }
}

So this dynamic block helps avoid writing multiple resource blocks.

Hope this article, clears your understanding of how we can apply terraform conditions at different levels.

Loading