In Ansible, passing a variable from one playbook to another playbook is not a straight forward. (If the target hosts are different). We might need to get the variable value from one host and use that value against another host in some cases. This article will provide a solution to overcome this kind of tricky situation in Ansible.
Here are the scenarios of passing a variable from one playbook to another playbook or register a variable to persist between plays in Ansible.
- Two playbooks which target single host – In the same play
- Two playbooks which target different hosts – In the same play
Environment:
- Ansible Engine: 2.7
Register a variable to persist between plays in Ansible – Same target host:
Here are the master playbook contents which includes other two playbooks.
[root@ansible-server ~]# cat global.yaml --- # Combine multiple playbooks - import_playbook: test.play1.yaml - import_playbook: test.play2.yaml [root@ansible-server ~]#
Playbook contents: test.play1.yaml
In test.play1 playbook, we are registering new variable “PLAY1VAR” to use it in the second playbook.
--- - hosts: localhost gather_facts: false tasks: - name: Register a new value shell: echo "/etc/resolv.conf" register: PLAY1VAR - debug: msg="{{PLAY1VAR.stdout}}"
Playbook contents: test.play2.yaml
In test.play2 playbook, we are using “PLAY1VAR” to view the last line of the file content and registering the result in PLAY2_RESULTS variable.
---
- hosts: localhost
gather_facts: false
tasks:
- name: Echo the output - PLAY1 variable vaule
shell: cat "{{PLAY1VAR.stdout}}" |tail -1
register: PLAY2_RESULTS
- debug: msg="{{PLAY2_RESULTS.stdout}}"
Test our work:
[root@ansible-server ~]# ansible-playbook -i localhost global.yaml PLAY [localhost] ************************************************************ ******* TASK [Register a new value] ****************************** *************************** changed: [localhost] TASK [debug] ****************************** ****************************** ************* ok: [localhost] => { "msg": "/etc/resolv.conf" } PLAY [localhost] ****************************** ****************************** ********* TASK [Echo the output - PLAY1 variable vaule] ****************************** ****************************** *************************** changed: [localhost] TASK [debug] ****************************** ****************************** ************* ok: [localhost] => { "msg": "nameserver 192.168.3.2" } PLAY RECAP ****************************** ****************************** **************** localhost : ok=4 changed=2 unreachable=0 failed=0 [root@ansible-server ~]#
We have successfully passed the variable from one playbook to another playbook (It the target host is the same). We have got the desired results.
Register a variable to persist between plays in Ansible – Different Target Hosts
What will happen if the target hosts are different? I have modified the test.play2.yaml‘s target host and test.play1.yaml still points to localhost. Let me re-run the job to check the results.
[root@ansible-server ~]# ansible-playbook -i inventory_1 global.yaml PLAY [localhost] ************************************************************ ********** TASK [Register a new value] ****************************** ***************************** changed: [127.0.0.1] TASK [debug] ****************************** ****************************** *************** ok: [127.0.0.1] => { "msg": "/etc/resolv.conf" } PLAY [192.168.3.151] ****************************** ****************************** ****** TASK [Echo the output - PLAY1 variable vaule] ****************************** *********** fatal: [192.168.3.151]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'PLAY1VAR' is undefined\n\nThe error appears to have been in '/root/test.play2.yaml': line 6, column 6, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - name: Echo the output - PLAY1 variable vaule\n ^ here\n"} PLAY RECAP ****************************** ****************************** **************** 127.0.0.1 : ok=2 changed=1 unreachable=0 failed=0 192.168.3.151 : ok=0 changed=0 unreachable=0 failed=1 [root@ansible-server ~]#
The Ansible play failed due to an undefined variable (PLAY1VAR)in test.play2.yaml file. We have got the most common error – “The task includes an option with an undefined variable“.
Solution:
1. Make the changes on test.play1.yaml.Highlighted the changes.
--- - hosts: localhost gather_facts: false tasks: - name: Register a new value shell: echo "/etc/resolv.conf" register: PLAY1VAR - debug: msg="{{PLAY1VAR.stdout}}" - name: Register dummy host with variable add_host: name: "DUMMY_HOST" PLAY1VAR_NEW: " {{ PLAY1VAR.stdout }}"
2. Make the change like below on test.play2.yaml. Highlighted the changes.
--- - hosts: 192.168.3.151 gather_facts: false tasks: - name: Echo the output - PLAY1 variable vaule shell: cat {{ hostvars['DUMMY_HOST']['PLAY1VAR_NEW'] }} |tail -1 register: PLAY2_RESULTS - debug: msg="{{PLAY2_RESULTS.stdout}}"
3. Re-run the playbook and check the results.
[root@ansible-server ~]# ansible-playbook -i inventory_1 global.yaml PLAY [localhost] ************************************************************ TASK [Register a new value] ****************************** ******************* changed: [127.0.0.1] TASK [debug] ****************************** ****************************** ***& ok: [127.0.0.1] => { "msg": "/etc/resolv.conf" } TASK [add_host] ****************************** ****************************** * changed: [127.0.0.1] PLAY [192.168.3.151] ****************************** ************************** TASK [Echo the output - PLAY1 variable vaule] ****************************** ****************************** ****************** changed: [192.168.3.151] TASK [debug] ****************************** ****************************** ***** ok: [192.168.3.151] => { "msg": "nameserver 192.168.3.2" } PLAY RECAP ****************************** ****************************** ****** 127.0.0.1 : ok=3 changed=2 unreachable=0 failed=0 192.168.3.151 : ok=2 changed=1 unreachable=0 failed=0 [root@ansible-server ~]#
We have successfully carried the registered variable from one playbook to another on different target hosts.
Hope this article is informative to you! Share it! Be Sociable !!!
Rohit says
This playbook works if there is single host.. For group of host is there any way?
somasekhar says
Hi Lingeswaran,
I Would like to pass the variables from one playbook to another playbook. I have already did set_facts in A play, but I am unable to access those variables in B play. Please suggest me.
Regards,
Somasekhar D.
ikomrad says
How would you have a modifiable shared variable? Say each hosts adds 1 to the variable value, then at the end, you print the value.
it
hosts: all
vars:
global_variable: 0
tasks:
– name: increment variable
set_var:
global_variable: “{{ global_variable + 1 }}”
-debug: global_variable
except this won’t work as you’ll get a fresh instance of global_variable for each host. the output of debug will always be the same.
ideas?
Vasanthi says
Hi Lingeswaran,
Does the Different Target Hosts soln works if playbook1 execute on set of 6 hosts(h4-9) which are basically a cluster and the playbook2 execute on the same set of 6 hosts(h4-h9) and I want to use output variable(can be retrieved from any one of the hosts) from playbook1 as input variable in playbook2 (on all hosts).
Vasanthi says
No issues. I’ve tested and it is working fine for me in the above case.