概要
今回遭遇したエラーは、テンプレートに関する内容で以下の通り。
- Ansible error: template error while templating string missing end of comment tag. - Ansible error: template error while templating string expected token end of print statement got '{'.
AnsibleでTemplateモジュールを使って、作成したシェルスクリプトをリモートサーバーに送ろうと思っていたところ、上記のエラーが発生しました。
原因
シェルスクリプトの中で変数以外に"{"を使っていたことが原因でした。
変数以外で"{"を使うと変数が閉じていない、つまり"{}"となっていないからエラーになったり、他には"{#}"と書いていたため、"#"以降がコメントアウトとして認識されてしまったりと、Ansibleのjinjaテンプレートのルールに従ってないからタスクを実行できないよ!とのことでした。
どんな内容のシェルスクリプトを書いてエラーになったか一部抜粋すると、下記の通り。
echo -n $hostname universal.discovery {"data":["{#VCPU}": > $output_file
とか
sed -ie 's/,]}/]}/g' $output_file
とかを書いていてひっかかりました。なんでこのように書いていたかというと、シェルスクリプト内でjsonファイルを作成するために"{"を使っていました。
環境
- CentOS7.6
- Ansible2.7
対処法
Ansibleのjinjaテンプレート内で変数以外で"{"を使いたい場合は、エスケープさせる必要があります。
対処法としては、2つあります。
1. エスケープさせたい処理を{{ }}で囲む
例えば、こんな感じで。
{{ echo -n $hostname universal.discovery {"data":["{#VCPU}": > $output_file }}
2. エスケープさせたい処理を{% raw %}~{% endraw %}で囲む
エスケープさせたい処理が複数行にわたるときは、そのセクションを{% raw %}~{% endraw %}で囲みます。
例えば、このように。
{% raw %} echo -n $hostname universal.discovery {"data":["{#VCPU}": > $output_file {% endraw %}
参考にした文献は以下です。
docs.ansible.com
jinja.palletsprojects.com
上記の2つでエラーを回避することはできますが、囲んでいるセクションの中にAnsibleの変数が含まれていると展開されないので、注意しましょう。
おしまい!