AnsiblePilot — Master Ansible Automation

AnsiblePilot is the leading resource for learning Ansible automation, DevOps, and infrastructure as code. Browse over 1,400 tutorials covering Ansible modules, playbooks, roles, collections, and real-world examples. Whether you are a beginner or an experienced engineer, our step-by-step guides help you automate Linux, Windows, cloud, containers, and network infrastructure.

Popular Topics

About Luca Berton

Luca Berton is an Ansible automation expert, author of 8 Ansible books published by Apress and Leanpub including "Ansible for VMware by Examples" and "Ansible for Kubernetes by Example", and creator of the Ansible Pilot YouTube channel. He shares practical automation knowledge through tutorials, books, and video courses to help IT professionals and DevOps engineers master infrastructure automation.

Ansible Plugins: Types, Usage & Custom Plugin Development Guide

By Luca Berton · Published 2024-01-01 · Category: installation

Complete guide to Ansible plugins. Understand lookup, callback, filter, connection, inventory, and module plugins with usage examples and custom development.

Ansible plugins are modular pieces of code that extend and enhance Ansible’s core functionality. They allow users to customize and optimize workflows for specific requirements. This article explains what Ansible plugins are, their types, and how to use them effectively.

What Are Ansible Plugins?

Ansible plugins are Python-based extensions that modify or add capabilities to Ansible’s automation engine. They provide additional functionality without altering the core Ansible codebase, making them highly flexible and reusable.

Key Features:

Extensibility: Add new behaviors to Ansible. • Reusability: Share plugins across projects or teams. • Customization: Tailor functionality to specific needs.

See also: Ansible Development: Write Custom Modules, Plugins & Collections

Types of Ansible Plugins

Ansible supports several plugin types, each serving a distinct purpose:

1. Action Plugins

Modify or enhance the behavior of modules when executed. • Example: Add custom logic to module execution.

2. Lookup Plugins

Fetch data from external sources and pass it into playbooks. • Example: Retrieve secrets from a vault:
     vars:
       secret: "{{ lookup('aws_secretsmanager', 'my_secret') }}"
     

3. Filter Plugins

Transform data or variables in templates or playbooks. • Example: Convert text to uppercase:
     vars:
       uppercase_text: "{{ 'hello' | upper }}"
     

4. Connection Plugins

Define how Ansible connects to target nodes (e.g., SSH, WinRM). • Example: Use a custom connection method for specialized devices.

5. Strategy Plugins

Control the execution flow of tasks in a play. • Built-in strategies include linear, free, and debug.

6. Callback Plugins

Customize output or perform actions during playbook execution. • Example: Send notifications to Slack after task completion.

7. Inventory Plugins

Dynamically generate inventory from external sources (e.g., AWS, GCP). • Example:
     plugin: aws_ec2
     regions:
       - us-east-1
     

8. Vars Plugins

Inject additional variables into playbooks dynamically. • Example: Load variables based on host properties.

Where Are Plugins Stored?

Built-In Plugins

Ansible’s default plugins are stored in the system directory:
/usr/share/ansible/plugins/

Custom Plugins

Custom plugins can be stored in: Project-Specific Directory:
   ./plugins/<plugin_type>/
   
Global Directory:
   ~/.ansible/plugins/<plugin_type>/
   
Specified Paths: Define custom plugin paths in the ansible.cfg file:
   [defaults]
   plugin_paths = /path/to/custom/plugins
   

See also: Ansible vs Terraform: Key Differences & When to Use Each (2026 Guide)

Creating Custom Plugins

Here’s an example of a custom filter plugin to reverse strings: Create a directory for custom plugins:

   ./plugins/filter/
   
Write the plugin in Python:
   # plugins/filter/reverse.py
   def reverse_string(value):
       return value[::-1]

class FilterModule(object): def filters(self): return { 'reverse': reverse_string }

Use the plugin in a playbook:
   vars:
     reversed_text: "{{ 'hello' | reverse }}"
   
Execute the playbook to see the plugin in action.

Best Practices for Using Plugins

Use Collections: Distribute and manage plugins using Ansible Collections for better organization. Test Custom Plugins: Validate plugins in a controlled environment to ensure reliability. Document Plugins: Provide clear documentation for custom plugins, including usage examples. Optimize for Performance: Ensure plugins do not introduce significant overhead to playbook execution.

See also: Ansible vs Terraform: Are They the Same? Key Differences Explained (2026)

Conclusion

Ansible plugins are a powerful way to extend Ansible’s functionality and customize workflows to meet unique requirements. With various built-in types and support for custom development, plugins empower users to optimize their automation tasks effectively.

Learn More About Ansible Plugins

Plugin Types

| Type | Purpose | Example | |------|---------|---------| | Connection | How Ansible connects to hosts | ssh, winrm, local, docker | | Callback | Output formatting and events | default, json, yaml, unixy | | Lookup | Retrieve data from external sources | file, env, password, template | | Filter | Transform data in Jinja2 | to_json, regex_search, combine | | Inventory | Dynamic inventory sources | aws_ec2, azure_rm, vmware_vm_inventory | | Strategy | Execution strategy | linear, free, debug | | Vars | Load variables from sources | host_group_vars | | Cache | Cache facts between runs | jsonfile, redis, memcached | | Test | Jinja2 test functions | defined, match, search | | Module | Task execution units | copy, apt, user |

Connection Plugins

# SSH (default)
ansible_connection: ssh

# Local (no SSH) ansible_connection: local

# Docker ansible_connection: community.docker.docker

# WinRM ansible_connection: winrm

Callback Plugins

# ansible.cfg
[defaults]
stdout_callback = yaml           # YAML formatted output
callbacks_enabled = timer, profile_tasks
# One-time override
ANSIBLE_STDOUT_CALLBACK=json ansible-playbook site.yml

Lookup Plugins

- debug:
    msg:
      - "File: {{ lookup('file', '/etc/hostname') }}"
      - "Env: {{ lookup('env', 'HOME') }}"
      - "Password: {{ lookup('password', '/tmp/pw length=16') }}"
      - "Template: {{ lookup('template', 'msg.j2') }}"
      - "URL: {{ lookup('url', 'https://api.example.com/status') }}"
      - "Pipe: {{ lookup('pipe', 'date +%Y-%m-%d') }}"

Filter Plugins

- debug:
    msg:
      - "{{ my_list | sort | unique }}"
      - "{{ my_dict | to_nice_json }}"
      - "{{ 'hello' | upper }}"
      - "{{ password | password_hash('sha512') }}"

Inventory Plugins

# aws_ec2.yml
plugin: amazon.aws.aws_ec2
regions:
  - us-east-1
keyed_groups:
  - key: tags.Environment
    prefix: env

Strategy Plugins

# Default: linear (task by task)
- hosts: all
  strategy: free  # Each host runs independently

# Debug strategy (interactive) - hosts: all strategy: debug # Pause on errors for debugging

Custom Plugin Locations

my-project/
  lookup_plugins/     # Custom lookup plugins
  filter_plugins/     # Custom filter plugins
  callback_plugins/   # Custom callback plugins
  connection_plugins/ # Custom connection plugins
  inventory_plugins/  # Custom inventory plugins

Write a Custom Filter Plugin

# filter_plugins/my_filters.py
class FilterModule:
    def filters(self):
        return {
            'double': lambda x: x * 2,
            'prefix': lambda x, p: f"{p}_{x}",
        }
- debug:
    msg: "{{ 5 | double }}"  # 10

List Available Plugins

ansible-doc -t callback -l    # List callback plugins
ansible-doc -t lookup -l      # List lookup plugins
ansible-doc -t connection -l  # List connection plugins
ansible-doc -t inventory -l   # List inventory plugins

FAQ

Plugins vs Modules?

Modules are a type of plugin that execute tasks. Other plugins extend Ansible's core functionality (connections, output, data retrieval).

Where are plugins installed?

Built-in: with Ansible installation. Collection plugins: ~/.ansible/collections/. Custom: in project *_plugins/ directories.

Can I use plugins from collections?

Yes — most collections include plugins. Use FQCN: community.general.json_query (filter), amazon.aws.aws_ec2 (inventory).

Plugin Types

| Type | Purpose | Example | |------|---------|---------| | Lookup | Retrieve data | file, env, password | | Filter | Transform data | to_json, regex_replace | | Callback | Control output | json, yaml, timer | | Connection | Connect to hosts | ssh, winrm, docker | | Inventory | Dynamic inventory | aws_ec2, azure_rm | | Module | Execute tasks | copy, apt, file | | Strategy | Execution strategy | linear, free, debug | | Vars | Load variables | host_group_vars | | Cache | Cache facts | jsonfile, redis | | Test | Jinja2 tests | match, search |

Lookup Plugins

# File
msg: "{{ lookup('file', '/etc/hostname') }}"

# Environment variable msg: "{{ lookup('env', 'HOME') }}"

# Password generation msg: "{{ lookup('password', '/dev/null length=16') }}"

# Template msg: "{{ lookup('template', 'my.conf.j2') }}"

# Pipe (run command) msg: "{{ lookup('pipe', 'date +%Y%m%d') }}"

# URL msg: "{{ lookup('url', 'https://api.example.com/version') }}"

# Vault-encrypted file msg: "{{ lookup('file', 'secrets/api_key.vault') }}"

Filter Plugins

# Built-in
"{{ name | upper }}"
"{{ list | join(', ') }}"
"{{ dict | to_nice_json }}"
"{{ hash | combine(overrides) }}"
"{{ 'text' | regex_replace('old', 'new') }}"
"{{ path | basename }}"
"{{ timestamp | to_datetime }}"

# Ansible-specific "{{ pass | password_hash('sha512') }}" "{{ groups['web'] | map('extract', hostvars, 'ansible_host') | list }}" "{{ my_var | type_debug }}"

Callback Plugins

# ansible.cfg
[defaults]
# Change output format
stdout_callback = yaml
# Enable additional callbacks
callbacks_enabled = timer, profile_tasks
# List available callbacks
ansible-doc -t callback -l

Connection Plugins

# SSH (default for Linux)
[linux]
server1 ansible_connection=ssh

# WinRM (Windows) [windows] win1 ansible_connection=winrm

# Docker container [containers] myapp ansible_connection=community.docker.docker

# Local (run on controller) [local] localhost ansible_connection=local

Custom Filter Plugin

# plugins/filter/custom_filters.py
class FilterModule:
    def filters(self):
        return {
            'reverse_dns': self.reverse_dns,
            'to_cidr': self.to_cidr,
        }

def reverse_dns(self, ip): parts = ip.split('.') return '.'.join(reversed(parts)) + '.in-addr.arpa'

def to_cidr(self, ip, prefix=24): return f"{ip}/{prefix}"

# Usage
msg: "{{ '10.0.1.5' | reverse_dns }}"
# "5.1.0.10.in-addr.arpa"

Custom Lookup Plugin

# plugins/lookup/my_lookup.py
from ansible.plugins.lookup import LookupBase

class LookupModule(LookupBase): def run(self, terms, variables=None, **kwargs): results = [] for term in terms: results.append(term.upper()) return results

Plugin Search Path

# ansible.cfg
[defaults]
lookup_plugins = ./plugins/lookup
filter_plugins = ./plugins/filter
callback_plugins = ./plugins/callback

FAQ

How to list all available plugins?

ansible-doc -t lookup -l    # Lookups
ansible-doc -t callback -l  # Callbacks
ansible-doc -t inventory -l # Inventory

Where are built-in plugins stored?

In the Ansible Python package: ansible/plugins/. Collection plugins are in ~/.ansible/collections/.

Can I override built-in plugins?

Yes — place a plugin with the same name in your local plugin directory. Local plugins take precedence.

Related Articles

secrets management with Ansible VaultAnsible template vs copy moduleAnsible Inventory GuideIAM management via Ansible on AWS

Category: installation

Browse all Ansible tutorials · AnsiblePilot Home