てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] インベントリファイルにおける INI と YAML の比較

はじめに

スタティックなインベントリファイルの書き方には、INI 形式YAML 形式、などがあります(ansbile.buitlint内の一覧はこちら)。

シンプルに定義する分には INI 形式が好みです。一方で、少し込み入ってきた場合は、YAML のほうが良いかなと思います。

両者を自分の視点で比較します。なお、あくまで Ansible の実装における比較であり、INI や YAML 一般的な仕様の比較ではありません。

  • 動作確認環境
    • ansible-core 2.14.6
    • Python 3.9.5

まとめ

先に一覧でまとめます。

INI YAML
1. インラインのコメントの可否 △: 一部不可 ○: 可
2. ディレクトリ指定時の扱い ×: 無視される ○: 読み込まれる
3. 真偽時の扱い △: INI 固有 ○: Playbookと同じ

1. インラインのコメントの可否

インベントリファイル内にコメントを書きたいときがありますが、INI 形式の場合で書けないケースがあります。

INI △: 一部不可

たとえば以下の inventory.ini があるとします。

[ios]
ios01 ansible_host=10.0.0.11        # ホスト定義にインラインコメント
ios02 ansible_host=10.0.0.12

[ios:vars]
ansible_connection=ansible.netcommon.network_cli
ansible_network_os=cisco.ios.ios    # グループ変数定義にインラインコメント(?)

2箇所にインラインでコメントらしきものがあります、

少々ややこしいのですが、このうち :vars 側に書いたものはコメントと見なされません。

確認のため、ansible-inventory コマンドで、変数の適用のされ方を見ます。

$ ansible-inventory -i inventory.ini --list
{
    "_meta": {
        "hostvars": {
            "ios01": {
                "ansible_connection": "ansible.netcommon.network_cli",
                "ansible_host": "10.0.0.11",
                "ansible_network_os": "cisco.ios.ios    # グループ変数定義にインラインコメント(?)"
            },
            "ios02": {
                "ansible_connection": "ansible.netcommon.network_cli",
                "ansible_host": "10.0.0.12",
                "ansible_network_os": "cisco.ios.ios    # グループ変数定義にインラインコメント(?)"
            }
        }
    },
    "all": {
        "children": [
            "ungrouped",
            "ios"
        ]
    },
    "ios": {
        "hosts": [
            "ios01",
            "ios02"
        ]
    }
}

上記のように、変数の ansible_network_os の値の中にコメントらしき値( # グループ変数定義にインラインコメント(?))も含まれてしまっています。

対策としては、コメントを独立した行に書きます。

[ios]
ios01 ansible_host=10.0.0.11        # ホスト定義にインラインコメント
ios02 ansible_host=10.0.0.12

[ios:vars]
ansible_connection=ansible.netcommon.network_cli
# グループ変数定義にインラインコメント
ansible_network_os=cisco.ios.ios    

なお、ansible.builtin.ini インベントリプラグインの説明ページとしては、以下の記載があります。

Unlike host lines, :vars sections accept only a single entry per line, so everything after the = must be the value for the entry.

YAML ○: 可

YAML 形式の場合はインラインコメントが可能です。

以下は、先ほどの INI 形式と同じ内容を YAML で定義したインベントリファイルです。

---
all:
  children:
    ios:
      hosts:
        ios01:
          ansible_host: 10.0.0.11           # ホスト定義にインラインコメント
        ios02:
          ansible_host: 10.0.0.12
      vars:
        ansible_connection: ansible.netcommon.network_cli
        ansible_network_os: cisco.ios.ios   # グループ変数定義にインラインコメント

ansible-inventory コマンドで確認します。

$ ansible-inventory -i inventory.yml --list
{
    "_meta": {
        "hostvars": {
            "ios01": {
                "ansible_connection": "ansible.netcommon.network_cli",
                "ansible_host": "10.0.0.11",
                "ansible_network_os": "cisco.ios.ios"
            },
            "ios02": {
                "ansible_connection": "ansible.netcommon.network_cli",
                "ansible_host": "10.0.0.12",
                "ansible_network_os": "cisco.ios.ios"
            }
        }
    },
    "all": {
        "children": [
            "ungrouped",
            "ios"
        ]
    },
    "ios": {
        "hosts": [
            "ios01",
            "ios02"
        ]
    }
}

2. ディレクトリ指定時の扱い

ansible-playbook などのコマンドの -i オプションは、ファイル名だけでなくディレクトリ名も指定できますディレクトリ名で指定した場合、INI と YAML とで扱いが異なります。

INI ×: 無視される

試しに inventories というディレクトリに inventory.ini を用意します。

inventories/
└── inventory.ini

この状態で、ansible-inventory コマンドで確認します。

$ ansible-inventory -i inventories/ --graph
[WARNING]: Unable to parse /home/yokochi/git/general/ansible/inventory_lab/inventories as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
@all:
  |--@ungrouped:

1つのインベントリも認識されませんでした。

なお、ドキュメント上は、ディレクトリ指定時は ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo で終わるファイルは無視されると記載があります。

あくまで拡張子の話なので、たとえば hosts のように拡張子なしのファイルで中身は INI とした場合は読み込まれます。

YAML ○: 読み込まれる

今度は inventories というディレクトリに inventory.yml を用意します。inventory.ini はありません。

inventories/
└── inventory.yml

続いて、ansible-inventory コマンドで確認します。

$ ansible-inventory -i inventories/ --graph
@all:
  |--@ungrouped:
  |--@ios:
  |  |--ios01
  |  |--ios02

無事に inventories/inventory.yml の内容が読み取られました。

3. 真偽値の扱い

真偽値(true/false など)の扱いも、INI と YAML で異なります。

INI △: INI 固有

たとえば、INI では True は真偽値における真ですが、trueyes は文字列です(参考 msg: "{{ 変数名 | type_debug }}" で確認)。

Playbook のフォーマットである YAML とは異なるので、注意が必要です。

YAML ○: Playbook と同様

YAML のインベントリでは Truetrueyes も真扱いです。Playbook の YAML と同じなので、あっちはああでこっちはこうで、と切り替えて考えなくて済みます。

インベントリファイルに指定した変数を、ホスト変数やグループ変数のYAMLの定義ファイルに移したい場合も簡単です。

おわりに

INI と YAML 形式のインベントリファイルの特徴をまとめました。

他にも YAML だと yamllint / ansible-lint でチェックできるなど、細かなメリットもあります。

サクッと書けるのは INI、手堅く書けるのは YAML、といった感じになるかなと思います。