6

I had already bunch of playbooks, so I started to organize them in playbooks dir. It cause there must be relative paths to vars files.

Actual playbook:

---
- hosts:  aws_instance.jenkins-agents
  user:   ec2-user
  vars_files:
    - ../../../vars/main.yaml
    - ../../../vars/vault.yaml
  ...

Is there any way to keep the dir structure, but avoid the lochness family (../../../)?

I know for roles You can specify path to them, but I did not find anything similar for vars_files

Project conditions:

  1. We need to run the playbooks from the root of the project
  2. Both vars and playbooks dir are in root of the project
  3. This project doesn't have static inventory/hosts, but it is generated on the fly when You run some playbook
  • 1
    Maybe you can use a variable for your relative part ../../../vars ? – Tensibai Jun 15 '17 at 14:34
5

You'll notice that the official recommendations for directory layout put all of the playbooks at the root level. This is intentional, as Ansible doesn't handle other schemes well.

You can put playbooks in a subdirectory, as you've started to do, but that will require (as you've already found) the use of relative paths from the playbooks to any other resources they use; Ansible uses the playbook path to start its search, that's just how it's written. For the most part, that's just what you get to deal with when you make the choice to move where playbooks live.

However, you seem to have more nesting than you should:

---
- hosts:  aws_instance.jenkins-agents
  user:   ec2-user
  vars_files:
    - ../../../vars/main.yaml
    - ../../../vars/vault.yaml
  ...

Why are you navigating up three directories? I'd expect a layout that's like the official one, but with one subfolder for playbooks; then you'd end up with just

---
- hosts:  aws_instance.jenkins-agents
  user:   ec2-user
  vars_files:
    - ../vars/main.yaml
    - ../vars/vault.yaml
  ...

which is a much more minor change.


Secondly, it's pretty rare that you actually want to use vars_files. Most variables used in Ansible either vary based on the host (and thus should go in group_vars/host_vars in the project root) or are role-specific (and thus should go in vars/defaults in the role directory). A few documentation links:

Personally, I think it's best to have as little as possible in your playbooks, but delegate everything out to roles. Here's an example entire playbook in your setup:

- hosts: aws_instance.jenkins-agents
  roles:
    - ../roles/jenkins_agent

This gives you far more flexibility for re-use.

And if you find yourself not wanting to use relative paths for roles, you can override roles_path in an ansible.cfg in the root directory where you run your Ansible commands from.

1

To avoid such issues, that is why there are Hosts and Groups in Ansible.

/etc/ansible/group_vars/raleigh # can optionally end in '.yml', '.yaml', or '.json'
/etc/ansible/group_vars/webservers
/etc/ansible/host_vars/foosball
  • This doesn't answer my question, but it is interesting idea to have the values let's say per group. The variables We have are mostly related to specific groups. Just the /etc variant would not work for us. I hope it'll be able to pick them up from the project. – Mailo Světel Jun 17 '17 at 15:06
  • It does not have to reside in the etc folder. If the hosts and groups vars dirs are located in ansible directory then it will work – 030 Jun 19 '17 at 8:07
1

Since I can't comment on 030's answer yet (just opened an account), I'll answer here.

Group vars directories are relative to the Ansible path.

You don't have to run Ansible from /etc/ansible. You can run it from ~/.hidden/directory/stuff if you wish. Just make sure to keep a directory structure. I.e.:

/pipeline/   # ansible playbooks are here
/pipeline/roles
/pipeline/group_vars

Then you can run something like

cd /pipeline
ansible-playbook deploy_app.yml

Which will read group vars from the pipeline/group_vars folder. Better to cd to your ansible root folder first since it looks for paths from the current folder you're in if it can't find them in default location (/etc/ansible), such that you can put your ansible.cfg in /pipeline without having to specify other command line arguments. You can also optionally define specific paths inside ansible.cfg as well.

You can take it a step further and set up separate group vars for each environment/location/etc:

/pipeline/prod/group_vars/all.yml
/pipeline/dev/group_vars/all.yml

And run as follows using include-vars.

ansible-playbook deploy_app.yml -i prod

Hope this helps.

  • I would recommend sorting the variables by groups, the only thing is that if you put your inventories into a subdirectory, you should put a symlink to group_vars and hosts_vars into the inventories subdirectory. – Jiri Klouda Jun 19 '17 at 9:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.