Terraform vsphere_tag unwanted deletion

Viewed 238

I'm using Terraform to deploy some dev and prod VMs on our VMware vCenter infrastructure and use vsphere tags to define responsibilities of VMs. I therefore added the following to the (sub)module:

  resource "vsphere_tag" "tag" {
    name        = "SYS-Team"
    category_id = "Responsibility"
    description = "Systems group"
  }

  ...

  resource "vsphere_virtual_machine" "web" {
    tags             = [vsphere_tag.tag.id]
    ...
  }

Now, when I destroy e.g. the dev infra, it also deletes the prod vsphere tag and leave the VMs without the tag.

I tried to skip the deletion with the lifecycle, but then I would need to separately delete each resource which I don't like.

lifecycle {
  prevent_destroy = true
}

Is there a way to add an existing tag without having the resource managed by Terraform? Something hardcoded without having the tag included as a resource like:

  resource "vsphere_virtual_machine" "web" {
    tags             = [{
      name        = "SYS-Team"
      category_id = "Responsibility"
      description = "Systems group"
      }
    ]
    ...
  }
2 Answers

You can use Terraform's data sources to refer to things that are either not managed by Terraform or are managed in a different Terraform context when you need to retrieve some output from the resource such as an automatically generated ID.

In this case you could use the vsphere_tag data source to look up the id of the tag:

data "vsphere_tag_category" "responsibility" {
  name = "Responsibility"
}

data "vsphere_tag" "sys_team" {
  name        = "SYS-Team"
  category_id = data.vsphere_tag_category.responsibility.id
}

...

resource "vsphere_virtual_machine" "web" {
  tags             = [data.vsphere_tag.sys_team.id]
  ...
}

This will use a vSphere tag that has either been created externally or managed by Terraform in another place, allowing you to easily run terraform destroy to destroy the VM but keep the tag.

If I understood correctly the real problem is on:
when I destroy e.g. the dev infra, it also deletes the prod vsphere tag

That should not be happening!
any cross environment deletions is a red flag

It feels like the problem is in your pipeline, not your terraform code ...
The deployment pipelines I create the dev resources are not mixed with prod,
and IF they are mix, you are just asking for troubles,
your team should make redesigning that a high priority


You do ask:
Is there a way to add an existing tag without having the resource managed by Terraform?

Yes you can use PowerCLI for that:
https://blogs.vmware.com/PowerCLI/2014/03/using-vsphere-tags-powercli.html

the command to add tags is really simple:
New-Tag –Name “jsmith” –Category “Owner”

You could even integrate that into terraform code with a null_resource something like:

resource "null_resource" "create_tag" {
  provisioner "local-exec" {
    when        = "create"
    command     = "New-Tag –Name “jsmith” –Category “Owner”"
    interpreter = ["PowerShell"]
  }
}
Related