ansiblecitrixxenhypervisor

Get list of ip addesses from multiple citrix hypervisors vm's using ansible


I am using ansible and the xenserver_guest_info module to create a list of ip addresses from multiple virtual machines on my citrix hypervisor server. Currently I just want to print a list of ip's but storing these ip's in an ansible list would be even better. I plan to loop through this list of ip's and run commands on all these vm's using ansible.

Here is my ansible playbook currently. It loops through the dictionary output that the xenserver module returns, trying to extract the ip address.:

- name: Manage VMs
  connection: local
  hosts: localhost

  # Hypervisor server info from vars file
  vars_files:
    - xen_vars.yml

  tasks:

  - name: Gather facts
    xenserver_guest_info:
      hostname: "{{ xen_address}}"
      username: "{{ admin_username }}"
      password: "{{ admin_password }}"
      name: "{{ item }}"
    loop: "{{ xen_machines }}"
    register: facts

  # - name: Get IP's of VM's

  - debug:
      msg: "{{item.instance.networks}}" 
    loop: "{{facts.results}}"

It produces the following output given a list of two vm's on my server:

PLAY [Manage VMs] **************************************************************

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

TASK [Gather facts] ************************************************************
ok: [localhost] => (item=Ubuntu 20)
ok: [localhost] => (item=Ubuntu 20 2)

TASK [debug] *******************************************************************
ok: [localhost] => (item={'failed': False, 'changed': False, 'instance': {'state': 'poweredoff', 'name': 'Ubuntu 20', 'name_desc': '', 'uuid': 'cf5db672-67cf-7e8c-6951-f5959ab62e26', 'is_template': False, 'folder': '', 'hardware': {'num_cpus': 1, 'num_cpu_cores_per_socket': 1, 'memory_mb': 1024}, 'disks': [{'size': 21474836480, 'name': 'Ubuntu 20 0', 'name_desc': 'Created by template provisioner', 'sr': 'Local storage', 'sr_uuid': 'd7bb817b-281e-fd9c-33a3-54db8935d596', 'os_device': 'xvda', 'vbd_userdevice': '0'}], 'cdrom': {'type': 'iso', 'iso_name': 'ubuntu-20.04.1-desktop-amd64.iso'}, 'networks': [{'name': 'Pool-wide network associated with eth0', 'mac': 'a2:07:be:29:5f:ad', 'vif_device': '0', 'mtu': '1500', 'ip': '', 'prefix': '', 'netmask': '', 'gateway': '', 'ip6': [], 'prefix6': '', 'gateway6': ''}], 'home_server': 'citrix-mwyqyqaa', 'domid': '-1', 'platform': {'timeoffset': '0', 'videoram': '8', 'hpet': 'true', 'secureboot': 'false', 'device-model': 'qemu-upstream-compat', 'apic': 'true', 'device_id': '0001', 'vga': 'std', 'nx': 'true', 'pae': 'true', 'viridian': 'false', 'acpi': '1'}, 'other_config': {'base_template_name': 'Ubuntu Focal Fossa 20.04', 'import_task': 'OpaqueRef:3b6061a0-a204-4ed4-be20-842a359a70fa', 'mac_seed': 'f6ae87b5-2f00-0717-559e-8b624fe92f35', 'install-methods': 'cdrom,nfs,http,ftp', 'linux_template': 'true'}, 'xenstore_data': {'vm-data': '', 'vm-data/mmio-hole-size': '268435456'}, 'customization_agent': 'custom'}, 'invocation': {'module_args': {'hostname': '192.168.0.187', 'username': 'root', 'password': 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER', 'name': 'Ubuntu 20', 'validate_certs': True, 'uuid': None}}, 'item': 'Ubuntu 20', 'ansible_loop_var': 'item'}) => {
    "msg": [
        {
            "gateway": "",
            "gateway6": "",
            "ip": "192.168.0.2",
            "ip6": [],
            "mac": "a2:07:be:29:5f:ad",
            "mtu": "1500",
            "name": "Pool-wide network associated with eth0",
            "netmask": "",
            "prefix": "",
            "prefix6": "",
            "vif_device": "0"
        }
    ]
}
ok: [localhost] => (item={'failed': False, 'changed': False, 'instance': {'state': 'poweredoff', 'name': 'Ubuntu 20 2', 'name_desc': '', 'uuid': 'b087832e-81f1-c091-1363-8b8ba8442c8e', 'is_template': False, 'folder': '', 'hardware': {'num_cpus': 1, 'num_cpu_cores_per_socket': 1, 'memory_mb': 1024}, 'disks': [{'size': 21474836480, 'name': 'Ubuntu 20 0', 'name_desc': 'Created by template provisioner', 'sr': 'Local storage', 'sr_uuid': 'd7bb817b-281e-fd9c-33a3-54db8935d596', 'os_device': 'xvda', 'vbd_userdevice': '0'}], 'cdrom': {'type': 'iso', 'iso_name': 'ubuntu-20.04.1-desktop-amd64.iso'}, 'networks': [{'name': 'Pool-wide network associated with eth0', 'mac': 'e6:cd:ca:ff:c3:e0', 'vif_device': '0', 'mtu': '1500', 'ip': '', 'prefix': '', 'netmask': '', 'gateway': '', 'ip6': [], 'prefix6': '', 'gateway6': ''}], 'home_server': 'citrix-mwyqyqaa', 'domid': '-1', 'platform': {'timeoffset': '0', 'videoram': '8', 'hpet': 'true', 'secureboot': 'false', 'device-model': 'qemu-upstream-compat', 'apic': 'true', 'device_id': '0001', 'vga': 'std', 'nx': 'true', 'pae': 'true', 'viridian': 'false', 'acpi': '1'}, 'other_config': {'base_template_name': 'Ubuntu Focal Fossa 20.04', 'import_task': 'OpaqueRef:3b6061a0-a204-4ed4-be20-842a359a70fa', 'mac_seed': '3c56a628-0f68-34f9-fe98-4bf2214a5891', 'install-methods': 'cdrom,nfs,http,ftp', 'linux_template': 'true'}, 'xenstore_data': {'vm-data': '', 'vm-data/mmio-hole-size': '268435456'}, 'customization_agent': 'custom'}, 'invocation': {'module_args': {'hostname': '192.168.0.187', 'username': 'root', 'password': 'VALUE_SPECIFIED_IN_NO_LOG_PARAMETER', 'name': 'Ubuntu 20 2', 'validate_certs': True, 'uuid': None}}, 'item': 'Ubuntu 20 2', 'ansible_loop_var': 'item'}) => {
    "msg": [
        {
            "gateway": "",
            "gateway6": "",
            "ip": "192.168.0.3",
            "ip6": [],
            "mac": "e6:cd:ca:ff:c3:e0",
            "mtu": "1500",
            "name": "Pool-wide network associated with eth0",
            "netmask": "",
            "prefix": "",
            "prefix6": "",
            "vif_device": "0"
        }
    ]
}

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

I tried accessing just the ip but it hasn't been working well since it is stored in a list.

Again my end goal is to just have ansible spit out a list of ip's like so:

192.168.0.2
192.168.0.3

Or even better to store these in an ansible list for later usage. Any help would be much appreciated.


Solution

  • If the only real problem you have is that the IPs are in a list, and you know (because of the way you have configured your VMs) that the list always has only one entry, then just get the first item in the list:

    item.instance.networks[0].ip
    

    If you want to then use these IP addresses to do some Ansible work on the VMs, I suggest that you use add_host to build a new inventory for a second play in your playbook:

    - name: Manage VMs
      connection: local
      hosts: localhost
    
      # Hypervisor server info from vars file
      vars_files:
        - xen_vars.yml
    
      tasks:
    
      - name: Gather facts
        xenserver_guest_info:
          hostname: "{{ xen_address}}"
          username: "{{ admin_username }}"
          password: "{{ admin_password }}"
          name: "{{ item }}"
        loop: "{{ xen_machines }}"
        register: facts
    
      # - name: Get IP's of VM's
    
      - debug:
          msg: "{{item.instance.networks[0].ip}}" 
        loop: "{{facts.results}}"
    
      - name: Build inventory of VMs
        add_host:
          name: "{{ item.instance.networks[0].ip }}"
          groups: vms
          # You can add other variables per-host here if you want
        loop: "{{ xen_machines }}"
        loop_control:
          label: "{{ item.instance.name }}"
    
    - name: Do stuff directly to the VMs
      hosts: vms  # This is the group you just created
      connection: ssh
    
      tasks:
        - debug:
            msg: "{{ Hello from a VM }}"