How to fetch a specific IP via vmware_guest_info? - ansible

I use vmware_guest_info: to get the DHCP address for my VMs. The problem is that after I have configured several static IP's, the guest.ipAddress is changed from the DHCP address, which is usually the first network adapter, to a randomly configured static IP:
---
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress is not none
register: gather_vm_info
delegate_to: localhost
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress != "0.0.0.0"
register: gather_vm_info
delegate_to: localhost
- debug: var=gather_vm_info.instance.guest.ipAddress
- debug: var=gather_vm_info
- name: "Update host_var with new IP Address"
set_fact:
ansible_host: "{{ gather_vm_info.instance.guest.ipAddress }}"
ansible_hostname: "{{ hostname }}"
This is what I get:
ok: [1-Europe-ECV-Site2] =>
gather_vm_info.instance.guest.net:
- _vimtype: vim.vm.GuestInfo.NicInfo
connected: true
deviceConfigId: -1
dnsConfig: null
ipAddress:
- fe80::fc70:f8ff:fe15:ae75
ipConfig:
_vimtype: vim.net.IpConfigInfo
autoConfigurationEnabled: null
dhcp: null
ipAddress:
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: fe80::fc70:f8ff:fe15:ae75
lifetime: null
origin: null
prefixLength: 64
state: unknown
macAddress: fe:70:f8:15:ae:75
netBIOSConfig: null
network: null
- _vimtype: vim.vm.GuestInfo.NicInfo
connected: true
deviceConfigId: -1
dnsConfig: null
ipAddress:
- fe80::dc8b:91ff:fefe:66dd
ipConfig:
_vimtype: vim.net.IpConfigInfo
autoConfigurationEnabled: null
dhcp: null
ipAddress:
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: fe80::dc8b:91ff:fefe:66dd
lifetime: null
origin: null
prefixLength: 64
state: unknown
macAddress: de:8b:91:fe:66:dd
netBIOSConfig: null
network: null
- _vimtype: vim.vm.GuestInfo.NicInfo
connected: true
deviceConfigId: -1
dnsConfig: null
ipAddress:
- fe80::f8ea:c4ff:fe90:99e2
ipConfig:
_vimtype: vim.net.IpConfigInfo
autoConfigurationEnabled: null
dhcp: null
ipAddress:
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: fe80::f8ea:c4ff:fe90:99e2
lifetime: null
origin: null
prefixLength: 64
state: unknown
macAddress: fa:ea:c4:90:99:e2
netBIOSConfig: null
network: null
- _vimtype: vim.vm.GuestInfo.NicInfo
connected: true
**deviceConfigId: 4000**
dnsConfig: null
ipAddress:
- 192.168.0.35
- fe80::250:56ff:fe91:c8c0
ipConfig:
_vimtype: vim.net.IpConfigInfo
autoConfigurationEnabled: null
dhcp: null
ipAddress:
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: 192.168.0.35
lifetime: null
origin: null
prefixLength: 16
state: preferred
- _vimtype: vim.net.IpConfigInfo.IpAddress
ipAddress: fe80::250:56ff:fe91:c8c0
lifetime: null
origin: null
prefixLength: 64
state: unknown
It looks like that VMWare assigned deviceConfigId: 4000 for the first Network Interface, but how can I access it on my Playbook?
debug: var=gather_vm_info.instance.guest.net[3].ipAddress[0]-?????
EDIT:
Can somebody explain, why vSphere register the IP address correctly for some VM's as guest.ipAddress and sometimes you have to get it as gather_vm_info.instance.hw_eth0.ipaddresses.
This would be fine, but in this example you can see that the IPAddress is only registered as gather_vm_info.instance.hw_eth0.ipaddresses and you don't get it as hw_eth0.ipaddresses???
TASK [debug] ******************************************************************************************************************************************************************************
ok: [1-USA-ECV-Site8] =>
gather_vm_info:
changed: false
failed: false
instance:
annotation: Silver Peak Systems ECV
current_snapshot: null
customvalues: {}
guest_consolidation_needed: false
guest_question: null
guest_tools_status: guestToolsRunning
guest_tools_version: '10341'
hw_cluster: null
hw_cores_per_socket: 1
hw_datastores:
- Datastore2
hw_esxi_host: 51.89.43.64
hw_eth0:
addresstype: assigned
ipaddresses: null <<-- IP Address is missing!?
label: Network adapter 1
macaddress: 00:50:56:91:55:12
macaddress_dash: 00-50-56-91-55-12
portgroup_key: null
portgroup_portkey: null
summary: Management
hw_eth1:
addresstype: assigned
ipaddresses: null
label: Network adapter 2
macaddress: 00:50:56:91:26:a1
macaddress_dash: 00-50-56-91-26-a1
portgroup_key: null
portgroup_portkey: null
summary: 1-MPLS
hw_eth2:
addresstype: assigned
ipaddresses:
- 10.8.10.1
- fe80::250:56ff:fe91:361d
label: Network adapter 3
macaddress: 00:50:56:91:36:1d
macaddress_dash: 00-50-56-91-36-1d
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_eth3:
addresstype: assigned
ipaddresses: null
label: Network adapter 4
macaddress: 00:50:56:91:b7:ce
macaddress_dash: 00-50-56-91-b7-ce
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_eth4:
addresstype: assigned
ipaddresses: null
label: Network adapter 5
macaddress: 00:50:56:91:68:73
macaddress_dash: 00-50-56-91-68-73
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_eth5:
addresstype: assigned
ipaddresses:
- fe80::250:56ff:fe91:b5c8
label: Network adapter 6
macaddress: 00:50:56:91:b5:c8
macaddress_dash: 00-50-56-91-b5-c8
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_eth6:
addresstype: assigned
ipaddresses: null
label: Network adapter 7
macaddress: 00:50:56:91:83:ab
macaddress_dash: 00-50-56-91-83-ab
portgroup_key: null
portgroup_portkey: null
summary: 1-Site8
hw_files:
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8.vmx'
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8.nvram'
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8.vmsd'
- '[Datastore2] 1-USA-ECV-Site8/vmware.log'
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8.vmdk'
- '[Datastore2] 1-USA-ECV-Site8/1-USA-ECV-Site8_1.vmdk'
hw_folder: /OVH/vm
hw_guest_full_name: Other 4.x or later Linux (64-bit)
hw_guest_ha_state: null
hw_guest_id: other4xLinux64Guest
hw_interfaces:
- eth0
- eth1
- eth2
- eth3
- eth4
- eth5
- eth6
hw_is_template: false
hw_memtotal_mb: 4096
hw_name: 1-USA-ECV-Site8
hw_power_status: poweredOn
hw_processor_count: 2
hw_product_uuid: 4211ed87-aa18-53bb-a983-7aff188b115a
hw_version: vmx-14
instance_uuid: 5011fd96-b512-e3d1-d6f0-ac58201e75db
ipv4: 192.168.0.212 <<-- IP Address is only assigned here!?
ipv6: null
module_hw: true
moid: vm-2296
snapshots: []
vimref: vim.VirtualMachine:vm-2296
vnc: {}

IP Address of the first interface can get through the hw_eth0 property of the vmware_guest_info module result.
Here's the sample playbook.
---
- name: Example Playbook
hosts: localhost
gather_facts: false
vars:
hostname: test_vm2
tasks:
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
register: gather_vm_info
- name: Display the first interface set IP Address of a virtual machine
debug:
msg: >-
{{ gather_vm_info.instance.hw_eth0.ipaddresses
| map('ipaddr', 'ipv4')
| select('!=', false)
| list
| first
}}
The hw_eth0 is the interface information of a virtual machine have.
If you want to get the second interface IP Address, change from hw_eth0 to hw_eth1.
The above playbook uses the ipaddr filter in getting only ipv4 address.
So it needs to install netaddr library.
(venv)$ pip install netaddr
By the way, the following playbook can be possible to get the first interface IP Address too.
---
- name: Example Playbook
hosts: localhost
gather_facts: false
hostname: test_vm2
tasks:
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.net
register: gather_vm_info
- name: Set device_config_ids variable
set_fact:
device_config_ids: >-
{{ device_config_ids | default([])
+ [item.deviceConfigId]
}}
loop: "{{ gather_vm_info.instance.guest.net }}"
- name: Display the first interface set IP Address of a virtual machine
debug:
msg: "{{ item.1.ipAddress.0 }}"
with_nested:
- "{{ device_config_ids | sort | first }}"
- "{{ gather_vm_info.instance.guest.net }}"
when:
- item.0 | int == item.1.deviceConfigId

Related

Nested loop in ansible. product undefined

I have this simple playbook:
---
- hosts: all
become: yes
vars:
my_hosts:
- 192.168.0.1
- 192.168.0.2
- 192.168.0.3
tasks:
- name: Check ports
wait_for:
port: "{{ item.1 }}"
host: "{{ item.0 }}"
timeout: 10
loop: "{{ product(my_hosts) | product([443, 80443]) | list }}"
When I run it like so ...
$ ansible-playbook -i,192.168.2.2 run_wait_for.yml
... I get this error ...
fatal: [192.168.2.2]: FAILED! => {"msg": "'product' is undefined"}
What am I doing wrong?
Fix the syntax
loop: "{{ my_hosts | product([443, 80443]) }}"
For example
- debug:
msg: "Check host: {{ item.0 }} port: {{ item.1 }}"
loop: "{{ my_hosts|product([443, 80443]) }}"
gives (abridged)
msg: 'Check host: 192.168.0.1 port: 443'
msg: 'Check host: 192.168.0.1 port: 80443'
msg: 'Check host: 192.168.0.2 port: 443'
msg: 'Check host: 192.168.0.2 port: 80443'
msg: 'Check host: 192.168.0.3 port: 443'
msg: 'Check host: 192.168.0.3 port: 80443'
I've Ansible 2.9 and this worked to me:
---
- name: Playbook for Check Ports
hosts: localhost
connection: local
gather_facts: no
vars:
my_hosts:
- 192.168.0.1
- 192.168.0.2
- 192.168.0.3
ports:
- 443
- 80443
tasks:
- name: Check Ports.
debug:
msg: "Check host: {{ item[0] }} port: {{ item[1] }}"
loop: "{{ my_hosts | product(ports) | list }}"
...

Trouble selecting particular entry in list

I am having a devil of a time sorting this out so any help is appreciated. I know I need to use selectattr but cannot figure out how exactly.
Using ansible I need to find the address associated with the neighbor that has a route map named BGP_TO_EC applied. I know selectattr will be involved but cannot figure out how exactly.
TIA
Parsed config:
address_family:
- afi: ipv4
neighbor:
- activate: true
address: 10.1.1.1
nexthop_self:
set: true
route_maps:
- name: BGP_TO_EC
out: true
- afi: ipv4
neighbor:
- activate: true
address: 10.2.2.2
remote_as: 3549
version: 4
network:
- address: 10.3.3.3
mask: 255.255.255.252
vrf: somevrf
Given the data
address_family:
- afi: ipv4
neighbor:
- activate: true
address: 10.1.1.1
nexthop_self:
set: true
route_maps:
- name: BGP_TO_EC
out: true
- afi: ipv4
neighbor:
- activate: true
address: 10.2.2.2
remote_as: 3549
version: 4
network:
- address: 10.3.3.3
mask: 255.255.255.252
vrf: somevrf
Simplify the data a bit. Put the below declarations into the vars as appropriate
neighbors_raw: "{{ address_family|json_query(nr_query) }}"
nr_query: "[].neighbor[].{address: address, names: route_maps[].name}"
gives
neighbors_raw:
- address: 10.1.1.1
names:
- BGP_TO_EC
- address: 10.2.2.2
names: null
Replace the null with an empty list
- set_fact:
neighbors_list: "{{ neighbors_list|d([]) +
[item|combine({'names': item.names|
ternary(item.names, [])})] }}"
loop: "{{ neighbors_raw }}"
gives
neighbors_list:
- address: 10.1.1.1
names:
- BGP_TO_EC
- address: 10.2.2.2
names: []
Now, you can select the address
- debug:
msg: "{{ neighbors_list|selectattr('names', 'contains', 'BGP_TO_EC')|
map(attribute='address')|list }}"
gives a list because, generally, there might be more selected items
msg:
- 10.1.1.1
You might want to select the first one
- debug:
msg: "{{ neighbors_list|selectattr('names', 'contains', 'BGP_TO_EC')|
map(attribute='address')|first }}"
gives
msg: 10.1.1.1

Ansible - ACI configure a range

I need to create a script that creates multiple AP with one EPG each , for the AP I can find how to build the range using the ap module , this is what I have so far:
---
- name: ACI Link Level Management
hosts: APIC
connection: local
gather_facts: no
vars:
username: admin
password: Admin
ap_list: "{{ lookup('sequence', 'start=11 count=5 format=ap%d', wantlist=True) }}"
tasks:
- name: Create link level policies
cisco.aci.aci_ap:
host: '{{ inventory_hostname }}'
user: '{{ username }}'
password: '{{ password }}'
validate_certs: false
tenant: DC
ap: '{{ ap_list }}'
description: default ap
monitoring_policy: default
state: present ...
But I'm getting the following error:
FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python3"}, "changed": false, "msg": "Connection failed for /api/mo/uni/tn-DC/ap-['ap11', 'ap12', 'ap13', 'ap14', 'ap15'].json?rsp-prop-include=config-only&rsp-subtree=full&rsp-subtree-class=fvRsApMonPol. An unknown error occurred: URL can't contain control characters. "/api/mo/uni/tn-DC/ap-['ap11', 'ap12', 'ap13', 'ap14', 'ap15'].json?rsp-prop-include=config-only&rsp-subtree=full&rsp-subtree-class=fvRsApMonPol" (found at least ' ')"}
The parameter ap requires a string. You provided a list instead
ap_list: [ap11, ap12, ap13, ap14, ap15]
See the doc
shell> ansible-doc -t module cisco.aci.aci_ap
Maybe you'd like to iterate the list?
- name: Create link level policies
cisco.aci.aci_ap:
host: '{{ inventory_hostname }}'
user: '{{ username }}'
password: '{{ password }}'
validate_certs: false
tenant: DC
ap: '{{ item }}'
description: default ap
monitoring_policy: default
state: present ...
loop: '{{ ap_list }}'

Ansible: need to combine information from 2 files for a task later

I'm running Ansible 2.7.9 on Red Hat Linux 7.4. In my playbook, I need to combine information in two yml files into one data structure that I can then iterate over in a task.
For example, in one .yml file I might have:
---
network_interfaces:
big_computer:
- name: eth0.10
- name: eth1.20
- name: ens224
- name: bond1
type: bond
device: intel
In another .yml file called definitions.yml I might have:
---
eth0.10:
type: vlan
slave: true
master: bond1
subnet: 192.168.10.0/24
eth1.20:
type: vlan
slave: true
master: bond1
subnet: 192.168.20.0/24
ens224:
type: ethernet
subnet: 172.19.22.0/23
bond1:
type: bond
I am able to set, for example, a variable network_interfaces_list from network_interfaces[computer_type]
When computer_type is big_computer, then, I want to take the names of network_interfaces_list, the data from network_interfaces_listand the data from definitions.yml, and create this combined data structure. Then use that data structure in a task. Note that some information may be included in the network_interfaces file, but some of it is found in the definitions file. Or it may remain undefined- there is no "slave" or "master" setting for the bond1 interface, for example.
network_interfaces_list should end up looking like this:
- eth0.10:
type: vlan
slave: true
master: bond1
subnet: 192.168.10.0/24
- eth1.20:
type: vlan
slave: true
master: bond1
subnet: 192.168.20.0/24
- ens224:
type: ethernet
subnet: 172.19.22.0/23
- bond1:
type: bond
device: intel
Entries missing in a dictionary for any given list item are considered unimportant for that item and are essentially null.
I've been wracking my brains all day on this one. I can debug either entry, but trying to put them together- especially without Ansible giving me errors about missing dictionary keys- I'm finding impossible to do.
Essentially what I want is a short file of information, and for those items that are considered unimportant at first glance, I want to put them in another layer that we can peruse to gather more detail, if we wish.
I have done this successfully:
- debug:
msg: "interface_list: {{ network_interfaces_list }}"
- name: MIKE debug
debug:
msg: "thingy: {{ interface['name'] }} \
{{ interface['type']|default('NULL') }} \
{{ interface['device']|default('NULL') }}"
loop: "{{ network_interfaces_list }}"
loop_control:
loop_var: interface
- name: MIKE2 debug
debug:
msg: "thing2: {{ lookup ( 'vars', interface['name'], default='XXX' ) }}"
loop: "{{ network_interfaces_list }}"
loop_control:
loop_var: interface
~~~
But I'm stuck in trying to get merge the members of `interface['name']` from the two data structures.
For example
- set_fact:
network_interfaces_list: "{{ network_interfaces_list|default([]) +
[{item: _val}] }}"
loop: "{{ _keys }}"
vars:
computer_type: big_computer
_keys: "{{ network_interfaces[computer_type]|map(attribute='name')|list }}"
_vals: "{{ network_interfaces[computer_type] }}"
_dict: "{{ dict(_keys|zip(_vals)) }}"
_val: "{{ _dict[item]|combine(definitions[item]) }}"
gives
network_interfaces_list:
- eth0.10:
master: bond1
name: eth0.10
slave: true
subnet: 192.168.10.0/24
type: vlan
- eth1.20:
master: bond1
name: eth1.20
slave: true
subnet: 192.168.20.0/24
type: vlan
- ens224:
name: ens224
subnet: 172.19.22.0/23
type: ethernet
- bond1:
device: intel
name: bond1
type: bond
Notes
The dictionaries keep the redundant attribute name
The names of the variables in definitions.yml are not valid. See Creating valid variable names. Include them in a dictionary, e.g.
- include_vars:
file: definitions.yml
name: definitions
gives
definitions:
bond1:
type: bond
ens224:
subnet: 172.19.22.0/23
type: ethernet
eth0.10:
master: bond1
slave: true
subnet: 192.168.10.0/24
type: vlan
eth1.20:
master: bond1
slave: true
subnet: 192.168.20.0/24
type: vlan
In some cases a dictionary might be a better structure, e.g.
- set_fact:
network_interfaces_dict: "{{ network_interfaces_dict|default({})|
combine({item: _val}) }}"
...
would give
network_interfaces_dict:
bond1:
device: intel
name: bond1
type: bond
ens224:
name: ens224
subnet: 172.19.22.0/23
type: ethernet
eth0.10:
master: bond1
name: eth0.10
slave: true
subnet: 192.168.10.0/24
type: vlan
eth1.20:
master: bond1
name: eth1.20
slave: true
subnet: 192.168.20.0/24
type: vlan

when condition does not match with "ansible_host" Ansible 2.10?

I try something very simple but it does not work:
I want to execute a task only, if two strings are the same:
hostname=1-Europe-ECV-Site2
ansible_host=1-Europe-ECV-Site2
This is the playbook:
- debug: var=hostname
- debug: var=ansible_host
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress is not none
register: gather_vm_info
delegate_to: localhost
when: ansible_host == hostname
I got this result, even if I can see by debugging, that both values are equal:
PLAY [Configure vyOS BGP LAN Router] *****************************************************************************************************************************************************
TASK [get_ip_vsphere : debug] ************************************************************************************************************************************************************
ok: [1-Europe-ECV-Site2] =>
hostname: 1-Europe-ECV-Site2
ok: [1-Europe-ECV-Site3] =>
hostname: 1-Europe-ECV-Site3
ok: [1-Europe-ECV-Site1-1] =>
hostname: 1-Europe-ECV-Site1-1
ok: [1-Europe-ECV-Site1-2] =>
hostname: 1-Europe-ECV-Site1-2
TASK [get_ip_vsphere : debug] ************************************************************************************************************************************************************
ok: [1-Europe-ECV-Site2] =>
ansible_host: 1-Europe-ECV-Site2
ok: [1-Europe-ECV-Site3] =>
ansible_host: 1-Europe-ECV-Site3
ok: [1-Europe-ECV-Site1-1] =>
ansible_host: 1-Europe-ECV-Site1-1
ok: [1-Europe-ECV-Site1-2] =>
ansible_host: 1-Europe-ECV-Site1-2
TASK [get_ip_vsphere : Gather a virtual machine info] ************************************************************************************************************************************
skipping: [1-Europe-ECV-Site2]
skipping: [1-Europe-ECV-Site3]
skipping: [1-Europe-ECV-Site1-1]
skipping: [1-Europe-ECV-Site1-2]
TASK [get_ip_vsphere : Gather a virtual machine info] ************************************************************************************************************************************
skipping: [1-Europe-ECV-Site2]
skipping: [1-Europe-ECV-Site3]
skipping: [1-Europe-ECV-Site1-1]
skipping: [1-Europe-ECV-Site1-2]
Question:
Why this condition does not match? Do I need to do something special if I want to use the build in variable ansible_host I use Ansible 2.10
EDIT:
The purpose of this playbook is to write only the discovered IP address into the inventory YAML file under host_vars, if it is not already defined. As you can see in my example, the ansible_host is equal to the hostname of the VM, if no IP address was detected.
For this I have to check if ansible_host == hostname and only then IP must be fetched and written into the YAML inventory file.
Another solution is to check if 192.168. is not included in "ansbile_host" and then execute the task:
when: "'192.168' in ansible_host"
But this also does not work!
What do I miss?
I don't think issue is with the ansible_host variable. It is because you are trying to match hostname with ansible_host, which should ideally match every time (looking at the debug output).
For example, when the task vmware_guest_info runs on 1-Europe-ECV-Site3:
hostname == ansible_host
Will be:
"1-Europe-ECV-Site3" == "1-Europe-ECV-Site3"
#=> True
Which is not what you want, even if it runs. If you want the task to run only when ansible_hostname matches 1-Europe-ECV-Site2, then the condition should be:
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress is not none
register: gather_vm_info
delegate_to: localhost
when: ansible_hostname == "1-Europe-ECV-Site2"
This solution works, I don't know why the other conditions does not fit:
---
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress is not none
register: gather_vm_info
delegate_to: localhost
when: "'192.168' not in ansible_host"
- name: Gather a virtual machine info
vmware_guest_info:
hostname: '{{ vsphere_host }}'
username: '{{ vsphere_user }}'
password: '{{ vsphere_password }}'
validate_certs: false
datacenter: "{{ vsphere_datacenter }}"
name: "{{ hostname }}"
schema: vsphere
properties:
- guest.ipAddress
retries: 60
delay: 10
until: gather_vm_info.instance.guest.ipAddress != "0.0.0.0"
register: gather_vm_info
delegate_to: localhost
when: "'192.168' not in ansible_host"
- debug: var=gather_vm_info.instance.guest.ipAddress
- name: Update IP
block:
- name: Add ansible_host IP to the YAML inventory file
delegate_to: localhost
lineinfile:
path: host_vars/{{ hostname }}.yml
line: " ansible_host: {{ gather_vm_info.instance.guest.ipAddress }}"
- name: Update dynamic ansible_host with new IP Address
set_fact:
ansible_host: "{{ gather_vm_info.instance.guest.ipAddress }}"
ansible_hostname: "{{ hostname }}"
when: "'192.168' not in ansible_host"
If you use IP address in when condition, it works. Hostname resolution did not happen in my case.
when: ansible_host == "xx.xx.xx.xx"

Resources