Generate TOML using Ansible Template
In this blog post, I will show how we can add to_toml filter to Ansible template filters. This filter can be
very helpful in situations where we want to generate config files that are in TOML format. TOML is a file format
very similar to JSON and YAML. You can read more about this format here: https://toml.io/. We will use Ansible filter plugins to implement our new filter.
Configuration
Let’s start with a simple Ansible playbook file where we define our configuration variables.
yaml_test.yml
- name: Test Yaml
hosts: localhost
vars:
config_data: # this is our config file variable
x: stringtest
a: 1
b: 2
t:
- test
- test2
d:
a: 1
b: 2
tasks:
- template:
src: config.toml.j2
dest: config.toml
Next, create a configuration template.
Here we are using the to_toml filter that will render our config_data dict from
Ansible playbook into TOML representation.
templates/config.toml.j2
{{ config_data | to_toml }}
The last step is an actual implementation of the to_toml filter.
We will start with the installation of the toml python package. You can install the toml package using this command.
pip install toml
Next, create a file named filters.py in filter_plugins dir on the same
lever where the playbook is located.
filter_plugins/filters.py
#!/usr/bin/python
import toml
import json
class FilterModule(object):
def filters(self):
return {'to_toml': self.to_toml}
def to_toml(self, variable):
s = json.dumps(dict(variable))
d = json.loads(s)
return toml.dumps(d)
As you can see we are doing some strange thing here. We are converting into string and back to Python dict using python JSON library. We need to do this to provide string in a good format for the YAML parser to be able to work as expected.
s = json.dumps(dict(variable))
d = json.loads(s)
After this operation, all strings inside d dict are in standard Python string format. Without is strings are in
<class 'ansible.parsing.YAML.objects.AnsibleUnicode'> format and this will cause TOML rendering to break. For example
this
x: stringtest
will be rendered like this
x = [ "s", "t", "r", "i", "n", "g", "t", "e", "s", "t",]
and we do not want that.
Usage
After we set up our new filter we can use it like this
ansible-playbook yaml_test.yml
Next check the contents of config.toml
x = "stringtest"
a = 1
b = 2
t = [ "test", "test2",]
[d]
a = 1
b = 2
As you can see we got TOML representation of our variable in Ansible Playbook.
Summary
In this blog post, I presented how you can render TOML config files using Ansible templates filters.
Toml files are
getting very popular and a lot of DevOps software is using it for example https://www.influxdata.com/time-series-platform/telegraf/.
Now you can start using to_toml filter in order to generate your own TOML configuration files using Ansible.