Menu

Virtual Geek

Tales from real IT system administrators world and non-production environment

Developing and writing Ansible Python custom module for VMware pyvmomi example

There may be requirement in RedHat Ansible when you write custom module when you don't fine tasks module for certain objects, that time you will need to write your own custom python module. In this given example I was using community VMware vSphere module with ansible and wanted to list all ESXi servers in the vCenter server, but I didn't find the required task module as shown on the official guide https://docs.ansible.com/ansible/latest/collections/community/vmware/index.html. So I wrote my own custom module using Python language.

redhat ansible yaml yml vmware vsphere vcenter esxi list esxi hosts inventory ansible-playbook playbook.yml module pythong configuration.png

I am writing this py script in python3 version. Before start there is requirement that PIP package Ansible.module_utils.basic is installed on your Ansible Host system, since I am using VMware so installing pyVmomi, pyvim.connect and ssl packages with python packager PIP. Next I have provided vCenter host, user and password as dictionary parameters under AnsibleModule(argument_spec=dict()), Using these parameter I am connecting to vCenter server object and written a Python code to get ESXi server list inventory and exporting information in the same Ansible module. I named the Python script as get-esxilist.py and kept it under modules folder.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env python3

DOCUMENTATION = '''
---
module: custom_esxi_hosts
short_description: Retrieve ESXi hosts from vCenter inventory
'''

from ansible.module_utils.basic import AnsibleModule
from pyVim.connect import SmartConnect, Disconnect
from pyVmomi import vim
import ssl

def main():
    module = AnsibleModule(
        argument_spec=dict(
            vcenter_host=dict(type='str', required=True),
            vcenter_user=dict(type='str', required=True),
            vcenter_password=dict(type='str', required=True, no_log=True)
        )
    )
    
    vcenter_host = module.params['vcenter_host']
    vcenter_user = module.params['vcenter_user']
    vcenter_password = module.params['vcenter_password']
    
    s = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
    s.verify_mode = ssl.CERT_NONE
    
    try:
        si = SmartConnect(host=vcenter_host, user=vcenter_user, pwd=vcenter_password, sslContext=s)
        content = si.content
        esxi_hosts = get_all_objs(content, [vim.HostSystem])
        esxi_host_info = []

        for esxi_host in esxi_hosts:
            host_name = esxi_host.name
            connection_status = check_connection_status(esxi_host)
            maintenance_mode = esxi_host.runtime.inMaintenanceMode
            power_state = esxi_host.runtime.powerState
            esxi_host_info.append({'name': host_name, 'connected': connection_status, 'maintenance_mode': maintenance_mode, 'power_state': power_state})

        Disconnect(si)
        
        response = {'esxi_hosts': esxi_host_info}
        module.exit_json(changed=False, meta=response)
    except Exception as e:
        module.fail_json(msg=str(e))

def get_all_objs(content, vimtype):
    obj = {}
    container = content.viewManager.CreateContainerView(content.rootFolder, vimtype, True)
    for managed_object_ref in container.view:
        obj.update({managed_object_ref: managed_object_ref.name})
    return obj

def check_connection_status(host):
    return host.runtime.connectionState == vim.HostSystemConnectionState.connected

if __name__ == "__main__":
    main()

To utilize this Python module file create ansible.cfg file and provide the module path in library.

Download this Basic custom Python module for Ansible or it is also available on github.com.

[defaults]
#remote-user = ansible
library = ./modules/

Next below is main Ansible playbook tasks yaml file. I am providing module file name in the task and parameters as shown below, which I provided in the Python py script. 

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
---
- name: Retrieve ESXi Hosts
  hosts: localhost
  tasks:
    - name: Call the custom module
      get_esxilist:
        vcenter_host: "192.168.34.80"
        vcenter_user: "[email protected]"
        vcenter_password: "Computer@123"
      register: esxi_host_output

    - name: Display ESXi Hosts
      debug:
        var: esxi_host_output

#ansible-playbook -i esxi_hosts_list.py playbook.yml

This is how you run the playbook in Ansible and below is the output of tasks with success.

ansible-playbook playbook.yml
/usr/lib/python3/dist-packages/paramiko/transport.py:219: CryptographyDeprecationWarning: Blowfish has been deprecated
  "class": algorithms.Blowfish,
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

PLAY [Retrieve ESXi Hosts] ************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************
ok: [localhost]

TASK [Call the custom module] *********************************************************************************************************************
ok: [localhost]

TASK [Display ESXi Hosts] *************************************************************************************************************************
ok: [localhost] => {
    "esxi_host_output": {
        "changed": false,
        "failed": false,
        "meta": {
            "esxi_hosts": [
                {
                    "connected": false,
                    "maintenance_mode": true,
                    "name": "flash.vcloud-lab.com",
                    "power_state": "unknown"
                },
                {
                    "connected": true,
                    "maintenance_mode": false,
                    "name": "batman.vcloud-lab.com",
                    "power_state": "poweredOn"
                },
                {
                    "connected": true,
                    "maintenance_mode": false,
                    "name": "wonderwoman.vcloud-lab.com",
                    "power_state": "poweredOn"
                },
                {
                    "connected": true,
                    "maintenance_mode": false,
                    "name": "superman.vcloud-lab.com",
                    "power_state": "poweredOn"
                }
            ]
        }
    }
}

PLAY RECAP ****************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

Useful Articles
How to install Ansible on Linux for vSphere configuration
Using Ansible for Managing VMware vsphere Infrastructure
Getting started Ansible AWX tower for IT automation run first playbook
Ansible for VMwary Using vmware_vm_inventory dynamic inventory plugin
Ansible selectattr The error was TemplateRuntimeError no test named 'equalto'
ansible create an array with set_fact
Ansible get information from esxi advanced settings nested dictionary with unique keynames
Install Ansible AWX Tower on Ubuntu Linux
Ansible AWX installation error Cannot have both the docker-py and docker python modules
Ansible AWX installation error docker-compose run --rm --service-ports task awx-manage migrate --no-input
docker: Got permission denied while trying to connect to the Docker daemon socket
Ansible AWX Tower create Manual SCM (Source Control Credential Type) project
Reset Ansible AWX Tower admin password
Install Ansible AWX on Microsoft Windows OS
Step by Step Install Ansible on Ubuntu OS
Install Ansible AWX Tower on Ubuntu Linux OS
Ansible AWX Tower Github inventory integration | Github inventory source

Go Back

Comment

Blog Search

Page Views

11391897

Follow me on Blogarama