eternaltyro
eternaltyro

Reputation: 336

Create nested resource parameter blocks based on conditional in terraform

I am trying to create a terraform module that creates a compute instance. I want the resource to have an attached disk if and only if I have a variable attached_disk_enabled set to true during module invocation. I have this:

resource "google_compute_disk" "my-disk" {
  name  = "data"
  type  = "pd-ssd"
  size  = 20
  count = var.attached_disks_enabled ? 1 : 0
}

resource "google_compute_instance" "computer" {
  name = "computer"

  boot_disk {
    ...
  }

  // How do I make this disappear if attached_disk_enabled == false?
  attached_disk {
    source      = "${google_compute_disk.my-disk.self_link}"
    device_name = "computer-disk"
    mode        = "READ_WRITE"
  }
}

Variables have been declared for the module in vars.tf. Module invocation is like this:

module "main" {
  source                = "../modules/computer"
  attached_disk_enabled = false
  ...
}

I know about dynamic blocks and how to use for loop to iterate over a list and set multiple blocks, but I'm not sure how to exclude a block from a resource using this method:

dynamic "attached-disk" {
  for_each in var.disk_list
  content {
    source      = "${google_compute_disk.my-disk.*.self_link}"
    device_name = "computer-disk-${count.index}"
    mode        = "READ_WRITE"
  }
}

I want if in place of for_each. Is there a way to do this?

$ terraform version
Terraform v0.12.0 

Upvotes: 3

Views: 2483

Answers (1)

Martin Atkins
Martin Atkins

Reputation: 74694

Because your disk resource already has the conditional attached to it, you can use the result of that resource as your iterator and thus avoid specifying the conditional again:

dynamic "attached_disk" {
  for_each = google_compute_disk.my-disk
  content {
    source      = attached_disk.value.self_link
    device_name = "computer-disk-${attached_disk.key}"
    mode        = "READ_WRITE"
  }
}

To answer the general question: if you do need a conditional block, the answer is to write a conditional expression that returns either a single-item list or an empty list:

dynamic "attached_disk" {
  for_each = var.attached_disk_enabled ? [google_compute_disk.my-disk[0].self_link] : []
  content {
    source      = attached_disk.value
    device_name = "computer-disk-${attached_disk.key}"
    mode        = "READ_WRITE"
  }
}

However, in your specific situation I'd prefer the former because it describes the intent ("attach each of the disks") more directly.

Upvotes: 4

Related Questions