あきろぐ

いろいろめもするよ

Ansibleでテンプレートエラーが出たときの対処法

概要

今回遭遇したエラーは、テンプレートに関する内容で以下の通り。

- 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の変数が含まれていると展開されないので、注意しましょう。

おしまい!