はじめに

Ansibleでは変数を定義していなくてもデフォルトの値を設定することができる。デフォルト値の設定の方法はdefaultフィルタを使うか、defaults/main.ymlに記載するかの二通りある。

たとえばRedisのredis.confでmaxmemoryの設定をするとする。Ansibleのテンプレートでredis.maxmemoryが定義されていたらその値を、定義されていなければメモリの40%を設定したい。

実行version: Ansible 2.3

defaultフィルタ

defaultフィルタで書くと以下のようになる。別のファイル(defaults/main.yml)を作成する必要がなく、テンプレートファイルの中で全て完結するので簡単に書ける。

略
maxmemory "{{ redis.maxmemory | default(ansible_memtotal_mb*0.4) | int }}mb"
略

しかしredisという変数自体が定義されていなければ、このテンプレートはエラーとなってしまう。defaultフィルタが処理してくれるのはmaxmemoryだけ。

無理やりdefaultフィルタで書くとdefaultだらけで複雑になってしまう。

maxmemory "{{ (redis | default({})).maxmemory | default(ansible_memtotal_mb*0.4) | int }}mb"

これではifを使った方がまだいい。

{% if redis is defined and redis.maxmemory is defined %}
maxmemory "{{ redis.maxmemory }}mb"
{% else %}
maxmemory "{{ (ansible_memtotal_mb*0.4) | int }}mb"
{% endif %}

defaults/main.yml

今回のように変数がネストしている場合はdefaults/main.ymlを書くのがベストプラクティスとなる。

$ cd roles/redis
$ cat defaults/main.yml
---

redis:
  maxmemory: "{{ (ansible_memtotal_mb*0.4) | int }}"

$ cat templates/redis.conf.j2
略
maxmemory "{{ redis.maxmemory }}mb"
略