2

I'm learning terraform, in the example below the first section puts a VM and returns the id of that VM. The second section adds an extra disk to vm. I have to enter an id in the virtual_machine_id parameter, but I don't know how (cloudstack_instance.worker[$name].id not working). Could someone have a hint?

resource "cloudstack_instance" "worker" {
  for_each = {
    for name, machine in var.machines :
    name => machine
    if machine.node_type == "worker"
  }
  name = "${var.prefix}-${each.key}"
  service_offering = "K8S-RBD"
  network_id = var.network_id
  template = var.template_id
  zone = var.zone
  project = var.project_id
  expunge = true
  group = var.prefix
  keypair = var.keypair
  tags = {
    name = "Terraform-VM"
  }
}

resource "cloudstack_disk" "worker" {
  for_each = {
    for name, machine in var.machines :
    name => machine
    if machine.node_type == "worker"
  }
  name = "${var.prefix}-${each.key}"
  attach = "true"
  disk_offering = "Custom-RBD"
  size = 50
  virtual_machine_id = cloudstack_instance.worker[$name].id
  zone = var.zone
  project = var.project_id

  depends_on = [cloudstack_instance.worker]
}
Agryppa
  • 33
  • 4

2 Answers2

1

The output from cloudstack_instance can contain multiple elements. If there is more than one output it will need some logic. But for this use case let's say that the output from cloudstack_instance is 1 element.

Try this:

 virtual_machine_id = join(", ", cloudstack_instance.worker.*.id)
tomarv2
  • 753
  • 3
  • 14
0

From your configuration it seems like your intent here is to declare one disk per virtual machine, with the disks each connected to their corresponding virtual machine.

That situation is a good use for Chaining for_each Between Resources, which means to use an upstream resource directly as the for_each for a downstream one, and thus quite literally declare that the disks correlate with the VMs:

resource "cloudstack_disk" "worker" {
  for_each = cloudstack_instance.worker

  name               = "${var.prefix}-${each.key}"
  attach             = "true"
  disk_offering      = "Custom-RBD"
  size               = 50
  virtual_machine_id = each.value.id
  zone               = var.zone
  project            = var.project_id
}

Because the cloudstack_instance resource also has for_each declared, cloudstack_instance.worker evaluates to a map from instance keys to objects. That means that in the above example each.value refers to whatever element value in cloudstack_instance.worker corresponds with the key each.key.

I also removed the depends_on argument, because it's redundant: Terraform can already see that dependency because for_each contains a reference to that resource.

Martin Atkins
  • 62,420
  • 8
  • 120
  • 138