Jinja Filters

Jinja filters provide a way to transform and manipulate data in actions within your rulebooks. These filters can be used to format strings, extract parts of file paths, and perform regex replacements on event data before it is used in actions.

Note

Jinja filters can be used in actions in rulebooks, but cannot be used in conditions. Conditions must use the native condition operators and tests provided by the rule engine.

Usage in Actions

Jinja filters are used in actions with the standard Jinja2 syntax using the pipe (|) operator. You can chain multiple filters together to perform complex transformations.

Example:

action:
  debug:
    msg: "{{ event.name | upper | replace('HELLO', 'GOODBYE') }}"

Available Filters

ansible-rulebook provides custom Jinja filters in addition to all standard Python string methods and built-in Jinja2 filters. The custom filters are:

  • regex_replace

  • basename

  • dirname

  • normpath

regex_replace

Perform a regex substitution on a string value.

Parameter

Description

Required

pattern

The regular expression pattern to search for

Yes

replacement

The replacement string

Yes

count

Maximum number of occurrences to replace (0 means replace all). Default: 0

No

ignore_case

Perform case-insensitive matching. Default: false

No

multiline

Enable multiline mode for regex. Default: false

No

mandatory_count

Minimum number of replacements required (raises error if not met). Default: 0

No

Examples:

action:
  debug:
    msg: "{{ event.name | regex_replace('host1', 'host195') }}"
action:
  post_event:
    event:
      msg: "{{ event.name | regex_replace('Bamm', 'Betty', count=1) }}"

basename

Extract the basename (filename) from a file path.

Examples:

# Input: "/etc/certs/cert.pem"
# Output: "cert.pem"
action:
  debug:
    msg: "{{ event.filepath | basename }}"
action:
  post_event:
    event:
      basename: "{{ event.filename | normpath | basename }}"

dirname

Extract the directory name from a file path.

Examples:

# Input: "/etc/certs/cert.pem"
# Output: "/etc/certs"
action:
  debug:
    msg: "{{ event.filepath | dirname }}"
# Chaining filters: first normalize, then get dirname
action:
  post_event:
    event:
      dirname: "{{ event.filename | normpath | dirname }}"

Note

If only a filename without a path is provided, dirname returns an empty string.

normpath

Normalize a file path by collapsing redundant separators and up-level references.

Examples:

# Input: "/abc//def//jhk/test.txt"
# Output: "/abc/def/jhk/test.txt"
action:
  debug:
    msg: "{{ event.filepath | normpath }}"
action:
  post_event:
    event:
      normal: "{{ event.filename | normpath }}"

Python String Methods

In addition to the custom filters above, all Python string methods are available as filters. Common examples include:

  • upper - Convert to uppercase

  • lower - Convert to lowercase

  • capitalize - Capitalize first character

  • replace(old, new) - Replace occurrences of a substring

  • split(separator) - Split string into a list

Examples:

action:
  debug:
    msg:
      - "{{ event.name | replace('.com', '') }}"
      - "{{ event.name.split('.') | first }}"
      - "{{ event.name | capitalize }}"

Chaining Filters

Filters can be chained together by using multiple pipe operators. Each filter processes the output of the previous filter in the chain.

Example:

action:
  post_event:
    event:
      # First normalize the path, then get the directory, then convert to uppercase
      clean_dir: "{{ event.filename | normpath | dirname | upper }}"

Complete Examples

Example 1: String manipulation with regex and string methods

---
- name: 97 jinja
  hosts: all
  sources:
    - eda.builtin.generic:
        payload:
           - name: "host1.net"
           - name: "Bamm Bamm Rubble"
        create_index: index
        shutdown_delay: 5
  rules:
    - name: regex rule
      condition: event.name is regex("host")
      actions:
        - debug:
            msg:
              - "{{ event.name | replace('.com', '') }}"
              - "{{ event.name.split('.') | first }}"
              - "{{ event.name | capitalize }}"
              - "{{ event.name | regex_replace('host1', 'host195') }}"
    - name: original event
      condition: event.name == "Bamm Bamm Rubble"
      actions:
        - post_event:
             event:
                msg: "{{ event.name | regex_replace('Bamm', 'Betty', count=1) }}"
    - name: posted event
      condition: event.msg == "Betty Bamm Rubble"
      action:
        print_event:

Example 2: File path manipulation

---
- name: 98 jinja files
  hosts: all
  sources:
    - eda.builtin.generic:
        payload:
           - filename: "/abc//def//jhk/test.txt"
        create_index: index
        shutdown_delay: 5
  rules:
    - name: basename
      condition: event.basename == "test.txt"
      actions:
        - print_event:
    - name: dirname
      condition: event.dirname == "/abc/def/jhk"
      actions:
        - print_event:
    - name: normpath
      condition: event.normal == "/abc/def/jhk/test.txt"
      actions:
        - print_event:
    - name: catch_all
      condition: true
      actions:
        - post_event:
            event:
              normal: "{{ event.filename | normpath }}"
        - post_event:
            event:
              dirname: "{{ event.filename | normpath | dirname }}"
        - post_event:
            event:
              basename: "{{ event.filename | normpath | basename }}"

Built-in Jinja2 Filters

ansible-rulebook also supports standard Jinja2 filters. Some commonly used ones include:

  • default(value) - Provide a default value if the variable is undefined

  • first - Get the first item from a list

  • last - Get the last item from a list

  • length - Get the length of a list or string

  • join(separator) - Join a list into a string

For a complete list of Jinja2 filters, see the Jinja2 documentation.

Example:

action:
  debug:
    msg: "{{ event.items | default([]) | length }}"

FAQ

Q: Can I use Jinja filters in conditions?
Ans: No, Jinja filters cannot be used in conditions. Conditions use the rule engine’s native
operators and tests. You can only use Jinja filters in actions to transform data before using it.
Q: What happens if a Jinja filter receives a None value?
Ans: The custom filters (regex_replace, basename, dirname, normpath) handle None values
gracefully by returning an empty string. For other filters, you should use the default filter
to provide a fallback value.
Q: Can I create custom Jinja filters?
Ans: Currently, ansible-rulebook provides the four custom filters listed above. For other
transformations, you can use Python string methods, built-in Jinja2 filters, or chain multiple
filters together.
Q: How do I handle errors in regex_replace?
Ans: You can use the mandatory_count parameter to ensure a minimum number of replacements
occur. If the mandatory count is not met, an error will be raised. Without this parameter, the
filter will return the original string if no matches are found.