What is Ansible Plugins and How to Extend Ansible Through Plugins?

What is Ansible Plugins?

Did you know a large portion of Ansible’s functionality comes from the Ansible plugin system? These important pieces of code augment Ansible’s core functionality such as parsing and loading inventory and Playbooks, running Playbooks and reading the results. Essentially, Ansible uses plugins to extend what the system is doing under the hood.

Plugins are pieces of code that augment Ansible’s core functionality. Ansible uses a plugin architecture to enable a rich, flexible and expandable feature set.

Ansible ships with a number of handy plugins, and you can easily write your own.

  • Action Plugins
  • Become Plugins
  • Cache Plugins
  • Callback Plugins
  • Cliconf Plugins
  • Connection Plugins
  • Httpapi Plugins
  • Inventory Plugins
  • Lookup Plugins
  • Netconf Plugins
  • Shell Plugins
  • Strategy Plugins
  • Vars Plugins
  • Filters
  • Tests
  • Plugin Filter Configuration

The following types of plugins are available:

  • Action plugins are front ends to modules and can execute actions on the controller before calling the modules themselves.
  • Cache plugins are used to keep a cache of ‘facts’ to avoid costly fact-gathering operations.
  • Callback plugins enable you to hook into Ansible events for display or logging purposes.
  • Connection plugins define how to communicate with inventory hosts.
  • Filters plugins allow you to manipulate data inside Ansible plays and/or templates. This is a Jinja2 feature; Ansible ships extra filter plugins.
  • Lookup plugins are used to pull data from an external source. These are implemented using a custom Jinja2 function.
  • Strategy plugins control the flow of a play and execution logic.
  • Shell plugins deal with low-level commands and formatting for the different shells Ansible can encounter on remote hosts.
  • Test plugins allow you to validate data inside Ansible plays and/or templates. This is a Jinja2 feature; Ansible ships extra test plugins.
  • Vars plugins inject additional variable data into Ansible runs that did not come from an inventory, playbook, or the command line.

Action Plugins

One of the core critical plugins used by Ansible are action plugins. Anytime you run a module, Ansible first runs an action plugin.

Action plugins are a layer between the executor engine and the module and allow for controller-side actions to be taken before the module is executed.

A good example of this is the template module. If you look at template.py in the modules directory, it’s basically a Python stub with documentation strings, everything is done by the action plugin. The template action plugin itself creates the template file locally as a temporary file, and then uses the copy or file modules to push it out to the target system.

If Ansible finds an action plugin with the same name as the module, that action plugin is used, otherwise the ‘normal’ action plugin is used.

Tasks which use ‘async’ have a special action plugin, which is used to launch the task using the ‘async_wrapper’ module.

Callback Plugins

One of the more heavily developed plugins, callbacks provide a way to react to events which occur during the execution of Playbooks. Ansible can load multiple callbacks, however, we differentiate between callbacks which send output to the screen and those that don’t. This allows us to ensure output to the screen is legible.

Connection Plugins

Connection plugins, alongside action and callback plugins, are probably the most important plugins since they are used during the execution of every task. Connection plugins provide the transport layer between the Ansible controller and managed hosts. The simple API includes five methods:

  • connect
  • exec_command
  • put_file
  • get_file
  • disconnect
    These make it very easy to write connection plugins to connect to hosts via a wide range of methods. Whether it’s SSH, LXC, chroot, Docker, and so on, it’s easy to write something for Ansible to take control of.

Strategy Plugins

Strategy plugins are a new addition to Ansible 2.0 that allow users to execute tasks on hosts differently than the way Ansible traditionally did in 1.9.x and earlier. Ansible currently includes three strategies:

Linear (classic 1.x Ansible) – All hosts in the inventory must complete each task before any move on to running the next task. Some users objected to the linear strategy because it slows the system, so we introduced the “free” strategy…
Free – This allows each host to execute the tasks in its list as quickly as possible without waiting for other hosts to complete the same task.
Debug – This is one of the coolest things that has come from the community, in my opinion. The debug strategy turns Ansible into an interactive debugger.

Lookup Plugins

  • Lookup plugins allow Ansible to access data from outside sources. This can include reading the filesystem in addition to contacting external datastores and services.
  • Like all templating, these plugins are evaluated on the Ansible control machine, not on the target/remote.
  • The data returned by a lookup plugin is made available using the standard templating system in Ansible, and are typically used to load variables or templates with information from those systems.
  • Lookups are an Ansible-specific extension to the Jinja2 templating language.
  • Lookups occur on the local computer, not on the remote computer.
  • They are executed within the directory containing the role or play, as opposed to local tasks which are executed with the directory of the executed script.
  • You can pass wantlist=True to lookups to use in jinja2 template “for” loops.
  • Lookups are an advanced feature. You should have a good working knowledge of Ansible plays before incorporating them.
  • These are used mainly by the template engine inside Ansible. They’re used in two ways.
  • First, in a function syntax to load external information:

{{lookup(pipe’,/usr/bin/whoami’)}}
{{lookup(etcd’,somekey’)}} – this allows you to fetch a key out of an NCD store.

  • Second, lookup plugins are also the source of with loops (with_items loads the items.py lookup plugin).
  • A couple of caveats to bear in mind about lookup plugins are that they always execute on the Ansible controller, not on a remote system. Furthermore, they are always expected to return a list of items, because of their potential use with loops.

Filter and Test Plugins

Filter and test plugin classes extend the Jinja2 templating system Ansible uses for variables. They allow you to do some cool things with data transformation and testing of the value or type of variable being run through the Jinja2 engine.

For example, filters are used to transform data:

{{foo|int}}
{{foo|default(‘some value’)}}
And tests are used to validate data:

{{foo is defined}}

Cache Plugins

Part of the templating variable system, cache plugins are used to store gathered facts outside of local memory. This is important because, by default, Ansible uses the in-memory cache plugin which can cause problems if your process involves running several individual Playbooks and you need fact data. In such instances, each of those individual runs would need to regather those facts because they only reside in memory as long as a Playbook is running. In addition to the in-memory default, Ansible includes cache plugins to store fact data in memcached and Redis, or even just a flat JSON file.

Shell Plugins

Shell plugins are used to properly format commands for remote execution (quoting, escaping, logic, etc.). They were originally written to simplify the handling of ssh vs. winrm execution, but more plugins have been added for other shells (csh, fish, dash, to name a few).

Each connection plugin has a default shell plugin, for instance the winrm connection defaults to PowerShell.

Vars Plugins

Vars plugins are used to bring in additional host and group data during inventory parsing time. Oddly, Ansible doesn’t ship any vars plugins ourselves, this is something that only exists outside of Ansible. As such, we have not defined a base class. However, we are looking at revamping inventory which may remove the need for vars plugins.

Reference

  • https://www.ansible.com/blog/how-to-extend-ansible-through-plugins
  • https://docs.ansible.com/ansible/latest/user_guide/playbooks_lookups.html
  • https://docs.ansible.com/ansible/latest/plugins/lookup.html
  • https://docs.ansible.com/ansible/latest/dev_guide/developing_locally.html
  • https://docs.ansible.com/ansible/latest/dev_guide/index.html
Rajesh Kumar
Follow me