'Ansible - Create Dynamic Inventory for ESXi Hosts via vCenter API
I had an ask to create a dynamic inventory of ESXi Hosts for each Cluster and I achieved that using the 'community.vmware.vmware_cluster_info' and doing some magic around extracting json values from register var in a playbook. I thought of sharing this with the community just in case anyone has got a similar task on hand.
FYI - There is an Ansible module for dynamic inventory but that is for VM's and NOT for ESXi Hosts inventory.
Step 1 - This is to get the Cluster info from vCenter and store/register the output in "cluster_info"
- name: Gather info about the cluster
community.vmware.vmware_cluster_info:
hostname: "{{ vcenter_hostname }}"
username: "{{ vcenter_username }}"
password: "{{ vcenter_password)}}"
cluster_name: "Cluster-Name"
validate_certs: no
delegate_to: localhost
register: cluster_info
Step 2 - This is to filter out the ESXi Hosts value and store it as a 'fact' in cluster_hosts. We are using register value 'cluster_info' (from step 1) with dict to filter out the required info.
- name: Generate Dynamic Inventory for Cluster
set_fact:
cluster_hosts: "{{ item.value.hosts | map(attribute='name') | list | sort }}"
with_dict: "{{ cluster_info.clusters }}"
loop_control:
label: '{{ item.key }}'
tags:
- dynamic_inventory
Step 3 - Now we are using the list generated from Step 2 and looping it and creating a Host group (using 'add_host' module) containing those hosts that can be used for next task/playbook.
- name: Dynamic Inventory Group created
add_host:
hostname: "{{ item }}"
groups: esxi_dynamic_inventory
loop: "{{ cluster_hosts }}"
tags:
- dynamic_inventory
Any questions feel free to ask.
Solution 1:[1]
I faced the same situation a few years ago.
What I did is take the source code from Ansible for one of the vmware modules and write a module that returned the host list.
You can take any vmware module from Ansible (like https://github.com/ansible-collections/community.vmware/blob/98fb3fe441de096778a0bf4b5ba9c3d146c47f72/plugins/modules/vmware_guest_find.py) and adapt it with the following code.
It is a custom module, so you should place it somewhere in the library directory of the role or collection you are writing.
class PyVmomiHelper(PyVmomi):
def __init__(self,module):
super(PyVmomiHelper, self).__init__(module)
cluster = self.params['cluster_name']
self.host_obj_list = self.get_all_host_objs(cluster_name=cluster)
def get_host_obj_list(self):
results = dict(changed=False, result=dict())
host_list = []
for host in self.host_obj_list:
host_list.append(host.name)
results['result']["host_list"] = host_list
self.module.exit_json(**results)
def main():
argument_spec = vmware_argument_spec()
argument_spec.update(dict(
cluster_name=dict(type='str')
))
module = AnsibleModule(argument_spec=argument_spec,
supports_check_mode=False,
required_one_of=[
['cluster_name']
])
try:
pyv = PyVmomiHelper(module)
pyv.get_host_obj_list()
except vmodl.RuntimeFault as runtime_fault:
module.fail_json(msg=to_native(runtime_fault.msg))
except vmodl.MethodFault as method_fault:
module.fail_json(msg=to_native(method_fault.msg))
except Exception as e:
module.fail_json(msg=to_native(e))
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Jordi Molina |
