Terraform – vSphere Tags

One of the first Terraform providers I tested was vsphere and attempting to get something as simple as tags applied to a VM left me less than enthused. At the time I didn’t fully grok the tf console for troubleshooting, tf looping, or tf resource chaining.

Now, over a year later I look back on one of my lab modules in disgust due to the crude tagging implementation. I wanted to address three annoyances I had with that initial module:

  1. Handle cardinality with text based keys (vs numeric keys)
  2. Support tag inputs similar to Azure, AWS, etc where merge function can be used between modules
  3. Display assigned tags with display names (vs vmomi IDs)

The key to all of this, pun intended, was passing a map object to the tag_lookup module which would then create a flattened list in a <tag category><separator><tag name> format. The other benefit of using this type of map input was that the merge() function could be used to override “common” tags as I’ve done with Azure and AWS providers when customizing resource tags.

Calling module tag definitions:

  # separator value used in split(), be sure it 
  # doesn't appear multiple times in your 
  # tag category or tag name
  separator = "="

  common_tags = {
    environment      = ["test"]
    deployment-type  = ["terraform"]
    iac-managed      = ["true"]
  tag_demo = {
    environment      = ["dev"]
    point-of-contact = ["devops", "finance"]
  # pass this merged map object to enumerate 
  # already existing tag categories and names
  merged_tags = merge(local.common_tags, local.tag_demo)
  # this list contains "<tag_category><separator><tag_value>" strings 
  # used to lookup display name for output folders {} block
  merged_tags_flat = flatten([
    for tcat,tval in local.merged_tags : [
      for i in tval : "${tcat}${local.separator}${i}"]

Long story short, find the module and examples in the Terraform registry: