動機

Ansibleで、ある変数がDNSサーバのIPアドレスのリストを持っている時に、templateモジュールを使ってIPアドレスをダブルクォートで囲んで、さらにカンマとスペースを区切り文字にして並べて出力したい、というのをやりたかった。
つまり例えば8.8.8.8と8.8.4.4からなるリストを"8.8.8.8", "8.8.4.4"と出力したい、という話である。

mapフィルタを使ってみたが失敗

forでリストを回せば書けるのはわかっているが、長くなって読みづらい。
そこでJinja2に2.7からあるmapフィルタを使って、リストの各項目にregex_replaceフィルタを適用しようとしてmap('regex_replace("(^|$)", """))とかやってみたがエラーになるばかり。
http://jinja2.readthedocs.io/en/latest/templates.html#map
(なお、regex_replaceフィルタはAnsibleの独自拡張なのでJinja2のドキュメントには載っていない)

正しいmapフィルタの使い方

google検索してみたが答えは見つからず、エラーメッセージを見てみると「template error while templating string: expected token ‘,’, got ‘regex_replace’」と書かれている。
これ自体は正しいことを書いていないのだが、しばらく考えてみたところ解答が閃いた。

というわけで以下が正解。(recursorsはDNSサーバのIPアドレスのリストを持っている変数)
{{ recursors | map('regex_replace', '(^|$)', '"') | join(', ') }}
mapの2番目以降の引数にregex_replaceの引数を指定してやれば良かった。

答えがわかってしまえばドキュメントの「Alternatively you can let it invoke a filter by passing the name of the filter and the arguments afterwards.」がそういう意味だとわかるのだが。

なお

mapフィルタなんて使わなくても"{{ recursors | join('", "') }}"で良いことに後で気付いた。
とはいえ私はgoogleで見つけられなかった内容なので、Web上に残しておくとそのうち誰かの役に立つかもしれない。

TOP