ansible: accessing register variables from other plays within same playbook
Register variables, like facts, are per host. The values can differ depending on the machine. So you can only use host/ip defined in the inventory as key, not the group name. I think you have already knowed this, as you marked this in code snippet 1.
-
In the code snippet 2, the
set_fact
line (- set_fact: the_count=result.stdout
) actually set the keythe_count
to the text valueresult.stdout
, sinceresult.stdout
is treated as plain text, not a variable. If you want to treat it as a variable, you'd better use{{ result.stdout }}
. You can verify this via running the playbook with-v
option.Tasks:
- set_fact: the_content1=content.stdout
- set_fact: the_content2={{ content.stdout }}
Output:
TASK [set_fact] **************************************************************** ok: [192.168.1.58] => {"ansible_facts": {"the_content1": "content.stdout"}, "changed": false} TASK [set_fact] **************************************************************** ok: [192.168.1.58] => {"ansible_facts": {"the_content2": "hello world"}, "changed": false}
-
The
debug
module has two possible parameter:var
andmsg
. Thevar
parameter expect a variable name.- debug: var={{hostvars}}
In this line, first of all, Ansible extracts the value of
hostvars
, since it is enclosed with two brackets. Secondly, it tries to find a variable whose name is the value ofhostvars
, sincevar
parameter expects a variable name directly. That is why you see the following strange output. This means Ansible couldn't find a variable whose name is<ansible.vars.hostvars.HostVars object at 0x7f3b6602b290>
."<ansible.vars.hostvars.HostVars object at 0x7f3b6602b290>": "VARIABLE IS NOT DEFINED!"
You can use the following:
- debug: var=hostvars
- debug: msg={{hostvars}}
References:
- Register variables don't survive across plays with different hosts
- set_fact - Set host facts from a task
- debug - Print statements during execution
dot
Updated on June 13, 2022Comments
-
dot almost 2 years
I'm trying to access the variable called "count" from the first "play" in my playbook in the second playbook. I found some other posts here about the same issue and I thought I was following the right steps, but the code below is still failing.
The Code
- hosts: group1 tasks: - name: count registrations on primary node shell: psql -U widgets widgets -c 'SELECT COUNT(*) FROM location' -t register: count - debug: var=count.stdout - hosts: group2 tasks: #the line below works... # - debug: msg={{ hostvars['myserver1.mydomain.com']['count']['stdout'] }} # but this one fails - debug: msg={{ hostvars['group1']['count']['stdout'] }}
This produces the following output:
PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [myserver1.mydomain.com] TASK [count registrations on node] ************************************** changed: [myserver1.mydomain.com] TASK [debug] ******************************************************************* ok: [myserver1.mydomain.com] => { "count.stdout": " 2" } PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [myserver2.mydomain.com] TASK [debug] ******************************************************************* fatal: [myserver1.mydomain.com]: FAILED! => {"failed": true, "msg": "'ansible.vars.hostvars.HostVars object' has no attribute 'can_sip1'"} NO MORE HOSTS LEFT ************************************************************* [ERROR]: Could not create retry file 'playbooks/test.retry'. The error was: [Errno 13] Permission denied: 'playbooks/test.retry' PLAY RECAP *********************************************************************
myserver1.mydomain.com : ok=3 changed=1 unreachable=0 failed=0
myserver2.mydomain.com : ok=1 changed=0 unreachable=0 failed=1The other post that I referring to is found here: How do I set register a variable to persist between plays in ansible?
It's probably something simple, but I can't see where the bug lies. Thanks.
EDIT 1
I've also tried to use set_fact like this:
- hosts: group1 tasks: - name: count registrations on primary node shell: psql -U widget widget -c 'SELECT COUNT(*) FROM location' -t register: result - debug: var=result.stdout - set_fact: the_count=result.stdout - debug: var={{the_count}} - hosts: group2 tasks: - name: retrieve variable from previous play shell: echo hello - debug: var={{hostvars}}
The results I get are:
PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [myserver1.mydomain.com] TASK [count reg on primary] **************************************************** changed: [myserver1.mydomain.com] TASK [debug] ******************************************************************* ok: [myserver1.mydomain.com] => { "result.stdout": " 2" } TASK [set_fact] **************************************************************** ok: [myserver1.mydomain.com] TASK [debug] ******************************************************************* ok: [myserver1.mydomain.com] => { "result.stdout": " 2" } PLAY *************************************************************************** TASK [setup] ******************************************************************* ok: [myserver2.mydomain.com] TASK [retrieve variable from previous play] ************************************ changed: [myserver2.mydomain.com] TASK [debug] ******************************************************************* ok: [myserver2.mydomain.com] => { "<ansible.vars.hostvars.HostVars object at 0x7f3b6602b290>": "VARIABLE IS NOT DEFINED!" } PLAY RECAP ********************************************************************* myserver1.mydomain.com : ok=5 changed=1 unreachable=0 failed=0 myserver2.mydomain.com : ok=3 changed=1 unreachable=0 failed=0
So It looks like there are no objects in the hostvars...
EDIT 3
This is what the playbook looks like this morning.
- hosts: group1 tasks: - name: count reg on primary shell: psql -U widgets widgets -c 'SELECT COUNT(*) FROM location' -t register: result - debug: var=result.stdout - set_fact: the_count={{result.stdout}} - debug: var={{the_count}} - hosts: group2 tasks: - name: retrieve variable from previous play shell: echo hello - debug: var={{hostvars}}
The "debug: var={{the_count}}" line from the first play prints out the correct value for the count but it also says the VARIABLE IS NOT DEFINED... like so:
TASK [set_fact] **************************************************************** task path: /etc/ansible/playbooks/test.yml:8 ok: [myserver1.mydomain.com] => {"ansible_facts": {"the_count": " 2"}, "changed": false, "invocation": {"module_args": {"the_count": " 2"}, "module_name": "set_fact"}}
TASK [debug] ******************************************************************* task path: /etc/ansible/playbooks/test.yml:10 ok: [myserver1.mydomain.com] => { " 2": "VARIABLE IS NOT DEFINED!" }
And then once I hit the second play, I still get the message
TASK [debug] ******************************************************************* task path: /etc/ansible/playbooks/test.yml:16 ok: [myserver2.mydomain.com] => { "<ansible.vars.hostvars.HostVars object at 0x7fb077fdc310>": "VARIABLE IS NOT DEFINED!" }
In your example, you are suggestion that I use "debug: var={{hostlers}}". If you can clarify that for me please. It looks like it's a typo.
EDIT 4:
If you take a look at Edit 3 carefully, you will see that I have implemented "debug:var={{hostvars}}" as you suggest in your answer. But it gives me the same error that the variable is not defined. I'm not just trying to pass variables from one play to another.. but from one set of hosts to another. Notice how play 1 uses group1 and play two applies only to group2.
-
longhua about 8 years@dot The error message in your edit 3 means Ansible tries to lookup a variable whose name is
2
, however it doesn't exist. Would you please check my answer #3? Thevar
parameter fordebug
expects a variable name in plain text. And{{the_count}}
provides the value2
ofthe_count
variable. So Ansible tries to lookup a variable with the name2
. -
longhua about 8 years@dot I am sorry I meant to use msg parameter of debug module.
-
dot about 8 yearsit's okay. would you be able to chat for a few minutes instead of going back and forth here?