# Importing user variables from multiple variable sources

**URL:** <https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788>\
**Category:** Ansible Project\
**Tags:** rhel\
**Created:** [February 27, 2019, 3:15pm UTC](https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788 "2019-02-27T15:15:58Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Suhail\_Choudhury](https://avatars.discourse-cdn.com/v4/letter/s/74df32/32.png) [@Suhail\_Choudhury](https://forum.ansible.com/u/Suhail_Choudhury)\
**Post date:** [February 27, 2019, 3:15pm UTC](https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788/1 "2019-02-27T15:15:58Z")

</div>

Hi,

I want to know how I can import user account variables at multiple levels using loops/arrays and importing them all.

i.e. i have a generic module which has users defined in roles/common/tasks/main.yml as an array(or loop if more precise):

- name: add admin users on RHEL  
user:  
name: “{{ item.username }}”  
comment: “{{ item.comment }}”  
state: present  
groups: wheel  
shell: /bin/bash  
password: “{{ item.password }}”  
with\_items: “{{ users }}”  
when: ansible\_facts[“os\_family”] == “RedHat”  
tags: common

and the user attributes are all set as variables and the variables for these users are being picked up from roles/common/vars/main.yml

I also have user variables defined under group\_vars/dev and group\_vars/prd

And I also have specific users defined at host level under host\_vars/server1

Now the problem is that Ansible is only picking up users from one level, whilst I want to pick up all the user variables from all levels, i.e. sysadmins, dev users & specific host users, and add them all in, not just from the most preferred variable source.

In Puppet this is achieved by using Hiera and “hiera\_hash” which allows variable values to get collectively applied from all hiera levels.

How can the same be achieved with Ansible please?

Regards,  
Suhail.

---

<div class="post-metadata">

**Author:** ![Suhail\_Choudhury](https://avatars.discourse-cdn.com/v4/letter/s/74df32/32.png) [@Suhail\_Choudhury](https://forum.ansible.com/u/Suhail_Choudhury)\
**Post date:** [February 28, 2019, 10:08am UTC](https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788/2 "2019-02-28T10:08:40Z")

</div>

Has anyone come across this before? Surely it must be a common ask.

---

<div class="post-metadata">

**Author:** ![Adam\_E](https://avatars.discourse-cdn.com/v4/letter/a/c68b51/32.png) [@Adam\_E](https://forum.ansible.com/u/Adam_E)\
**Post date:** [March 3, 2019, 12:25am UTC](https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788/3 "2019-03-03T00:25:45Z")

</div>

I have a similar issue and solved it by this PR [https://github.com/ansible/ansible/pull/51466](https://github.com/ansible/ansible/pull/51466) . if you want to use it, just grab the source code and add it to your local library directory until it's merged. Also see this thread [https://groups.google.com/forum/?utm\_medium=email&utm\_source=footer#!msg/ansible-project/Ssnk6exNjNs/sCKlrOp\_FQAJ](https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/ansible-project/Ssnk6exNjNs/sCKlrOp_FQAJ)

With the approach above, the code would merge together all lists that match a pattern, this way you can defined as many "users" variables as you want as long as they are unique and start with say "users\_"

If you don't want to copy the library or wait for the PR, then you could also just merge a set of predefined lists.

ie..  
with\_items: "{{ users\_host|default() + users\_group\_l1|default() + users\_group\_l2|default([[) }}"

---

<div class="post-metadata">

**Author:** ![Suhail\_Choudhury](https://avatars.discourse-cdn.com/v4/letter/s/74df32/32.png) [@Suhail\_Choudhury](https://forum.ansible.com/u/Suhail_Choudhury)\
**Post date:** [March 21, 2019, 11:58am UTC](https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788/4 "2019-03-21T11:58:58Z")

</div>

Thanks for your earlier reply Adam.

So how can I combine variables for a list of “users” defined like so:

group\_vars/all

users:

- name: alice  
comment: Alice

group\_vars/group1

users:

- name: bob  
comment: Bob

host\_vars/host1

users:

- name: charlie  
comment: Charlie

How can all these variables be combined using “loop” or “with\_items”?  
What if there are duplicates?  
Can the “host\_vars/host1” variables override and take precedence over the “group\_vars/all” variables?

Regards,  
Suhail.

---

<div class="post-metadata">

**Author:** ![Kai\_Stian\_Olstad](https://avatars.discourse-cdn.com/v4/letter/k/e19adc/32.png) [@Kai\_Stian\_Olstad](https://forum.ansible.com/u/Kai_Stian_Olstad)\
**Post date:** [March 21, 2019, 6:49pm UTC](https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788/5 "2019-03-21T18:49:52Z")

</div>

> Thanks for your earlier reply Adam.
> 
> So how can I combine variables for a list of "users" defined like so:
> 
> \*group\_vars/all\*
> 
> users:  
> &nbsp;&nbsp;&nbsp;- name: alice  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comment: Alice
> 
> \*group\_vars/group1\*
> 
> users:  
> &nbsp;&nbsp;&nbsp;- name: bob  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comment: Bob
> 
> \*host\_vars/host1\*
> 
> users:  
> &nbsp;&nbsp;&nbsp;- name: charlie  
> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;comment: Charlie
> 
> How can all these variables be combined using "loop" or "with\_items"?

You can't, they will be overwritten in the order listed here  
[https://docs.ansible.com/ansible/latest/user\_guide/playbooks\_variables.html#variable-precedence-where-should-i-put-a-variable](https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable)

> What if there are duplicates?

They are duplicates since all are call users and will be overwritten.

> Can the "host\_vars/host1" variables override and take precedence over the  
> "group\_vars/all" variables?

It does.

---

<div class="post-metadata">

**Author:** ![Suhail\_Choudhury](https://avatars.discourse-cdn.com/v4/letter/s/74df32/32.png) [@Suhail\_Choudhury](https://forum.ansible.com/u/Suhail_Choudhury)\
**Post date:** [March 21, 2019, 7:06pm UTC](https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788/6 "2019-03-21T19:06:48Z")

</div>

Hi.

Thanks for reply Kai.

Default Ansible cannot solve this problem, which I find very odd as it  
was a common issue that is very elegantly addressed in Pupept using  
Hiera.

However.... a solution has been found!

Have a look at:

[http://leapfrogonline.io/articles/2017-02-22-explicit-merging-of-ansible-variables/](http://leapfrogonline.io/articles/2017-02-22-explicit-merging-of-ansible-variables/)  
[https://github.com/leapfrogonline/ansible-merge-vars](https://github.com/leapfrogonline/ansible-merge-vars)

They have solved exactly this issue and I'm testing their plugin and  
so far so good. Certainly not as elegant as Puppet/Hiera but it's a  
working solution.

Regards,  
Suhail.

---

<div class="post-metadata">

**Author:** ![Adam\_E](https://avatars.discourse-cdn.com/v4/letter/a/c68b51/32.png) [@Adam\_E](https://forum.ansible.com/u/Adam_E)\
**Post date:** [March 21, 2019, 7:32pm UTC](https://forum.ansible.com/t/importing-user-variables-from-multiple-variable-sources/29788/7 "2019-03-21T19:32:21Z")

</div>

another alternative if you don’t want to use an external plugin is to predefine your variable names and then combine them…

ie…

> users\_global

> users\_group

> users\_host (variable you set in host\_vars)

and then use the “[combine](https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#combining-hashes-dictionaries)” filter to combine them together .  
ie…

> users\_global | combine(users\_group, recursive=True) | combine(users\_host, recursive=True)

I agree though, I am also coming from puppet and miss hiera. I may still consider going back to using it as there appears to be [support](https://docs.ansible.com/ansible/latest/plugins/lookup/hiera.html) for it, but it would be nice to be fully integrated

The strategy I ended up going with for the similar problem you have is

1. I created a “users” hash in vars/ which contains all users that can be managed
2. then in my host & group\_vars I populate a list such as “linux\_users\_global” or linux\_users\_unique\_name which contains the list of users that should be managed either globally, group or at the host level
3. then in my playbook I merge all the variables that match the pattern “linux\_users.\*” . (see this [link](https://docs.ansible.com/ansible/devel/plugins/lookup/varnames.html))
4. then I loop through that merged list and manage those users

for me, the above solution works quite well.
