Stage 4 · Provision
Roles & Collections
Designing Configurable Roles
Sensible defaults, documented variables, and interfaces.
defaults vs vars
roles/role_name/defaults/main.yml contains variables with the lowest precedence — they can be overridden by almost anything. roles/role_name/vars/main.yml contains variables with higher precedence. Use defaults for safe, overridable values and vars for internal role state.
---
# Role: nginx
# Default configuration — override these in group_vars or host_vars
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_listen_port: 80
nginx_server_name: localhost
nginx_root: /var/www/html
nginx_log_dir: /var/log/nginx
nginx_user: www-data
# SSL settings
nginx_enable_ssl: false
nginx_ssl_cert_path: ""
nginx_ssl_key_path: ""Defaults are the entry point for your role's configuration. Users override only what they need to change.
Designing the Variable Interface
- Prefix all variables with the role name to avoid collisions
- Use descriptive names that explain the purpose
- Provide sensible defaults for every variable
- Use boolean flags for optional features (nginx_enable_ssl)
- Group related variables logically
- Keep the interface stable across versions
# Good: prefixed, descriptive, with defaults
nginx_worker_processes: auto
nginx_worker_connections: 1024
nginx_enable_ssl: false
nginx_ssl_cert_path: ""
# Bad: unprefixed, vague, no defaults
worker: auto
conns: 1024
ssl: false
cert: ""Prefixed variables prevent naming collisions when multiple roles are combined. Descriptive names make the role self-documenting.
Documenting Variables
---
# Number of nginx worker processes
# Default: auto (matches CPU cores)
# Type: string or integer
nginx_worker_processes: auto
# Maximum connections per worker
# Default: 1024
# Type: integer
# Minimum: 512
nginx_worker_connections: 1024
# Enable SSL termination
# Default: false
# Type: boolean
# Requires: nginx_ssl_cert_path, nginx_ssl_key_path
nginx_enable_ssl: falseDocument every variable with its purpose, type, default, and constraints. This makes your role usable without reading the tasks.
Variable Validation
- name: Validate required variables
assert:
that:
- nginx_ssl_cert_path | length > 0
- nginx_ssl_key_path | length > 0
fail_msg: "SSL enabled but cert paths not configured"
when: nginx_enable_ssl | bool
- name: Validate port range
assert:
that:
- nginx_listen_port | int >= 1
- nginx_listen_port | int <= 65535
fail_msg: "Invalid port number"Validate variables at the start of your role to catch configuration errors early. This prevents partial deployments.
Override Patterns
# 1. Role defaults (lowest) — roles/nginx/defaults/main.yml
nginx_listen_port: 80
# 2. Inventory group_vars — group_vars/webservers.yml
nginx_listen_port: 443
# 3. Playbook vars
vars:
nginx_listen_port: 8080
# 4. Extra vars (highest)
# ansible-playbook site.yml -e nginx_listen_port=9090Extra vars always win. Playbook vars override group_vars. group_vars override role defaults. This layered approach lets you customize at every level.
In your role README, document which variables users should override and at which level. This prevents confusion when variables do not behave as expected.
Mark this lesson complete to store local progress and unlock a cleaner resume path the next time you visit.