Terrafor 0.13 data manipulation

Dear all,

I need to do this transformation using terraform and don’t know how to achieve this:

I retrieve a list of IDs like this:

data.openstack_blockstorage_volume_v3.hadoop_master_data1.*.id
data.openstack_blockstorage_volume_v3.hadoop_master_data2.*.id
data.openstack_blockstorage_volume_v3.hadoop_master_data3.*.id

my goal is to mix this information like this in an array:

[ master_data1[0].id, master_data2[0].id, master_data3[0].id, master_data1[1].id, , master_data2[1].id, master_data3[1].id, master_data1[2].id, , master_data2[3].id, master_data3[4].id, etc.... ]

Of course all this lists have the same size.

Could you please tell me how to achieve this ?

Thanks in advance for your help
Best,
Jerome

This seems like a bit of an odd thing to do to me, so I might have misunderstood your intent. But you can achieve what I think you’re asking for using flatten and some for expressions:

locals {
  data1 = ["a", "b", "c", "d"]
  data2 = ["1", "2", "3", "4"]
  data3 = ["w", "x", "y", "z"]
  all_ids = [local.data1, local.data2, local.data3]

  interleaved = flatten([
    for i, id in local.all_ids[0]: [
      for ids in local.all_ids: ids[i]
    ]
  ])
}

output "result" {
  value = local.interleaved
}

This gives the following value for result:

["a","1","w","b","2","x","c","3","y","d","4","z"]

Can you say more about what your use case is here?

Thanks a LOT it works !

The use case is indeed a bit specific. We have created an “instance” module which take care of creating instance, attaching volume etc… Of course, there could be multiple instances created in the same time… here is the signature:

variable "instance" {
  type    = object({
    name               = string,
    count              = number,
    image_name         = string,
    flavor_name        = string,
    ansible_groups     = string,
    additional_meta    = map(any),
    security_groups_id = list(string),
    fip_recordset      = string,
    volume_ids         = list(string),
    single_instance    = bool,
    subnet             = object({
      network_id = string,
      id         = string
    })
  })
  description = "Instance configuration"

  validation {
    condition = (
      (length(var.instance.volume_ids) == 0 || (length(var.instance.volume_ids) % var.instance.count) == 0 ) &&
      var.instance.count >= 1
    )
    error_message = "Here are the rules that you must follow:\n  - Volumes number must be proportional to the instance number\n  - instance_count must be >= 1."
  }
}

The tricky part comes when you have multiple instances and multiple volumes per instance. We are attaching using this simple mechanism:

resource "openstack_compute_volume_attach_v2" "volume" {
  count       = length(var.instance.volume_ids)
  instance_id = openstack_compute_instance_v2.instance[floor(count.index / (length(var.instance.volume_ids) / var.instance.count))].id
  volume_id   = var.instance.volume_ids[count.index]
}

So it attach first all the volumes to instance one, then all the volumes to instance 2 etc…

That is why I need this ordering.

Thanks again.

Best,
Jerome