---
- hosts: "{{ run_on_node|default('mysql_cluster_sql[0]')}}"
connection: "{% if migrated is defined and migrated == 'yes' %}local{% else %}ssh{% endif %}" # This works as we are assigning non boolean value
gather_facts: "{% if migrated is defined and migrated == 'yes' %}false{% else %}true{% endif %}" #This doesnt work well
tasks:
- debug: var=ansible_all_ipv4_addresses
- debug: var=ansible_default_ipv4.address
Inventory File:
[mysql_cluster_sql]
10.200.1.191 migrated=yes
The variable has the value as true and false based on condition but even when gather_facts is false, it gathers the facts.
The when clause is a raw Jinja2 expression without double curly braces (see group_by_module). When you run the task or playbook, Ansible evaluates the test for all hosts. On any host where the test passes (returns a value of True), Ansible runs that task.
You can define these variables in your playbooks, in your inventory, in re-usable files or roles, or at the command line. You can also create variables during a playbook run by registering the return value or values of a task as a new variable.
Ansible facts are data gathered about target nodes (host nodes to be configured) and returned back to controller nodes. Ansible facts are stored in JSON format and are used to make important decisions about tasks based on their statistics. Facts are in an ansible_facts variable, which is managed by Ansible Engine.
In Ansible, facts gathering is essentially an unwritten task. When it is turned on (the default) at the start of each play, each host will get a task to gather facts from it.
This module takes care of executing the configured facts modules, the default is to use the ansible.builtin.setup module. This module is automatically called by playbooks to gather useful variables about remote hosts that can be used in playbooks. It can also be executed directly by /usr/bin/ansible to check what variables are available to a host.
The simplest conditional statement applies to a single task. Create the task, then add a when statement that applies a test. The when clause is a raw Jinja2 expression without double curly braces (see group_by_module ). When you run the task or playbook, Ansible evaluates the test for all hosts.
When you run the task or playbook, Ansible evaluates the test for all hosts. On any host where the test passes (returns a value of True), Ansible runs that task. For example, if you are installing mysql on multiple machines, some of which have SELinux enabled, you might have a task to configure SELinux to allow mysql to run.
Simplify and fix the condition. Use the default value. This will cover both tests, e.g.
shell> cat pb.yml
- hosts: localhost
gather_facts: "{{ (migrated|default('no') == 'yes')|ternary(false, true) }}"
tasks:
- meta: noop
will gather facts without the variable migrated defined
shell> ansible-playbook pb.yml
PLAY [localhost] ********************************************************
TASK [Gathering Facts] **************************************************
ok: [localhost]
, or when the variable is set to other value than 'yes'
shell> ansible-playbook pb.yml -e migrated=no
PLAY [localhost] ********************************************************
TASK [Gathering Facts] **************************************************
ok: [localhost]
When the variable is set to 'yes' no facts will be gathered
shell> ansible-playbook pb.yml -e migrated=yes
PLAY [localhost] ********************************************************
PLAY RECAP **************************************************************
Jinja
If you insist on Jinja the playbook below gives the same results
shell> cat pb.yml
- hosts: localhost
gather_facts: "{% if migrated|default('no') == 'yes' %}
false
{% else %}
true
{% endif %}"
tasks:
- meta: noop
Boolean
You can further simplify the test by explicit conversion to Boolean, e.g.
- hosts: localhost
gather_facts: "{{ (migrated|default('no')|bool)|ternary(false, true) }}"
tasks:
- meta: noop
Truthy/Falsy
Make sure you understand how Boolean conversion and testing work. See results of the tasks
- debug:
msg: "True"
loop: [yes, Yes, true, True, xxx]
when: item|bool
- debug:
msg: "False"
loop: [no, No, false, False, xxx]
when: not item|bool
- debug:
msg: "{{ item|bool|ternary(True, False) }}"
loop: [yes, Yes, true, True, xxx,
no, No, false, False, xxx]
- debug:
msg: "{{ item|ternary(True, False) }}"
loop: [yes, Yes, true, True, xxx,
no, No, false, False, xxx]
Q: "Passing the variable 'migrated' from within the inventory does not work."
A: You're right. It seems that the inventory variables are not available at the time gather_facts is running. Use setup as a workaround. For example
- hosts: localhost
gather_facts: false
tasks:
- setup:
when: (migrated|default('no')|bool)|ternary(false, true)
gather_facts
will be evaluted before the play loop has started so ansible cannot know which group/host var it should load in this case. The problem is exactly the same for the connection
attribute.
I only see one way to fulfill your requirement by gathering facts explicitly and setting the connection for each host. Ini format does not play well with this for the inventory so I transformed to yaml. I also modified your default hosts
expression in playbook so that it directly get the host name from inventory. You can keep yours if it suits your needs if you wish.
Inventory:
---
all:
children:
mysql_cluster_sql:
hosts:
10.200.1.191:
migrated: yes
vars:
ansible_connection: "{{ migrated | default(false) | bool | ternary('local', 'ssh') }}"
Playbook:
---
- hosts: "{{ run_on_node | default(groups['mysql_cluster_sql'][0]) }}"
gather_facts: false
tasks:
- name: gather_facts if not migrated
setup:
when: not (migrated | default(false) | bool)
- debug:
var: ansible_all_ipv4_addresses
- debug:
var: ansible_default_ipv4.address
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