Nicolas
Nicolas

Reputation: 39

Jinja2 syntax error: expected token 'end of print statement'

The below Jinja2 template is used by Ansible to generate a named zone configuration file. It fails during playbook execution (using template module) but the error is a bit cryptic to me so I didn't manage to fix it.

{# This template defines a named zone based on the dictionnary of the containers metadata #}
@   IN SOA {{ net_search_domain }}. admin.{{ net_search_domain }}. (
    {{ ansible_date_time['epoch'] }} ; serial
    3600       ; refresh
    1800       ; retry
    604800     ; expire
    600 )      ; ttl

{{ ansible_hostname }} IN A    {{ ansible_{{net_int_dmz_untrusted}}['ipv4']['address'] }}
{{ ansible_hostname }} IN AAAA {{ ansible_{{net_int_dmz_untrusted}}['ipv6']['address'] }}

{% for items in net_containers %}
{{ item.value.rproxy_be }} IN A    {{ item.value.ipv4_container }}
{{ item.value.rproxy_be }} IN AAAA {{ item.value.ipv6_container }}
{% if {{ item.value.rproxy_fe }} != {{ item.value.rproxy_be }} %}
{{ item.value.rproxy_fe }} IN A    {{ ansible_{{net_int_dmz_untrusted}}['ipv4']['address'] }}
{{ item.value.rproxy_fe }} IN AAAA {{ ansible_{{net_int_dmz_untrusted}}['ipv6']['address'] }}
{% endif %}
{% endfor %}

rtr     IN AAAA xxxx:yyyy:zzzz:wwww:208:a2ff:fe0e:d127
printer IN AAAA xxxx:yyyy:zzzz:wwww:3205:5CFF:FE7C:6240

The error at Ansible run time:

    failed: [192.168.11.6] (item={'file': '/home/nicolas/Documents/Configurations/Ansible/server/roles/containers/templates/named_domain.j2', 'target': '/srv/docker/dns/example.net'}) => {"changed": false, "item": {"file": "/home/nicolas/Documents/Configurations/Ansible/server/roles/containers/templates/named_domain.j2", "target": "/srv/docker/dns/example.net"}, 
"msg": "AnsibleError: template error while templating string: expected token 'end of print statement', got '{'. String: {# This template defines a named zone based on the dictionnary of the containers metadata #}
\n@   IN SOA {{ net_search_domain }}. admin.{{ net_search_domain }}. (\n    {{ ansible_date_time['epoch'] }} ; serial\n    3600       ; refresh
\n    1800       ; retry\n    604800     ; expire\n    600 )      ; ttl\n\n{{ ansible_hostname }} IN A    {{ ansible_{{net_int_dmz_untrusted}}['ipv4']['address'] }}
\n{{ ansible_hostname }} IN AAAA {{ ansible_{{net_int_dmz_untrusted}}['ipv6']['address'] }}\n\n{% for items in net_containers %}\n{{ item.value.rproxy_be }} IN A    {{ item.value.ipv4_container }}
\n{{ item.value.rproxy_be }} IN AAAA {{ item.value.ipv6_container }}\n{% if {{ item.value.rproxy_fe }} != {{ item.value.rproxy_be }} %}\n{{ item.value.rproxy_fe }} IN A    {{ ansible_{{net_int_dmz_untrusted}}['ipv4']['address'] }}\n{{ item.value.rproxy_fe }} IN AAAA {{ ansible_{{net_int_dmz_untrusted}}['ipv6']['address'] }}
\n{% endif %}\n{% endfor %}\n\nrtr     IN AAAA xxxx:yyyy:zzzz:wwww:208:a2ff:fe0e:d127\nprinter IN AAAA xxxx:yyyy:zzzz:wwww:5CFF:FE7C:6240\n\n\n"}

Upvotes: 0

Views: 9052

Answers (2)

Nicolas
Nicolas

Reputation: 39

Adding an answer here as the first one solves half of the error. The below Jinja2 template is the final one which provides the expected output:

@   IN SOA {{ net_search_domain }}. admin.{{ net_search_domain }}. (
    {{ ansible_date_time['epoch'] }} ; serial
    3600       ; refresh
    1800       ; retry
    604800     ; expire
    600 )      ; ttl

{% set addr4 = hostvars[inventory_hostname]['ansible_default_ipv4']['address'] %}
{% set addr6 = hostvars[inventory_hostname]['ansible_default_ipv6']['address'] %}
{{ ansible_hostname }} IN A    {{ addr4 }}
{{ ansible_hostname }} IN AAAA {{ addr6 }}

{% for item in net_containers %}
{{ net_containers[item].rproxy_be }} IN A    {{ net_containers[item].ipv4_container }}
{{ net_containers[item].rproxy_be }} IN AAAA {{ net_containers[item].ipv6_container }}
{% if net_containers[item].rproxy_be != net_containers[item].rproxy_fe %}
{{ net_containers[item].rproxy_fe }} IN A    {{ addr4 }}
{{ net_containers[item].rproxy_fe }} IN AAAA {{ addr6 }}
{% endif %}
{% endfor %}

Upvotes: 1

mdaniel
mdaniel

Reputation: 33203

{{ ansible_hostname }} IN A {{ ansible_{{net_int_dmz_untrusted}}['ipv4']['address'] }}

You can't use nested expressions like that, as Jinja does not do recursive evaluation. To do what you're trying to do, treat the vars as a dict and look up the key that way:

{{ ansible_hostname }} IN A    {{ vars["ansible_"+net_int_dmz_untrusted]['ipv4']['address'] }}

Separately, although you didn't ask this, you really will be much happier assigning those expressions to variables, instead of copy-pasting it all over the place:

{# This template defines a named zone based on the dictionnary of the containers metadata #}
{% set the_addr4 = vars["ansible_"+net_int_dmz_untrusted]['ipv4']['address'] %}
{% set the_addr6 = vars["ansible_"+net_int_dmz_untrusted]['ipv6']['address'] %}
{{ ansible_hostname }} IN A    {{ the_addr4 }}
{{ ansible_hostname }} IN AAAA {{ the_addr6 }}

Upvotes: 0

Related Questions