How to Escape JINJA
When working on big projects, sometimes you must know how to escape the syntax of Jinja. You can escape the syntax of Jinja using the following two ways:
-
One way is to escape the individual string or variable.
-
The second one is to escape the complete block.
If you want to escape a string in Jinja, you can use the following syntax:
{{ '{{' }}
In case you want to escape a large block that has the syntax of Jinja, you can use the raw blocks:
{% raw %}
Here you can put any text that has jinja characters that you want to escape.
{% endraw %}
The raw tags are very important. You can use them to escape a large block of code. You can use them when working with the file.managed and the contents_pillar option for managing files with a consul-template. It is because the consul-template shares a subset of syntax with the Jinja.
Raw blocks are essential so that the Jinja in the pillar can be rendered even before the calling of the file.managed. So, we need to escape the Jinja Syntax:
{% raw %}
- contents_pillar: |
job "test-job" {
<snipped>
task "test" {
driver = "docker"
config {
image = "docker-registry.service.consul:5000/test-job:{{key "nomad/jobs/test-job/version"}}"
<snipped>
{% endraw %}
Calling Salt Functions in Jinja
For the salt dictionary of execution function, the Jinja renderer offers a shortened lookup syntax.
# The following two function calls are equivalent.
{{ salt['cmd.run']('whoami') }}
{{ salt.cmd.run('whoami') }}
Debugging in Jinja
You can output every variable in the current Jinja context using the show full context function.
Context is: {{ show_full_context()|yaml(False) }}
Debug Logs
Yes, it is possible to troubleshoot a complicated Jinja template using the logs in Salt. For instance, when you try to make the call:
{%- do salt.log.error('testing the jinja logging') -%}
It will record the error message in the logs of the minions with the date and the time.
2022-12-6 01:24:40,728 [salt.module.logmod][ERROR ][3779] testing jinja logging
Profiling in Jinja
Identifying inefficiencies with state and pillar render times becomes increasingly crucial while working with a massive codebase. The profile jinja block gives the user access to highly specific data about the most expensive parts of the codebase.
Profiling Blocks
You can use a profile block to enclose any jinja code block. A profile block is written as follows:
{% profile as '<name>' %}<jinja code>{% endprofile%}
In the above syntax, <name> can be any string. Along with the block's render time, the <name> token will be recorded in the log at the profile level.
# /srv/salt/test.sls
{%- profile as 'local data' %}
{%- set local_data = {'ctr': 0} %}
{%- for i in range(313577) %}
{%- do local_data.update({'ctr': i}) %}
{%- endfor %}
{%- endprofile %}
test:
cmd.run:
- name: |-
printf 'test data: %s' '{{ local_data['ctr'] }}'
The profile block will produce the following log statement in the test.sls state:
salt-call --local -l profile state.apply test
[...]
[PROFILE ] Time (in seconds) to render profile block 'local data': 0.9385035056994385
[...]
Profiling Imports
The import_json, import_text, and import_yaml blocks will output quite the same statements at the profile log level by applying the same logic as the profile block.
# /srv/salt/data.sls
{%- set values = {'ctr': 0} %}
{%- for i in range(526288) %}
{%- do values.update({'ctr': i}) %}
{%- endfor %}
data: {{ values['ctr'] }}
# /srv/salt/test.sls
{%- import_yaml 'data.sls' as imported %}
test:
cmd.run:
- name: |-
printf 'test data: %s' '{{ imported['data'] }}'
The profile log statement has the following format for import_* blocks:
# salt-call --local -l profile state.apply test
[...]
[PROFILE ] Time (in seconds) to render import_yaml 'data.sls': 1.55007364566572266
[...]
Working with Python Methods
You can use the native python methods of the variable type. It is an essential feature of jinja that is only lightly mentioned in the official jinja documentation.
{% set hostname,domain = grains.id.partition('.')[::2] %}{{ hostname }}
{% set strings = grains.id.split('-') %}{{ strings[0] }}
The Custom Execution Modules
You can use the custom execution modules to supplement or take the place of complex Jinja. When Python is used in a Salt execution module, many jobs that call for complex looping and hard logic become simple. Salt execution modules are simple to create and deliver to Salt minions.
The Salt execution module dictionary has functions for both built-in and custom execution modules:
{{ salt['my_custom_module.my_custom_function']() }}
Working with Custom Jinja Filters
Given that the Jinja template contains all execution modules defining a unique module and using it as a Jinja filter is a simple process. Please be aware that the pipe will not provide access to it.
For instance, in place of
{{ my_variable | my_jinja_filter }}
You must define the my_jinja_filter function inside an extension module, such as my_filters, and use it as,
{{ salt.my_filters.my_jinja_filter(my_variable) }}
The main benefit is that you have access to thousands of already-existing functionalities, such as:
- Using dnsutil, you can find the DNS AAAA entries for a particular address:
{{ salt.dnsutil.AAAA('www.codingninjas.com') }}
- You can retrieve a Redis hash's individual field value:
{{ salt.redis.hget('foo_hash', 'bar_field') }}
- You can use the NAPALM route to obtain the routes to 0.0.0.0/0:
{{ salt.route.show('0.0.0.0/0') }}
Frequently Asked Questions
What is Jinja in DBT?
In the data build tool (dbt), SQL can be combined with Jinja. Jinja is a templating language. Your dbt project into a programming environment using Jinja for SQL. It allows you to do things that aren't usually possible in SQL. For example, with Jinja, you can use control statements in SQL.
Is Jinja2 a library?
Jinja is a library for Python. It is designed to be fast, flexible, and secure. Suppose you have worked with other text-based template languages, such as Django or Smarty. Then you will find it super easy to work with.
What is the difference between Jinja and Jinja2?
Jinja 2 has a similar syntax as Jinja 1. The difference is that around the argument list, macros now require parentheses. Also, Jinja 2 allows dynamic inheritance and dynamic includes. The old helper function rendertemplate is invalid now and included used instead.
What is Jinja salt?
Jinja is the default templating language. Jinja supports a secure, sandboxed template execution environment. It is the advantage used by Salt. Salt highly recommends the usage of jinja/jinja |yaml files.
What is Salt software used for?
SALT is also known as Systematic Analysis of Language Transcripts. It is software that standardizes the process of transcribing, eliciting, and analyzing language samples. It includes standard reports, a transcription editor, and reference databases for comparison with typical peers.
Conclusion
In this article, we have studied one of the automation engines, i.e., Salt Project. We have studied Jinja in Salt in detail. We have tried to understand Jinja in the files as well. We have also seen how to escape Jinja, debugging, Python methods, and many other concepts.
We hope that this article has provided you with the help to enhance your knowledge regarding Salt Project and if you would like to learn more, check out our articles on salt-as-a-cloud-controller and salt-states-and-commands-in-docker-containers.
Refer to our guided paths on Coding Ninjas Studio to learn more about DSA, Competitive Programming, JavaScript, System Design, etc. Enroll in our courses and refer to the mock test and problems available; take a look at the interview experiences and interview bundle for placement preparations.
Do upvote our blog to help other ninjas grow.
Merry Learning!