How to Use the Ternary Operator in Terraform

This article summarizes how to use the ternary operator in Terraform, along with practical examples.

Introduction

Using the ternary operator in Terraform allows for simpler conditional expressions.

Since it's a frequently used and useful feature, let's go over how to use it.

# Working Version in this post
$ terraform --version
Terraform v1.2.6
on linux_amd64

Note: This article was translated from my original post.

Ternary Operator in Terraform

How to Use

The basic usage is as described in the official documentation:

condition ? true_val : false_val

The condition must be a boolean value. If it evaluates to true, the first value (true_val) is returned; otherwise, the second value (false_val) is returned.

Since condition only needs to evaluate to a boolean, operators like ==, !=, &&, and || can also be used.

Additionally, true_val and false_val must be of the same type.
(If they can be cast to the same type, Terraform will cast them accordingly.)

Practical Examples

Here are some practical examples of using the ternary operator.

Simple Example

true ? "true val" : "false val"
# "true val"

false ? "true val" : "false val"
# "false val"

Combining Conditions

var.a == "" ? "default-a" : var.a

If var.a is an empty string (""), it returns "default-a"; otherwise, it returns var.a.


0 <= var.i && var.i <= 5 ? "between 0-5" : "out of range"

This example uses the && operator to combine multiple conditions.
If var.i is between 0 and 5 (inclusive), it returns "between 0-5"; otherwise, it returns "out of range".

Example of Type Casting

true ? 100 : "this is string"
# "100"

true ? true : "this is string"
# "true"

true ? null : "this is string"
# tostring(null)

Here, 100 is treated as a string to match "this is string".

Similarly, true is also treated as a string.

null is cast as tostring(null).

Error: Specifying Different Types

If you specify types that cannot be cast to the same type, it results in an error.

Example: Number and Boolean:

true ? 100 : true
╷
│ Error: Inconsistent conditional result types
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ The true and false result expressions must have consistent types. The 'true' value is number, but the 'false' value is bool.


Example: List and String:

true ? [] : "this is string"
╷
│ Error: Inconsistent conditional result types
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ The true and false result expressions must have consistent types. The 'true' value is tuple, but the 'false' value is string.

Error: Non-Boolean Condition

If you specify a non-boolean value as the condition, it results in an error.

10 ? true : false
╷
│ Error: Incorrect condition type
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ The condition expression must be of type bool.
"I am string" ? true : false
╷
│ Error: Incorrect condition type
│ 
│   on <console-input> line 1:
│   (source code not available)
│ 
│ The condition expression must be of type bool.

Use Case: Controlling resource Count

One of the most common uses of the ternary operator in Terraform is to control whether a resource is created using the count argument.

Here’s an example from the official AWS VPC module, taken from this code:

locals {
  # ~~snip~~
  create_vpc = var.create_vpc && var.putin_khuylo
}

# ~~snip~~

resource "aws_vpc" "this" {
  count = local.create_vpc ? 1 : 0

  cidr_block                       = var.cidr
  instance_tenancy                 = var.instance_tenancy
  enable_dns_hostnames             = var.enable_dns_hostnames
  enable_dns_support               = var.enable_dns_support
  enable_classiclink               = var.enable_classiclink
  enable_classiclink_dns_support   = var.enable_classiclink_dns_support
  assign_generated_ipv6_cidr_block = var.enable_ipv6

  tags = merge(
    { "Name" = var.name },
    var.tags,
    var.vpc_tags,
  )
}

Here, count = local.create_vpc ? 1 : 0 determines whether to create a VPC based on module variables.

Use Case: dynamic Block

Using the ternary operator with the dynamic block is another useful pattern.

Here’s an example from the AWS VPC module, taken from this code:

  dynamic "destination_options" {
    for_each = var.flow_log_destination_type == "s3" ? [true] : []

    content {
      file_format                = var.flow_log_file_format
      hive_compatible_partitions = var.flow_log_hive_compatible_partitions
      per_hour_partition         = var.flow_log_per_hour_partition
    }
  }

The for_each argument is controlled using the ternary operator.

If var.flow_log_destination_type == "s3" is false, the for_each list is empty ([]), meaning the "destination_options" parameter is not specified.

Conclusion

This article covered how to use the ternary operator in Terraform, along with some examples.

Terraform offers many convenient features, so use them to enhance your IaC experience!

[Related Articles]

en.bioerrorlog.work

References