LoginSignup
19
19

More than 5 years have passed since last update.

Ansibleのテンプレートファイルを分割する際はJinja2のmacroが便利でした

Posted at

はじめに

この記事はAnsibleのタグを付けていますが、Ansible特有の話は無くてJinja2のmacroの話です。

Ansibleのplaybookを書いていて、テンプレートファイルが大きくなってくると共通部分を別ファイルにして読み込むようにしたくなってきます。複数箇所で読み込む際にパラメータを渡してテンプレート内の変数を違う値に展開したいと思いました。

Jinja2のincludeにはパラメータを渡せない

Ansibleのtemplateモジュールのドキュメントからリンクされている
Jinja2のTemplate Designer Documentationを見てみました。

Includeといういかにもな名前のステートメントがあるので使い方を見てみました。が、下記の例のように変数コンテキストを引き継ぐという指定はできますが、パラメータを渡すことは出来ないようです。

{% include "sidebar.html" ignore missing with context %}

Jinja2のユーザ定義マクロならパラメータを渡せる

さらに見ていくとImportというステートメントがありました。

以下の例のようにマクロを定義します。

forms.j2
{% macro input(name, value='', type='text') -%}
    <input type="{{ type }}" value="{{ value|e }}" name="{{ name }}">
{%- endmacro %}

使う側はImport Context Behaviorの説明にあるように、from ファイル名 import マクロ名 with context として読み込みます。

{% from 'forms.j2' import input with context %}

後は使いたい箇所で以下のようにパラメータを渡して呼び出せばOKです。

{{ input('username', value='John') }}

あるいは

{% import 'forms.j2' as forms with context %}

としてインポートして

{{ forms.input('username', value='John') }}

のように呼び出すことも可能です。Pythonのimportと同じですね。

with context無しだとエラーになった

with contextを付けずに試してみると、以下の様なエラーが出ました。

fatal: [cent65] => {'msg': "AttributeError: 'NoneType' object has no attribute 'add_locals'", 'failed': True}

よくわかっていませんが、with contextは必要なようです。

まとめ

ということで、Ansibleでテンプレートファイルを分割する場合は、Jinja2のマクロ機能を使うのがお勧めです。

19
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
19