Is there a possibility to unset a fact (variable) in Ansible?
Unset in such a way that the check is defined fails.
For execution decisions I regularly check conditions with is defined. However, it may be necessary to unset these before execution, e.g. if a role is used multiple times via include_role or tasks are used multiple times via include_tasks.
Is there a special syntax for this, e.g. to use the set_fact module?
If I understood it correctly, meta: clear_facts takes care of clearing all facts and cannot be restricted to individual ones.
WARNING: vars: on an include_* are considered include params
See:
Variable precedence: Where should I put a variable?
Modified "vars:" not visible inside include_role
include params from the list of variable precedence list has no examples
For example, the vars: below is not task vars (precedence 17.). It is include params (precedence 21.). As a result, potential set_facts (precedence. 19) inside the role will not override the variable test_var
- include_role:
name: test_role
vars:
test_var: first run
Use apply if you want to provide task vars (precedence 17.) to a role
- include_role:
name: test_role
apply:
vars:
test_var: first run
This hasn't been documented yet.
Q: "Is there a possibility to unset a fact (variable) in Ansible?"
A: No. It is not possible to unset variables in Ansible. Instead, it's possible to define variables in various scopes. Such variables won't be defined above the particular scope. See Playbook Keywords. You can define variables in this hierarchy of scopes
There are various scenarios on how to solve the use cases: "It may be necessary to unset variables before execution, e.g. if a role is used multiple times via include_role or tasks are used multiple times via include_tasks."
For example, create a role
shell> tree roles/
roles/
└── test_role
└── tasks
└── main.yml
with the single task
shell> cat roles/test_role/tasks/main.yml
- debug:
var: test_var
Use case 1. A role is used multiple times via include_role
For example, the playbook
- hosts: localhost
tasks:
- include_role:
name: test_role
vars:
test_var: first run
- include_role:
name: test_role
- include_role:
name: test_role
vars:
test_var: third run
gives (abridged)
test_var: first run
test_var: VARIABLE IS NOT DEFINED!
test_var: third run
Use case 2. Tasks are used multiple times via include_tasks
In the same way, the playbook below gives the same result
- hosts: localhost
tasks:
- include_tasks: roles/test_role/tasks/main.yml
vars:
test_var: first run
- include_tasks: roles/test_role/tasks/main.yml
- include_tasks: roles/test_role/tasks/main.yml
vars:
test_var: third run
Use case 3. Use roles
The playbook below gives also the same result
- hosts: localhost
roles:
- role: test_role
test_var: first run
- role: test_role
- role: test_role
test_var: third run
Notes
See Variable Scopes
It's good to understand what will happen when you declare an empty variable. For example, the playbook
- hosts: localhost
vars:
test_var: default_value
tasks:
- debug:
var: test_var
- set_fact:
test_var:
- debug:
msg: "test_var is defined: {{ test_var is defined }}"
- debug:
var: test_var
shows (abridged) that an empty variable is defined and null. You will receive the same results when you set the variable explicitly to null by test_var: !!null
TASK [debug] **********************************************************************************************
ok: [localhost] =>
test_var: default_value
TASK [set_fact] *******************************************************************************************
ok: [localhost]
TASK [debug] **********************************************************************************************
ok: [localhost] =>
msg: 'test_var is defined: True'
TASK [debug] **********************************************************************************************
ok: [localhost] =>
test_var: null
- debug:
var: test_var
- debug:
var: test_var|default('default when undef')
shows that the filter default doesn't by default cares the value is null and doesn't set the value because the variable is defined
TASK [debug] **********************************************************************************************
ok: [localhost] =>
test_var: null
TASK [debug] **********************************************************************************************
ok: [localhost] =>
test_var|default('default when undef'): ''
True. For example, - debug:
var: test_var
- debug:
var: test_var|default('default when undef or null', true)
gives
TASK [debug] **********************************************************************************************
ok: [localhost] =>
test_var: null
TASK [debug] **********************************************************************************************
ok: [localhost] =>
test_var|default('default when undef or null', true): default when undef or null
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With