jonas
jonas

Reputation: 21

How to dynamically attach multiple volumes to multiple instances via terraform in openstack?

I have written a terraform module(v0.14) that can be used to provision multiple instances in openstack with the correct availability_zone,network-port, correct flavor, can create 1 local disk or 1 blockstorage_volume based on boolean input variables and so forth. Now I have gotten a feature request to be able to add dynamically multiple blockstorage_volumes(=network/shared storage volumes) on multiple instances.

Example of how everything dynamically works for 1 blockstorage_volume on multiple instances:

#Dynamically create this resource ONLY if boolean "volume_storage" = true
resource "openstack_blockstorage_volume_v3" "shared_storage" {
  for_each          = var.volume_storage ? var.nodes : {}
  name              = "${each.value}-${each.key}.${var.domain}"
  size              = var.volume_s
  availability_zone = each.key
  volume_type       = var.volume_type
  image_id          = var.os_image
}
resource "openstack_compute_instance_v2" "instance" {
  for_each          = var.nodes
  name              = "${each.value}-${each.key}.${var.domain}"
  flavor_name       = var.flavor
  availability_zone = each.key
  key_pair          = var.key_pair
  image_id     = (var.volume_storage == true ? "" : var.os_image)
  config_drive = true
  #Dynamically create this parameter ONLY if boolean "volume_storage" = true
  dynamic "block_device" {
    for_each = var.volume_storage ? var.volume : {}
    content {
      uuid                  = openstack_blockstorage_volume_v3.shared_storage[each.key].id
      source_type           = "volume"
      destination_type      = "volume"
      delete_on_termination = var.volume_delete_termination
    }
  }
  user_data = data.template_file.cloud-init[each.key].rendered
  scheduler_hints {
    group = openstack_compute_servergroup_v2.servergroup.id
  }
  network {
    port = openstack_networking_port_v2.network-port[each.key].id
  }
}

So let's say now that I have 2 instances, where I want to add dynamically 2 extra blockstorage_volumes to each instance, my first idea was to add 2 extra dynamic resources as a try-out:

#Dynamically create this resource if boolean "multiple_volume_storage" = true
resource "openstack_blockstorage_volume_v3" "multiple_shared_storage" {
  for_each          = var.multiple_volume_storage ? var.multiple_volumes : {}
  name              = each.value
  size              = var.volume_s
  availability_zone = each.key
  volume_type       = var.volume_type
  image_id          = var.os_image
}

Example of 2 extra blockstorage_volumes defined in a .tf file:

variable "multiple_volumes" {
  type = map(any)
  default = {
    dc1 = "/volume/mysql"
    dc2 = "/volume/postgres"

  }
}

Example of 2 instances defined in a .tf file:

  nodes = {
    dc1 = "app-stage"
    dc2 = "app-stage"
  }

Here I try to dynamically attach 2 extra blockstorage_volumes to each instance:

resource "openstack_compute_volume_attach_v2" "attach_multiple_shared_storage" {
  for_each  = var.multiple_volume_storage ? var.multiple_volumes : {}
  instance_id = openstack_compute_instance_v2.instance[each.key].id
  volume_id   = openstack_blockstorage_volume_v3.multiple_shared_storage[each.key].id
}

The openstack_compute_instance_v2.instance [each.key] is obviously not correct since it now only creates 1 extra blockstorage_volume per instance. Is there a clean/elegant way to solve this? So basically to attach all given volumes in variable "multiple_volumes" to each single instance that is defined in var.nodes

Kind regards, Jonas

Upvotes: 2

Views: 1370

Answers (0)

Related Questions