Hem_Mu
(Hem_Mu)
December 17, 2024, 8:33am
1
Hello everyone,
I’m encountering an issue with my Ansible playbook where the values set by set_fact
and the delay
values don’t seem to change during task retries. I suspect it might be related to using Jinja2 template expressions. Here’s the relevant part of my playbook.
I suspect that variables using template expressions have fixed values.
$ansible --version
ansible 2.10.8
config file …
Any insights or suggestions would be greatly appreciated!
Hem_Mu
(Hem_Mu)
December 17, 2024, 8:35am
2
If that’s not possible, I think I need to handle it with a custom module…
Hem_Mu
(Hem_Mu)
December 17, 2024, 9:11am
3
TASK [Mock test] *******************************************************************************************************task path: /home/hamster/test.yml:6
FAILED - RETRYING: Mock test (5 retries left).Result was: {
“ansible_facts”: {
“status”: “off”
},
“attempts”: 1,
“changed”: false,
“retries”: 6
}
FAILED - RETRYING: Mock test (4 retries left).Result was: {
“ansible_facts”: {
“status”: “off”
},
“attempts”: 2,
“changed”: false,
“retries”: 6
}
FAILED - RETRYING: Mock test (3 retries left).Result was: {
“ansible_facts”: {
“status”: “off”
},
“attempts”: 3,
“changed”: false,
“retries”: 6
}
FAILED - RETRYING: Mock test (2 retries left).Result was: {
“ansible_facts”: {
“status”: “off”
},
“attempts”: 4,
“changed”: false,
“retries”: 6
}
FAILED - RETRYING: Mock test (1 retries left).Result was: {
“ansible_facts”: {
“status”: “off”
},
“attempts”: 5,
“changed”: false,
“retries”: 6
}
fatal: [localhost]: FAILED! => {
“ansible_facts”: {
“status”: “off”
},
“attempts”: 5,
“changed”: false
}
PLAY RECAP *************************************************************************************************************
localhost : ok=0 changed=0 unreachable=0 failed=1 skipped=0 rescued=0 ignored=0
I find it unreasonable that the random value remains the same consecutively.
Hem_Mu
(Hem_Mu)
December 17, 2024, 9:13am
4
other random value
TASK [Mock test] ***********************************************************************************************************************************
task path: /home/hamster/test.yml:6
ok: [localhost] => {
“ansible_facts”: {
“status”: “on”
},
“attempts”: 1,
“changed”: false
}
TASK [Print timestamp after all retries] ***********************************************************************************************************
task path: /home/hamster/test.yml:19
ok: [localhost] => {
“msg”: “Timestamp after checker creation: 2024-12-17 18:12:02”
}
TASK [Debug] ***************************************************************************************************************************************
task path: /home/hamster/test.yml:23
ok: [localhost] => {
“msg”: “status: {‘changed’: False, ‘ansible_facts’: {‘status’: ‘on’}, ‘failed’: False, ‘attempts’: 1}”
}
bvitnik
(Bojan Vitnik)
December 17, 2024, 11:43am
5
You are using the same variable status
in set_fact
and register
. One is overwriting the other.
This is also incorrect. set_facts
is not setting a variable in ansible_facts
dictionary (maybe missleading?) but instead sets variable in hostvars[inventory_hostname][<your_variable>]
.
Hem_Mu
(Hem_Mu)
December 17, 2024, 11:59am
6
Then why doesn’t the delay
value change when retrying a task? I manually measured the time using a stopwatch.
bvitnik
(Bojan Vitnik)
December 17, 2024, 12:45pm
7
I presume, but I’m not 100% sure, that delay
is evaluated only once, not on every retry.
1 Like
Hem_Mu
(Hem_Mu)
December 17, 2024, 1:15pm
8
I also think that the delay
and set_fact
values are fixed at evaluation time.
1 Like
bcoca
(Brian Coca)
December 17, 2024, 4:56pm
9
yes set_fact
was a bad name, it is as you state, it is ‘set a host variable’.
Hem_Mu
(Hem_Mu)
December 18, 2024, 12:21am
10
Could the fixed values of set_fact
and delay
during evaluation be due to Jinja2 expressions? It seems like they don’t change even during retries.
If it’s confirmed that the values are fixed during evaluation, I would handle it with Python instead.
shertel
December 18, 2024, 12:55pm
11
Yes, the module arg is templated once (see this explanation strings templated using a lookup in a loop shouldn't be cached and re-used · Issue #82955 · ansible/ansible · GitHub - there are also a few workarounds mentioned on that issue). If you’re able to update to 2.18, then you could do use loop
for retries and loop_control.break_when
to stop looping when the condition is met:
- name: Set fact until status is "on"
set_fact:
status: "{{ ['on', 'off'] | random }}"
register: status_result
loop: "{{ range(0, 5) }}"
loop_control:
pause: >
{% if (ansible_loop.index|default(0)) == 0 %}
{{ 2 + (1 | random(start=0)) }}
{% else %}
{{ (2 ** (ansible_loop.index + 1)) + (1 | random(start=0)) }}
{% endif %}
break_when: status == "on"
Hem_Mu
(Hem_Mu)
December 18, 2024, 1:17pm
12
Thank you, it seems I’ll need to handle it with Python in the current version.
1 Like
shertel
December 18, 2024, 1:23pm
13
bcoca
(Brian Coca)
December 18, 2024, 2:47pm
14
To clarify, delay
is constant across the retry/until loop, it is only templated at the start of the loop, not every iteration.
1 Like
Hem_Mu
(Hem_Mu)
December 19, 2024, 12:41am
15
Template expressions wrapped in {{ }}
appear to be evaluated only once.