Introduction
Ansible Lint Rule 106 (role-name) enforces naming conventions for Ansible roles. Role names must use only lowercase alphanumeric characters and underscores, and must start with a letter. This prevents issues with Galaxy imports, cross-platform compatibility, and playbook readability. This article covers the rule, common violations, how to rename roles, and Galaxy namespace requirements.
The Rule
Role names must follow these requirements:
- Start with a letter (a-z)
- Contain only lowercase letters (a-z), digits (0-9), and underscores (_)
- No uppercase, hyphens, dots, spaces, or special characters
Valid Role Names
webserver
my_app
database_backup
nginx_proxy_v2
role42
load_balancer_ha
Invalid Role Names
1myrole # starts with a digit
my-role # contains hyphen
myRole # contains uppercase
my.role # contains dot
web server # contains space
rôle_config # contains non-ASCII character
The Error
Problematic Code
---
- name: Example playbook
hosts: all
roles:
- My-WebServer # uppercase + hyphen
- 1st_database # starts with digit
- cache.server # contains dot
Lint Output
$ ansible-lint playbook.yml
WARNING Listing 3 violation(s) that are fatal
role-name[non-lowercase]: Role name 'My-WebServer' is not valid.
playbook.yml:5
role-name[non-alphanumeric]: Role name '1st_database' does not start with alphabetic character.
playbook.yml:6
role-name[non-alphanumeric]: Role name 'cache.server' contains invalid characters.
playbook.yml:7
Failed: 3 failure(s), 0 warning(s) on 1 files.
Fixed Code
---
- name: Example playbook
hosts: all
roles:
- my_webserver
- first_database
- cache_server
Why These Rules Exist
1. Ansible Galaxy Compatibility
Galaxy enforces the same naming rules. Roles with invalid names cannot be published:
# This fails on Galaxy upload
$ ansible-galaxy role import my-org My-WebServer
ERROR! Invalid role name 'My-WebServer'
# This works
$ ansible-galaxy role import my_org my_webserver
2. Cross-Platform File Systems
Some operating systems are case-insensitive (macOS, Windows). A role named WebServer and webserver would collide:
roles/
├── WebServer/ # On case-insensitive FS, these
├── webserver/ # are the SAME directory
3. Python Module Compatibility
When roles are part of collections, they map to Python namespaces. Python modules must follow the same naming rules:
# Valid Python module name
from ansible_collections.my_namespace.my_collection.roles import webserver
# Invalid — hyphens aren't allowed in Python identifiers
from ansible_collections.my_namespace.my_collection.roles import web-server # SyntaxError
4. URL and Path Safety
Role names appear in URLs (Galaxy), file paths, and variable names. Special characters cause issues:
# Galaxy URL — clean
https://galaxy.ansible.com/ui/standalone/roles/geerlingguy/docker/
# Broken if role had dots or spaces
https://galaxy.ansible.com/ui/standalone/roles/my org/web.server/ # broken URL
Renaming Existing Roles
Step 1: Rename the Directory
# Old name
mv roles/My-WebServer roles/my_webserver
Step 2: Update meta/main.yml
# roles/my_webserver/meta/main.yml
galaxy_info:
role_name: my_webserver
author: your_name
description: Install and configure nginx web server
company: example
license: MIT
min_ansible_version: "2.14"
platforms:
- name: Ubuntu
versions:
- jammy
- noble
- name: EL
versions:
- "8"
- "9"
galaxy_tags:
- webserver
- nginx
Step 3: Update All References
# Find all references to the old name
grep -r "My-WebServer" --include="*.yml" --include="*.yaml" .
# Update playbooks
sed -i 's/My-WebServer/my_webserver/g' site.yml deploy.yml
Step 4: Update Dependencies
# roles/my_app/meta/main.yml
dependencies:
- role: my_webserver # was: My-WebServer
vars:
http_port: 8080
Role Name in Different Contexts
In Playbooks
# Direct reference
roles:
- my_webserver
# With variables
roles:
- role: my_webserver
vars:
http_port: 443
# Using include_role
tasks:
- name: Include webserver role
ansible.builtin.include_role:
name: my_webserver
In requirements.yml
# Galaxy role
- name: geerlingguy.docker
version: "7.1.0"
# Git source — src can have hyphens, name must not
- src: https://github.com/example/ansible-role-webserver.git
name: my_webserver
version: main
In Collections
Collection roles follow the same rules, with the namespace prefix:
my_namespace.my_collection.my_role # valid
my_namespace.my_collection.My-Role # invalid
Common Patterns for Converting Names
| Old Name | New Name | Issue |
|---|---|---|
My-WebServer | my_webserver | Uppercase + hyphen |
1st-deploy | first_deploy | Starts with digit + hyphen |
app.server.v2 | app_server_v2 | Dots |
Load-Balancer | load_balancer | Uppercase + hyphen |
DB Backup | db_backup | Space |
CacheLayer | cache_layer | CamelCase |
Automated Conversion Script
#!/bin/bash
# Convert role directory names to valid format
for dir in roles/*/; do
old_name=$(basename "$dir")
# Convert to lowercase, replace hyphens/dots/spaces with underscores
new_name=$(echo "$old_name" | tr '[:upper:]' '[:lower:]' | sed 's/[-. ]/_/g')
# Remove leading digits
new_name=$(echo "$new_name" | sed 's/^[0-9]*//')
if [ "$old_name" != "$new_name" ]; then
echo "Renaming: $old_name → $new_name"
mv "roles/$old_name" "roles/$new_name"
fi
done
Galaxy Namespace Rules
Galaxy namespaces have similar but slightly different rules:
| Component | Allowed Characters | Example |
|---|---|---|
| Namespace | a-z, 0-9, _ (start with letter) | geerlingguy |
| Role name | a-z, 0-9, _ (start with letter) | docker |
| Collection | namespace.name | ansible.builtin |
# Valid Galaxy references
$ ansible-galaxy role install geerlingguy.docker
$ ansible-galaxy collection install community.general
# Invalid — hyphens not allowed in namespace
$ ansible-galaxy role install my-org.my-role # ERROR
Auto-Fix with ansible-lint
# ansible-lint cannot auto-fix role names (requires directory rename)
# But it clearly reports what needs changing:
$ ansible-lint roles/
role-name: Role name 'My-WebServer' does not comply with requirements.
Best Practices
- Use snake_case —
my_webserver, notmyWebServerormy-webserver - Be descriptive —
nginx_reverse_proxyoverrole1 - Prefix with purpose —
deploy_app,configure_database,install_monitoring - Match Galaxy convention —
author.role_name(e.g.,geerlingguy.docker) - Avoid version numbers in names — use Galaxy versioning instead of
my_role_v2 - Set
role_namein meta — explicitly declare the name inmeta/main.yml - Check before creating — run
ansible-linton new roles immediately
Related Articles
Conclusion
Ansible Lint Rule 106 (role-name) ensures role names use only lowercase alphanumeric characters and underscores, starting with a letter. This prevents Galaxy import failures, cross-platform path collisions, and Python namespace issues. Use snake_case for all role names, update meta/main.yml with the role_name field, and run ansible-lint to catch violations early.