Ansibleの変数の扱いが思うようにいかなかった件
ずっと下書きのまま温められてたので投下。
直面した事象
こんな感じのplaybookを書いた。
- name: test_play
hosts: localhost
vars:
test_var1: play1
test_var2: play2
roles:
- role: test_role1
- role: test_role2
- role: test_role3
vars:
test_var1: role1
test_var2: role2
- name: print vars
debug:
msg: "{{ test_var1 }}, {{ test_var2 }}"
test_role3 実行時のみ別の変数を渡したかったのだが…
実行結果は以下のとおり、すべて roles:
配下で定義した変数で上書きされていた
$ ansible-playbook testplaybook.yml
PLAY [test_play] ************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************
ok: [localhost]
TASK [test_role1 : print vars] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "role1, role2"
}
TASK [test_role2 : print vars] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "role1, role2"
}
TASK [test_role3 : print vars] **********************************************************************************************************************************************************************************
ok: [localhost] => {
"msg": "role1, role2"
}
PLAY RECAP ******************************************************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ちなみにAnsibleにおける変数の優先順位は以下のとおり。
※下にいくほど優先度高
command line values (eg “-u user”)
role defaults [1]_
inventory file or script group vars [2]_
inventory group_vars/all [3]_
playbook group_vars/all [3]_
inventory group_vars/* [3]_
playbook group_vars/* [3]_
inventory file or script host vars [2]_
inventory host_vars/* [3]_
playbook host_vars/* [3]_
host facts / cached set_facts [4]_
play vars
play vars_prompt
play vars_files
role vars (defined in role/vars/main.yml)
block vars (only for tasks in block)
task vars (only for the task)
include_vars
set_facts / registered vars
role (and include_role) params
include params
extra vars (always win precedence)
Why?
調べてみると以下の記載があった。
When using vars: within the roles: section of a playbook, the variables are added to the play variables, making them available to all tasks within the play before and after the role. This behavior can be changed by DEFAULT_PRIVATE_ROLE_VARS.
つまるところデフォルト設定だと roles:
配下の vars:
で変数を定義すると、role params ではなく play vars 扱いとなる模様。。。
結局どうすりゃいいのよ
- ansible.cfg で DEFAULT_PRIVATE_ROLE_VARS を True に設定する。
$ sudo vi /etc/ansible/ansible.cfg
--- snip
# by default, variables from roles will be visible in the global variable
# scope. To prevent this, the following option can be enabled, and only
# tasks and handlers within the role will see the variables there
#private_role_vars = yes ← このコメントアウトを外す
--- snip
実行結果確認
$ ansible-playbook testplaybook.yml
PLAY [test_play] ************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************ok: [localhost]
TASK [test_role1 : print vars] **********************************************************************************************************************************************************************************ok: [localhost] => {
"msg": "play1, play2"
}
TASK [test_role2 : print vars] **********************************************************************************************************************************************************************************ok: [localhost] => {
"msg": "play1, play2"
}
TASK [test_role3 : print vars] **********************************************************************************************************************************************************************************ok: [localhost] => {
"msg": "role1, role2"
}
PLAY RECAP ******************************************************************************************************************************************************************************************************localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
-
roles:
配下のvars:
を使わない
- name: test_play
hosts: localhost
vars:
test_var1: play1
test_var2: play2
roles:
- role: test_role1
- role: test_role2
- role: test_role3
test_var1: role1
test_var2: role2
実行結果確認
$ ansible-playbook testplaybook.yml
PLAY [test_play] ************************************************************************************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************************************************************ok: [localhost]
TASK [test_role1 : print vars] **********************************************************************************************************************************************************************************ok: [localhost] => {
"msg": "play1, play2"
}
TASK [test_role2 : print vars] **********************************************************************************************************************************************************************************ok: [localhost] => {
"msg": "play1, play2"
}
TASK [test_role3 : print vars] **********************************************************************************************************************************************************************************ok: [localhost] => {
"msg": "role1, role2"
}
PLAY RECAP ******************************************************************************************************************************************************************************************************
localhost : ok=4 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Discussion