Reputation: 47
I made something that is working but I look for something more 'elegant' ;)
- name: Wait for DNS propagation
ansible.builtin.shell:
cmd: host "{{ vm_fqdn }}"
register: dns_result
until: dns_result.rc == 0
retries: 30
delay: 10
But previously I tried with a lookup
and the community.general.dig
- name: Wait for DNS propagation
ansible.builtin.set_fact:
dns_result: "{{ lookup('community.general.dig', vm_fqdn)}}"
until: dns_result == vm_ip
retries: 30
delay: 10
Unfortunately, even I added a register
I couldn't get the dns_result
variable updated after multiple tries. It's like the lookup
happens only once on the first iteration, but is not 're-triggered' on the next try. So maybe it is the behavior of lookup
or something else, but I'm curious to know.
Upvotes: 3
Views: 2597
Reputation: 12063
I couldn't get the
dns_result
variable updated after multiple tries ... but is not 're-triggered' on the next try.
Right, that is the expected behavior for your given example.
It's like the
lookup
happens only once on the first iteration
But this caused by the way variables becomes registered and handled internally. For the retries
loop run the variable content for until
condition will stay at the initial value since it is set (registered) at "compile time" and not "re-set during run time".
The following example will show the behavior.
---
- hosts: localhost
become: false
gather_facts: false
vars:
RETRIES: [1, 2, 3]
tasks:
- name: Set Facts in loop
set_fact:
RESULT: "{{ ansible_loop.index }}"
# Inner loop
until: RESULT == '3'
retries: 3
delay: 1
# Outer loop
loop: "{{ RETRIES }}"
loop_control:
extended: true
label: "{{ item }}"
As one can see from the result output, the retries
behaves like an loop for the inner object, which is a single outer loop state here.
PLAY [localhost] *************************************
FAILED - RETRYING: Set Facts in loop (3 retries left).
FAILED - RETRYING: Set Facts in loop (2 retries left).
FAILED - RETRYING: Set Facts in loop (1 retries left).
TASK [Set Facts in loop] *****************************
failed: [localhost] (item=1) => changed=false
ansible_facts:
RESULT: '1'
...
ansible_loop_var: item
attempts: 3
item: 1
FAILED - RETRYING: Set Facts in loop (3 retries left).
FAILED - RETRYING: Set Facts in loop (2 retries left).
FAILED - RETRYING: Set Facts in loop (1 retries left).
failed: [localhost] (item=2) => changed=false
ansible_facts:
RESULT: '2'
...
ansible_loop_var: item
attempts: 3
item: 2
ok: [localhost] => (item=3)
To summarize, the construct set_fact
- lookup('dig')
- retries
- until
can't work unless the initial condition is already true
. This is shown in the example run #3.
Documentation
Retrying a task until a condition is met
When you run a task with
until
and register the result as a variable, the registered variable will include a key called “attempts”, which records the number of the retries for the task.
Further Q&A
Possible Solutions
You may
either stay with you first approach
try something with the wait_for
module – Waits for a condition before continuing since according Parameter host:
there is the option for
A resolvable hostname or IP address to wait for.
- name: Wait for host
wait_for:
host: test.example.com
port: 22
timeout: 5
register: result
but you will need a port to check for at least.
or better use the here proposed solution
Upvotes: 0
Reputation: 16836
The cleanest and most ansible-native approach I use is:
- name: Getting ready to start
hosts: all
gather_facts: false
tasks:
- name: Wait for DNS propagation
delegate_to: localhost
when: not inventory_hostname is ansible.utils.resolvable
ansible.builtin.debug:
msg: Waiting...
until: inventory_hostname is ansible.utils.resolvable
retries: 900
delay: 10
Here is the bonus also that it will not be printing "Waiting..." for the FQDNs which are already resolvalble.
Upvotes: 1
Reputation: 2939
You're using the lookup at the wrong point. It should be directly in the until
, so that it is evaluated each time.
- name: Wait for DNS propagation
debug:
msg: waiting
until: lookup('community.general.dig', vm_fqdn) == vm_ip
retries: 30
delay: 10
Upvotes: 4