Map/for_each and destroy prevention

Let say I have a list of VMs to create defined:

variable "VM_defs" {
  type = list(object({
    device_name       = string
    region            = string
    zone              = string
  }))
}
variable "VM_name" {
  type        = string
}

VM_defs = [
  {
    device_name       = "vm1",
    region            = "us-central1",
    zone              = "a",
  },
  {
    device_name       = "vm2",
    region            = "us-central1",
    zone              = "a",
  },
  {
    device_name       = "vm3",
    region            = "us-central2",
    zone              = "b",
  }
]

and I build them via this code:

locals {
  VM_names = split(",", var.VM_name)
}

resource "google_compute_instance" "map" {
  for_each = {
    for myVm in var.VM_defs :
    myVm.device_name => myVm
    if contains(local.VM_names, myVm.device_name)
  }

  zone         = "${each.value.region}-${each.value.zone}"
  name         = each.value.device_name
[...]
}

When I run terraform, I pass as a “VM_name” list of VMs that I want to create, e.g.:

VM_name=“vm1”
or
VM_name=“vm2,vm3”

My issue is that if I create “vm1” and then next time run the code to build vm2 and vm3 by this:
VM_name=“vm2,vm3”
terraform assumes I dont want vm1 anymore and destroy it :slight_smile:

so to keep vm1 and create vm2,vm3, I have to remember about vm1 and run:
VM_name=“vm1,vm2,vm3”

is there a way to make terraform to do not destroy vm1 if not specified on the list?

Hi @book.wsz,

What you’ve discovered here is the result of Terraform being a “desired state” system, rather than an imperative system. In other words, instead of commanding Terraform to create something, we tell Terraform what ought to exist and Terraform itself determines whether objects need to be created, updated, or deleted to make that be true.

This is a core part of Terraform’s design and so there is no way to avoid it. If you just want to imperatively create objects and then not touch them again, Terraform is not the appropriate tool for that job; it’s typically better in that case to use the CLI tool provided by the vendor to directly exercise the remote API’s “create” action.

1 Like

thank you so much for addressing my ignorance and saving me a lot of time for trying to force terraform to do something it’s not designed for! :slight_smile: