Pythian Blog: Technical Track

Harnessing the power of Jinja2 with Ansible

Configuration files management is the core component of every configuration management tool. Templates are one of the best methods for creating configuration files as they allow dynamic variables. Ansible has a template module that uses Jinja2 in its core. Jinja2 is written in Python and allows Python-like expressions which allows us to have Python features and flexibility to be embedded into our configuration file management strategy.

Looping and Testing

The following is a standard template usage to create multiple files using the same template. Using the loop method with_items, multiple files can be created based on the declared variable log_path. [code] vars: set_category: true log_path: - name: "auth" path: "/var/log/auth.log" category: auth - name: "syslog" path: "/var/log/syslog" category: syslog tasks: - name: create config files template: src=./templates/sources.j2 dest=/etc/sumo/sumo.d/{{item.name}}.json with_items: "" [/code] With this, variables like log_path.path can be called as item.path from the template. Tests using “ if" expressions can be used as seen in the following example. If only set_category variable is set to TRUE, the category will be updated. [code] { "api.version": "v1", "source": { "name": "{{item.name}}", "sourceType": "LocalFile", "pathExpression": "{{item.path}}", } } [/code] The above code would create the following files: /etc/sumo/sumo.d/auth.json [code] { "api.version": "v1", "source": { "name": "auth", "sourceType": "LocalFile", "pathExpression": "/var/log/auth.log", "category": "auth" } } [/code] /etc/sumo/sumo.d/syslog.json [code] { "api.version": "v1", "source": { "name": "syslog", "sourceType": "LocalFile", "pathExpression": "/var/log/syslog", "category": "syslog" } } [/code] Repeated configuration becomes an easy task and if it is required in a file - “ for loop” can be used from a template. [code] [/code] This would create an entry like below: [code] auth : /var/log/auth.log syslog : /var/log/syslog [/code]

Filters

Jinja2 provides a wide range of filters that can transform the data inside the template. For example, join filter would take a list and concatenate it to a string with a separator. The following is an example: [code] [/code] The above join filter would take the following list: [code] allhosts: - localhost - 10.0.0.1 - 10.0.0.2 [/code] and create the following: [code] localhost,10.0.0.1,10.0.0.2 [/code] json_query is a filter which would allow searching inside a data structure. The below query would search inside the log_paths variable for a name key with value auth and would print the value of associated path: [code] /var/log/auth.log [/code] Another advantage of filters is that multiple filters can be lined up using pipe. For example, adding a basename filter to the above query would get the last name of the above file path. [code] auth.log [/code] map filter is another filter, which is very useful. It can either look up an attribute from a list or apply another filter on the objects. For example, the following would look for all values with attribute category: [code] auth, syslog [/code] In the following example, another filter called regex_replace is called by map filter to attach https:// to all the ip addresses which starts with 10: [code] localhost, https://10.0.0.1, https://10.0.0.2 [/code] As we can see, Ansible Jinja2 templates use the power of Python, allowing complex data manipulation while managing diverse environments. Custom filters can also be created using Python and added to filter_plugins/ under the ansible top directory.

No Comments Yet

Let us know what you think

Subscribe by email