Jinja2

Delimiters

  • {%....%} are for statements

  • {{....}} are expressions used to print to template output

  • {#....#} are for comments which are not included in the template output

  • #....## are used as line statements

Let’s create a new playbook named jinja.yml and use the code below. One additional Jinja function we’ll use is joiner. Joiner allows the passing of list items and all but the last item will get the delimiter added to it. In our example that’s the , .

jinja.yml
---
- hosts: all
  gather_facts: false
  connection: local

  vars:
    var1: itema,itemb,itemc,itemd

  tasks:

  - name: Set Fact from vars (build a list)
    ansible.builtin.set_fact:
      jinja: "{{ var1.split(',') }}"

  - name: Echo jinja List
    ansible.builtin.debug:
      var: jinja

  - name: Echo jinja loop
    ansible.builtin.debug:
      msg: "{% set comma=joiner(',') %} {% for item in jinja %} {{comma()}} {{ item }} {% endfor %}"

To run this example:

ansible-playbook -i "localhost," jinja.yml

An example of a F5 deployment using a j2 (Jinja) template

Example Ansible task
 1- name: Push Declaration
 2  ansible.builtin.uri:
 3    url: "https://{{ hostvar[groups['adc'][0]]['ansible_host']/mgmt/shared/appsvcs/declare"
 4    method: POST
 5    body: "{{ lookup('template', 'exampleFile.j2', split_lines=False) }}"
 6    body_format: json
 7    headers:
 8      Content-type: application/json
 9      X-F5-Auth-Token: "{{ Auth.tok.json.token.token }}"
10    status_code: 200
11    timeout: 300
12    validate_certs: no
13  delegate_to: localhost

This example (thanks to Forrest Crenshaw @F5 on Linklight Exercise 3) is used to loop through all our pool members from inventory and add them to the Virtual Server

"members": [
        {
            "servicePort": {{ item.svc_port }},
            "serverAddresses": [
            {% set comma = joiner(",") %}
            {% for mem in item.pool_members %}
              {{comma()}} "{{ hostvars[mem]['ansible_host'] }}"
            {% endfor %}
            ]

You can run Jinja2 functions on an online parser here .

In this example you can use the online parser to run your tempate code and supply the associated YAML values.

Jinja Template
 {
   "allowed-ip": [
     {% set comma = joiner(",") %}
     {% for acl in acls %}{{ comma() }}
       {
         "name": "{{ acl.acl_name }}",
         "config": {
             "ipv4": {
                 "address": "{{ acl.acl_ip }}",
                 "prefix-length": "{{ acl.acl_prefixLength }}",
                 "port": {{ acl.acl_port }}
             }
         }
       }{% endfor %}
   ]
 }
Values(YAML)
acls:
  - acl_name: test
    acl_ip: 10.1.10.11
    acl_prefixLength: 24
    acl_port: 22
  - acl_name: test
    acl_ip: 10.1.10.12
    acl_prefixLength: 24
    acl_port: 22