Introduction

VMware tags organize virtual infrastructure — VMs, datastores, networks, and hosts — into logical groups for policy, search, and automation. The community.vmware collection provides modules to manage tags, categories, and tag assignments entirely through Ansible. This article covers tag verification, creation, bulk assignment, and integration with VM provisioning workflows.

Prerequisites

# Install the collection
ansible-galaxy collection install community.vmware

# Install Python dependencies
pip install pyvmomi requests

Connection Variables

# group_vars/vmware.yml (encrypt with Vault)
vcenter_hostname: vcenter.example.com
vcenter_username: administrator@vsphere.local
vcenter_password: "{{ vault_vcenter_password }}"
vcenter_validate_certs: false

Verify and Create Tags

Single Tag

---
- name: Ensure VMware tag exists
  hosts: localhost
  gather_facts: false
  vars_files:
    - vars/vcenter_creds.yml
  tasks:
    - name: Ensure tag category exists
      community.vmware.vmware_category:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: "{{ vcenter_validate_certs }}"
        category_name: Environment
        category_description: "Deployment environment classification"
        category_cardinality: single
        associable_object_types:
          - VirtualMachine
          - Datastore
          - HostSystem
        state: present
      register: category_result

    - name: Ensure tag exists
      community.vmware.vmware_tag:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: "{{ vcenter_validate_certs }}"
        category_name: Environment
        tag_name: Production
        tag_description: "Production environment resources"
        state: present

    - name: Display result
      ansible.builtin.debug:
        msg: "Tag 'Production' in category 'Environment' is present"

Multiple Tags in Bulk

---
- name: Create tag taxonomy
  hosts: localhost
  gather_facts: false
  vars:
    tag_categories:
      - name: Environment
        description: "Deployment environment"
        cardinality: single
        tags:
          - Production
          - Staging
          - Development
          - DR
      - name: Application
        description: "Application tier"
        cardinality: multiple
        tags:
          - Web
          - Database
          - Cache
          - Queue
          - Monitoring
      - name: Owner
        description: "Team ownership"
        cardinality: single
        tags:
          - Platform
          - Backend
          - Frontend
          - Data
  tasks:
    - name: Create categories
      community.vmware.vmware_category:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: false
        category_name: "{{ item.name }}"
        category_description: "{{ item.description }}"
        category_cardinality: "{{ item.cardinality }}"
        associable_object_types:
          - VirtualMachine
        state: present
      loop: "{{ tag_categories }}"

    - name: Create tags
      community.vmware.vmware_tag:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: false
        category_name: "{{ item.0.name }}"
        tag_name: "{{ item.1 }}"
        state: present
      loop: "{{ tag_categories | subelements('tags') }}"

Assign Tags to VMs

- name: Tag virtual machines
  community.vmware.vmware_tag_manager:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: false
    tag_names:
      - "Environment:Production"
      - "Application:Web"
      - "Owner:Platform"
    object_name: webserver-01
    object_type: VirtualMachine
    state: set

Tag Multiple VMs

- name: Tag all web servers
  community.vmware.vmware_tag_manager:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: false
    tag_names:
      - "Environment:Production"
      - "Application:Web"
    object_name: "{{ item }}"
    object_type: VirtualMachine
    state: set
  loop:
    - webserver-01
    - webserver-02
    - webserver-03

Query Tags

Get Tag Info

- name: Get tag information
  community.vmware.vmware_tag_info:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: false
  register: tag_info

- name: Display all tags
  ansible.builtin.debug:
    var: tag_info.tag_info

Get Category Info

- name: Get category information
  community.vmware.vmware_category_info:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: false
  register: category_info

- name: List all categories
  ansible.builtin.debug:
    msg: "{{ category_info.tag_category_info | map(attribute='category_name') | list }}"

Integration with VM Provisioning

---
- name: Provision and tag VM
  hosts: localhost
  gather_facts: false
  vars:
    vm_name: app-server-04
    vm_env: Production
    vm_app: Database
  tasks:
    - name: Clone VM from template
      community.vmware.vmware_guest:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: false
        name: "{{ vm_name }}"
        template: ubuntu-22.04-template
        datacenter: DC1
        cluster: Production-Cluster
        folder: /DC1/vm/Applications
        state: poweredon
        wait_for_ip_address: true
      register: vm_result

    - name: Apply tags to new VM
      community.vmware.vmware_tag_manager:
        hostname: "{{ vcenter_hostname }}"
        username: "{{ vcenter_username }}"
        password: "{{ vcenter_password }}"
        validate_certs: false
        tag_names:
          - "Environment:{{ vm_env }}"
          - "Application:{{ vm_app }}"
        object_name: "{{ vm_name }}"
        object_type: VirtualMachine
        state: set

    - name: Verify tags applied
      ansible.builtin.debug:
        msg: "VM {{ vm_name }} tagged with {{ vm_env }} and {{ vm_app }}"

Remove Tags

# Remove specific tags from a VM
- name: Remove tag from VM
  community.vmware.vmware_tag_manager:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: false
    tag_names:
      - "Environment:Development"
    object_name: old-dev-server
    object_type: VirtualMachine
    state: absent

# Delete a tag entirely
- name: Delete tag
  community.vmware.vmware_tag:
    hostname: "{{ vcenter_hostname }}"
    username: "{{ vcenter_username }}"
    password: "{{ vcenter_password }}"
    validate_certs: false
    category_name: Environment
    tag_name: Deprecated
    state: absent

Best Practices

  1. Use categories with cardinality — single for mutually exclusive tags (Environment), multiple for additive (Application)
  2. Standardize naming — agree on tag names before creating them
  3. Vault all vCenter credentials — never hardcode passwords
  4. Tag at provisioning time — include tagging in your VM creation workflow
  5. Use state: set — replaces existing tags in a category; state: add appends
  6. Audit tags periodically — query vmware_tag_info to find untagged VMs

Conclusion

The community.vmware collection provides complete tag lifecycle management — create categories, create tags, assign tags to VMs, query tag state, and remove tags. Use vmware_tag_manager with state: set for consistent tagging and integrate tag assignment into your VM provisioning playbooks for automatic classification at creation time.