Slide 1

Slide 1 text

ADVANCED JINJA2 FOR TEMPLATES REVIEW JINJA2 ORIGIN STORY COMPARING TO DIY, JINJA 101, AND A DIVE INTO SOME LESS COMMONLY USED PATTERNS Keith Resar @KeithResar

Slide 2

Slide 2 text

@KeithResar Keith Resar: Bio Wear many hats @KeithResar [email protected] Coder Open Source Contributor and Advocate Infrastructure Architect

Slide 3

Slide 3 text

TEMPLATING THE HARD WAY, FROM AN AMATUER FOCUSSED ON DIY

Slide 4

Slide 4 text

From: Pro-Speller <[email protected]>
Date: %{{exec("%s" % ((datetime.today() - timedelta(minutes = 47)).strftime("%A, %B %e, %Y at %l:%M %p")))}}%
To: Andrea Jacobs <[email protected]>
Subject: Your Scan Results - %{{url_f}}%
THE ILL ADVISED DIY TEMPLATE

Slide 5

Slide 5 text

THE ILL ADVISED DIY TEMPLATE %{{INNER_TPL}}%
%{{INNER.WORD}}%  :   %{{INNER.SUGGESTIONS}}%
%{{INNER.CONTEXT}}%
%{{ENDINNER_TPL}}%

Slide 6

Slide 6 text

PERL BOOTSTRAPPING > perl -p -i -e \ 's/^PermitRootLogin .*/PermitRootLogin no' \ sshd_config

Slide 7

Slide 7 text

JINJA2, AN ORIGIN STORY

Slide 8

Slide 8 text

APPLICATION LOGIC IS FOR THE CONTROLLER, BUT DON'T MAKE THE TEMPLATE DESIGNER'S LIFE DIFFICULT BY RESTRICTING FUNCTIONALITY TOO MUCH. https://github.com/pallets/jinja#philosophy

Slide 9

Slide 9 text

{% extends "layout.html" %} {% block body %} {% endblock %} PURE, BEAUTIFUL JINJA

Slide 10

Slide 10 text

PURE, BEAUTIFUL JINJA Sandboxed Execution Mode Every aspect of the template execution is monitored and explicitly whitelisted or blacklisted, whatever is preferred. This makes it possible to execute untrusted templates. Template Inheritance Makes it possible to use the same or a similar layout for all templates. Easy to Debug With a debug system that integrates template compile and runtime errors into the standard Python traceback system. Configurable Syntax For instance you can reconfigure Jinja2 to better fit output formats such as LaTeX or JavaScript. (skipped the features more relevant to high-volume usage such as in Django)

Slide 11

Slide 11 text

JINJA2 TEMPLATE MODULE 101

Slide 12

Slide 12 text

TEMPLATE FILE NAMING CONVENTIONS Accepts any text file type text, xml, html, etc Convention is to name files with .j2 extension http.conf.j2, sshd_config.j2 Convention to place in the templates/ directory templates/http.conf.j2, templates/sshd_config.j2

Slide 13

Slide 13 text

DEFAULT DELIMITERS {{ ... }} {% ... %} {# ... #}

Slide 14

Slide 14 text

EXPRESSIONS AS PYTHON Accessing Ansible variables like {{ ansible_hostname }} {{ ansible_date_time.epoch }} We can do math like {{ 1+3 }} Standard data types, like my list: {{ ('a','b','c') }} We can call standard methods associated with our types: {{ "lorem ipsum".upper() }} {{ ['a','b','c'].pop() }}

Slide 15

Slide 15 text

EXPRESSIONS JINJA STYLE Inline Conditionals: {{ '[%s]' % page.title if page.title }} Built-in Filters: {{ my_var | default('my_var undefined') }} Maths: abs, int, float, round, sum Str: capitalize, length, center, escape, lower, regex Lists: join, last, sort, shuffle, json_query

Slide 16

Slide 16 text

STATEMENTS Loops: Conditionals: {% if kenny.sick %} Kenny is sick. {% elif kenny.dead %} You killed Kenny! You bastard!!! {% else %} Kenny looks okay --- so far {% endif %}

Slide 17

Slide 17 text

COMMENTS {# Note: Nothing in the comment will be included in the template output {% for user in users %} ... {% endfor %} #}

Slide 18

Slide 18 text

WHEN THINGS GO WRONG fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "AnsibleUndefinedVariable: 'my_var' is undefined"} fatal: [localhost]: FAILED! => {"changed": false, "failed": true, "msg": "AnsibleError: template error while templating string: expected token 'end of print statement', got '...' String: <...>"}

Slide 19

Slide 19 text

MAKING WAVES WITH THE TEMPLATE MODULE, THANKS JINJA2!

Slide 20

Slide 20 text

OVERRIDING BEHAVIOR Include as first line in the template file: #jinja2:variable_start_string:'[%' , variable_end_string:'%]', trim_blocks: False

Slide 21

Slide 21 text

NESTING TEMPLATES {% include "file1.j2" %} {% include ['file1.j2', 'file2.j2'] %}

Slide 22

Slide 22 text

INTERESTING LOOPS Alternation: {% for row in rows %}
  • {{ row }}
  • {% endfor %} Empty Lists:
      {% for user in users %}
    • {{ user.username|e }}
    • {% else %}
    • no users found
    • {% endfor %}

    Slide 23

    Slide 23 text

    SORTING AND GROUPING FILTERS Sort by Attribute: {% for item in iterable|sort(attribute='date') %} ... {% endfor %} Group by Attribute: {% for group in persons|groupby('gender') %}
  • {{ group.grouper }}
      {% for person in group.list %}
    • {{ person.first_name }}
    • {% endfor %}
  • {% endfor %}

    Slide 24

    Slide 24 text

    RESOURCES Ansible Template Module http://docs.ansible.com/.../template_module.html jinja2 Template Designer Documentation http://jinja.pocoo.org/docs/2.9/templates/ ANSIBLE MINNEAPOLIS MEETUP https://www.meetup.com/Ansible-Minneapolis/

    Slide 25

    Slide 25 text

    @KeithResar @KeithResar THANKS!