Terraform 0.11 — conditional assignment of a map to attribute.

Jacek Kikiewicz
2 min readDec 11, 2018

--

I present a way to achieve that with some small hacks.

Problem :
You have a Terraform module in which you want to configure an attribute of a resource that takes a map as input.

As of Terraform 0.11 it’s not possible to pass maps or nested structures into the module. A workaround is to pass either minimum set of strings or flat arrays (with join-split) to module and inside a module, build variations of a map and then conditionally use it depending on parameters passed to module.

Example:
Kubernetes provider — resource replication controller https://www.terraform.io/docs/providers/kubernetes/r/replication_controller.html

has an attribute ‘readiness_probe’ and ‘liveness_probe’ those can be of type ‘exec’ or ‘http_get’, map for exec looks like that:

exec = [{
command = [“${split(“,”,var.readiness_probe_exec)}”]
}]
failure_threshold = “${var.failure_threshold}”
period_seconds = “${var.period_seconds}”
success_threshold = “${var.success_threshold}”
timeout_seconds = “${var.timeout_seconds}”
initial_delay_seconds = “${var.initial_delay_seconds}"

http_get on the other hand requires such config:

http_get = [{
path = “${var.http_probe_url}”
port = “${var.http_probe_port}”
}]
failure_threshold = “${var.failure_threshold}”
period_seconds = “${var.period_seconds}”
success_threshold = “${var.success_threshold}”
timeout_seconds = “${var.timeout_seconds}”
initial_delay_seconds = “${var.initial_delay_seconds}”

As we can see there are some differences, so big question is, how to conditionally assign a check to a resource in a module. Answer is, pre-defined map of maps and conditional as a key. Remember here that conditional assignments can only be done with string and strings only.

How does it look in practice:

locals {
probe {
http_probe {
http_get = [{
path = “${var.http_probe_url}”
port = “${var.http_probe_port}”
}]
failure_threshold = “${var.failure_threshold}”
period_seconds = “${var.period_seconds}”
success_threshold = “${var.success_threshold}”
timeout_seconds = “${var.timeout_seconds}”
initial_delay_seconds = “${var.initial_delay_seconds}”
}
exec_probe {
exec = [{
command = [“${split(“,”,var.readiness_probe_exec)}”]
}]
failure_threshold = “${var.failure_threshold}”
period_seconds = “${var.period_seconds}”
success_threshold = “${var.success_threshold}”
timeout_seconds = “${var.timeout_seconds}”
initial_delay_seconds = “${var.initial_delay_seconds}”
}
}
}
readiness_probe = [“${local.probe[“${var.http_probe_url == “” || var.http_probe_port == “” ? “exec_probe” : “http_probe”}”]}”]

Above example is also available (in more readable form) on my github: https://github.com/jaceq/terraform-examples/blob/master/examples/conditional-map.tf

Also, have a look at my other Terraform articles on medium!

--

--