Terraform: How to compare two strings case-insensitively

Updated: February 3, 2024 By: Guest Contributor Post a comment

Introduction

In the world of Infrastructure as Code (IaC), Terraform stands out for its simplicity and power in managing and provisioning infrastructure across various providers. A common need in many Terraform configurations is string comparison, often for validation, conditional logic, or simply comparing resource names or tags. However, Terraform’s string comparison is case-sensitive by default, which can lead to unexpected results or extra boilerplate code to handle cases consistently.

This tutorial seeks to guide you through various methods of comparing strings case-insensitively in Terraform, demonstrating each approach with practical examples. Whether you are new to Terraform or an experienced practitioner, understanding how to effectively compare strings regardless of case can enhance your Terraform configurations and make your infrastructure management more robust.

Getting Started

Before diving into string comparison, ensure you have Terraform installed on your system. The examples provided in this tutorial are based on Terraform v1.0 and above. You can check your Terraform version using the command:

terraform version

If you’re new to Terraform, visit the official Terraform documentation to get started on installing and setting up Terraform on your platform of choice.

Basic String Comparison

In Terraform, comparing two strings for equality is straightforward using the == operator. However, such comparisons are inherently case-sensitive. For instance:

locals {
  string1 = "Hello"
  string2 = "hello"
}

output "basic_comparison" {
  value = local.string1 == local.string2
}

This would output false since “Hello” and “hello” are not exactly the same.

Lowercasing Strings

A simple approach to perform case-insensitive comparisons is to convert both strings to lower (or upper) case using Terraform’s built-in lower (or upper) function. Here is how you can do it:

locals {
  string1 = "Hello"
  string2 = "hello"
}

output "lowercase_comparison" {
  value = lower(local.string1) == lower(local.string2)
}

This will output true, demonstrating a case-insensitive comparison by normalizing both strings to lowercase before the comparison.

Using Regex

For more complex comparisons or when you need to validate patterns without regard to case, Terraform’s regex function can be utilized alongside case conversion. This approach is somewhat advanced but highly versatile. Consider a scenario where you need to check if a string follows a particular pattern:

locals {
  test_string = "Terraform123"
}

output "regex_comparison" {
  value = can(regex("^(?i)terraform[0-9]+", lower(local.test_string)))
}

The (?i) in the regex pattern makes the comparison case-insensitive. Additionally, converting the test string to lowercase ensures that the pattern matches regardless of the original case. The output here, considering our test string, will be true.

Custom Functions

In scenarios where built-in functions are not sufficient, Terraform allows the use of external data sources or custom logic encapsulated in modules. While Terraform itself does not support user-defined functions directly, you can effectively achieve similar results by external scripting, using a null_resource with a provisioner that handles string comparison in your desired programming language, or by deploying custom modules that encapsulate your logic. This method should be considered for complex logic that cannot be directly implemented in Terraform configuration.

Here is a hypothetical example using null_resource:

resource "null_resource" "string_comparison" {
  triggers = {
    always_run = timestamp()
  }

  provisioner "local-exec" {
    command = "if [ \"$(echo ${var.string1} | tr '[:upper:]' '[:lower:]')\" \"$(echo ${var.string2} | tr '[:upper:]' '[:lower:]')\" ]; then echo true; else echo false; fi"
  }
}

This example demonstrates a shell-based comparison converting strings to lowercase, illustrating the adaptability of Terraform in integrating with external scripts for specific needs. Note that this approach involves side-effects, and it’s considered good practice to use it sparingly, ensuring infrastructure declaration remains declarative as much as possible.

Conclusion

Comparing strings case-insensitively in Terraform can be achieved through various methods, from simple lowercasing to regex validations or even custom scripting for complex scenarios. Understanding these approaches enables Terraform practitioners to write more flexible and error-tolerant configurations, effectively managing infrastructure across different environments and systems.