What are Templates?
Back in the days, servers used to have a collection of files, like HTML files, which were sent over as requested by clients. These were static data being sent over.
Now, in the modern web world, we have less of static data and more of dynamic data being requested from clients and therefore sent by the server. The web totally depends on what the client is asking for, and on which user is signing in and who is logging out. So, Jinja2 templating is being used.
What is Jinja2?
Jinja2 is a modern and designer-friendly templating language for Python frameworks. It is fast, reliable and widely used for dynamic file generation based on its parameter.
It is used to create HTML, XML or other markup formats that are returned to the user via an HTTP request.
Jinja2 Features:
- Sandboxed execution
- Powerful automatic HTML escaping system for XSS prevention
- Template inheritance
- Compiles down to the optimal python code just in time
- Optional ahead-of-time template compilation
- Easy to debug. Line numbers of exceptions directly point to the correct line in the template.
- Configurable syntax
Why do we need Jinja 2?
Sandboxed Execution: It provides a protected framework for automation of testing programs, whose behaviour is unknown and must be investigated.
HTML Escaping: Jinja 2 has a powerful automatic HTML Escaping, which helps preventing Cross-site Scripting (XSS Attack). There are special characters like >,<,&, etc. which carry special meanings in the templates. So, if you want to use them as regular text in your documents then, replace them with entities. Not doing so might lead to XSS-Attack.
Template Inheritance: This is the most important feature, which I will expand on to later in the post.
Delimiters Used in Jinja 2
{%....%} are for statements such as condition and loop
{{....}} are expressions used to print to template output
{#....#} are for comments which are not included in the template output
#....## are used as line statements
How To Install Jinja 2
$ pip install jinja2
$ easy_install jinja2
<title>{% block title %}{% endblock %}</title>
<ul>
{% for user in users %}
<li><a href="{{ user.url }}">{{ user.username }}</a></li>
{% endfor %}
</ul>
<!DOCTYPE html>
<html>
<p>Hello {{ username }}</p>
</body>
</html>
We use for loop to iterate over the list_example and print it with this placeholder{{ name }}. To end for loop use {%endfor%} and to end if loop, use {%endif%}.
<!DOCTYPE html>
<html>
<head>
<title>Conditions</title>
</head>
<body>
<ul>
{% for name in list_example %}
<li>{{ name }}</li>
{% endfor %}
</ul>
<ol>
{% for name in list_example %}
<li>{{ name }}</li>
{% endfor %}
</ol>
</body>
</html>
Jinja 2 supports Template Inheritance, which is one of the most powerful and useful features of any template engine. It means one template can inherit from another template.
** /app/templates/base.html **
<! — “Parent Template” →
<!DOCTYPE html>
<html>
<head>
{% block head %}
<title>{% block title %}{% endblock %}</title>
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>
** /app/templates/index.html **
<! — “Child Template” →
{% extends “base.html” %}
{% block title %} Index {% endblock %}
{% block head %}
{{ super() }}
{% endblock %}
{% block body %}
<h1>Hello World</h1>
<p>Welcome to my site.</p>
{% endblock %}
/app/templates/404.html
{% extends ‘base.html’ %}
{% block title %} Page Not Found {% endblock %}
{% block body %}
<h1>404 Error :(</h1>
<p>What you were looking for is just not there.<p>
<a href=”{{ url_for(‘index’) }}”>go somewhere nice</a>
{% endblock %}
mysql_conf.yml
---
# MySQL connection settings.
mysql_port: "3306"
mysql_data_dir: "/var/lib/mysql"
mysql_pid_file: "{{ mysql_data_dir }}/mysqld.pid"
mysql_socket: "{{ mysql_data_dir }}/mysql.sock"
# Slow query log settings.
mysql_slow_query_log_enabled: yes
mysql_slow_query_time: "2"
mysql_slow_query_log_file: "{{ mysql_data_dir }}/mysql-slow.log"
# Based on resources
mysql_max_connections: "{{ (ansible_memtotal_mb // 12) | int }}"
# Set .._buffer_pool_size up to 70% of RAM but beware of setting too high.
mysql_innodb_buffer_pool_size: "{{ (ansible_memtotal_mb * 0.7) | int }}M"
# Set .._log_file_size to 25% of buffer pool size.
mysql_innodb_log_file_size: '{{ ((mysql_innodb_buffer_pool_size | string | replace("M", "") | int) * 0.25) | int }}M'
playbook.yml
- hosts: 127.0.0.1
vars_files:
- mysql_conf.yml
tasks:
- name: Creating my.cnf with respected resources
template:
src: mysql_conf.j2
dest: my.cnf
mysql_conf.j2
# {{ ansible_managed }}
[client]
port = {{ mysql_port }}
socket = {{ mysql_socket }}
[mysqld]
port = {{ mysql_port }}
datadir = {{ mysql_data_dir }}
socket = {{ mysql_socket }}
pid-file = {{ mysql_pid_file }}
# Slow query log configuration.
{% if mysql_slow_query_log_enabled %}
slow_query_log = 1
slow_query_log_file = {{ mysql_slow_query_log_file }}
long_query_time = {{ mysql_slow_query_time }}
{% endif %}
# InnoDB settings.
innodb_buffer_pool_size = {{ mysql_innodb_buffer_pool_size }}
innodb_log_file_size = {{ mysql_innodb_log_file_size }}
# Setting max connections
{% if mysql_max_connections | int > 3000 %}
max_connections = 3000
thread_cache_size = {{ (3000 * 0.15) | int }}
{% elif mysql_max_connections | int < 150 %}
max_connections = 150
thread_cache_size = {{ (150 * 0.15) | int }}
{% else %}
max_connections = {{ mysql_max_connections }}
thread_cache_size = {{ (mysql_max_connections | int * 0.15) | int }}
{% endif %}
Refernece
- https://jinja.palletsprojects.com/en/2.11.x/
- https://codeburst.io/jinja-2-explained-in-5-minutes-88548486834e
- https://mydbops.wordpress.com/2019/04/17/jinja2-for-better-ansible/

















I’m a DevOps/SRE/DevSecOps/Cloud Expert passionate about sharing knowledge and experiences. I am working at Cotocus. I blog tech insights at DevOps School, travel stories at Holiday Landmark, stock market tips at Stocks Mantra, health and fitness guidance at My Medic Plus, product reviews at I reviewed , and SEO strategies at Wizbrand.
Please find my social handles as below;
Rajesh Kumar Personal Website
Rajesh Kumar at YOUTUBE
Rajesh Kumar at INSTAGRAM
Rajesh Kumar at X
Rajesh Kumar at FACEBOOK
Rajesh Kumar at LINKEDIN
Rajesh Kumar at PINTEREST
Rajesh Kumar at QUORA
Rajesh Kumar at WIZBRAND