Skip to content

Writing a JSON File by a Template#

Problem#

How to write JSON using Ansible or create JSON using a template?

Solution#

Take the filter to_json and apply it with a Dict or List:

- hosts: docker_hosts
  vars:
    docker_daemon_config:
      metrics-addr : "0.0.0.0:9323"
      experimental : true
  tasks:
    - name: Configure docker daemon
      ansible.builtin.copy:
        content: "{{ docker_daemon_config | to_json }}\n"
        dest: /etc/docker_daemon.json
      notify: restart docker
This results as the following:

/etc/docker/daemon.json
{
  "metrics-addr": "0.0.0.0:9323",
  "experimental": true
}

If part of the JSON is to come from a template, convert the document to YAML and apply lookup with a Filter. Based on the desired result in JSON, which contains the authentication data:

credentials.json
{
  "credentials" : [
    {
      "principal": "user1",
      "secret": "secret1"
    },
    {
      "principal": "user2",
      "secret": "secret2"
    }
  ]
}

We want to provide the configuration for Ansible in a simpler Dict:

defaults/main.yaml
auth_users:
  user1: secret1
  user2: secret2

We transform the outgoing JSON to YAML and make the necessary adjustments for our Template:

templates/credentials.yaml.j2
credentials:
{% for principal, secret in auth_users.items() %}
- principal: {{ principal }}
  secret: {{ secret }}
{% endfor %}

Finally, we use lookup with template and apply the to_json filter:

tasks/main.yml
- name: Configure credentials
  copy:
    content: "{{ lookup('template', 'credentials.yaml.j2') | to_json(ensure_ascii=False) }}\n"
    dest: /etc/myapp/credentials.json

Explanation#

It is much easier to create YAML format in a Template than JSON. In addition, comments such as # comment can be added to YAML, but these will of course not be visible in the resulting JSON, as JSON does not offer the option of comments.

Warning

To ensure that Unicode remains and is not converted to ASCII, use to_json(ensure_ascii=False) for passwords.