Reputation: 15472
I have a requirement to do some complicated merging of input data in Terraform 0.12. I can't figure out if it's possible, but maybe I'm just doing something wrong.
I have two variables:
variable "ebs_block_device" {
description = "Additional EBS block devices to attach to the instance"
type = list(map(string))
default = [
{
device_name = "/dev/sdg"
volume_size = 5
volume_type = "gp2"
delete_on_termination = false
},
{
device_name = "/dev/sdh"
volume_size = 5
volume_type = "gp2"
delete_on_termination = false
}
]
}
variable "mount_point" {
description = "Mount point to use"
type = list(string)
default = ["/data", "/home"]
}
I want to then combine these sources inside a template like this:
#!/usr/bin/env bash
%{for e in merged ~}
mkfs -t xfs ${e.device_name}
mkdir -p ${e.mount_point}
mount ${e.device_name} ${e.mount_point}
%{endfor}
Where merged
would contain the combined data.
It seems that only simple for loops are supported in the template language, so doing the merge in there seems to be out of the question.
So, I assume the data munging needs to happen in the DSL. But, I would need to do this:
enumerate()
in Python, or each.with_index
in Ruby)My problem, specifically, is that there doesn't seem to be any equivalent of Python's enumerate
function, and this prevents me tracking the index. If there was, I imagine I could do something like this:
merged = [for index, x in enumerate(var.ebs_block_device): {
merge(x, {mount_point => var.mount_point[index]})
}]
Is such a data transformation as I am trying to do here currently possible in Terraform? And if not possible, what is the preferred alternative implementation?
Upvotes: 6
Views: 10189
Reputation: 15472
It turns out this is in fact possible like this:
variable "ebs_block_device" {
description = "Additional EBS block devices to attach to the instance"
type = list(map(string))
default = [
{
device_name = "/dev/sdg"
volume_size = 5
volume_type = "gp2"
delete_on_termination = false
},
{
device_name = "/dev/sdh"
volume_size = 5
volume_type = "gp2"
delete_on_termination = false
}
]
}
variable "mount_point" {
description = "Mount point to use"
type = list(string)
default = ["/data", "/home"]
}
output "merged" {
value = [
for index, x in var.ebs_block_device:
merge(x, {"mount_point" = var.mount_point[index]})
]
}
With thanks to HashiCorp support.
Upvotes: 4