Terraform - how to use exported attributes?

2.7k Views Asked by At

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]
}

2

There are 2 best solutions below

1
On BEST ANSWER

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.

1
On

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)