Naftuli Kay
Naftuli Kay

Reputation: 91830

Resolve Local Files by Playbook Directory?

I have the following Ansible role which simply does the following:

  1. Create a temporary directory.
  2. Download Goss, a server testing tool, into that temporary directory.
  3. Upload a main Goss YAML file for the tests.
  4. Upload additional directories for additional included tests.

Here are a couple places where I'm using it:

Specifically, these playbooks upload a local file adjacent to the playbook named goss.yml and a directory goss.d again adjacent to the playbook.

Unfortunately, it seems that Ansible logic has changed recently, causing my tests to not work as expected. My role ships with a default goss.yml, and it appears that when I set goss_file: goss.yml within my playbook, it uploads degoss/files/goss.yml instead of the Goss file adjacent to my playbook.

If I'm passing the name of a file to a role, is there a way to specify that Ansible should look up the file in the context of the playbook or the current working directory?

The actual role logic that is no longer working is this:

# deploy test files including the main and additional test files
- name: deploy test files
  copy: src={{ item }} dest={{ degoss_test_root }} mode=0644 directory_mode=0755 setype=user_tmp_t
  with_items: "{{ [goss_file] + goss_addtl_files + goss_addtl_dirs }}"
  changed_when: degoss_changed_when

I am on Ansible 2.3.2.0 and I can reproduce this across distributions (namely CentOS 7, Ubuntu 14.04, and Ubuntu 16.04).

Upvotes: 1

Views: 3372

Answers (1)

Konstantin Suvorov
Konstantin Suvorov

Reputation: 68329

Ansible searches for relative paths in role's scope first, then in playbook's scope.

For example if you want to copy file test.txt in role r1, search order is this:

/path/to/playbook/roles/r1/files/test.txt
/path/to/playbook/roles/r1/test.txt
/path/to/playbook/roles/r1/tasks/files/test.txt
/path/to/playbook/roles/r1/tasks/test.txt
/path/to/playbook/files/test.txt
/path/to/playbook/test.txt

You can inspect your search_path order by calling ansible with ANSIBLE_DEBUG=1.

To answer your question, you have to options:

  1. Use filename that doesn't exist within role's scope. Like:

    goss_file: local_goss.yml
    
  2. Supply absolute path. For example, you can use:

    goss_file: '{{ playbook_dir }}/goss.yml'
    

Ansible doesn't apply search logic if the path is absolute.

Upvotes: 1

Related Questions