Ansibleのhostsファイル設計|INI形式とYAML形式の書き分け・グループ入れ子・ホスト範囲指定の実践

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > Ansibleのhostsファイル設計|INI形式とYAML形式の書き分け・グループ入れ子・ホスト範囲指定の実践
「Ansibleのhostsファイル、どう書けばいいんだろう」——。インベントリの設定をしようとネットで調べると「INI形式」と「YAML形式」の2種類の書き方が出てきて、どちらを選べばいいか迷った経験はないでしょうか。

Ansibleのhostsファイル(インベントリファイル)は、操作対象のサーバーを定義するファイルです。どちらの形式も同等の機能を持ちますが、グループ入れ子やホスト範囲指定の書き方が大きく異なります。

この記事では、INI形式とYAML形式それぞれの記法を実例で比較しながら、グループ入れ子と連番ホストの範囲指定まで一通り解説します。記述が正しく解釈されているか確認するコマンドも紹介するので、初めてインベントリを設計する方もすぐに実践できる内容です。

この記事のポイント

・hostsファイルはINI形式とYAML形式の2種類で書ける
・グループ入れ子は[グループ名:children](INI)で定義する
・ホスト範囲はweb[01:05]形式でまとめて指定できる
・ansible-inventory --graphでグループ階層をツリー確認できる


「このままじゃマズい」と感じていませんか?
参考書を開く気力もない、同年代に取り残される不安——
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Ansibleのhostsファイル(インベントリ)の役割

Ansibleが「どのサーバーに対して操作を実行するか」を定義するファイルがインベントリファイルです。デフォルトのパスは /etc/ansible/hosts ですが、-i オプションで任意のパスを指定したり、プロジェクトの ansible.cfginventory = ./inventory/hosts と書いて切り替えることが一般的です。

インベントリファイルに書く主な内容は次の3つです。

・管理対象ホストのIPアドレスまたはFQDN
・ホストを分類するグループ
・ホストやグループに紐づける変数(ansible_useransible_port 等)

この記事では記法の書き方に集中します。どの軸でホストをグループ分けするかという設計判断や、変数をどのファイルで管理するかは別記事で扱います。

INI形式でhostsファイルを書く

INI形式はAnsible初期から使われている記法です。シンプルで行数が少なく、小規模なインベントリに最も向いています。

1. 基本的な書き方

グループを定義せずホストを並べる最小構成です。

# /etc/ansible/hosts(最小構成) 192.168.1.10 192.168.1.11 web01.example.com web02.example.com

ホストはIPアドレスでもFQDNでも書けます。ただし、グループを定義しないとPlaybookで hosts: all しか使えないため、実運用では必ずグループを定義します。

2. グループを定義してホストを分類する

[グループ名] の行の後にホストを列挙します。

[web] web01.example.com web02.example.com [db] db01.example.com [cache] cache01.example.com

Playbookで hosts: web と書けば web01.example.comweb02.example.com だけが対象になります。同じホストを複数のグループに所属させることもできます。

3. グループ入れ子(children)でサーバー群を階層化する

本番環境のWebサーバー・DBサーバー・キャッシュサーバーをまとめて「production」グループとして扱いたい場合など、グループを別のグループの子に含めることができます。INI形式では [親グループ名:children] という特殊なセクションで定義します。

[web] web01.example.com web02.example.com [db] db01.example.com [cache] cache01.example.com # productionはweb・db・cacheを束ねる親グループ [production:children] web db cache [staging] stg01.example.com [all_servers:children] production staging

[production:children] の下にグループ名を並べると、それらのグループが production の子グループになります。この記述で hosts: production と書けば、web・db・cacheグループのホスト全員が対象になります。

[all_servers:children] で production と staging を包む構造にしていますが、このようにグループの入れ子は何段でも重ねられます。

4. ホスト範囲指定で連番ホストをまとめる

web01.example.com から web05.example.com まで5台を書く場合、1行ずつ書く必要はありません。[開始:終了] の範囲指定構文が使えます。

[web] # web01.example.com ~ web05.example.comを1行で指定 web[01:05].example.com [db] # db01 ~ db03 db[01:03].example.com [app] # ゼロ埋めなし(app1 ~ app10) app[1:10].example.com

web[01:05] は0埋め2桁の01から05を展開します。app[1:10] のようにゼロ埋めなしの指定も可能です。アルファベット範囲 [a:f] も使えます。

YAML形式でhostsファイルを書く

YAML形式はAnsible 2.4から正式サポートされた記法です。データ構造が明示的で、Playbookと同じ書き方になるため、チーム開発やGit管理との相性が高い場面で選ばれます。INI形式より行数は増えますが、グループの入れ子関係が視覚的に把握しやすくなります。

1. 基本的な書き方

# inventory/hosts.yml all: children: web: hosts: web01.example.com: web02.example.com: db: hosts: db01.example.com: cache: hosts: cache01.example.com:

YAML形式では必ずトップレベルが all: から始まります。all は全ホストを含む暗黙のグループです。グループは children: の下に、ホストは hosts: の下に書きます。

注意点が1つあります。hosts: の下のホスト名の末尾にコロン(:)が必要です。web01.example.com: のように書くのがYAML辞書構文のルールで、コロンを省いた web01.example.com だけではAnsibleがホストと認識しません。

2. グループ入れ子をYAML形式で書く

INI形式で [production:children] と書いていた入れ子関係は、YAMLでは親グループの中に children: キーを置いて子グループを入れる形になります。

all: children: # 全サーバーを束ねる最上位グループ all_servers: children: # 本番環境グループ production: children: web: hosts: web01.example.com: web02.example.com: db: hosts: db01.example.com: cache: hosts: cache01.example.com: # ステージング環境グループ staging: hosts: stg01.example.com:

インデントを深くすることでグループの入れ子関係がそのまま表現されます。INI形式の [production:children] セクションが分散して書かれるのに対し、YAML形式は「どのグループが誰の子か」が一目で読み取れる点が利点です。

3. ホスト範囲指定をYAML形式で書く

INI形式と同じ [01:05] 構文がYAML形式でも使えます。

all: children: web: hosts: web[01:05].example.com: db: hosts: db[01:03].example.com:

ホスト名の末尾コロンはYAML形式固有のルールなので忘れずに付けてください。範囲指定構文の書き方自体はINIとYAMLで共通です。

ansible-inventoryコマンドで記述を検証する

hostsファイルを書いたら、実際にAnsibleがどう解釈しているかを必ず確認しましょう。インベントリ設計を体系的に学びたい方は、>> Ansibleハンズオン講座の詳細を見る もご参照ください。

1. ansible-inventory --listで全ホスト・グループ構成を確認する

# デフォルトの/etc/ansible/hostsを確認 ansible-inventory --list # 任意のINI形式インベントリを指定 ansible-inventory -i inventory/hosts.ini --list # YAML形式のインベントリを指定 ansible-inventory -i inventory/hosts.yml --list

実行すると次のようなJSONが出力されます(INI形式のhostsファイルで検証した実例)。

{ "_meta": { "hostvars": { "web01.example.com": {}, "web02.example.com": {}, "db01.example.com": {} } }, "all": { "children": [ "production", "ungrouped" ] }, "production": { "children": [ "web", "db" ] }, "web": { "hosts": [ "web01.example.com", "web02.example.com" ] }, "db": { "hosts": [ "db01.example.com" ] } }

2. ansible-inventory --graphでグループ階層をツリー表示する

--list のJSONが読みにくい場合は --graph オプションでツリー形式を確認できます。hostsファイルを書いたら必ずこのコマンドで検証することをおすすめします。

ansible-inventory -i inventory/hosts.ini --graph

@all: |--@production: | |--@web: | | |--web01.example.com | | |--web02.example.com | |--@db: | | |--db01.example.com | |--@cache: | | |--cache01.example.com |--@staging: | |--stg01.example.com |--@ungrouped:

グループの入れ子関係が階層で表示され、どのホストがどのグループに属しているか一目で確認できます。

@ungrouped: は、どのグループにも属さないホストが表示される予約グループです。意図せずホストが ungrouped に入っていたら、hostsファイルの記述ミスを疑いましょう。

範囲指定が正しく展開されているかも --graph で確認できます。web[01:05].example.com と書いた場合、web01から web05 の5ホストが個別に表示されていれば正常です。

INI形式とYAML形式の使い分け

両形式は同等の機能を持ちます。どちらを選ぶかはチームの方針と規模感で判断します。

観点 INI形式 YAML形式
記述量 少ない(シンプル) 多め(インデント分)
グループ入れ子の可読性 [グループ名:children]が各所に分散する インデントで構造が一目瞭然
ホスト範囲指定 web[01:05]構文が使える web[01:05]:構文が使える
Playbookとの統一感 記法が異なる Playbookと同じYAMLで統一できる
向いている規模 数十台以下の小規模 階層が複雑な中大規模
小規模な個人環境や素早く試したいときはINI形式、複数チームで管理する本番環境や階層的なグループ設計が必要な場合はYAML形式を選ぶと迷いにくいです。どちらの形式でも ansible-inventory --graph で検証できますし、途中で変換することも難しくありません。

よくあるエラーと対処法

1. 「Host pattern 'X' did not match any hosts」

Playbookで指定したグループ名が見つからない場合に出るエラーです。グループ名のスペルミスが最も多い原因です。

ansible-inventory --graph でグループ名の一覧を確認する
・YAMLの場合、インデントがずれていてグループが正しく階層化されていないケースも多い
・INIの場合、[production:children] と書くべきところを [production] と書いてしまうケースも多い

2. YAML形式でホストが認識されない

最も多いのがコロン漏れです。

# NG: コロンなし(ホストとして認識されない) hosts: web01.example.com # OK: コロンあり hosts: web01.example.com:

YAMLではホスト名が辞書のキーとして扱われるため、末尾のコロンは省略できません。

3. 範囲指定が展開されない

シェルのグロブ展開と混同してシングルクォートで囲むと、Ansibleがリテラル文字列として扱い展開されません。

# NG: クォートで囲むと範囲展開されない 'web[01:05].example.com' # OK: クォートなしで直接書く web[01:05].example.com

hostsファイルではクォートなしで直接書きます。

4. INI形式でインライン変数に空白が含まれる

# NG: 値にスペースを含む場合(パースエラーになる) web01.example.com ansible_ssh_extra_args=-o StrictHostKeyChecking=no # OK: シングルクォートで囲む web01.example.com ansible_ssh_extra_args='-o StrictHostKeyChecking=no'

INI形式でホスト変数(インライン変数)を書く場合、値にスペースが含まれるならシングルクォートで囲みます。

本記事のまとめ

やりたいこと INI形式の書き方 YAML形式の書き方
ホストをグループに分類する [グループ名] セクションにホストを列挙 children: グループ名: hosts: ホスト名:
グループを入れ子にする [親グループ:children] に子グループを列挙 親グループの children: に子グループを記述
連番ホストを範囲指定する web[01:05].example.com web[01:05].example.com:(末尾コロン必須)
記述を検証する ansible-inventory -i hosts.ini --graph ansible-inventory -i hosts.yml --graph
hostsファイルの記法を習得したら、次のステップはグループ変数(group_vars)とホスト変数(host_vars)の設計です。どの変数をどのスコープで管理するかによって、Playbookの再利用性が大きく変わります。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

無料メルマガで学習を続ける

Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。

登録無料・いつでも解除できます

暗記不要・1時間後にはサーバーが動く

3,100名以上が実践した「型」を無料で公開中

プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。

姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら

Linux無料マニュアル(図解60P) 名前とメールで30秒登録
宮崎 智広

この記事を書いた人

宮崎 智広(みやざき ともひろ)

株式会社イーネットマーキュリー代表。現役のLinuxサーバー管理者として20年以上の実務経験を持ち、これまでに累計3,100名以上のエンジニアを指導してきたLinux教育のプロフェッショナル。「現場で本当に使える技術」を体系的に伝えることをモットーに、実践型のLinuxセミナーの開催や無料マニュアルの配布を通じてLinux人材の育成に取り組んでいる。

趣味は、キャンプにカメラ、トラウト釣り。好きな食べ物は、ラーメンにお酒。休肝日が作れない、酒量を減らせないのが悩み。最近、ドラマ「フライトエンジェル」を観て涙腺が崩壊しました。