Skip to main content

Implementing Role Patterns

1. Including Roles Dynamically

Property Description Example
include_role Include a role dynamically with variables
- name: Include dynamic role
  include_role:
    name: common_tasks
    vars:
      env: production
import_role Import a role at parse time (static)
- name: Import static role
  import_role:
    name: common_tasks

Example: Including a Role with Variables

- name: Deploy app with dynamic role
  include_role:
    name: deploy_app
    vars:
      app_name: myapp
      version: 1.2.3
Note: include_role allows runtime variable substitution, while import_role is parsed at playbook load time.

2. Importing Roles Statically

Property Description Example
import_role Used to import a role statically into a playbook
import_role:
  name: common
  tasks_from: setup
name Name of the role to import name: webserver
tasks_from Specifies a different task file within the role to execute tasks_from: deploy

Example: Importing a Static Role

---
- hosts: all
  tasks:
    - name: Import the common role
      import_role:
        name: common

Example: Importing a Specific Task File from a Role

---
- hosts: web
  tasks:
    - name: Import setup tasks from the webserver role
      import_role:
        name: webserver
        tasks_from: setup

3. Passing Variables to Roles

Variable Type Source Usage Notes
host_vars Host-specific variables in host_vars/<hostname> ansible_host, ansible_user Overrides default inventory variables
group_vars Group-specific variables in group_vars/<groupname> http_port, app_env Applies to all hosts in group
role_defaults Default values in defaults/main.yml app_version, config_file Used when no other value is set
role_vars Variables in vars/main.yml database_url, api_key Available within role scope only
extra_vars Command-line or file via -e environment=prod, deploy_user=root Overrides all other sources

Example: Setting Variables in Role

---
- name: Configure web server
  hosts: webservers
  roles:
    - role: nginx
      vars:
        nginx_port: 8080
        ssl_enabled: true

Example: Using Extra Vars

ansible-playbook deploy.yml -e "app_env=production" -e "db_host=localhost"
Note: Variables are processed in order of precedence: extra_vars > host_vars > group_vars > role_defaults

4. Setting Role Tags

Tag Description Usage
tags List of tags to apply to a role Used in meta/main.yml or tasks/main.yml
role_tags Tags specific to a role's tasks Applied in tasks/main.yml or individual task files

Example: Defining tags in meta/main.yml

---
galaxy_info:
  author: ansible_team
  description: Example role with tags
  license: MIT
  min_ansible_version: "2.10"
  platforms:
    - name: Ubuntu
      versions:
        - focal
tags:
  - web
  - nginx
  - deployment

Example: Applying tags in tasks

- name: "Install nginx"
  apt:
    name: nginx
    state: present
  tags:
    - web
    - nginx

- name: "Start nginx service"
  systemd:
    name: nginx
    state: started
  tags:
    - web
    - deployment
Note: Tags can be used to selectively run or skip roles during playbook execution using ansible-playbook --tags "web".
Warning: Tags are not inherited by included roles; they must be explicitly defined in each role's meta/main.yml or task files.

5. Using Role Conditionals

Condition Description Usage
when Evaluates a boolean expression to determine if the role should run when: ansible_facts.os_family == 'RedHat'
delegate_to Runs the role on a different host than the one it's defined on delegate_to: localhost

Example: Conditional Role Execution

- name: Install packages on RedHat systems
  hosts: web_servers
  roles:
    - role: nginx
      when: ansible_facts.os_family == 'RedHat'

Example: Delegating to Localhost

- name: Run a task on localhost
  hosts: all
  tasks:
    - name: Create directory on localhost
      file:
        path: /tmp/mydir
        state: directory
      delegate_to: localhost

6. Setting Role Privilege Escalation

Option Values Description
become true Enable privilege escalation for the role
become_user root User to escalate privileges to
become_method sudo Privilege escalation method (e.g., sudo, su)
become_flags -H Flags to pass to the become method (e.g., -H for home directory)

Example: Using become in a role

- name: Install package with elevated privileges
  apt:
    name: nginx
    state: present
  become: true
  become_user: root
  become_method: sudo
Note: Ensure that the user running the playbook has the necessary permissions to escalate privileges, typically via sudo rules.

7. Understanding Static vs Dynamic

Aspect Static Dynamic
Definition Variables defined at playbook or role level, evaluated once during execution. Variables computed at runtime using Jinja2 expressions or lookup plugins.
Evaluation Timing At parse time or during playbook load. Dynamically at runtime when referenced.
Use Case Example
vars:
  server_port: 8080
vars:
  current_time: "{{ lookup('pipe', 'date +%s') }}"
Performance Impact Fast, evaluated once. May be slower due to runtime computation or external lookups.
Flexibility Less flexible; fixed values. Highly flexible; can adapt based on conditions or external data.

Example: Using Dynamic Variables in a Playbook

---
- hosts: all
  vars:
    timestamp: "{{ lookup('pipe', 'date +%Y-%m-%d') }}"
  tasks:
    - name: Display current date
      debug:
        msg: "Today's date is {{ timestamp }}"

8. Using Role Collections

Property Description Example
ansible-galaxy collection install Installs a collection from Ansible Galaxy or a local path ansible-galaxy collection install ansible.posix
collections List of collections to be used in a playbook or role
collections:
  - ansible.posix
  - community.docker
requirements.yml File specifying collections to be installed
- name: ansible.posix
  version: "1.5.0"

Example: Installing a Collection

ansible-galaxy collection install ansible.posix</code>
</pre>
</div>
</div>
<div class="example">
<h2 id="example-using-collections-in-a-playbook">Example: Using Collections in a Playbook<a href="#example-using-collections-in-a-playbook" class="toc__headingLink" aria-label="Link to this section"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<div class="codeBlock" data-language="yaml">
<pre><code>---
- hosts: all
  collections:
    - ansible.posix
  tasks:
    - name: Check system uptime
      command: uptime</code>
</pre>
</div>
</div>
<div class="note">
<strong>Note:</strong> Collections can be used to group related roles and modules into a single distributable unit.
</div>
<h2 id="9-handling-role-dependencies">9. Handling Role Dependencies<a href="#9-handling-role-dependencies" class="toc__headingLink" aria-label="Link to this section"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<table>
<tbody>
<tr>
<th>Property</th>
<th>Description</th>
<th>Example</th>
</tr>
<tr>
<td class="property">dependencies</td>
<td>List of roles that this role depends on</td>
<td><code>[{ role: 'common' }, { role: 'nginx' }]</code></td>
</tr>
</tbody>
</table>
<div class="example">
<h2 id="example-role-dependencies-in-metamainyml">Example: Role Dependencies in meta/main.yml<a href="#example-role-dependencies-in-metamainyml" class="toc__headingLink" aria-label="Link to this section"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg></a></h2>
<div class="codeBlock" data-language="yaml">
<pre><code>---
dependencies:
  - role: common
    vars:
      common_var: value
  - role: nginx
    when: ansible_os_family == 'RedHat'
Note: Dependencies are resolved in the order they appear in the list.
Warning: Circular dependencies will cause a runtime error.
Dependency Type Description Support
role Standard role dependency Supported
when Conditional dependency execution Supported
vars Variables passed to dependent roles Supported

10. Creating Reusable Roles

Component Description Usage
roles/role_name/tasks/main.yml Primary task file for defining the role's behavior Define all tasks to be executed by the role
roles/role_name/handlers/main.yml Handler definitions for notifying services Define handlers to be triggered by tasks (e.g., restart a service)
roles/role_name/vars/main.yml Default variables for the role Set default values that can be overridden in playbooks or inventories
roles/role_name/defaults/main.yml Role default variables (highest precedence) Define role-specific defaults that override vars/main.yml
roles/role_name/meta/main.yml Role dependencies and metadata Define dependencies on other roles or platform support
roles/role_name/templates/ Jinja2 templates for configuration files Use templates to dynamically generate configuration files
roles/role_name/files/ Static files to be copied to managed nodes Place files such as scripts or config files here for copying

Example: Basic Role Structure

roles/
└── web_server/
    ├── tasks/
    │   └── main.yml
    ├── handlers/
    │   └── main.yml
    ├── vars/
    │   └── main.yml
    ├── defaults/
    │   └── main.yml
    ├── meta/
    │   └── main.yml
    └── templates/
        └── nginx.conf.j2

Example: Using Variables in a Role

# roles/web_server/vars/main.yml
nginx_port: 80
nginx_server_name: "example.com"

# roles/web_server/tasks/main.yml
- name: Ensure nginx is installed
  apt:
    name: nginx
    state: present

- name: Configure nginx
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
  notify: restart nginx
Note: Roles can be reused across multiple playbooks and inventories, making them a powerful way to encapsulate configuration logic.

11. Organizing Role Libraries

Example: Role Library Structure


roles/
├── common/
│   ├── tasks/
│   │   └── main.yml
│   ├── handlers/
│   │   └── main.yml
│   └── vars/
│       └── main.yml
├── webserver/
│   ├── tasks/
│   │   └── main.yml
│   ├── handlers/
│   │   └── main.yml
│   └── vars/
│       └── main.yml
└── database/
    ├── tasks/
    │   └── main.yml
    ├── handlers/
    │   └── main.yml
    └── vars/
        └── main.yml
Directory Description Usage
roles/common/ Shared tasks, handlers, and variables for all roles Used as base for other roles
roles/webserver/ Tasks specific to web server setup and configuration Applies to web server hosts
roles/database/ Tasks specific to database setup and management Applies to database hosts
Note: Use include_role or import_role to reuse roles from libraries.

Best Practices

  • Organize roles into logical groups under a roles/ directory
  • Use common roles to define shared functionality across multiple roles
  • Keep role-specific tasks, handlers, and variables in their respective directories
  • Use include_role or import_role to reuse roles in playbooks

Was this article helpful?