Your playbook runs and immediately fails with an error about missing roles or unresolved dependencies. Roles are Ansible's way to organize reusable automation, and dependency issues can stop your playbooks before they even start.

Understanding the Error

Role dependency errors show up in several ways:

bash
ERROR! the role 'nginx' was not found in /path/to/roles:/etc/ansible/roles:/usr/share/ansible/roles

Or:

bash
ERROR! A dependency role 'geerlingguy.docker' could not be found

Or from meta dependencies:

bash
ERROR! Could not find role 'common' in required roles

Step 1: Verify Role Exists

Check if the role is installed:

```bash # List installed roles ansible-galaxy list

# Check specific role ansible-galaxy list | grep nginx ```

Or check role directories manually:

bash
ls -la roles/
ls -la ~/.ansible/roles/
ls -la /etc/ansible/roles/

Step 2: Install Missing Roles from Galaxy

Ansible Galaxy hosts community roles:

```bash # Install role from Galaxy ansible-galaxy install geerlingguy.nginx

# Install specific version ansible-galaxy install geerlingguy.nginx,v2.7.0

# Install to specific path ansible-galaxy install geerlingguy.nginx --roles-path ./roles ```

Install from a requirements file:

```yaml # roles/requirements.yml - src: geerlingguy.nginx version: v2.7.0

  • src: geerlingguy.docker
  • version: master
  • src: https://github.com/user/custom-role.git
  • name: custom-role
  • `

Install all requirements:

bash
ansible-galaxy install -r roles/requirements.yml

Step 3: Configure Role Paths

Ansible searches for roles in configured paths. Check what's configured:

bash
ansible-config dump | grep ROLES_PATH

Set role paths in ansible.cfg:

ini
[defaults]
roles_path = ./roles:~/.ansible/roles:/usr/share/ansible/roles

Or relative to playbook:

yaml
- hosts: all
  roles:
    - nginx  # Looks in ./roles/nginx first

Step 4: Fix Meta Dependencies

Roles can declare dependencies in meta/main.yml:

yaml
# roles/app/meta/main.yml
dependencies:
  - role: common
  - role: geerlingguy.docker
    version: v3.1.0
  - role: nginx
    when: enable_nginx

If dependency roles aren't installed, the role fails. Install all dependencies:

```bash # Check role meta dependencies cat roles/app/meta/main.yml

# Install listed dependencies ansible-galaxy install geerlingguy.docker ansible-galaxy install geerlingguy.nginx ```

Step 5: Handle Role Dependency Order

Dependencies execute before the role itself:

yaml
# meta/main.yml
dependencies:
  - role: base     # Runs first
  - role: docker   # Runs second
  - role: nginx    # Runs third
# Then this role's tasks run

Circular dependencies cause failures:

bash
ERROR! Circular dependency detected: app -> docker -> app

Break circular dependencies by restructuring roles:

yaml
# Instead of app depending on docker which depends on app
# Create separate roles:
# - base (shared requirements)
# - docker (docker only)
# - app (depends on base and docker)

Step 6: Fix Role Import vs Include

roles: and import_role: execute at playbook parse time:

```yaml # These resolve dependencies BEFORE playbook runs - hosts: all roles: - nginx

  • hosts: all
  • tasks:
  • - import_role:
  • name: nginx
  • `

include_role: executes at runtime:

yaml
- hosts: all
  tasks:
    - include_role:
        name: nginx
    # Dependencies resolve when this task runs

Import fails if role missing at parse time. Include fails at runtime.

Step 7: Handle Role Name Resolution

Role names can be specified differently:

```yaml # Short name (requires role in path) roles: - nginx

# Galaxy name (uses src from Galaxy) roles: - geerlingguy.nginx

# Full path roles: - ./roles/local/nginx

# Git URL roles: - src: https://github.com/geerlingguy/ansible-role-nginx.git name: nginx ```

Check what Ansible sees:

bash
# Test role exists
ansible localhost -m debug -a "msg={{ lookup('first_found', 'roles/nginx') }}"

Step 8: Debug Role Loading

See role loading details:

bash
ansible-playbook site.yml -vvv 2>&1 | grep role

Look for:

bash
Loading role 'nginx' from /path/to/roles/nginx
Processing role dependencies...

Step 9: Handle Private Roles

For roles not in Galaxy, use Git:

yaml
# requirements.yml
- src: git@github.com:company/private-role.git
  scm: git
  name: private-role
  version: master

Install:

bash
ansible-galaxy install -r requirements.yml

For roles in private Galaxy:

yaml
- src: company.private-role
  galaxy: https://galaxy.company.com

Step 10: Fix Role Version Conflicts

Different roles may need different versions of the same dependency:

```yaml # Role A needs nginx v1.0 dependencies: - role: nginx version: v1.0

# Role B needs nginx v2.0 dependencies: - role: nginx version: v2.0 ```

This causes version conflicts. Resolve by:

Option 1: Use compatible versions:

yaml
dependencies:
  - role: nginx
    version: v2.0  # Works for both roles

Option 2: Separate role versions:

bash
# Install both versions with different names
ansible-galaxy install geerlingguy.nginx,v1.0 --roles-path roles/nginx-v1
ansible-galaxy install geerlingguy.nginx,v2.0 --roles-path roles/nginx-v2

Option 3: Override in playbook:

yaml
- hosts: all
  roles:
    - role: nginx
      version: v2.0  # Override dependency version

Step 11: Verify Role Structure

Roles must have correct structure:

bash
roles/nginx/
├── defaults/
│   └── main.yml
├── files/
├── handlers/
│   └── main.yml
├── meta/
│   └── main.yml
├── tasks/
│   └── main.yml
├── templates/
└── vars/
    └── main.yml

At minimum, tasks/main.yml must exist:

bash
ls roles/nginx/tasks/main.yml

If missing, the role fails.

Step 12: Handle Role Parameters

Pass parameters to roles:

yaml
- hosts: all
  roles:
    - role: nginx
      nginx_port: 8080
      nginx_user: www-data

Parameters override role defaults:

yaml
# roles/nginx/defaults/main.yml
nginx_port: 80
nginx_user: nginx

Missing parameters with required defaults cause failures:

yaml
# roles/app/meta/main.yml
dependencies:
  - role: database
    db_name: "{{ app_db_name }}"  # Must be defined

Define required variables:

yaml
# Playbook vars
vars:
  app_db_name: myapp_db

Quick Verification

Test role installation:

```bash # List roles ansible-galaxy list

# Check role structure tree roles/nginx/ ```

Test role in playbook:

yaml
- hosts: localhost
  gather_facts: no
  roles:
    - nginx

Run:

bash
ansible-playbook test_role.yml --check

Success:

``` PLAY [localhost] *************

TASK [nginx : First task] ************ changed: [localhost] ```

Prevention Best Practices

  1. 1.Use requirements.yml for all roles:
yaml
# roles/requirements.yml
- src: geerlingguy.nginx
  version: v2.7.0
- src: geerlingguy.docker
- src: ./roles/local/custom
  1. 1.Install roles before running playbooks:
bash
ansible-galaxy install -r roles/requirements.yml
  1. 1.Document role dependencies:
yaml
# roles/app/README.md
# Dependencies:
# - geerlingguy.docker (v3.0+)
# - nginx (any version)
  1. 1.Pin versions for reproducibility:
yaml
- src: geerlingguy.nginx
  version: v2.7.0  # Pin specific version
  1. 1.Test role availability before playbook:
bash
# CI script
ansible-galaxy install -r requirements.yml
ansible-galaxy list
ansible-playbook site.yml --syntax-check

Role dependency issues usually mean missing roles, wrong paths, or unresolved meta dependencies. Use ansible-galaxy to install, verify role structure, and ensure meta dependencies are available.