はじめに
2020/10/10 に、YouTube Live で「つまずき Ansible 【Part18】boolean と仲良くなりたい」という配信をしました。
実際に作業しながらエラーと戦って進めるシリーズです。
今回は、when や assert などで特にする boolean 値 についていろいろ試します。 Ansible 2.10 で変わった挙動も扱います。
やったことや、わかったことをふりかえります。
- 環境
- ansible 2.9.14
- デフォルトからの設定変更
HOST_KEY_CHECKINGのみ
- デフォルトからの設定変更
- 一部明示した箇所のみ ansible 2.10.0
- ansible 2.9.14
動画
■ やったこと
おためし
以下のように、when にさまざまな値を与えて、そのタスクが実行されれば True、skip されれば False 扱いだと理解しながらひとつずつ試しました。
その結果をコメントとして付記します。一部は 変数未定義の undefined となりました。
--- - hosts: localhost gather_facts: false connection: local tasks: - name: debug: msg: mathed!!! when: - "'None'" # True - "None" # False - "'Null'" # True - "Null" # undefined - Null # True - "'NaN'" # True - "NaN" # undefined - NaN # undefined - "'False'" # True - 'False' # False - -1 # True - '' # True * python の bool() とは違う - "" # True * python の bool() とは違う - "''" # False - "'hogehoge'" # True - "hogehoge" # undefined - 'hogehoge' # undefined - True # True - TRUE # True - true # True - 0 # False - 1 # True
概ね、最終的な評価は Python の bool() に渡した結果と同じと言えると思います。
ただ、最終的に文字列として評価されるのかどうかは意識する必要があります。たとえば、'False' という指定は文字列ではなく、"'False'" は文字列として評価されます。
2.10 との比較
Ansible 2.10 で、CONDITIONAL_BARE_VARS という設定項目のデフォルトが True から、False に変更されました(2.9のドキュメント、2.10のドキュメント)。
これにより、最悪 2.9 と 2.10 とで判定が反転するケースがあります。
以下の Playbook を CONDITIONAL_BARE_VARS はデフォルトのまま、 2.9.14 と 2.10.0 で実行してためしました。結果をコメントで付記します。
--- - hosts: localhost gather_facts: false connection: local tasks: - name: 1-1 debug: msg: "matched!!" when: - item loop: - 0 # 同じ(False) - 1 # 同じ(True - "0" # 2.9 False、2.10 True - "1" # 同じ(True) - '0' # 2.9 False、2.10 True - '1' # 同じ(True) - "'0'" # 同じ(True) - "'1'" # 同じ(True) - name: 1-2 debug: msg: "matched!!" when: - item loop: - True # 同じ(True) - False # 同じ(False) - "True" # 同じ(True) - "False" # 2.9 False、2.10 True - 'True' # 同じ(True) - 'False' # 2.9 False、2.10 True - "'True'" # 同じ(True) - "'False'" # 同じ(True) - name: debug 1-3 debug: msg: matched! when: - condition # 2.9 False、2.10 True vars: condition: "1 == 0"
どういうことか
やや推測も入りますが、こういうことかなと思います。たとえば、
when: - condition
で condition の中身が "1 == 0" だったとき CONDITIONAL_BARE_VARS がデフォルトで True な 2.9 では、
when: - "1 == 0"
という解釈になり、結果的に False。
一方で、 CONDITIONAL_BARE_VARS がデフォルトで False な 2.10 では、
when: - "'1 == 0'"
という解釈になり、結果的に True。(1文字以上の文字列は True)
bare vars が厳密に何を指すのかは詳細はわからないのですが、前述のように、評価式に変数名だだけが与えられることを指すようです。 このような状態のときは警告が表示されます。この警告は 2.9 でも表示されます。もし表示されたら 2.10 への移行時は特に注意したほうが良さそうです。
[DEPRECATION WARNING]: evaluating 'item' as a bare variable, this behaviour will go away and you might need to add |bool to the expression in the future. Also see CONDITIONAL_BARE_VARS configuration toggle. This feature will be removed in version 2.12. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
もちろん CONDITIONAL_BARE_VARS の設定は、 ansible.cfg などで変更できます。
参考: 2.9.14 の結果(クリックして開く)
PLAY [localhost] *****************************************************************
TASK [1-1] ***********************************************************************
skipping: [localhost] => (item=0)
ok: [localhost] => (item=1) => {
"msg": "matched!!"
}
skipping: [localhost] => (item=0)
ok: [localhost] => (item=1) => {
"msg": "matched!!"
}
skipping: [localhost] => (item=0)
ok: [localhost] => (item=1) => {
"msg": "matched!!"
}
ok: [localhost] => (item='0') => {
"msg": "matched!!"
}
ok: [localhost] => (item='1') => {
"msg": "matched!!"
}
TASK [1-2] ***********************************************************************
ok: [localhost] => (item=True) => {
"msg": "matched!!"
}
skipping: [localhost] => (item=False)
ok: [localhost] => (item=True) => {
"msg": "matched!!"
}
skipping: [localhost] => (item=False)
ok: [localhost] => (item=True) => {
"msg": "matched!!"
}
skipping: [localhost] => (item=False)
ok: [localhost] => (item='True') => {
"msg": "matched!!"
}
ok: [localhost] => (item='False') => {
"msg": "matched!!"
}
TASK [debug 1-3] *****************************************************************
skipping: [localhost]
PLAY RECAP ***********************************************************************
localhost : ok=2 changed=0 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0
参考: 2.10.0 の結果(クリックして開く)
PLAY [localhost] ***************************************************************
TASK [1-1] *********************************************************************
skipping: [localhost] => (item=0)
ok: [localhost] => (item=1) => {
"msg": "matched!!"
}
ok: [localhost] => (item=0) => {
"msg": "matched!!"
}
ok: [localhost] => (item=1) => {
"msg": "matched!!"
}
ok: [localhost] => (item=0) => {
"msg": "matched!!"
}
ok: [localhost] => (item=1) => {
"msg": "matched!!"
}
ok: [localhost] => (item='0') => {
"msg": "matched!!"
}
ok: [localhost] => (item='1') => {
"msg": "matched!!"
}
TASK [1-2] *********************************************************************
ok: [localhost] => (item=True) => {
"msg": "matched!!"
}
skipping: [localhost] => (item=False)
ok: [localhost] => (item=True) => {
"msg": "matched!!"
}
ok: [localhost] => (item=False) => {
"msg": "matched!!"
}
ok: [localhost] => (item=True) => {
"msg": "matched!!"
}
ok: [localhost] => (item=False) => {
"msg": "matched!!"
}
ok: [localhost] => (item='True') => {
"msg": "matched!!"
}
ok: [localhost] => (item='False') => {
"msg": "matched!!"
}
TASK [debug 1-3] ***************************************************************
ok: [localhost] => {
"msg": "matched!"
}
PLAY RECAP *********************************************************************
localhost : ok=3 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Part19 にむけて
以下のネタを検討中です。気が向いたものをやります。