Search code examples
ansiblejinja2

How do I template a Javascript file with Ansible?


I want to create an Ansible role to install and configure Node-RED and I'm struggling with templating the settings.j2 file.

- name: Write the NodeRED settings file
  ansible.builtin.template:
    src: templates/settings.js.j2
    dest: "{{ _nodered_user_info.home }}/.config/node-red/settings.js"
    mode: "0644"
    owner: "{{ _nodered_user_info.name }}"
    group: "{{ _nodered_user_info.name }}"
  become: true

settings.js.j2

This always throws the error:

The error was: . expected token 'end of print statement', got 'string'

I assume that Jinja2 is having difficulties with the single curly braces in the JavaScript file.

The syntax highlighting is not highlighting the first if tag properly.

I tried to replace all {with {{ '{' }} and all } with {{ '}' }}, but this makes the file unreadable and breaks the syntax highlighting.


Solution

  • When your template source file is supposed to contain a lot of characters conflicting with the default jinja2 delimiters, you can change those directly in the template module. So for example:

    - name: Template my js file
      ansible.builtin.template:
        src: my.js.j2
        dest: path/to/dest.js
        block_start_string: '<@'
        block_end_string: '@>'
        comment_start_string: '<#'
        comment_end_string: '#>'
        variable_start_string: '<:'
        variable_end_string: ':>'
    

    should let you process a template looking like the following. Of course change the above (and below) to whatever best suits your needs:

    <# This is a jinja template with custom delimiters #>
    {
      "toto": "<: my_variable :>",
      "titi": {
      <@ if some_titi_switch @>
        "some_key": "a static value"
      <@ else @>
        "other_key": "some other value"
      <@ endif @>
    }