Filter plugins

Filter plugins #

  • Directory: ./filter_plugins

Filters are actually a feature of the Jinja2 templating engine that Ansible uses. Jinja2 allows defining custom filters, and Ansible will automatically find custom filters if they are placed in the right location.

A filter might combine two objects, or remove properties from an object, or transform an object.

Knowing how to write filter plugins is perhaps the first Ansible extension skill I recommend, because:

  • They are very easy, requiring little code
  • They keep you from doing strange and incomprehensible things with set_fact
  • The name belies how useful they are; you may write filter plugins for reasons beyond a normal-English understanding of what “filtering” is

Filters and actions: pure functions and side effects #

If you are familiar with functional programming, it’s useful to think of filters and actions are FP-style “pure functions” and “functions with side effects”.

That is, a filter plugin should be an idempotent transformation returning a copy of new data that does not persist state or make any changes. By contrast, an action (whether implemented as a plugin or a module) might make permanent state changes like writing a file or formatting a disk.

Please take this as a rule of thumb, not an iron law.

TODO

refactor much of the prose here into this chapter https://me.micahrl.com/blog/ansible-filter-pure-function/

Recipes #

Filter template
Filter template # This filter template can be used as the starting point for writing your own filters. As you can see, there’s not much to it. After all, a filter must simply take input and return output. """A template for an Ansible filter plugin""" def some_filter(input): """Filter some text and return some other text""" # Calculate the result from the input here result = "..." return result # Your Python module must export a class called 'FilterModule' # with a 'filters()' function that returns a dict of filters.
Public key filters
Public key filters # Let’s say you have stored a private key in your Ansible vault. Do you have to store the public key next to it, or can you generate it from the private key? For crypto systems including SSH and Wireguard, you can generate the public key from the private key, which is especially useful when rotating keys or generating them programmatically. Here are some filters that accomplish this:
RFC 4122 name-based UUID filters
RFC 4122 name-based UUID filters # Per RFC4122, a name-based UUID is generated from a ‘name’ (any input) and a ‘namespace’ (itself a UUID which uniquely represents the namespace). Given the same name and namespace, will always return the same value. If you find yourself needing a unique identifier for something based on a static piece of data, NBUUIDs are a good choice. I wrote this plugin because I needed UUID-style identifiers for an Apple .
Custom dict operation filters
Custom dict operation filters # Filters are not limited to text. Ansible makes it easy to write dict vars like this: example_var: dict_key_1: The value of dict key one another_key: This is another value Et: cetera And filters can work on these variables as well. You might think of them as “dictionaries”, “associative arrays”, “hashtables”, “hashmaps”, or the like. However, it is not always easy to modify these dicts, depending on what you want to do.