Ansible plugins are pieces of code that augment Ansible's core functionality. They allow you to extend Ansible's capabilities in various ways, such as adding new connection methods, lookup methods, or even custom actions. This topic will cover the different types of plugins available in Ansible, how to create your own plugins, and practical examples to help you understand their usage.
Types of Ansible Plugins
Ansible supports several types of plugins, each serving a different purpose:
- Action Plugins: Modify the behavior of Ansible modules.
- Callback Plugins: Respond to events during playbook execution.
- Connection Plugins: Define how Ansible connects to hosts.
- Lookup Plugins: Retrieve data from external sources.
- Filter Plugins: Transform data within Jinja2 templates.
- Test Plugins: Provide custom tests for conditionals in Jinja2 templates.
- Vars Plugins: Load variables from external sources.
- Inventory Plugins: Dynamically generate inventory from external sources.
Creating a Custom Filter Plugin
Let's create a simple custom filter plugin that reverses a string. This example will help you understand the structure and implementation of a filter plugin.
Step-by-Step Guide
-
Directory Structure: Create a directory structure for your custom plugin. For this example, we'll place our plugin in a directory named
filter_plugins
.my_ansible_project/ ├── filter_plugins/ │ └── reverse.py └── playbook.yml
-
Plugin Code: In the
reverse.py
file, write the following code:# reverse.py class FilterModule(object): def filters(self): return { 'reverse_string': self.reverse_string } def reverse_string(self, value): return value[::-1]
Explanation:
FilterModule
class: Defines the plugin.filters
method: Returns a dictionary mapping filter names to their corresponding methods.reverse_string
method: Implements the logic to reverse a string.
-
Using the Plugin in a Playbook: Create a playbook
playbook.yml
to use the custom filter plugin.# playbook.yml - name: Test custom filter plugin hosts: localhost vars: my_string: "Hello, Ansible!" tasks: - name: Reverse the string debug: msg: "{{ my_string | reverse_string }}"
Explanation:
vars
: Defines a variablemy_string
.tasks
: Uses thedebug
module to print the reversed string using the custom filterreverse_string
.
-
Running the Playbook: Execute the playbook to see the custom filter in action.
ansible-playbook playbook.yml
Expected Output:
TASK [Reverse the string] **************************************************** ok: [localhost] => { "msg": "!elbisnA ,olleH" }
Practical Exercises
Exercise 1: Create a Custom Lookup Plugin
Objective: Create a custom lookup plugin that reads data from a local JSON file.
-
Directory Structure:
my_ansible_project/ ├── lookup_plugins/ │ └── json_lookup.py ├── data.json └── playbook.yml
-
Plugin Code:
# json_lookup.py import json class LookupModule(object): def __init__(self, *args, **kwargs): pass def run(self, terms, variables=None, **kwargs): with open(terms[0], 'r') as f: data = json.load(f) return [data]
-
JSON Data (
data.json
):{ "name": "Ansible", "type": "Automation" }
-
Playbook (
playbook.yml
):- name: Test custom lookup plugin hosts: localhost tasks: - name: Read data from JSON file debug: msg: "{{ lookup('json_lookup', 'data.json') }}"
-
Run the Playbook:
ansible-playbook playbook.yml
Expected Output:
TASK [Read data from JSON file] ok: [localhost] => { "msg": [ { "name": "Ansible", "type": "Automation" } ] }
Exercise 2: Create a Custom Callback Plugin
Objective: Create a custom callback plugin that logs task results to a file.
-
Directory Structure:
my_ansible_project/ ├── callback_plugins/ │ └── log_results.py └── playbook.yml
-
Plugin Code:
# log_results.py from ansible.plugins.callback import CallbackBase class CallbackModule(CallbackBase): def v2_runner_on_ok(self, result): with open('task_results.log', 'a') as f: f.write(f"Task {result.task_name} succeeded: {result._result}\n")
-
Playbook (
playbook.yml
):- name: Test custom callback plugin hosts: localhost tasks: - name: Test task debug: msg: "This is a test message"
-
Run the Playbook:
ANSIBLE_STDOUT_CALLBACK=log_results ansible-playbook playbook.yml
Expected Output:
Check the task_results.log
file for the logged task results.
Summary
In this section, we covered the different types of Ansible plugins and how they can extend Ansible's functionality. We walked through creating a custom filter plugin and provided practical exercises for creating custom lookup and callback plugins. Understanding and utilizing plugins can significantly enhance your Ansible automation capabilities, allowing for more flexible and powerful playbooks.
Ansible: From Beginner to Advanced
Module 1: Introduction to Ansible
Module 2: Ansible Basics
Module 3: Playbooks
- Introduction to Playbooks
- Writing Your First Playbook
- Playbook Structure
- Variables and Facts
- Conditionals and Loops
Module 4: Roles
Module 5: Advanced Playbook Techniques
Module 6: Ansible Galaxy
Module 7: Ansible Tower
- Introduction to Ansible Tower
- Installing Ansible Tower
- Using Ansible Tower
- Managing Projects and Inventories