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.