【Ansible講座 第2回】ターゲットを支配せよ。インベントリの書き方とansible.cfgの最適解

「毎回オプションを打つ」のは、自動化とは呼ばない。

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
前回は、Ansibleのインストールと、ping モジュールによる最初の疎通確認を行いました。

しかし、前回の最後のコマンドを覚えていますか?
ansible all -i hosts -m ping -u user --private-key=~/.ssh/id_ed25519
…長いですよね。あまりにも長すぎます。
たかが接続確認をするだけで、毎回ユーザー名や鍵ファイルのパスを指定していては、指が腱鞘炎になってしまいます。

コウ君

先生、まさにそれです!
さっきコマンド打とうとして -u を忘れたり、インベントリファイルの名前を間違えたりしてイライラしてました。
もっとこう、「ansible all ping」だけでドカンと実行できないんですか?
あと、サーバーによってSSHのポート番号が違う時とかどうすればいいんですか?

リナックス先生

もちろんできるわ。
Ansibleには、デフォルトの振る舞いを決める設定ファイル「ansible.cfg」と、サーバーごとの個別の事情(ポート番号や変数の違い)を吸収する「インベントリ」の仕組みがあるの。
これを正しく設定すれば、コマンドは驚くほど短くなるし、複雑なサーバー構成もスッキリ管理できるようになるわよ!

本記事では、AlmaLinux 9 をベースに、実務レベルのインベントリ記述方法(INI形式 vs YAML形式)と、作業効率を劇的に向上させる ansible.cfg のチューニングについて徹底解説します。

🚀 Ansible完全攻略講座(バックナンバー)

現在地:【第2回】ターゲットを支配せよ。インベントリの書き方とansible.cfgの最適解

  • 【第1回】構成管理の革命児!エージェントレスで始める自動化入門&環境構築
  • 【第2回】ターゲットを支配せよ。インベントリの書き方とansible.cfgの最適解
  • 【第3回】Playbookの基礎。YAMLの作法と「モジュール」によるタスク定義
  • 【第4回】変数を使いこなせ。Jinja2テンプレートによる設定ファイルの動的生成
  • 【第5回】コードを整理整頓。Rolesディレクトリ構成と再利用性の最大化
  • 【第6回】秘密情報の管理と通知。Ansible Vaultの暗号化とHandlers
  • 【第7回】実践演習。LAMP環境(Apache+MySQL+PHP)をボタン一つで構築する
  • 【第8回】GUIで管理。Ansible AWX(Tower)入門とCI/CDパイプラインへの統合

第1章:インベントリ(Inventory)の深層

前回はIPアドレスを羅列しただけの簡単なインベントリファイルを作成しました。
しかし、実際の現場では「Webサーバー」「DBサーバー」「開発環境」などが混在しています。
これらを整理して管理するためのテクニックを学びましょう。

1. グループ化と範囲指定

サーバーを用途ごとにグループ分けすることで、「WebサーバーだけにApacheを入れる」「DBサーバーだけにMySQLを入れる」といった操作が可能になります。

hosts (INI形式) の例:

[web]
web01.example.com
web02.example.com

[db]
db01.example.com

# 連番の場合は省略記法が使える
[app]
app[01:50].example.com  # app01 から app50 まで一括指定!

2. グループのグループ化 (children)

「Webサーバー」と「DBサーバー」をまとめて「本番環境(production)」として扱いたい場合などは、:children サフィックスを使います。
これにより、グループを入れ子構造にできます。

[web]
192.168.1.10
192.168.1.11

[db]
192.168.1.20

# webとdbをまとめた親グループ
[production:children]
web
db

これで ansible production -m ping とすれば、WebとDBの両方に対して実行されます。

3. 変数の定義 (vars)

サーバーごとに接続設定(ポート番号など)が異なる場合、インベントリファイル内に「変数」として記述できます。

ホスト変数(特定のサーバーだけ設定を変える):

[web]
# このサーバーだけSSHポートが2222、ユーザーがhoge
web01.example.com ansible_port=2222 ansible_user=hoge
web02.example.com

グループ変数(グループ全体の設定を変える):

[web:vars]
# webグループは全員この鍵ファイルを使う
ansible_ssh_private_key_file=~/.ssh/web_key

主要な接続変数一覧

変数名 意味
ansible_host 実際の接続先IPアドレス(インベントリ上の名前とIPが違う場合に便利)
ansible_port SSHポート番号(デフォルト: 22)
ansible_user SSH接続ユーザー名
ansible_ssh_pass SSHパスワード(鍵認証推奨のため非推奨)
ansible_ssh_private_key_file 秘密鍵のパス
ansible_become_pass sudo時のパスワード

第2章:現代の主流「YAML形式」インベントリ

古くからのAnsibleユーザーはINI形式([]を使う形式)に慣れていますが、現在はPlaybookと同じ **YAML(ヤムル)形式** で書くことが推奨されています。
ファイル名は hosts.ymlinventory.yml とすることが多いです。

YAML形式のメリットは、構造が視覚的にわかりやすく、変数にリストや辞書といった複雑なデータを持たせられる点です。

inventory.yml の記述例

先ほどのINI形式をYAMLで書き直すとこうなります。

all:
  children:
    # --- Web Server Group ---
    web:
      hosts:
        web01.example.com:
          ansible_port: 2222  # ホスト変数
        web02.example.com:
      vars:
        ansible_user: nginx_admin  # グループ変数
    
    # --- DB Server Group ---
    db:
      hosts:
        db01.example.com:
    
    # --- Parent Group ---
    production:
      children:
        web:
        db:

階層構造がハッキリしましたね。
本講座では、今後スタンダードになるYAML形式での記述を推奨します。


第3章:ansible.cfg で「手抜き」を極める

さて、ここからが本題です。
毎回コマンドライン引数でインベントリファイルや秘密鍵を指定するのはナンセンスです。
設定ファイル ansible.cfg を作って、デフォルト設定を上書きしましょう。

設定ファイルの優先順位

Ansibleは以下の順番で設定ファイルを探し、最初に見つかったものを使用します。

  1. 環境変数 ANSIBLE_CONFIG で指定されたファイル
  2. カレントディレクトリの ./ansible.cfg (← これを使います!)
  3. ホームディレクトリの ~/.ansible.cfg
  4. システム全体の /etc/ansible/ansible.cfg

プロジェクト(作業ディレクトリ)ごとに ansible.cfg を置いておけば、そのプロジェクト専用の設定が適用されるため、管理が非常に楽になります。

【実践】最強の ansible.cfg を作る

作業ディレクトリ(~/ansible-demo)に ansible.cfg を作成します。

nano ansible.cfg

以下の内容を記述してください。

[defaults]
# インベントリファイルのデフォルトパス
inventory = ./inventory.yml

# SSH接続するユーザー名
remote_user = admin

# 秘密鍵のパス
private_key_file = ~/.ssh/id_ed25519

# SSHの指紋確認(yes/no?)をスキップする
# ※開発環境やクラウドでIPが頻繁に変わる場合に便利
host_key_checking = False

# ログを保存する場所
log_path = ./ansible.log

# 実行結果の表示形式を読みやすくする
stdout_callback = yaml

[privilege_escalation]
# 特権昇格(sudo)をデフォルトで有効にする
become = True

# 特権昇格の方法(sudo / su)
become_method = sudo

# 特権昇格するユーザー(root)
become_user = root

# sudoパスワードを聞かない(パスワードレスsudo設定済みの場合)
become_ask_pass = False

各設定の解説

[defaults] セクション

  • inventory: これを指定すれば、もう -i hosts は不要です。
  • host_key_checking = False: 初めて接続するサーバーで出る「Are you sure you want to continue connecting (yes/no)?」を自動で無視します。
    セキュリティリスク(中間者攻撃など)を理解した上で、自動化のためには有効にしておくと便利です。
  • stdout_callback = yaml: デフォルトのJSONっぽい出力ではなく、読みやすいYAML形式で結果を表示してくれます。

[privilege_escalation] セクション

  • become = True: これを設定すると、全てのタスクがデフォルトで sudo 実行されます。
    Webサーバーのインストールや設定変更など、構成管理は基本的にroot権限が必要なので、Trueにしておくと便利です。

第4章:動作確認と効果の検証

設定が終わりました。
では、どれくらい楽になったか確認してみましょう。

Before(設定前)

ansible all -i hosts -u admin --private-key=~/.ssh/id_ed25519 -m ping

After(設定後)

ansible all -m ping

どうですか? 劇的に短くなりましたね!
ansible.cfg がカレントディレクトリにあるおかげで、ユーザー名も鍵もインベントリも自動で読み込まれています。

sudo権限の確認

become = True の効果を確認するために、root権限が必要なコマンドを実行してみましょう。
例えば /root ディレクトリの中身を見るコマンドです。

ansible web -a "ls -l /root"

実行結果:

web01.example.com | CHANGED | rc=0 >>
total 4
-rw-------. 1 root root 1234 ... anaconda-ks.cfg

通常なら「Permission denied」になるところが、見事に表示されました。
裏側で自動的に sudo が実行されている証拠です。

⚠️ 注意:sudoパスワードが必要な場合
ターゲットサーバー側のsudo設定が「パスワードあり」の場合、コマンド実行時にエラーになります。
その場合は以下のいずれかの対策をとります。

  1. コマンド実行時にパスワードを入力: -K オプション(大文字)をつけて実行する。
    ansible all -m ping -K
  2. 設定ファイルで有効化: ansible.cfgbecome_ask_pass = True にする。
  3. インベントリに変数を書く: ansible_become_pass: password123 を記述する(セキュリティ上非推奨。第6回のAnsible Vaultを使うべき)。

第5章:SSH接続の高速化(パイプライニング)

サーバー台数が増えてくると、Ansibleの実行速度が気になってきます。
Ansibleはデフォルトでは、1つのタスクを実行するたびにSSH接続・切断を繰り返し、ファイルを転送して実行するため、オーバーヘッドが大きいのです。

これを解消するのが Pipelining(パイプライニング) です。
ansible.cfg に以下を追記します。

[ssh_connection]
pipelining = True

これを有効にすると、SSH接続を維持したまま複数の処理を送り込むようになり、実行速度が数倍速くなることもあります。
※ただし、ターゲットサーバーの /etc/sudoers 設定で requiretty が無効になっている必要があります(最近のRHEL系OSならデフォルトで無効なので問題ありません)。


第6章:ディレクトリ構成のベストプラクティス

最後に、将来的に管理台数が増えても破綻しないための、ディレクトリ構成の「お作法」を紹介します。
全ての変数を inventory.yml 1つに書くとファイルが巨大になりすぎるため、変数を別ファイルに分割するのが一般的です。

推奨される構成

.
├── ansible.cfg          # 設定ファイル
├── inventory.yml        # ホスト名とグループ定義のみ
├── group_vars/          # グループごとの変数を格納
│   ├── all.yml          # 全ホスト共通の変数
│   ├── web.yml          # [web]グループ用の変数
│   └── db.yml           # [db]グループ用の変数
└── host_vars/           # ホストごとの変数を格納
    └── web01.example.com.yml

Ansibleは自動的に group_varshost_vars ディレクトリを探しに行き、インベントリの定義に合わせて変数を読み込んでくれます。
こうすることで、インベントリファイル自体はシンプルに保ちつつ、詳細な設定を管理しやすくなります。


まとめ:準備は整った。いざ構築へ。

お疲れ様でした!
今回は、Ansibleをストレスなく使いこなすための環境整備を行いました。

今回の重要ポイント:

  • インベントリはYAML形式で書くと階層構造が見やすい。
  • サーバーごとの違い(ポートやユーザー)は変数(vars)で吸収する。
  • カレントディレクトリに ansible.cfg を置けば、コマンド引数を省略できる。
  • host_key_checking = False は開発環境での自動化に必須。
  • pipelining = True で実行速度を爆上げする。

これで、ターゲットサーバーを自由に操るためのコントローラーは完成しました。
次はいよいよ、Ansibleの真骨頂である「Playbook(プレイブック)」の作成に入ります。

Ad-Hocコマンド(ansible コマンド)は単発の処理しかできませんが、Playbookを使えば「Apacheを入れて、設定ファイルを書き換えて、起動して、自動起動をONにする」といった一連の流れをコードとして記述できます。

次回、第3回は「Playbookの基礎。YAMLの作法と『モジュール』によるタスク定義」です。
Ansibleの世界共通語であるYAMLの書き方から、主要なモジュール(dnf, copy, systemd)の使い方まで、自動構築の第一歩を踏み出しましょう。お楽しみに!

▼ 環境構築を試すなら ▼

ターゲットノードを準備
「VPS」で自分専用環境

おすすめVPSを見る

IaCスキルを年収に
「ITエンジニア転職」

転職エージェントを見る

コメント