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:
ERROR! the role 'nginx' was not found in /path/to/roles:/etc/ansible/roles:/usr/share/ansible/rolesOr:
ERROR! A dependency role 'geerlingguy.docker' could not be foundOr from meta dependencies:
ERROR! Could not find role 'common' in required rolesStep 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:
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:
ansible-galaxy install -r roles/requirements.ymlStep 3: Configure Role Paths
Ansible searches for roles in configured paths. Check what's configured:
ansible-config dump | grep ROLES_PATHSet role paths in ansible.cfg:
[defaults]
roles_path = ./roles:~/.ansible/roles:/usr/share/ansible/rolesOr relative to playbook:
- hosts: all
roles:
- nginx # Looks in ./roles/nginx firstStep 4: Fix Meta Dependencies
Roles can declare dependencies in meta/main.yml:
# roles/app/meta/main.yml
dependencies:
- role: common
- role: geerlingguy.docker
version: v3.1.0
- role: nginx
when: enable_nginxIf 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:
# meta/main.yml
dependencies:
- role: base # Runs first
- role: docker # Runs second
- role: nginx # Runs third
# Then this role's tasks runCircular dependencies cause failures:
ERROR! Circular dependency detected: app -> docker -> appBreak circular dependencies by restructuring roles:
# 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:
- hosts: all
tasks:
- include_role:
name: nginx
# Dependencies resolve when this task runsImport 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:
# Test role exists
ansible localhost -m debug -a "msg={{ lookup('first_found', 'roles/nginx') }}"Step 8: Debug Role Loading
See role loading details:
ansible-playbook site.yml -vvv 2>&1 | grep roleLook for:
Loading role 'nginx' from /path/to/roles/nginx
Processing role dependencies...Step 9: Handle Private Roles
For roles not in Galaxy, use Git:
# requirements.yml
- src: git@github.com:company/private-role.git
scm: git
name: private-role
version: masterInstall:
ansible-galaxy install -r requirements.ymlFor roles in private Galaxy:
- src: company.private-role
galaxy: https://galaxy.company.comStep 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:
dependencies:
- role: nginx
version: v2.0 # Works for both rolesOption 2: Separate role versions:
# 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-v2Option 3: Override in playbook:
- hosts: all
roles:
- role: nginx
version: v2.0 # Override dependency versionStep 11: Verify Role Structure
Roles must have correct structure:
roles/nginx/
├── defaults/
│ └── main.yml
├── files/
├── handlers/
│ └── main.yml
├── meta/
│ └── main.yml
├── tasks/
│ └── main.yml
├── templates/
└── vars/
└── main.ymlAt minimum, tasks/main.yml must exist:
ls roles/nginx/tasks/main.ymlIf missing, the role fails.
Step 12: Handle Role Parameters
Pass parameters to roles:
- hosts: all
roles:
- role: nginx
nginx_port: 8080
nginx_user: www-dataParameters override role defaults:
# roles/nginx/defaults/main.yml
nginx_port: 80
nginx_user: nginxMissing parameters with required defaults cause failures:
# roles/app/meta/main.yml
dependencies:
- role: database
db_name: "{{ app_db_name }}" # Must be definedDefine required variables:
# Playbook vars
vars:
app_db_name: myapp_dbQuick Verification
Test role installation:
```bash # List roles ansible-galaxy list
# Check role structure tree roles/nginx/ ```
Test role in playbook:
- hosts: localhost
gather_facts: no
roles:
- nginxRun:
ansible-playbook test_role.yml --checkSuccess:
``` PLAY [localhost] *************
TASK [nginx : First task] ************ changed: [localhost] ```
Prevention Best Practices
- 1.Use requirements.yml for all roles:
# roles/requirements.yml
- src: geerlingguy.nginx
version: v2.7.0
- src: geerlingguy.docker
- src: ./roles/local/custom- 1.Install roles before running playbooks:
ansible-galaxy install -r roles/requirements.yml- 1.Document role dependencies:
# roles/app/README.md
# Dependencies:
# - geerlingguy.docker (v3.0+)
# - nginx (any version)- 1.Pin versions for reproducibility:
- src: geerlingguy.nginx
version: v2.7.0 # Pin specific version- 1.Test role availability before playbook:
# CI script
ansible-galaxy install -r requirements.yml
ansible-galaxy list
ansible-playbook site.yml --syntax-checkRole 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.