Answers: <p>You'll notice that <a href="https://docs.ansible.com/ansible/playbooks_best_practices.html#content-organization" rel="noreferrer">the official recommendations for directory layout</a> put all of the playbooks at the root level.  This is intentional, as Ansible doesn't handle other schemes well.</p>
  
  <p>You <em>can</em> 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.</p>
  
  <p>However, you seem to have more nesting than you should:</p>
  
  <pre><code>---
  - hosts:  aws_instance.jenkins-agents
    user:   ec2-user
    vars_files:
      - ../../../vars/main.yaml
      - ../../../vars/vault.yaml
    ...
  </code></pre>
  
  <p>Why are you navigating up <em>three</em> 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</p>
  
  <pre><code>---
  - hosts:  aws_instance.jenkins-agents
    user:   ec2-user
    vars_files:
      - ../vars/main.yaml
      - ../vars/vault.yaml
    ...
  </code></pre>
  
  <p>which is a much more minor change.</p>
  
  <hr>
  
  <p>Secondly, it's pretty rare that you actually want to use <code>vars_files</code>.  Most variables used in Ansible either vary based on the host (and thus should go in <code>group_vars</code>/<code>host_vars</code> in the project root) or are role-specific (and thus should go in <code>vars</code>/<code>defaults</code> in the role directory).  A few documentation links:</p>
  
  <ul>
  <li><a href="https://docs.ansible.com/ansible/intro_inventory.html#splitting-out-host-and-group-specific-data" rel="noreferrer">https://docs.ansible.com/ansible/intro_inventory.html#splitting-out-host-and-group-specific-data</a></li>
  <li><a href="https://docs.ansible.com/ansible/playbooks_roles.html#roles" rel="noreferrer">https://docs.ansible.com/ansible/playbooks_roles.html#roles</a></li>
  <li><a href="https://docs.ansible.com/ansible/playbooks_roles.html#role-default-variables" rel="noreferrer">https://docs.ansible.com/ansible/playbooks_roles.html#role-default-variables</a></li>
  </ul>
  
  <p>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:</p>
  
  <pre><code>- hosts: aws_instance.jenkins-agents
    roles:
      - ../roles/jenkins_agent
  </code></pre>
  
  <p>This gives you far more flexibility for re-use.</p>
  
  <p>And if you find yourself not wanting to use relative paths for roles, you can override <a href="https://docs.ansible.com/ansible/intro_configuration.html#roles-path" rel="noreferrer"><code>roles_path</code></a> in an <code>ansible.cfg</code> in the root directory where you run your Ansible commands from.</p>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-18T20:03:30.107Z
Answers: 2017-06-18T20:03:30.107Z
Answers: Xiong Chiamiov
Answers: <p>Since I can't comment on 030's answer yet (just opened an account), I'll answer here.</p>
  
  <p>Group vars directories are relative to the Ansible path.</p>
  
  <p>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.:</p>
  
  <pre><code>/pipeline/   # ansible playbooks are here
  /pipeline/roles
  /pipeline/group_vars
  </code></pre>
  
  <p>Then you can run something like</p>
  
  <pre><code>cd /pipeline
  ansible-playbook deploy_app.yml
  </code></pre>
  
  <p>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.</p>
  
  <p>You can take it a step further and set up separate group vars for each environment/location/etc:</p>
  
  <pre><code>/pipeline/prod/group_vars/all.yml
  /pipeline/dev/group_vars/all.yml
  </code></pre>
  
  <p>And run as follows using include-vars.</p>
  
  <p>ansible-playbook deploy_app.yml -i prod</p>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-19T09:05:06.187Z
Answers: 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.
Answers: Jiri Klouda
Answers: CC BY-SA 4.0
Answers: 2017-06-18T06:30:12.443Z
Answers: 2019-12-23T07:26:21.120Z
Answers: 2019-12-23T07:26:21.120Z
Answers: maplebird
Answers: <p>Ansible usually takes relative path according to <code>inventory_dir</code> &amp; <code>playbook_dir</code>:</p>
  <pre class="lang-yaml prettyprint-override"><code>- debug: var=inventory_dir
  - debug: var=playbook_dir
  </code></pre>
  
Answers: CC BY-SA 4.0
Answers: 2020-10-26T11:18:20.550Z
Answers: 2020-10-26T11:18:20.550Z
Answers: gavenkoa
Answers: <p>To avoid such issues, that is why there are <a href="http://docs.ansible.com/ansible/intro_inventory.html#hosts-and-groups" rel="nofollow noreferrer">Hosts and Groups in Ansible</a>.</p>
  
  <blockquote>
  <pre><code>/etc/ansible/group_vars/raleigh # can optionally end in '.yml', '.yaml', or '.json'
  /etc/ansible/group_vars/webservers
  /etc/ansible/host_vars/foosball
  </code></pre>
  </blockquote>
  
Answers: CC BY-SA 3.0
Answers: 2017-06-17T15:06:09.863Z
Answers: 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.
Answers: Mailo Světel
Answers: CC BY-SA 3.0
Answers: 2017-06-19T08:07:32.013Z
Answers: 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
Answers: 030
Answers: CC BY-SA 3.0
Answers: 2017-06-17T09:08:30.577Z
Answers: 2017-06-17T09:08:30.577Z
Answers: 030
Body: <p>I had already bunch of playbooks, so I started to organize them in <em>playbooks</em> dir. It cause there must be relative paths to vars files.</p>
  
  <p><strong>Actual playbook:</strong></p>
  
  <pre><code>---
  - hosts:  aws_instance.jenkins-agents
    user:   ec2-user
    vars_files:
      - ../../../vars/main.yaml
      - ../../../vars/vault.yaml
    ...
  </code></pre>
  
  <p>Is there any way to keep the dir structure, but avoid the lochness family (<code>../../../</code>)?</p>
  
  <p>I know for roles You can specify path to them, but I did not find anything similar for <em>vars_files</em></p>
  
  <p><strong>Project conditions:</strong></p>
  
  <ol>
  <li>We need to run the playbooks from the root of the project</li>
  <li>Both <em>vars</em> and <em>playbooks</em> dir are in root of the project</li>
  <li>This project doesn't have static inventory/hosts, but it is generated on the fly when You run some playbook</li>
  </ol>
  
Comments: CC BY-SA 3.0
Comments: 2017-06-15T14:34:00.323Z
Comments: Maybe you can use a variable for your relative part `../../../vars` ?
Comments: Tensibai
Tags: <ansible>
Title: Playbook without relative path to vars
UserDisplayName: Mailo Světel
ThreadText: # Playbook without relative path to vars
  
  (Asked by: username_0 on 2017-06-15)
  
  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
  
  **Tags:** ansible
  
  > **Comments:**
  > **username_1**: Maybe you can use a variable for your relative part `../../../vars` ?  
  
  ---
  
  ## 4 answers
  
  ### Answer by username_2 on 2017-06-18. Score: 7
  
  You'll notice that [the official recommendations for directory layout](https://docs.ansible.com/ansible/playbooks_best_practices.html#content-organization) 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:
  
  * <https://docs.ansible.com/ansible/intro_inventory.html#splitting-out-host-and-group-specific-data>
  * <https://docs.ansible.com/ansible/playbooks_roles.html#roles>
  * <https://docs.ansible.com/ansible/playbooks_roles.html#role-default-variables>
  
  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`](https://docs.ansible.com/ansible/intro_configuration.html#roles-path) in an `ansible.cfg` in the root directory where you run your Ansible commands from.
  
  
  ---
  
  ### Answer by username_3 on 2017-06-18. Score: 2
  
  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
  
  > **Comments:**
  > **username_4**: 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.  
  
  ---
  
  ### Answer by username_5 on 2020-10-26. Score: 1
  
  Ansible usually takes relative path according to `inventory_dir` & `playbook_dir`:
  
  ```yaml
  - debug: var=inventory_dir
  - debug: var=playbook_dir
  
  ```
  
  
  ---
  
  ### Answer by username_6 on 2017-06-17. Score: 1
  
  To avoid such issues, that is why there are [Hosts and Groups in Ansible](http://docs.ansible.com/ansible/intro_inventory.html#hosts-and-groups).
  
  > ```
  > /etc/ansible/group_vars/raleigh # can optionally end in '.yml', '.yaml', or '.json'
  > /etc/ansible/group_vars/webservers
  > /etc/ansible/host_vars/foosball
  >
  > ```
  
  > **Comments:**
  > **username_0**: 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.  
  > **username_6**: 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  
  
  ---
  
  