てくなべ (tekunabe)

ansible / network / automation

[Ansible] INI形式の変数定義では yes や true は 文字列、True は boolean

■ はじめに

いままで INI 形式のインベントリファイル内での変数は ansible_host くらいしか定義してなかったので気が付かったのですが、boolean の値を定義する場合は YAML とは異なる事情があるようです。

ansibleで変数に入れたyes/noの扱いに苦しんだ - Qiita

自分なりにしらべたことや、試したことをまとめます。

ポイントは、 INI 形式では boolean 値になりそうな値の中では、大文字から始まる True / False が boolean になる点です。

INI 形式では True / False のみが boolean

以下の回答によると、大文字から始まる TrueFalse のみを boolean として扱って、それ以外は文字列扱いになるようです。

How Exactly Does Ansible Parse Boolean Variables? - Stack Overflow

また、以下の公式サイトのページによると、INI 形式で定義した変数は pythonast.literal_eval で処理されるようです。 ini – Uses an Ansible INI file as inventory source. — Ansible Documentation


■ おためし

以下の Playbook で動作を確認します。環境は Ansible 2.7.5 です。

- hosts: localhost
  connection: local
  gather_facts: no

  tasks:
    - name: print value
      debug:
        msg: "{{ test_bool }}"

    - name: print type
      debug:
        msg: "{{ test_bool | type_debug }}"

type_debug フィルターで、Python としての型を確認できます。

INI 形式のインベントリファイルの場合

yes は文字列

インベントリファイル (INI)

localhost test_bool=yes

実行結果

文字列になりました。"yes" のようにダブルコーテーションがついています。

TASK [print value] *************************************************************
ok: [localhost] => {
    "msg": "yes"
}

TASK [print type] **************************************************************
ok: [localhost] => {
    "msg": "unicode"
}

true も文字列

インベントリファイル (INI)

localhost test_bool=true

実行結果

文字列になりました。

TASK [print value] *************************************************************
ok: [localhost] => {
    "msg": "true"
}

TASK [print type] **************************************************************
ok: [localhost] => {
    "msg": "unicode"
}

TRUE は文字列

インベントリファイル (INI)

localhost test_bool=TRUE

実行結果

文字列になりました。

TASK [print value] *************************************************************
ok: [localhost] => {
    "msg": "TRUE"
}

TASK [print type] **************************************************************
ok: [localhost] => {
    "msg": "unicode"
}

True は boolean

インベントリファイル (INI)

localhost test_bool=True

実行結果

booleanになりました。

TASK [print value] *************************************************************
ok: [localhost] => {
    "msg": true
}

TASK [print type] **************************************************************
ok: [localhost] => {
    "msg": "bool"
}

以降、比較のために YAML 形式でも試します。

YAML 形式のインベントリファイルの場合

yes は boolean

イベントリファイル (YAML)

all:
  hosts:
    localhost:
      test_bool: yes

実行結果

INI 形式のインベトリファイルで test_bool=yes と指定したときとは異なり、boolean になりました。

TASK [print value] *************************************************************
ok: [localhost] => {
    "msg": true
}

TASK [print type] **************************************************************
ok: [localhost] => {
    "msg": "bool"
}

vars で定義した場合

yes は boolean

イベントリファイル (INI)

ここでは変数は定義しません。

localhost

./host_vars/localhost.yml

ここに変数定義します。

test_bool: yes
実行結果
TASK [print value] *************************************************************
ok: [localhost] => {
    "msg": true
}

TASK [print type] **************************************************************
ok: [localhost] => {
    "msg": "bool"
}


■ まとめ

INI 形式と YAML 形式で boolean として扱う値の違いについて確認しました。

YAML 形式については、公式ドキュメントの YAML Syntax に記載されている通りyes / no / True / False などでも boolean になります。

一方、INI 形式については、boolean になりそうな値の中では、大文字から始まる True / False が boolean になります。

公式ドキュメントの Working with Inventory には、以下の注意書きがありました。

Values passed in the INI format using the key=value syntax are not interpreted as Python literal structure (strings, numbers, tuples, lists, dicts, booleans, None), but as a string. For example var=FALSE would create a string equal to ‘FALSE’. Do not rely on types set during definition, always make sure you specify type with a filter when needed when consuming the variable.

以下に結果をまとめます。

フォーマット 定義 結果 備考
INI test_bool=yes 文字列
INI test_bool=no 文字列
INI test_bool=true 文字列
INI test_bool=false 文字列
INI test_bool=TRUE 文字列
INI test_bool=FALSE 文字列
INI test_bool=True boolean
INI test_bool=False boolean
YAML test_bool: yes boolean YAML Syntax 通り
YAML test_bool: no boolean YAML Syntax 通り
YAML test_bool: true boolean YAML Syntax 通り
YAML test_bool: false boolean YAML Syntax 通り
YAML test_bool: True boolean YAML Syntax 通り
YAML test_bool: False boolean YAML Syntax 通り
YAML test_bool: yes boolean YAML Syntax 通り