前回の記事でも軽く触れましたが、Ansibleで使える変数はいくつかの場所で定義を書くことができ、それには優先順位があります。同じ名前の変数を2ヶ所で定義した時には、優先順位が低い方の値が高い方の値で上書きされます。
今回は実際に変数をあちこちで定義して、どのように上書きされるかを試してみます。
サンプルとして作ったプレイブックをこちらからダウンロードできます。
このプレイブックでは、いくつかの変数をそれぞれ2ヶ所で定義していて、最終的には以下の roles/foo/template/variables.txt.j2
で値を展開します。
var_role_defaults : {{ var_role_defaults }}
var_inventory_group_vars : {{ var_inventory_group_vars }}
var_inventory_host_vars : {{ var_inventory_host_vars }}
var_group_vars_hosts : {{ var_group_vars_hosts }}
var_group_vars_group : {{ var_group_vars_group }}
var_host_vars_group : {{ var_host_vars_group }}
var_host_vars_hosts : {{ var_host_vars_hosts }}
var_role_vars : {{ var_role_vars }}
プレイブックを次の要領で実行すると、
$ ansible-playbook -i hosts book.yml
PLAY ***************************************************************************
TASK [setup] *******************************************************************
ok: [localhost]
TASK [foo : write to /tmp/variables.txt] ***************************************
ok: [localhost]
PLAY RECAP *********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0
/tmp/variables.txt
に変数を展開した結果が書き出されます。
var_role_defaults : value of roles/foo/defaults/main.yml
var_inventory_group_vars : value of [foo:vars]
var_inventory_host_vars : value of hosts
var_group_vars_hosts : value of hosts
var_group_vars_group : value of group_vars/foo/main.yml
var_host_vars_group : value of host_vars/localhost/main.yml
var_host_vars_hosts : value of host_vars/localhost/main.yml
var_role_vars : value of roles/foo/vars/main.yml
それぞれの変数は2ヶ所で定義されていて、定義した場所を含む文字列を値に指定しています。
grepで検索するとどこで定義されてどこで使われているかが分かります。
例えば var_inventory_group_vars
変数の場合は、
$ grep -nr var_inventory_group_vars * README.md:13:|var_inventory_group_vars| hostsのグループ変数行 | roles/foo/defaults/main.yml | hosts:5:var_inventory_group_vars="value of [foo:vars]" roles/foo/templates/variables.txt.j2:2:var_inventory_group_vars : {{ var_inventory_group_vars }} roles/foo/defaults/main.yml:2:var_inventory_group_vars: value of roles/foo/defaults/main.yml
この結果から以下の2ヶ所で定義されていることが分かります。
hosts
ファイルの5行目([foo:vars]
セクションの中)roles/foo/defaults/main.yml
の2行目そして展開された値が value of [foo:vars]
なので、roles/XXX/defaults/ での定義よりもhostsのグループ変数定義の方が優先される事が分かります。
先述した要領で、それぞれの変数についてどちらの定義が優先されるかをまとめた表がこちらです。
変数名 | 優先度高い | 優先度低い |
---|---|---|
var_role_defaults | roles/foo/defaults/main.yml | |
var_inventory_group_vars | hostsのグループ変数行 | roles/foo/defaults/main.yml |
var_inventory_host_vars | hostsのホスト名行 | hostsのグループ変数行 |
var_group_vars_hosts | hostsのホスト名行 | group_vars/foo/main.yml |
var_group_vars_group | group_vars/foo/main.yml | hostsのグループ変数行 |
var_host_vars_group | host_vars/localhost/main.yml | group_vars/foo/main.yml |
var_host_vars_hosts | host_vars/localhost/main.yml | hostsのホスト名行 |
var_role_vars | roles/foo/vars/main.yml | host_vars/localhost/main.yml |
この表を元に変数の定義場所を優先度が低い順に並べると、次のようになります。
[group:vars]
セクションの内側)hostname varname=value
の行)注目したいのは group_vars/GROUPNAME/
の位置で、inventory(hosts)のホスト行に書くよりも優先度が低くなっています。
Ansibleの公式ドキュメントでは次のような順番であると書かれていますが、
group_vars/GROUPNAME/
以下のファイルを “playbook group_vars” だと認識していると矛盾することになります(ということに、今回初めて気がつきました…)が、どうもこのディレクトリに書いた変数は “inventory group_vars”と理解するのが正解のようです。
今回の検証で、group_vars/
ディレクトリは”inventory group_vars”、host_vars/
ディレクトリは”inventory host_vars”を定義するためのディレクトリだと分かりました。
でもそうすると、”playbook group_vars”とは一体なんなのでしょうか…。
謎を残したまま終わります。それでは皆さん良いお年を!!?