Search code examples
vagrantansible

ansible : get roles from playbook in a subfolder


I have this tree:

├── plays
│   ├── ansible.cfg
│   ├── playbook_01.yml
│   ├── playbook_02.yml
│   └── playbook_03.yml
├── README.rst
├── roles
│   ├── role_A
│   │   ├── files
│   │   └── tasks
│   │       └── main.yml
│   └── role_B
│       ├── files
│       └── tasks
│           └── main.yml
├── serverlist
│   ├── client1_serverlist_prod
│   ├── client1_serverlist_test
│   ├── client1_serverlist_train
│   ├── client2_serverlist_prod
│   ├── client2_serverlist_test
│   └── client2_serverlist_train
└── vagrant
    └── Vagrantfile

With ansible.cfg in play folder::

$ cat plays/ansible.cfg
[defaults]
roles_path=../roles/
$

I call from vagrant the ansible.playbook::

$ grep playbook vagrant/Vagrantfile
ansible.playbook = "../plays/playbook_01.yml

on playbook_01.yml::

$ cat plays/playbook_01.yml
- hosts: vagrant
  vars:
    user: fox
    home: /home/fox
  roles:
    - role_B

with role_B::

$ cat roles/role_B/tasks/main.yml
---
- name: Create user group
  group: name={{ user }} state=present

- name: Create home directory for user
  file: state=directory path={{ home }} group=www-data owner={{ user }}
$

But ansible when only went to see roles in play folder, I get this error::

vagrant$ vagrant provision
==> vagrant: Running provisioner: ansible...
PYTHONUNBUFFERED=1 ANSIBLE_HOST_KEY_CHECKING=false ANSIBLE_FORCE_COLOR=true
ANSIBLE_SSH_ARGS='-o UserKnownHostsFile=/dev/null -o IdentitiesOnly=yes -o
ForwardAgent=yes -o ControlMaster=auto -o ControlPersist=60s' ansible-playbook
--user=vagrant --connection=ssh --timeout=30 --limit='vagrant'
--inventory-file=/home/luis/lab/sandbox/akd-iac/stack/vagrant/.vagrant/provisioners/ansible/inventory
--sudo -vvvv ../plays/playbook_01.yml
ERROR: cannot find role in
~/stack/plays/roles/role_B or
~/stack/plays/role_B or /etc/ansible/roles/role_B
Ansible failed to complete successfully. Any error output should be
visible above. Please fix these errors and try again.
vagrant$

Solution

  • I make it work just moving roles folder inside the plays folder and removing the play/ansible.cfg:

    .
    ├── plays
    │   ├── playbook_01.yml
    │   ├── playbook_02.yml
    │   ├── playbook_03.yml
    │   └── roles
    │       ├── role_A
    │       │   ├── files
    │       │   └── tasks
    │       │       └── main.yml
    │       └── role_B
    │           ├── files
    │           └── tasks
    │               └── main.yml
    ├── README.rst
    ├── serverlist
    │   ├── client1_serverlist_prod
    │   ├── client1_serverlist_test
    │   ├── client1_serverlist_train
    │   ├── client2_serverlist_prod
    │   ├── client2_serverlist_test
    │   └── client2_serverlist_train
    └── vagrant
        └── Vagrantfile
    

    Details about the ansible.cfg configuration that make it work::

    $ ls ~/.ansible.cfg
    ls: cannot access ~/.ansible.cfg: No such file or directory
    
    $ grep roles_path /etc/ansible/ansible.cfg
    #roles_path    = /etc/ansible/roles
    
    $ echo $ANSIBLE_CONFIG
    
    $
    

    I still call from vagrant the ansible.playbook::

    $ grep playbook vagrant/Vagrantfile
    ansible.playbook = "../plays/playbook_01.yml
    

    on playbook_01.yml::

    $ cat plays/playbook_01.yml
    - hosts: vagrant
      vars:
        user: fox
        home: /home/fox
      roles:
        - role_B
    

    with role_B::

    $ cat roles/role_B/tasks/main.yml
    ---
    - name: Create user group
      group: name={{ user }} state=present
    
    - name: Check Python version
      command: python --version
      register: pyver
    
    - name: Print version
      debug:
        msg: "Python Version: {{ pyver.stderr }}"
    

    With this modification that work like a charm:

    $ vagrant provision
    ==> vagrant: Running provisioner: ansible...
    
    PLAY [vagrant] ************************************************************
    GATHERING FACTS ***********************************************************
      ok: [vagrant]
    TASK: [role_B | Create user group] ****************************************
      ok: [vagrant]
    TASK: [role_B | Check Python version] *************************************
      changed: [vagrant]
    TASK: [role_B | Print version] ********************************************
      ok: [vagrant] => {
        "msg": "Python Version: Python 2.7.9"
    }
    PLAY RECAP ****************************************************************
    vagrant                    : ok=4    changed=1    unreachable=0    failed=0
    $
    

    It look like that roles folder need to be inside the folder playbooks lives.