DEV Community

Harsh Mishra
Harsh Mishra

Posted on

1 1

Ansible Roles and Plugins: Complete Guide for Beginners

Ansible Roles: Complete Guide

Ansible roles are a powerful feature that helps organize playbooks into reusable components. Roles allow you to break down playbooks into smaller, more manageable parts by grouping related tasks, handlers, variables, templates, and other resources into a standardized directory structure.

This guide will cover everything about roles, from creating and using them to advanced features and best practices.


1. What Are Ansible Roles?

Ansible roles are a way to automate configuration and deployment tasks by organizing them into reusable and shareable directories. Each role is a self-contained collection of files, tasks, and configurations.

Advantages of Roles

  • Reusability: Roles can be reused across multiple playbooks or projects.
  • Modularity: Simplifies complex configurations by breaking them into smaller components.
  • Scalability: Helps manage configurations for large infrastructures.
  • Readability: Improves the organization and readability of playbooks.

2. Directory Structure of a Role

Ansible roles follow a standardized directory structure. Below is the layout of a typical role:

roles/
└── <role_name>/
    ├── defaults/      # Default variables for the role
    │   └── main.yml
    ├── files/         # Static files to copy to managed hosts
    ├── handlers/      # Handlers triggered by tasks
    │   └── main.yml
    ├── meta/          # Role metadata (dependencies, author info)
    │   └── main.yml
    ├── tasks/         # List of tasks to execute
    │   └── main.yml
    ├── templates/     # Jinja2 templates to deploy
    ├── tests/         # Test playbooks for the role
    ├── vars/          # Variables with higher precedence
    │   └── main.yml
    └── README.md      # Documentation for the role
Enter fullscreen mode Exit fullscreen mode

3. Components of a Role

3.1 Tasks

Tasks define the actions to be performed by the role. These are usually the primary logic of the role.

File: roles/<role_name>/tasks/main.yml

---
- name: Install Nginx
  apt:
    name: nginx
    state: present

- name: Start Nginx service
  service:
    name: nginx
    state: started
Enter fullscreen mode Exit fullscreen mode

3.2 Handlers

Handlers are tasks triggered by notifications. They are defined in the handlers/main.yml file.

File: roles/<role_name>/handlers/main.yml

---
- name: Restart Nginx
  service:
    name: nginx
    state: restarted
Enter fullscreen mode Exit fullscreen mode

Tasks can notify handlers:

---
- name: Update Nginx config
  copy:
    src: nginx.conf
    dest: /etc/nginx/nginx.conf
  notify:
    - Restart Nginx
Enter fullscreen mode Exit fullscreen mode

3.3 Variables

Roles support variables for dynamic configurations. These can be defined in:

  • defaults/main.yml (default values, lowest precedence).
  • vars/main.yml (higher precedence).

File: roles/<role_name>/defaults/main.yml

---
nginx_package: nginx
Enter fullscreen mode Exit fullscreen mode

File: roles/<role_name>/vars/main.yml

---
nginx_config_file: /etc/nginx/nginx.conf
Enter fullscreen mode Exit fullscreen mode

3.4 Files

Static files to be copied to managed hosts are stored in the files/ directory.

Example task to copy a file:

---
- name: Copy default Nginx config
  copy:
    src: default.conf
    dest: /etc/nginx/sites-available/default
Enter fullscreen mode Exit fullscreen mode

Place default.conf in the roles/<role_name>/files/ directory.


3.5 Templates

Templates are Jinja2 files that allow dynamic content generation.

Example Jinja2 template (nginx.conf.j2):

server {
    listen {{ nginx_port }};
    server_name {{ nginx_server_name }};
}
Enter fullscreen mode Exit fullscreen mode

Task to deploy the template:

---
- name: Deploy Nginx config template
  template:
    src: nginx.conf.j2
    dest: /etc/nginx/nginx.conf
Enter fullscreen mode Exit fullscreen mode

Place nginx.conf.j2 in the roles/<role_name>/templates/ directory.


3.6 Meta

The meta/main.yml file defines metadata for the role, such as dependencies.

File: roles/<role_name>/meta/main.yml

---
dependencies:
  - role: common
    vars:
      some_variable: value
Enter fullscreen mode Exit fullscreen mode

3.7 Tests

The tests/ directory contains test playbooks for validating the role.

File: roles/<role_name>/tests/test.yml

---
- hosts: localhost
  roles:
    - my_role
Enter fullscreen mode Exit fullscreen mode

4. Using Roles in Playbooks

Once a role is created, it can be included in a playbook using the roles keyword.

Example Playbook

File: site.yml

---
- name: Configure webservers
  hosts: webservers
  become: yes
  roles:
    - nginx
Enter fullscreen mode Exit fullscreen mode

Run the playbook:

ansible-playbook site.yml
Enter fullscreen mode Exit fullscreen mode

5. Role Dependencies

Roles can depend on other roles. Dependencies are defined in the meta/main.yml file.

Example:

---
dependencies:
  - role: common
  - role: firewall
    vars:
      allow_http: true
Enter fullscreen mode Exit fullscreen mode

When the role is executed, its dependencies are automatically run first.


6. Installing Roles

6.1 Downloading Roles

You can download roles from Ansible Galaxy.

Example:

ansible-galaxy install geerlingguy.nginx
Enter fullscreen mode Exit fullscreen mode

This will install the role in /etc/ansible/roles/ or $HOME/.ansible/roles/.


6.2 Role Directory Structure

Ansible looks for roles in the following directories:

  1. /etc/ansible/roles/
  2. $HOME/.ansible/roles/
  3. roles/ directory in the project.

You can override the role path using ansible.cfg:

[defaults]
roles_path = ./my_roles:/etc/ansible/roles
Enter fullscreen mode Exit fullscreen mode

7. Best Practices for Roles

  1. Organize Roles Properly: Use the standard directory structure.
  2. Use Variables: Define all customizable parameters in defaults/main.yml.
  3. Use Handlers: Trigger handlers for tasks like restarting services.
  4. Write Documentation: Include a README.md in the role directory.
  5. Test Roles: Validate roles using the tests/ directory.
  6. Use Dependencies: Define dependent roles in meta/main.yml.

8. Example: Complete Role

Directory Structure:

roles/
└── nginx/
    ├── defaults/
    │   └── main.yml
    ├── files/
    │   └── default.conf
    ├── handlers/
    │   └── main.yml
    ├── meta/
    │   └── main.yml
    ├── tasks/
    │   └── main.yml
    ├── templates/
    │   └── nginx.conf.j2
    └── vars/
        └── main.yml
Enter fullscreen mode Exit fullscreen mode

Playbook:

---
- name: Configure Nginx servers
  hosts: webservers
  roles:
    - nginx
Enter fullscreen mode Exit fullscreen mode

Run the playbook:

ansible-playbook site.yml
Enter fullscreen mode Exit fullscreen mode

9. Advanced Role Features

9.1 Role Variables

Override role variables in the playbook:

---
- hosts: webservers
  roles:
    - role: nginx
      vars:
        nginx_port: 8080
Enter fullscreen mode Exit fullscreen mode

9.2 Conditional Role Inclusion

Include roles conditionally using the when statement:

---
- hosts: all
  roles:
    - { role: nginx, when: ansible_os_family == "Debian" }
Enter fullscreen mode Exit fullscreen mode

10. Conclusion

Roles are a cornerstone of scalable and reusable Ansible configurations. By mastering roles, you can:

  • Modularize your playbooks.
  • Simplify complex automation tasks.
  • Promote consistency across projects.

Key Takeaways

  • Use roles for better organization and reusability.
  • Follow the standard directory structure.
  • Leverage Ansible Galaxy for pre-built roles.
  • Test roles thoroughly to ensure reliability.

With roles, Ansible becomes a powerful tool for managing even the largest infrastructures effectively.


Ansible Plugins: Complete Guide

Ansible plugins are specialized components that extend Ansible’s functionality, allowing you to customize and enhance the way Ansible interacts with systems, modules, and tasks. Plugins are powerful tools that allow for more advanced configuration management and automation beyond standard modules, and they are integral to extending Ansible's core behavior.

This comprehensive guide will cover everything you need to know about Ansible plugins, from the basics to advanced usage.


1. What Are Ansible Plugins?

Ansible plugins are reusable pieces of code that extend or modify Ansible’s behavior. They provide the flexibility to implement customized functionalities for various operations within Ansible, such as managing inventories, configuring connections, logging, and executing tasks.

Types of Plugins

  • Action Plugins: Modify or define the execution of tasks.
  • Connection Plugins: Manage connections to target machines.
  • Callback Plugins: Handle custom reporting.
  • Lookup Plugins: Retrieve data from external sources.
  • Filter Plugins: Modify variables or outputs.
  • Inventory Plugins: Load and manage dynamic inventory sources.
  • Strategy Plugins: Control the execution strategy for playbooks.

2. Ansible Plugin Architecture

Plugins are stored in specific directories and are categorized based on their functionality. Ansible provides a standardized directory structure where plugins are typically stored.

Plugin Locations

  • Global Plugin Directory: /usr/share/ansible/plugins/
  • User Plugin Directory: ~/.ansible/plugins/
  • Project-Specific Plugin Directory: ./plugins/

The exact location depends on how Ansible is configured.


3. Common Types of Plugins in Ansible

Ansible supports various types of plugins that cater to different aspects of automation. Let’s dive deeper into each plugin type.

3.1 Action Plugins

Action plugins modify how tasks are executed. They are used to change the behavior of task execution and to implement custom actions. The default action plugin is used when Ansible tasks interact with modules.

Action plugins are not typically used directly by the user but can be extended to create custom behaviors.

3.2 Connection Plugins

Connection plugins manage the connection between the Ansible control node and the managed nodes. These plugins handle how Ansible communicates with remote systems (SSH, WinRM, etc.).

Examples of connection plugins:

  • SSH (ssh): Default plugin for connecting to remote hosts via SSH.
  • WinRM (winrm): For connecting to Windows hosts.
  • Local (local): For executing tasks locally on the control node.
  • Docker (docker): Used to connect to Docker containers.

3.3 Callback Plugins

Callback plugins handle custom output generation for playbook runs. They are used to modify how the output is displayed or logged.

For example, the profile_tasks callback plugin displays performance profiling information for each task.

Example of Callback Plugin Usage:

To enable profiling callback plugin:

ANSIBLE_CALLBACK_ENABLED=profile_tasks ansible-playbook playbook.yml
Enter fullscreen mode Exit fullscreen mode

3.4 Lookup Plugins

Lookup plugins allow Ansible to retrieve data from external sources, such as databases, files, or web services. These plugins enable dynamic data fetching during playbook execution.

Examples of lookup plugins:

  • File Lookup (file): Retrieve the content of a file.
  • Env Lookup (env): Retrieve environment variables.
  • Password Lookup (passwordstore): Retrieve a password from a password manager.

Example of a Lookup Plugin in Action:

- name: Fetch password from environment
  debug:
    msg: "{{ lookup('env', 'SECRET_PASSWORD') }}"
Enter fullscreen mode Exit fullscreen mode

3.5 Filter Plugins

Filter plugins modify the content of variables or outputs by applying transformations. They are typically used in conjunction with Jinja2 templates to manipulate data.

Example:

You can use the length filter to get the length of a list:

- name: Get the length of the list
  debug:
    msg: "{{ my_list | length }}"
Enter fullscreen mode Exit fullscreen mode

Ansible includes several built-in filter plugins, such as:

  • default: Returns a default value if the variable is undefined.
  • lower: Converts a string to lowercase.
  • join: Joins a list of strings.

3.6 Inventory Plugins

Inventory plugins allow Ansible to pull inventory from dynamic sources (such as cloud providers, databases, or APIs). This is useful for working with dynamic infrastructure environments.

Examples of inventory plugins:

  • EC2 Inventory (ec2): Pulls inventory from AWS EC2 instances.
  • Azure Inventory (azure_rm): Retrieves inventory from Azure.
  • YAML Inventory (yaml): Loads inventory from a YAML file.

Example:

You can configure the ec2 plugin to retrieve EC2 instances dynamically from AWS:

[all]
plugin: ec2
aws_access_key: YOUR_AWS_ACCESS_KEY
aws_secret_key: YOUR_AWS_SECRET_KEY
regions:
  - us-west-1
Enter fullscreen mode Exit fullscreen mode

3.7 Strategy Plugins

Strategy plugins determine the order in which tasks are executed in a playbook. Ansible’s default strategy is linear, which executes tasks one after another. However, other strategies, such as free and host_pinned, are available to change how tasks are executed.

Example of Changing Strategy:

---
- name: Run tasks in a non-linear order
  hosts: all
  strategy: free
  tasks:
    - name: Task 1
      command: echo "Task 1"
    - name: Task 2
      command: echo "Task 2"
Enter fullscreen mode Exit fullscreen mode

4. Configuring Plugins

You can configure plugins using the ansible.cfg configuration file or by setting environment variables. Here's how to manage plugins globally or per-playbook.

Configuring Plugins in ansible.cfg

Ansible allows you to configure plugins in the ansible.cfg file by setting values under the [defaults] section.

For example, to enable a callback plugin for output:

[defaults]
callback_enabled = profile_tasks
Enter fullscreen mode Exit fullscreen mode

Using Environment Variables

Certain plugins can be controlled or configured using environment variables. For instance, you can enable a callback plugin with:

export ANSIBLE_CALLBACK_ENABLED=profile_tasks
ansible-playbook playbook.yml
Enter fullscreen mode Exit fullscreen mode

5. How to Create Custom Plugins

Creating custom plugins can help extend Ansible's functionality for your specific needs. Ansible provides a clear structure for creating custom plugins, which can be done by creating Python files in the appropriate plugin directory.

Creating a Custom Lookup Plugin

  1. Create a Python file inside ~/.ansible/plugins/lookup/.
  2. Define the plugin logic.
  3. Use the plugin in a playbook.

Example of a custom lookup plugin:

from ansible.plugins.lookup import LookupBase

class LookupModule(LookupBase):
    def run(self, terms, variables=None, **kwargs):
        return [str(term).upper() for term in terms]
Enter fullscreen mode Exit fullscreen mode

This plugin takes a list of terms and returns them as uppercase.


6. Plugin Development Best Practices

  1. Follow Ansible’s Plugin API: Ensure that custom plugins follow the official Ansible Plugin API for compatibility.
  2. Documentation: Document your plugins well to ensure they are understandable by others.
  3. Modular Design: Keep your plugins modular and focused on a single task.
  4. Testing: Write unit tests for custom plugins to ensure they behave as expected.
  5. Error Handling: Provide meaningful error messages and logging.

7. Examples of Common Plugins

7.1 Action Plugin Example

An action plugin can change the execution of a task by modifying how the task is executed.

from ansible.plugins.action import ActionBase

class ActionModule(ActionBase):
    def run(self, tmp=None, task_vars=None):
        self._run_module(tmp, task_vars)
Enter fullscreen mode Exit fullscreen mode

7.2 Connection Plugin Example

A connection plugin can manage how Ansible connects to a target machine, such as using SSH or WinRM.

from ansible.plugins.connection import ConnectionBase

class ConnectionPlugin(ConnectionBase):
    def connect(self):
        pass
Enter fullscreen mode Exit fullscreen mode

8. Conclusion

Ansible plugins are powerful extensions that can drastically improve automation workflows by adding custom functionality, enhancing connectivity, and supporting dynamic configurations. Understanding the core types of plugins—such as action, connection, callback, and inventory—enables you to make full use of Ansible’s advanced features and fine-tune your automation strategy.

Key Takeaways

  • Plugins extend Ansible’s core behavior for flexibility.
  • Common plugin types include action, connection, callback, inventory, and filter plugins.
  • Custom plugins allow you to create tailored solutions for your automation needs.
  • Plugins can be configured through ansible.cfg or environment variables.

Mastering plugins gives you the ability to tailor Ansible to meet your specific infrastructure requirements, ensuring more robust and efficient automation across a wide range of systems and environments.

Billboard image

Monitoring as code

With Checkly, you can use Playwright tests and Javascript to monitor end-to-end scenarios in your NextJS, Astro, Remix, or other application.

Get started now!

Top comments (0)

Billboard image

The Next Generation Developer Platform

Coherence is the first Platform-as-a-Service you can control. Unlike "black-box" platforms that are opinionated about the infra you can deploy, Coherence is powered by CNC, the open-source IaC framework, which offers limitless customization.

Learn more

👋 Kindness is contagious

Discover a treasure trove of wisdom within this insightful piece, highly respected in the nurturing DEV Community enviroment. Developers, whether novice or expert, are encouraged to participate and add to our shared knowledge basin.

A simple "thank you" can illuminate someone's day. Express your appreciation in the comments section!

On DEV, sharing ideas smoothens our journey and strengthens our community ties. Learn something useful? Offering a quick thanks to the author is deeply appreciated.

Okay