Help us understand the problem. What is going on with this article?

YAMLでAnsibleのインベントリファイルを書く

More than 1 year has passed since last update.

(2017-01-03 : 変数の値にシークエンスやディクショナリを書けることに気付いたので修正)


Ansibleの2017年を眺めておこうを読んだけど、Ansibleのインベントリファイルは実は2.1以降YAMLで書けるという事実はきっとまだほとんど知られていないに違いない。

そりゃまあ、ドキュメントに書いてないしな。


というわけでソースがドキュメントだ。

まず、lib/ansible/inventory/dir.pyを見るとYAMLで書いたインベントリファイルの拡張子はlib/ansible/constants.pyのYAML_FILENAME_EXTENSIONSに定義されているもののうちのどれかである必要がある。
つまり、拡張子なし、yml、yaml、jsonのうちのどれかである必要がある。

lib/ansible/inventory/yaml.pyを見ると、以下のようなフォーマットで記述する必要がある。

(グループ1):
  hosts:
    (ホストa):
      (ホストaに適用する変数A): (Aの値)
      (ホストaに適用する変数B):
      - (Bの値1)
      - (Bの値2)
    (ホストb):
      (ホストbに適用する変数A): (Aの値)
      (ホストbに適用する変数B):
      - (Bの値1)
      - (Bの値2)
  vars:
    (グループ1のすべてのホストに適用する変数C): (Cの値)
    (グループ1のすべてのホストに適用する変数D):
    - (Dの値1)
    - (Dの値2)
  children:
    (子とするグループ2):
    (子とするグループ3):
(グループ2):
  hosts:
    (以下、省略)
  • ini(に似た何か)形式で書くインベントリファイルと違い、グループ名を省略してホスト名だけを書くことはできないようだ。
  • 各グループの子要素にできるのはhostsかvarsかchildrenだけ。各ホストはグループの子要素にできずhostsの子要素にする必要がある。
  • childrenに書くべきものはただのグループ名のリストであるが、シークエンスではなく値を空にしたディクショナリで記述する必要がある。
  • varsや各ホストの変数の値としてスカラーだけでなくシークエンスやディクショナリを記述できる。この点、ini(に似た何か)形式より優秀。
  • 試した限りでは、ホストに[1:9]のような繰り返しや(ホスト名):(ポート番号)のような記述も特に問題はなく想定通りに動作する。

2017-01-17追記:ini(に似た何か)形式だと暗黙的にすべてのグループがallグループのchildとなっていたが、YAML形式だとそうならない。バグだと思われるので報告した。
2017-03-29追記:本件、2.2.2で修正されたことを確認した。
https://github.com/ansible/ansible/issues/20252

2017-04-17追記:2.3.0にてallグループにホストが追加されず常に空となるバグがある。すでに修正済みなので2.3.1では直っているだろう。この修正が2.3ブランチにマージされたのは2.3.0リリースの翌日くらいだった模様。
2017-06-03追記:本件、2.3.1で修正されたことを確認した。
https://github.com/ansible/ansible/pull/23366

例として、前回の記事で使ったインベントリファイルをYAMLで書き直すと以下のようになる。

windows.hosts.yml
local_windows:
  hosts:
    local_windows:
  vars:
    ansible_host: localhost
    ansible_user: (ユーザ名)
    ansible_password: (パスワード)
    ansible_port: 5986
    ansible_connection: winrm
    ansible_winrm_server_cert_validation: ignore

また、JSONはYAMLの一種なので、JSONで書いても構わない。

windows.hosts.json
{
  "local_windows" : {
    "hosts" : {
      "local_windows" : ""
    },
    "vars" : {
      "ansible_host" : "localhost",
      "ansible_user" : "(ユーザ名)",
      "ansible_password" : "(パスワード)",
      "ansible_port" : "5986",
      "ansible_connection" : "winrm",
      "ansible_winrm_server_cert_validation" : "ignore"
    }
  }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away