Upgrade Your Drupal Skills

We trained 1,000+ Drupal Developers over the last decade.

See Advanced Courses NAH, I know Enough

Terraform: conditional operator with list values

It's not possible to use list values in a conditional operator. For example, if you try:
resource "aws_elasticsearch_domain" "es_domain" {
  ...

  vpc_options {
    ...
    subnet_ids = [ "${var.es_zone_awareness_enabled ? list("subnet-1", "subnet-2") : list("subnet-1")}" ]
  }

  ...
}
it will fail with "conditional operator cannot be used with list values" message. This is because terraform cannot assert that list's element types are consistent.

The workaround is to join list values into a string to bypass type check and then split string back to list:

resource "aws_elasticsearch_domain" "es_domain" {
  ...

  vpc_options {
    ...
    subnet_ids = [ "${split(",", var.es_zone_awareness_enabled ? join(",", list("subnet-1", "subnet-2")) : join(",", list("subnet-1", "")))}" ]
  }

  ...
}
You might've mentioned that there is an empty string as a second list value in second join function. This is needed to make result string contain a "," character for splitting by final split function.

Of course, it's just a synthetic example with list functions. In real life, those lists come from variables. For instance, I had a map variable which looked like

variable "private_subnet_ids" {
  type = "map"
  default = { "zone-1,zone-2" = "subnet-1,subnet-2" }
}
and I wanted to get a list which contains one or both subnet ids depending on bool variable. Possible steps were:
  1. Turn a map into a list.
  2. If we need both subnets:
    1. Get the first list value (string, "subnet-1,subnet-2").
  3. If we need only one subnet:
    1. Get the first list value (string, "subnet-1,subnet-2").
    2. Split by "," character (list, ["subnet-1", "subnet-2"]).
    3. Get needed list element (string, "subnet-1").
    4. Put it to a list along with an empty string (list, ["subnet-1", ""]).
    5. Join this list into a string by "," character (string, "subnet-1,").
  4. Split by "," character.
Result resource definition looked as:
resource "aws_elasticsearch_domain" "es_domain" {
  ...

  vpc_options {
    ...
    subnet_ids = [ "${split(",", var.es_zone_awareness_enabled ? element(values(var.private_subnet_ids), 0) : join(",", list(element(split(",", element(values(var.private_subnet_ids), 0)), 0), "")))}" ]
  }

  ...
}
Author: 
Original Post: 

About Drupal Sun

Drupal Sun is an Evolving Web project. It allows you to:

  • Do full-text search on all the articles in Drupal Planet (thanks to Apache Solr)
  • Facet based on tags, author, or feed
  • Flip through articles quickly (with j/k or arrow keys) to find what you're interested in
  • View the entire article text inline, or in the context of the site where it was created

See the blog post at Evolving Web

Evolving Web