Search code examples
terraformterraform-provider-vsphere

Terraform vsphere_tag unwanted deletion


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

Solution

  • 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.