Specifying a base directory for resolving includes

3,185 views
Skip to first unread message

Lorin Hochstein

unread,
Feb 6, 2013, 12:21:36 PM2/6/13
to ansible...@googlegroups.com
Does ansible have any mechanism for specifying a base directory for including things like variable files, playbooks, and tasks?

Here's my use case: 

We keep our playbooks in a git repository called "ansible-playbooks". Anyone with admin privileges should be able to clone this repo and run the ansible playbooks. Because a git repo can be cloned to anywhere, we can't use absolute paths for things like vars_files and playbook includes. So we end up using relative paths, e.g. I have a playbook in ansible-playbooks/django/setup.yaml that has:

# Reconfigure nginx if needed
- include: ../nginx/setup.yaml

The problem with these relative includes is that they're brittle. If I move the ansible-playbooks/django/setup.yaml to ansible-playbooks/setup.yaml or ansible-playbooks/django/foo/setup.yaml, the relative include will break. I'd prefer to be able to do something like:

# Reconfigure nginx if needed
- include: $basedir/nginx/setup.yaml

This would also make it easier to find and replace import statemetns if I change the location of nginx/setup.yaml.

The problem is: how do I define basedir? I could make everyone write their own local.yaml file that contains something like:

basedir: /Users/lorin/ansible-playbooks

And then I'd include local.yaml in all of my plays:

vars_files:
  - ../local.yaml

Is there a better way of doing this?  In particular, is there a way to do this that would not require somebody editing a local.yaml file? 


Take care,

Lorin

Brian Coca

unread,
Feb 6, 2013, 1:14:29 PM2/6/13
to ansible...@googlegroups.com
I've done something similar using, -e "basedir=$ENV_BASEDIR", -e
"basedir=$(pwd)" or using vars_prompt.

--
Brian Coca
Stultorum infinitus est numerus
0110000101110010011001010110111000100111011101000010000001111001011011110111010100100000011100110110110101100001011100100111010000100001
Pedo mellon a minno

Brian Coca

unread,
Feb 6, 2013, 1:17:38 PM2/6/13
to ansible...@googlegroups.com
I might also note, I have a Makefile in the config repo that does this
for people so they just need to: git checkout config && cd config &&
make

Tin Tvrtković

unread,
Feb 6, 2013, 3:34:37 PM2/6/13
to ansible...@googlegroups.com
I haven't looked into this, but I will be facing a similar problem at work soon. Basically, we want to produce a number of general purpose playbooks (for Postgres, JBoss, etc) for company-wide, general purpose tasks. We'd like these playbooks to be usable by themselves, and for individual projects to be able to include these playbooks in their custom playbooks. These playbooks will probably have accompanying files (configuration templates and the like).

As I said, we haven't gotten there quite yet, but I'm interested in the best approach.

Brice Burgess

unread,
Feb 15, 2013, 4:57:44 PM2/15/13
to ansible...@googlegroups.com
Hi Lorin. We use ansible scripts checked out from a git repository named `SysOps`. I include a global_vars.yml file in each playbook -- we use a similar structure to the one outlined in the Ansible Best Practices section; http://ansible.cc/docs/bestpractices.html

In this file I set the base dir (named "automation_home" by piping `pwd` to grep). e.g.

---
automation_home: $PIPE(pwd | grep -Po '(.*)/SysOps/automation')

NOTES:
  1. For this to work the ansible/ansible-playbook command MUST be run from a path within the repositories automation folder. E.g. I must call ansible-playbook from /home/brice/SysOps/automation/ ..  e.g. `cd /home/brice/SysOps/automation/deployment && ansible-playbook test.yml`

  2. I've heard reports that Mac OS X's `grep` command no longer accepts perl regular expressions. Use sed or awk as a substitute(??)

Hope this helps.

~ Brice

Lorin Hochstein

unread,
Feb 15, 2013, 8:49:10 PM2/15/13
to ansible...@googlegroups.com
Hi Brice:

Using $PIPE() is a clever idea. Note that if your playbooks are in a git repository, you can use "git rev-parse --show-toplevel" to get the root of the repository.

I just wrote up a coderwall tip on this:



Lorin


--
You received this message because you are subscribed to the Google Groups "Ansible Project" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ansible-proje...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--
Lorin Hochstein
Lead Architect - Cloud Services
Nimbis Services, Inc.

Brice Burgess

unread,
Feb 20, 2013, 1:45:56 PM2/20/13
to ansible...@googlegroups.com
Lorin,

That's a better approach, as sometimes people (like myself!) checkout the git repo into a directory they explicitly name, which would cause the grep command to fail. Nice work.

I guess use the grep command as a "backup approach" for those who do not keep their scripts in a git repository.

I do still wonder if there's an "ansible way" for this -- but the PIPE has been working great thus far ;)

~ Brice

Brice Burgess

unread,
Oct 9, 2013, 5:57:33 PM10/9/13
to ansible...@googlegroups.com
It has been awhile, and I'm trying to now register the base directory in Ansible 1.3 fashion;

My initial attempt failed (YAML parse failure). The command is:
  echo `pwd` | sed 's/\(.*\)\/automation.*/\1/'

Using the pipe lookup inside an ansible 1.3 variable file it, it looks like:
  sysops_home: "{{ lookup('pipe_once','echo `pwd` | sed \'s/\(.*\)\/automation.*/\1/\'') }}"

I have tried a combination quotes and escaping sequences, but can't seem to get passed the YAML. Sed needs to use quotes, the lookup plugin needs quotes, and the variable registration seems to need quotes as well (e.g.)
  sysops_home_without_quotes: {{ ... }}  [ does not work ]

Any ideas?

In any case I think this approach may be backwards and perhaps I can rewrite things to use a common role with relative includes. Is there a magic variable/lookup plugin which will output the directory a role or playbook file resides within?

Thanks!

~ Brice

Michael DeHaan

unread,
Oct 9, 2013, 6:49:28 PM10/9/13
to ansible...@googlegroups.com
As far as I can recall, there isn't a playbook_basedir variable.

There's an inventory_basedir, and an inventory_file.

I might be mistaken, but patches would be considered!



Michael DeHaan <mic...@ansibleworks.com>
CTO, AnsibleWorks, Inc.
http://www.ansibleworks.com/

Serge van Ginderachter

unread,
Oct 10, 2013, 3:19:48 AM10/10/13
to ansible...@googlegroups.com
There's already an issue filed for that:

Miguel Pontes

unread,
Oct 10, 2013, 11:24:47 AM10/10/13
to ansible...@googlegroups.com
Had this exact same problem today, inventory_dir works just fine for my purposes, though, since I keep the inventory files on the root of the playbooks repo.

Is there any place that lists all ansible variables, though? I find myself trawling the web / source code for variables that might or might not already exist in ansible somewhat blindly. The setup module is only useful to find the ansible_ vars, not other hidden gems like that.

Michael DeHaan

unread,
Oct 10, 2013, 8:12:38 PM10/10/13
to ansible...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages