Reputation: 488
I am trying to create a bash script in a jinja template. I have the following line:
SOME_ARRAY_COUNT=${#SOME_ARRAY[@]}
But it throws an error:
AnsibleError: template error while templating string: Missing end of comment tag
After investigating I found out that a {% raw %}...{% endraw %}
block can be used to take literals, but it still doesn't work for {#
obtaining a similar error:
An unhandled exception occurred while templating
Error was a <class 'ansible.errors.AnsibleError'>, original message: template error while templating string: Missing end of comment tag
Is there a workaround for this without changing bash logic?
Thanks
UPDATE: including examples
ansible playbook:
... more ansible playbook stuff ...
tasks:
- name: create script
template:
src: "src/path/to/script.sh.j2"
dest: "dest/path/to/output/script.sh"
- name: user data script as string
set_fact:
userdata: "{{ lookup('file', 'path/to/script.sh') }}"
- name: some cloudformation thing
cloudformation:
stack_name: "stack_name"
state: present
region: "some region"
template: "path/to/template/cloudformation.json"
template_parameters:
... a bunch of params ...
UserDataScript: "{{ userdata }}"
tags:
... tags ..
metadata: "... metadata ..."
register: cloudformation_results
jinja template (script.sh.j2):
... more script stuff ...
SOME_ARRAY="some array with elements"
SOME_ARRAY=($SOME_ARRAY)
SOME_ARRAY_COUNT=${#SOME_ARRAY[@]}
... more script stuff ...
THE PROBLEM:
This line: SOME_ARRAY_COUNT=${#SOME_ARRAY[@]}
caused in the first template task to ask for a closing #}
comment tag. First fix adding raw block:
{% raw %}
SOME_ARRAY_COUNT=${#SOME_ARRAY[@]}
{% endraw %}
Fixes the templating part, but the cloudformation module also applies templating substitutions so it would then have the same error.
THE FIX:
{% raw %}
SOME_ARRAY_COUNT=${{ '{#' }}SOME_ARRAY[@]}
{% endraw %}
First template module removes raw block and keeps {{ '{$' }}
and cloudformation module finds {{ '{$' }}
and applies literal substitution.
Upvotes: 11
Views: 9578
Reputation: 312263
If I put this into script.sh
:
SOME_ARRAY="some array with elements"
SOME_ARRAY=($SOME_ARRAY)
{% raw %}
SOME_ARRAY_COUNT=${#SOME_ARRAY[@]}
{% endraw %}
And this into playbook.yml
:
---
- hosts: localhost
gather_facts: false
tasks:
- name: create script
template:
src: ./script.sh.j2
dest: ./script.sh
When I run ansible-playbook playbook.yml
, I get as output:
PLAY [localhost] *************************************************************************************************************************************************************
TASK [create script] *********************************************************************************************************************************************************
changed: [localhost]
And script.sh
looks like:
SOME_ARRAY="some array with elements"
SOME_ARRAY=($SOME_ARRAY)
SOME_ARRAY_COUNT=${#SOME_ARRAY[@]}
As far as I can tell, everything seems to work as expected.
Upvotes: 10