# Using inventory variables from external inventory script to specify which other variables to use (like hiera)

**URL:** <https://forum.ansible.com/t/using-inventory-variables-from-external-inventory-script-to-specify-which-other-variables-to-use-like-hiera/24776>\
**Category:** Ansible Project\
**Created:** [June 20, 2017, 9:39pm UTC](https://forum.ansible.com/t/using-inventory-variables-from-external-inventory-script-to-specify-which-other-variables-to-use-like-hiera/24776 "2017-06-20T21:39:05Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![William\_Saxton](https://avatars.discourse-cdn.com/v4/letter/w/b3f665/32.png) [@William\_Saxton](https://forum.ansible.com/u/William_Saxton)\
**Post date:** [June 20, 2017, 9:39pm UTC](https://forum.ansible.com/t/using-inventory-variables-from-external-inventory-script-to-specify-which-other-variables-to-use-like-hiera/24776/1 "2017-06-20T21:39:05Z")

</div>

Our current configuration management system stores hostnames and attributes for each of our systems, including things like “project” and “site”. I’d like to use these attributes when determining which values to provision a system with using ansible, just like Puppet does with hiera.

Right now I have an external inventory script working pretty well. Here’s an example output:

_{_  
_“generic”: [“[swrgen1.example.com](http://swrgen1.example.com)”, “swrgen2. **example**.com”],_

_“\_meta”: {_  
_“hostvars”: {_  
_“swrgen1. **example**.com”: {_  
_“site”: “california”_  
_},_  
_“swrgen2. **example**.com”: {_  
_“site”: “newyork”_  
_}_  
_}_  
_}_  
_}_

What I’d like to do is for ansible to be able to override default variables if a site or project-based file exists that contains this variable. Right now, I have the following setup working:

# example\_playbook.yml

---

<div class="post-metadata">

**Author:** ![Dick\_Davies](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Dick\_Davies](https://forum.ansible.com/u/Dick_Davies)\
**Post date:** [June 21, 2017, 7:07pm UTC](https://forum.ansible.com/t/using-inventory-variables-from-external-inventory-script-to-specify-which-other-variables-to-use-like-hiera/24776/2 "2017-06-21T19:07:54Z")

</div>

I played around with 'flat file' variables and a dynamic inventory a while back;  
group variables seemed to override the inventory level ones.

YMMV, check the precedence levels for vars for the version of Ansible  
you're running.

---

<div class="post-metadata">

**Author:** ![William\_Saxton](https://avatars.discourse-cdn.com/v4/letter/w/b3f665/32.png) [@William\_Saxton](https://forum.ansible.com/u/William_Saxton)\
**Post date:** [June 21, 2017, 8:50pm UTC](https://forum.ansible.com/t/using-inventory-variables-from-external-inventory-script-to-specify-which-other-variables-to-use-like-hiera/24776/3 "2017-06-21T20:50:57Z")

</div>

Yeah, I’m currently playing around with exactly these things. I guess I’m looking for some best-practice guidance for how to handle this situation. I see a couple of ways people are handling these kinds of things…but none seem to be very elegant.

I’m trying to talk my team into using Ansible over Puppet because it, initially, seemed a lot easier to get started with. Now that I’m digging deep into this, though, Puppet is much easier when it comes to managing hierarchical data (via hiera).

---

<div class="post-metadata">

**Author:** ![Dick\_Davies](https://avatars.discourse-cdn.com/v4/letter/d/b9e5f3/32.png) [@Dick\_Davies](https://forum.ansible.com/u/Dick_Davies)\
**Post date:** [June 21, 2017, 10:12pm UTC](https://forum.ansible.com/t/using-inventory-variables-from-external-inventory-script-to-specify-which-other-variables-to-use-like-hiera/24776/4 "2017-06-21T22:12:20Z")

</div>

I don't think there's a One True Way, it really boils down to the team  
you're working  
with and what makes sense for them given the mix of environments  
they're managing.

Some people use one inventory for ALL their servers, if you need cross-site  
plays that might be necessary. If you're lucky enough to not need that...

Personally I'm a huge fan of one inventory per site. I think I posted  
it earlier,  
but the gist is this layout:

.  
├── california  
│ ├── group\_vars  
│ │ ├── all  
│ │ ├── group1  
│ │ └── group2  
│ └── hosts  
├── newyork  
│ ├── group\_vars  
│ │ ├── all  
│ │ ├── group1  
│ │ └── group2  
│ └── hosts  
└── site.yml

> \_\_\_ (other ad hoc playbooks etc. up at this level too)

Each playbook run just needs a '-i environment\_name' and you're set.

It works great if you run isolated environments (prod / dev / staging)  
which you want broad consistency between, but also are likely  
to have differences in number of servers, types of users with SSH access,  
levels of encryption, etc.

When it comes to setting vars, my general rule of thumb is to use  
as few 'tiers' of variables as possible, otherwise it gets messy and its  
hard to find where they're set. There are about a dozen places to set vars  
in Ansible, you don't need to use them all. Generally, I go with:

1. environment-wide globals in $inventory/group\_vars/all  
&nbsp;&nbsp;&nbsp;&nbsp;(I used to set them inline in static inventories, but group\_vars  
support yaml syntax  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;and it plays nicer with dynamic inventories)

2. roles have 'sane' defaults in $rolename/defaults/main.yml.  
&nbsp;&nbsp;&nbsp;&nbsp;Logfile paths, service account names, etc.  
&nbsp;&nbsp;&nbsp;&nbsp;If no sane default exists, that's where it is documented  
&nbsp;&nbsp;&nbsp;&nbsp;(via a commented out example var, with a suggestion where to set this).  
&nbsp;&nbsp;&nbsp;&nbsp;This is essentially the 'README' for the role.

3. $inventory/group\_vars/groupname - relevant to roles those  
&nbsp;&nbsp;&nbsp;&nbsp;groups are performing. Easy to 'cat' to see how e.g. preprods  
mongodb is setup.

4. host\_vars/hostname is a Last Resort, usually on brownfield  
&nbsp;&nbsp;&nbsp;&nbsp;sites to track inconsistencies.  
&nbsp;&nbsp;&nbsp;&nbsp;"ls \*/host\_vars/\*" returns a handy list of servers we probably  
need to rebuild.

In theory, this approach should mean diffing 2 inventory directories  
gives a good idea of what's different between them.  
I've built pretty complex stacks with  
this approach from a single site.yml and it can work really well.
