Reputation: 846
My inventory file looks like below.
[host-group-1]
x.x.x.1
x.x.x.2
[host-group-2]
x.x.x.3
x.x.x.4
Now I want to select and perform tasks on these groups based on the parameter return by a script. The playbook looks below.
---
- host: 127.0.0.1
tasks:
- name: something
local_action: /home/script.py
register: result
- host: host-group-1:host-group-2
task: ?????????
Here on the 2nd task I want something like if result== yes perform the task on host-group-1 and if result==no perform the task host-group-2
Please help me here.
Upvotes: 2
Views: 4376
Reputation: 23881
The following example shows how to use Jinja in a playbook. Most people use only Jinja expressions {{ ... }}
. But if you need to do more complicate tasks, it is also possible to use Jinja statements {% ... %}
. But a statement has no return value. So you have to end with an expression, if you want to return a value to the set_fact
task.
---
- name: Get group
hosts: localhost
connection: local
tasks:
- shell: |-
echo {{ say }}
register: group
ignore_errors: true
changed_when: false
- set_fact:
group: >-
{% if group.stdout == "yes" -%}
{% set group = "host-group-1" -%}
{% elif group.stdout == "no" -%}
{% set group = "host-group-2" -%}
{% else -%}
{% set group = "" -%}
{% endif -%}
{{ group }}
- hosts: "{{ hostvars.localhost.group }}"
tasks:
- debug: var=group
If you run the playbook with yes
it used the first group. The debug action is skipped, because I have not specified an inventory file.
$ ansible-playbook if.yml --extra-vars say=yes
PLAY [Get group] *****************************************************************************
TASK [command] *******************************************************************************
ok: [localhost]
TASK [set_fact] ******************************************************************************
ok: [localhost]
PLAY [host-group-1] **************************************************************************
skipping: no hosts matched
PLAY RECAP ***********************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
And if you run it with no
it uses the second group.
$ ansible-playbook if.yml --extra-vars say=no
PLAY [Get group] *****************************************************************************
TASK [command] *******************************************************************************
ok: [localhost]
TASK [set_fact] ******************************************************************************
ok: [localhost]
PLAY [host-group-2] **************************************************************************
skipping: no hosts matched
PLAY RECAP ***********************************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
Some hints about shell scripts:
Whenever the return value of a shell script is not zero, Ansible treats this as an error. This breaks your Ansible run. If you want to handle any error in your Ansible code your have to ignore the error with ignore_errors: true
.
Each shell script is treated as change, because Ansible has no understand, what the shell code does. And because it might change something, Ansible treats it always as a change. If you just collect information on your local host, this is no change at all. So it is necessary to tell Ansible that the code does not change anything with changed_when: false
.
A hint how Ansible stores information:
Ansible's internal data structure is one big messy global variable, which is called hostvars
. Ansible has virtually no kind of scope, which makes nested loops challenging (but this is another topic). All results of tasks are stored in this single global monster hash variable with the name of the host as a key. Whatever you run on localhost
is stored in hostvars.localhost
. Every host has full access to the data of each other host. This makes it possible to collect information in localhost to use it later in the task working on other hosts.
btw. I have no idea, why you got so many down votes. I think this is not a trivial question.
Upvotes: 4