Question:
I’ve registered a variable in a play.
1 2 3 4 5 6 7 8 9 10 11 12 |
--- - hosts: 127.0.0.1 gather_facts: no connection: local sudo: no vars_files: - vars.yml tasks: - name: build load balancer os_load_balancer: net=mc_net ext_net=vlan3320 name=load_balancer protocol=HTTPS port=80 register: my_lb |
I can access that variable fine, until I make the request inside a role.
For example, in a separate role in the same run, I want to access that registered variable:
1 2 |
- debug: var=my_lb |
I get the following output:
1 2 |
{'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'my_lb' is undefined", 'failed': True} |
How can I access variables registered in a separate role, within the same play?
Edit for clarity of how things piece together:
1234567891011121314 Top Play-includes:- Sub play 1- registers variable foo- Sub play 2-includes:- sub play A- role 1- role 2- role 3- references variable foo in template- Sub play B- Sub play 3
Answer:
NB: This was written referring to Ansible 1.X. I suspect variable parsing and scoping has changed considerably with Ansible 2.0, so bear that in mind. I’ll try to update the answer if I get time (or maybe someone else will answer for v2.0!)
There are two options here. The simplest is to define the variables in your top-level playbook, then propagate them down into your various roles. You can either set these as simple vars, or use pre_tasks
to lookup / calculate values dynamically, e.g.
1 2 3 4 5 6 7 8 9 10 11 |
vars: foo_static: "value_bar" pre_tasks: - set_fact: foo_ncpu: "{{ ansible_processor_vcpus }}" roles: - {role: role1, role1_var1: "{{foo_static}}", role1_var2: "{{foo_ncpu}}" } - {role: role2, role2_var1: "{{foo_static}}", role2_var2: "{{foo_ncpu}}" } |
The second option requires that you add a task to whichever role you need to extract a variable from (though since all ansible roles are open-source, that should be easy enough). The trick is to use set_fact to export a variable as a ‘host_fact’, e.g.
1 2 3 4 |
- name: Export role1_varfoo to a 'host-fact' type variable set_fact: role1_varfoo: "{{ role1_varfoo }}" |
Which can then be accessed later like so:
1 2 3 |
vars: role2_varfoo: "{{ hostvars['myhost']['role1_varfoo']}}" |
As described in this bit of the ansible docs.
Note that if you always want to lookup the hostvars of the current machine you’re running commands on (without knowing what it’s actually called in the ansible hosts file), you can use the variable inventory_hostname
like so:
1 2 3 |
vars: role2_varfoo: "{{ hostvars[inventory_hostname]['role1_varfoo']}}" |
(Note lack of quote-marks, since it’s a variable, not a string-literal.)
Slightly awkward, but those combinations have met all my needs so far.