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.
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 }}"