How to Use Jinja2 Filters in Ansible

How to Use Jinja2 Filters in Ansible
In: Ansible NetDevOps

Hello! In this blog post, we're going to explore how to use Jinja2 filters in Ansible. Jinja2 filters are a key part of Ansible, helping you modify and manage data easily in your playbooks. We'll look at some basic and advanced uses of these filters to enhance your Ansible tasks. Let's get started!

Introduction to Jinja2 in Ansible

Jinja2 is a powerful templating engine for Python, and it's an integral part of Ansible. It's primarily used for generating text files (like configuration files) from templates, but its capabilities extend far beyond that. In Ansible, Jinja2 comes into play for variable substitution and data manipulation within playbooks.

At its core, Jinja2 uses placeholders for rendering dynamic content. These placeholders are defined in double curly braces, like {{ variable_name }}. When Ansible runs a playbook, it replaces these placeholders with actual variable values, making the content dynamic.

What makes Jinja2 especially useful in Ansible is its filtering capability. Filters in Jinja2 are used to transform the data passed to them. They can modify strings, manage lists, perform logical operations, and much more. A filter is typically applied to a variable using the pipe syntax, {{ variable_name | filter_name }}.

Basic Use of Jinja2 Filters in Ansible

Let's start with a simple example to illustrate the basic usage of Jinja2 filters in an Ansible playbook. Suppose you have a variable containing a string, and you want to convert this string to uppercase. This can be easily achieved using the upper filter in Jinja2. Here's a small playbook snippet demonstrating this.

---
- name: Jinja2 Filters Basic Example
  hosts: localhost
  gather_facts: False

  vars:
    original_string: "hello world"
    
  tasks:
    - name: Convert string to uppercase
      debug:
        msg: "{{ original_string | upper }}"
  • We define a variable original_string with the value "hello world".
  • The task uses the debug module to print a message. The message is the original_string variable passed through the upper filter.
  • The upper filter transforms the string to all uppercase letters.
  • When this playbook runs, it will output "HELLO WORLD".

Chaining Multiple Jinja2 Filters in Ansible

An advanced yet incredibly useful feature in Ansible is the ability to chain multiple Jinja2 filters together to perform complex data manipulations in a single line. This technique allows you to combine the functionality of several filters, enabling more sophisticated and streamlined data processing within your playbooks.

Understanding Filter Chains

When chaining filters, the output of one filter becomes the input for the next. This is done using the pipe (|) symbol. The beauty of filter chaining is that it allows you to compactly express a series of transformations that would otherwise require multiple tasks or complex coding. Here are the key points to remember.

  1. Order Matters - The order in which you apply filters is crucial. Each filter transforms the data in a specific way, and the next filter in the chain acts on this transformed data.
  2. Readability - While chaining filters can be powerful, it's important to maintain readability. Overly complex chains can become difficult to understand and maintain.
  3. Common Uses - Common scenarios for filter chaining include string formatting (like trimming whitespace and then changing to uppercase), list processing (like filtering and then sorting), and data extraction (like converting JSON and then querying it).

Suppose you have a string variable that contains extra whitespace and mixed case, and you want to clean it up by trimming the whitespace and converting the string to uppercase.

---
- name: Chaining Jinja2 Filters Example
  hosts: localhost
  gather_facts: False

  vars:
    messy_string: "   Hello World   "
    
  tasks:
    - name: Clean and format the string
      debug:
        msg: "{{ messy_string | trim | upper }}"

Using Jinja2 Filters for List Manipulation in Ansible

Now, let's look at an example of using Jinja2 filters to manipulate lists in an Ansible playbook. Imagine you have a list of numbers and you want to filter out only the even numbers. This can be accomplished using the select filter in Jinja2.

---
- name: Jinja2 Filters for List Manipulation
  hosts: localhost
  gather_facts: False

  vars:
    number_list: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    
  tasks:
    - name: Filter even numbers from the list
      debug:
        msg: "{{ number_list | select('even') }}"
  • We have a list number_list containing numbers from 1 to 10.
  • The task uses the debug module to print a message. The message is the number_list passed through the select('even') filter. This filter selects only even numbers from the list.
  • When this playbook runs, it will output the even numbers [2, 4, 6, 8, 10].

Formatting Strings with Jinja2 Filters in Ansible

Moving forward, let's explore how Jinja2 filters can be used for advanced string formatting in an Ansible playbook. Often, there's a need to modify strings by replacing certain substrings with others. This can be efficiently done using the replace filter in Jinja2.

---
- name: Jinja2 Filters for String Formatting
  hosts: localhost
  gather_facts: False

  vars:
    original_sentence: "Hello, this is a sample sentence."
    
  tasks:
    - name: Replace 'sample' with 'test'
      debug:
        msg: "{{ original_sentence | replace('sample', 'test') }}"

Using the Default Filter in Ansible for Setting Fallback Values

The default filter in Jinja2, used within Ansible, is essential for handling variables that might not be defined in certain contexts. This filter allows you to set a default value for a variable if it's not already defined or is undefined. Let's see an example of how this can be effectively used in an Ansible playbook.

Imagine you have a task that needs to use a variable, but you aren't sure if it's always going to be passed into the playbook. You can use the default filter to set a fallback value.

---
- name: Using the default filter
  hosts: localhost
  gather_facts: False
  vars:
    # Assume some_var might not be always defined
  tasks:
    - name: Use a variable with a default value
      debug:
        msg: "{{ some_var | default('default_value') }}"
  • The variable some_var is used, but it's not defined under vars. This might simulate a scenario where the variable could be provided in some runs and not in others.
  • In the debug task, we use some_var | default('default_value'). This means if some_var is not defined or is null, it will default to 'default_value'.
  • The output of this task will be 'default_value' if some_var is undefined. If some_var is defined elsewhere (like in inventory, command line, or another variable file), it will use that value instead.

Some of the Useful Jinja2 Filters in Ansible

Here's a list of some simple yet incredibly handy Jinja2 filters that you can use in Ansible for everyday data manipulation tasks:

  1. upper: Converts a string to uppercase. Ideal for standardizing text format, especially useful in cases where case consistency is required.
  2. lower: Transforms a string to lowercase. It's great for ensuring case-insensitive comparisons or processing user input.
  3. trim: Removes leading and trailing whitespace from a string. This is particularly useful for cleaning up user input or data extracted from files or external sources.
  4. replace: Replaces occurrences of a substring within a string with a different substring. A straightforward way to modify text content.
  5. length: Provides the length of a string or list.
  6. join: Concatenates the elements of a list into a single string, with an optional separator. Useful for creating a single string out of a list of items.
  7. split: Splits a string into a list of substrings based on a separator. This can be used for breaking down user input or parsing structured text.
  8. round: Rounds a floating-point number to a specified number of decimal places.
  9. sort: Sorts the elements of a list. It can sort strings alphabetically and numbers numerically, providing an easy way to organize data.

Closing Up

In conclusion, Jinja2 filters in Ansible offer a powerful and flexible way to manipulate data within your playbooks. From simple string transformations to more complex operations like list manipulation and JSON data processing, these filters allow for elegant and efficient scripting solutions.

Table of Contents
Written by
Suresh Vina
Tech enthusiast sharing Networking, Cloud & Automation insights. Join me in a welcoming space to learn & grow with simplicity and practicality.
Comments
More from Packetswitch
Great! You’ve successfully signed up.
Welcome back! You've successfully signed in.
You've successfully subscribed to Packetswitch.
Your link has expired.
Success! Check your email for magic link to sign-in.
Success! Your billing info has been updated.
Your billing was not updated.