Hi @harshavmb,
The goal when working with for_each
or count
is always to transform your input value into a collection that has one element per instance you want to create, which commonly involves the flatten
function. So in this case, we need one element per instance_count
per image, I think.
locals {
# A list of objects with one object per instance.
instances = flatten([
for image_key, image in var.images : [
for index in range(image.instance_count) : {
availability_zone = image.availability_zone
flavor = image.flavor
instance_index = index
image_key = image_key
image_name = image.image_name
}
]
])
}
The above works by initially constructing a list of lists. The first level of lists represents the images, and the second level represents the instances for each image, created using range
. The above is a combination of the example in the flatten
docs and the example in the range
docs.
We can then use local.instances
as part of the for_each
argument in the resource
block:
resource "openstack_compute_instance_v2" "instance" {
for_each = {
# Generate a unique string identifier for each instance
for inst in local.instances : format("%s-%02d", inst.image_key, inst.instance_index + 1) => inst
}
image_name = each.value.image_name
flavor_id = each.value.flavor
name = each.key
security_groups = var.security_groups
availability_zone = each.value.availability_zones
key_pair = "foptst"
network {
name = var.network_name
}
}
This uses for_each
instead of count
, because count
is for creating a number of equivalent instances, where all are redundantly performing the same function. In this case, the instances are differentiated by the image they are created from and so using for_each
allows us to customize the tracking keys to include the image keys, giving instance addresses like this:
openstack_compute_instance_v2.instance["rhel-8-factory-os-ready-01"]
openstack_compute_instance_v2.instance["rhel-8-factory-os-ready-02"]
openstack_compute_instance_v2.instance["rhel-7-factory-os-ready-01"]
openstack_compute_instance_v2.instance["rhel-7-factory-os-ready-02"]
openstack_compute_instance_v2.instance["rhel-7-factory-os-ready-03"]
openstack_compute_instance_v2.instance["rhel-6-factory-os-ready-01"]
openstack_compute_instance_v2.instance["rhel-6-factory-os-ready-02"]
openstack_compute_instance_v2.instance["rhel-6-factory-os-ready-03"]
If you were to decrease instance_count
for rhel-7-factory-os-ready
on a subsequent run, Terraform would plan to destroy openstack_compute_instance_v2.instance["rhel-7-factory-os-ready-03"]
and leave all of the other instances untouched, because it can see that there is no longer an element with key "rhel-7-factory-os-ready-03"
in the for_each
map.