Specifying a base directory for resolving includes

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

I've done something similar using, -e "basedir=$ENV_BASEDIR", -e
"basedir=$(pwd)" or using vars_prompt.

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

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.

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.

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:

https://coderwall.com/p/ej_6da

Lorin

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 :wink:

~ Brice

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

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!

There’s already an issue filed for that:

https://github.com/ansible/ansible/issues/4246

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.

http://www.ansibleworks.com/docs/playbooks_variables.html#magic-variables-and-how-to-access-information-about-other-hosts

It will be easier when google reindexes.