Are you trying to manage private clouds easily and efficiently using Ansible Automation Platform? When it comes to VMware infrastructure automation, the latest release of the vmware.vmware_rest Collection and new lookup plugins bring a set of fresh features to build, manage and govern various VMware use cases and accelerate the process from development to production.

The modules in the vmware.vmware_rest Collection rely on the resource MOID a lot. This is a design decision that we covered in an earlier blog. Consequently, when the users want to modify a VMware resource, they need to first write Ansible tasks to identify its MOID.

The new 2.1.0 release of vmware.vmware_rest Collection comes with a series of filter plugins dedicated to gathering the resource MOID. In this blog post, we will help you to keep your VMware automation playbooks concise.

 

But first, What is a MOID?

Internally VMware vSphere manages resources in the form of objects. Every object has a type and an ID. What we are calling MOID stands for Managed Object ID. Using the vSphere UI obfuscates the MOID logic from users and presents the objects in a visible hierarchy, potentially at several different locations.

 

So, Can I just pick the object path from the vSphere resource browser?

Well… no. vSphere UI actually hides a bit of information. For instance, a data center comes with a VM folder. This is where the virtual machines are stored. However, you won’t find it if you use the vSphere UI. This is the same for the host, network and datastore folders.

 

A real-world example

To properly back up a virtual machine, we need to turn it off first. Once this first step is done, we can safely take a snapshot of its disks. Without this initial operation, the snapshot may be corrupted. We’ve already got a playbook to trigger our backup. It runs every night, but we are looking for a way to ensure we’ve got this first step right.

In our lab, we’ve got a backup VM called test_vm1 that we want to shut down.

As mentioned above, vSphere does not expose the actual path of the resource. However, the govc CLI command is helpful to get the MOID quickly:

$ govc ls -i /my_dc/vm/test_vm1
VirtualMachine:vm-1024

You can then use the vSphere MOB interface to browse the objects. For instance: in our case, we can point your browser to this URL: https://vcenter.test/mob/?moid=vm-1024.

 

The /my_dc/vm/test_vm1 path can be split in three different parts:

  • my_dc is the name of our data center
  • vm is the folder
  • test_vm1 is the name of the virtual machine. Here vm-1024 is the MOID of this resource as checked from the govc CLI

 

Let’s automate finding the MOID!

As explained above, Ansible will use the MOID to target the right virtual machine. The ID will remain the same during the VM life-cycle, so we can just store it in a configuration variable. But this becomes an issue when VM is redeployed, and this would also prevent us from reusing the same login for a different VM.

We will instead discover it dynamically using Ansible. And since the 2.1.0 release of vmware.vmware_rest includes two different ways to achieve this, it will be interesting to compare them:

  • Using the info modules
  • Using the new lookup plugins.

 

Identify a VM with the info modules

We will look up each object of the path until we reach the final virtual machine. The first step is to identify the datacenter MOID. We can use the vcenter_datacenter_info module to search a datacenter called my_dc.

- vmware.vmware_rest.vcenter_datacenter_info:
  names:
    - my_dc
  register: result

Response:

{
    "changed": false,
    "value": [
        {
            "datacenter": "datacenter-1001",
            "name": "my_dc"
        }
    ]
}

From this result, we set a fact with the datacenter MOID:

- set_fact:
    dc_id: "{{ result.value[0].datacenter  }}

Response:

{
    "ansible_facts": {
        "dc_id": "datacenter-1001"
    },
    "changed": false
}

The next step is to get the folder MOID:

- vmware.vmware_rest.vcenter_folder_info:
   names:
      - vm
      filter_type: VIRTUAL_MACHINE
      parent_folders: "{{ dc_id }}"
      register: result

Response:

{
    "changed": false,
    "value": [
        {
            "folder": "group-v1002",
            "name": "vm",
            "type": "VIRTUAL_MACHINE"
        }
    ]
}

Here, we can also set a fact with the folder MOID:

- set_fact:
    folder_id: "{{ result.value[0].folder  }}

Response:

{
    "ansible_facts": {
        "folder_id": "group-v1002"
    },
    "changed": false
}

Now, we’ve got enough information to call the vcenter_vm_info module to identify our VM’s MOID:

- vmware.vmware_rest.vcenter_vm_info:
   names:
     - test_vm1
    folders: "{{ folder_id }}"
    register: result

Response:

{
    "changed": false,
     "value": [
         {
            "cpu_count": 1,
            "memory_size_MiB": 1080,
            "name": "test_vm1",
            "power_state": "POWERED_ON",
            "vm": "vm-1024"
          }
    ]
}

Ansible returns the list of virtual machines that match our criterias. Since we’ve used both a name and a folder, we can safely assume our VM is the first and single entry in this list.

- set_fact:
    vm_id: "{{ result.value[0].vm  }}

Response:

{
    "ansible_facts": {
        "vm_id": "vm-1024"
    },
    "changed": false
}

 

Identify a VM with the new lookup plugin

The Collection provides new lookup plugins for the following type of resources:

  • cluster
  • datacenter
  • datastore
  • folder
  • host
  • network
  • resource_pool
  • vm

The plugins can be used in isolation or chained together. Let’s see now at the syntax required by each lookup plugin. The plugins take an object path as a parameter and return the resource MoID. This is really similar to our govc example in the first paragraph.

- set_fact:
    vm_id: "{{ lookup('vmware.vmware_rest.vm_moid', '/my_dc/vm/test_vm1')  }}"

Response:

{
    "ansible_facts": {
        "vm_id": "vm-1024"
    },
    "changed": false
}

The result of this task is a string containing the MOID of the object. Generally, the MOID naming starts with a prefix stating the object type followed by a hyphen and a number, for example, vm-126, host-19, domain-c31.

This time, we get our result in just one single operation. Since we are doing it from a Jinja2 expression, the result is also directly available for the task.

We can even mix the two in the same playbook. For instance, here we retrieve all the virtual machines of the /my_dc/vm folder. By using the folder_moid lookup plugin, so we avoid some extra tasks.

- vmware.vmware_rest.vcenter_folder_info:
   filter_type: VIRTUAL_MACHINE
   parent_folders: "{{ lookup('vmware.vmware_rest.folder_moid', '/my_dc/vm')  }}"

Response:

{
    "changed": false,
    "value": [
        {
            "folder": "group-v1011",
            "name": "Discovered virtual machine",
            "type": "VIRTUAL_MACHINE"
        },

        {
            "folder": "group-v1021",
            "name": "vCLS",
            "type": "VIRTUAL_MACHINE"
        }
    ]
}

 

Which approach fits my needs the best?

The two solutions complement each other. These two paragraphs highlight the main differences.

 

info module benefits

Pros:

  • Advanced search criterias, e.g: name and location
  • Ability to return a list, e.g: to iterate on all the VMs of a given folder

Cons:

  • May take several steps.
  • Possible to inadvertently return another object with the same name, e.g: two VMs with the same name in different folders.

 

lookup plugin benefits

Pros:

  • Target the right object.
  • No additional steps.
  • Faster

Cons:

  • The full path is a requirement.

Also, Ansible evaluates the Jinja2 expressions on the control node before it sends the tasks to the remote nodes. This is also the case for the lookup plugins.

 

Deep dive into the filter logic

As mentioned, these plugins leverage vSphere’s RESTful API to retrieve the resources MOID. vSphere organizes these resources into an inventory tree hierarchy, where the hierarchy represents the logical relationships between them.

The following figure comes from VMware’s pyvmomi-community-samples project. It illustrates a hierarchical arrangement of resources.

Using a top-down approach, the inventory is managed as a collection of datacenters. Each datacenter contains computing, data storage, and networking resources. Virtual machines and virtual applications can be created in these datacenters, while folders can be used to hierarchically group objects of the same type. The nested structure allows objects in the datacenter to be organized into an easily manageable structure.

For example, the HostFolder could contain ComputeResource (compute resources of an ESXi host) and ClusterComputeResource (aggregated compute resources forming a vSphere Cluster) which in turn can have multiple ResourcePools (set of compute resources that could be further splitted up) and HostSystem (single ESXi host). Similarly, to retrieve other vSphere objects such as VirtualMachine, simply traverse the appropriate top-level folders as shown in the figure.

Unfortunately, information about such hierarchy is totally absent from the API responses. To recreate it, we need to loop through all sorts of lists. Let’s assume we want to find the folder in which a VirtualMachine resides. We simply traverse the appropriate top-level folders as shown in the figure.

  1. Get all the top level folders GET /api/vcenter/folder. Notice that the response includes only folder name, MOID and type.
  2. Select only the datacenter contained within the specified folder GET /api/vcenter/datacenter?filter.folders={folder-id}.
  3. Get all the folders contained by the Datacenter GET /api/vcenter/folder?filter.datacenters={datacenter-id}.
  4. Get only the VMs contained using the specified filters. GET /api/vcenter/vm?filter.folders={folder-id}&filter.datacenters={datacenter-id}

The newly moid/name lookup plugins follow this logic to retrieve the MOID of a resource.

 

Conclusion

We hope you found this article useful. You can reach use on the #ansible-vmware IRC channel or through GitHub. Hopefully you find this new approach simpler and it helps to reduce the size of the playbooks. And as we saw, the classic info modules remain handy for a lot of cases.

For further reading and information, visit the other blogs related to VMware automation. If you are unfamiliar with Ansible Content Collections, check out our YouTube playlist for everything about Ansible Collections. The videos will get you up to speed quickly.

Also, don’t forget to check out our Automate infrastructure workflows e-book if you want to learn more about building a unified, automated pipeline for infrastructure operations.

 

*This blog was co-written by Gonéri Le Bouder*

About the author

Alina Buzachis, PhD, is a Senior Software Engineer at Red Hat Ansible, where she works primarily on cloud technologies. Alina received her PhD in Distributed Systems in 2021, focusing on advanced microservice orchestration techniques in the Cloud-to-Thing continuum. In her spare time, Alina enjoys traveling, hiking, and cooking.

Read full bio