【無料ツール】画像をPDFに変換するPhotoPDF Appを公開しました!

【Ansible応用講座 第1回】静的ファイルは捨てろ。Dynamic InventoryによるAWS/クラウド環境の自動追従

「サーバーが増えるたびに、hostsファイルを書き換える」なんて、ナンセンスだ。

こんにちは!「LINUX工房」管理人の「リナックス先生」です。
「Ansible入門講座」の完走、おめでとうございます。
あなたはもう、基本的なLAMP環境の構築や、Roleを使ったコードの整理ができるようになりました。

しかし、時代は「クラウド(Cloud)」です。
AWSやAzureなどのクラウド環境では、オートスケーリングによってサーバーが勝手に増えたり減ったりします。
また、IPアドレスも再起動のたびに変わることがあります。

そんな環境で、今まで通り inventory.yml にIPアドレスを手書きしていては、運用が破綻するのは目に見えています。

コウ君

先生、お久しぶりです!
実は今、AWSで運用してるんですけど、Auto Scalingでサーバーが増えるたびにAnsibleがエラーになるんです。
「IPが変わったから接続できない」とか「新しいサーバーがリストにない」とか…。
これ、自動でなんとかならないんですか? スクリプト書くしかないですか?

リナックス先生

ふふ、コウ君もついに「静的インベントリ」の壁にぶつかったようね。
でも安心して。Ansibleには「Dynamic Inventory(ダイナミック・インベントリ)」という強力な機能があるの。
これを使えば、AWS上のサーバー一覧を自動で取得して、Ansibleの実行対象にしてくれるわ。
応用講座の第1回は、この「動的インベントリ」をマスターして、クラウド時代の運用へアップデートしましょう!

本記事では、AlmaLinux 9 をコントロールノードとし、ターゲットとなるAWS (EC2) 環境に対して、Dynamic Inventory プラグイン を導入・設定する手順を徹底解説します。

🚀 Ansible応用講座(全8回)スタート!

入門編を終えたエンジニアに向けた、実務直結の高度なテクニック集です。

  • 【第1回】静的ファイルは捨てろ。Dynamic InventoryによるAWS/クラウド環境の自動追従
  • 【第2回】ロジックを極める。Loop制御、Block例外処理、Jinja2フィルタの魔術
  • 【第3回】爆速化チューニング。Forks、Pipelining、Mitogenによるパフォーマンス改善
  • 【第4回】標準機能で足りないなら。PythonによるCustom Module開発入門
  • 【第5回】品質を保証する。MoleculeによるRoleの自動テストとCI連携
  • 【第6回】Windowsも支配する。WinRM接続とPowerShell操作の完全ガイド
  • 【第7回】ネットワーク機器の自動化。Cisco/Juniperスイッチの設定管理
  • 【第8回】新時代の実行環境。Ansible Builder/RunnerによるExecution Environment (EE)

※入門編の復習はこちら:【入門 第2回】ターゲットを支配せよ。インベントリの書き方


第1章:Dynamic Inventory とは何か?

これまで使ってきた hostsinventory.yml は、人間がサーバーの情報を手書きするファイルでした。これを「Static Inventory(静的インベントリ)」と呼びます。
小規模で固定的な環境ならこれで十分です。

Dynamic Inventory の仕組み

対して Dynamic Inventory は、Ansible が実行時に外部のAPI(AWS, Azure, VMware, OpenStackなど)に問い合わせを行い、リアルタイムでサーバーリストを生成する仕組みです。

  • メリット1: サーバーの増減(Auto Scaling)に何もしなくても追従できる。
  • メリット2: タグ(Tag)情報を使って、「Environment=Production のサーバーだけ」といった指定が簡単にできる。
  • メリット3: 手動管理による IP アドレスの記載ミスがなくなる。

スクリプト形式からプラグイン形式へ

昔のAnsibleでは、Pythonなどで書かれた「インベントリスクリプト(ec2.pyなど)」を使っていました。
しかし現在は、より設定が簡単で高機能な「インベントリプラグイン」の使用が推奨されています。
本講座でも、最新のプラグイン形式を採用します。


第2章:AWS接続の準備(コントロールノード側)

今回はターゲットとして AWS (Amazon EC2) を例にします。
Ansibleを実行するコントロールノード(手元のPCや踏み台サーバー)に、AWSと通信するための準備を行います。

1. Pythonライブラリ (boto3) のインストール

AnsibleのAWSモジュールやプラグインは、裏側でAWS公式のPython SDKである boto3botocore を使用します。

# pipでインストールする場合
pip install boto3 botocore

# AlmaLinux 9でdnfを使う場合
sudo dnf install python3-boto3

2. Ansible Collection のインストール

AWS用の機能は amazon.aws コレクションに含まれています。
ansible-galaxy コマンドでインストールします。

ansible-galaxy collection install amazon.aws

3. IAMユーザーの認証情報設定

AnsibleがAWS APIを叩くための権限が必要です。
AWSコンソールで、AmazonEC2ReadOnlyAccess 権限を持つIAMユーザーを作成し、アクセスキーを取得しておいてください。

環境変数でセットするのが最も手軽で安全です。

export AWS_ACCESS_KEY_ID='AKIAXXXXXXXXXXXXXXXX'
export AWS_SECRET_ACCESS_KEY='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
export AWS_REGION='ap-northeast-1'

第3章:インベントリファイル (aws_ec2.yml) の作成

ここが今回のハイライトです。
静的な inventory.yml の代わりに、動的に情報を取得するための設定ファイル aws_ec2.yml を作成します。

※ファイル名の末尾は必ず aws_ec2.yml または aws_ec2.yaml で終わる必要があります。Ansibleはこの拡張子を見てプラグインを起動するからです。

基本設定

# aws_ec2.yml
plugin: amazon.aws.aws_ec2

# 対象リージョン
regions:
  - ap-northeast-1

# 変数として利用したい情報を指定
# (例: プライベートIP, タグ, インスタンスタイプなど)
compose:
  ansible_host: private_ip_address  # 接続先にプライベートIPを使う場合
  # パブリックIPを使いたい場合は public_ip_address にする

フィルタリング設定 (filters)

AWS上の「全てのEC2」を取得すると、停止中のサーバーや、管理対象外のサーバーまで拾ってしまいます。
filters オプションで対象を絞り込みます。

filters:
  # 実行中のインスタンスのみ
  instance-state-name: running
  # 特定のタグを持つインスタンスのみ (例: Project=MyService)
  "tag:Project": MyService

グルーピング設定 (keyed_groups)

これがDynamic Inventoryの真骨頂です。
取得したEC2を、タグやインスタンスタイプに基づいて自動的にグループ分けします。

keyed_groups:
  # タグ "Environment" の値でグループを作る
  # 例: Environment: Production -> aws_tag_Environment_Production というグループになる
  - key: tags.Environment
    prefix: env
    separator: "_"

  # タグ "Role" の値でグループを作る
  # 例: Role: Web -> role_Web というグループになる
  - key: tags.Role
    prefix: role
    separator: "_"

第4章:動作確認とグラフ表示

設定ファイルができたら、実際にAWSから情報が取れるか確認しましょう。
ansible-inventory コマンドを使います。

1. インベントリ情報の取得確認

ansible-inventory -i aws_ec2.yml --graph

実行結果のイメージ:

@all:
  |--@aws_ec2:
  |  |--ip-10-0-1-50.ap-northeast-1.compute.internal
  |  |--ip-10-0-1-51.ap-northeast-1.compute.internal
  |--@env_Production:
  |  |--ip-10-0-1-50.ap-northeast-1.compute.internal
  |--@env_Staging:
  |  |--ip-10-0-1-51.ap-northeast-1.compute.internal
  |--@role_Web:
  |  |--ip-10-0-1-50.ap-northeast-1.compute.internal
  |--@role_DB:
  |  |--ip-10-0-1-51.ap-northeast-1.compute.internal

成功です!
AWS上のタグ設定に基づいて、自動的に env_Productionrole_Web といったグループが生成されているのが分かります。

2. JSON形式で詳細確認

どんな変数が取れているか詳細に見たい場合は --list を使います。

ansible-inventory -i aws_ec2.yml --list

第5章:Playbookからの利用と応用テクニック

Dynamic Inventoryが動けば、あとは普段のPlaybookでグループ名を指定するだけです。

1. Playbookでの指定

---
- name: Setup Web Servers
  # 自動生成されたグループ名を指定
  hosts: role_Web
  become: true
  
  tasks:
    - name: Ping
      ansible.builtin.ping:

2. ansible.cfg への登録

毎回 -i aws_ec2.yml を打つのは面倒なので、ansible.cfg に登録してしまいましょう。
ただし、プラグインを有効化する設定も必要です。

[defaults]
inventory = ./aws_ec2.yml

[inventory]
# aws_ec2プラグインを許可する
enable_plugins = amazon.aws.aws_ec2, host_list, script, auto, yaml, ini, toml

3. 【応用】EC2タグを変数として使う

Dynamic Inventoryで取得したタグ情報は、Playbook内で変数として利用できます。
例えば、AWS側で Version: 1.0.5 というタグをつけておき、Ansibleでそのバージョンのアプリをデプロイする、といったことが可能です。

- name: Print Tag Value
  ansible.builtin.debug:
    msg: "Deploying version {{ tags.Version }} to {{ tags.Name }}"

💡 SSH接続設定の自動化
EC2インスタンスへのSSH接続には、通常 ec2-user が使われますが、Ubuntuなら ubuntu です。
これもAWSのAMI情報などから判断するか、group_vars を使って動的グループに対して変数を割り当てるのがスマートです。

group_vars/role_Web.yml:

ansible_user: ec2-user
ansible_ssh_private_key_file: ~/.ssh/my-aws-key.pem

第6章:トラブルシューティング

Dynamic Inventoryでよくあるエラーと対策です。

Q1. “Failed to import the required Python library (botocore or boto3)”

原因: Pythonライブラリが入っていません。
対策: pip install boto3 を実行してください。Ansibleを実行しているPython環境と同じ場所に入れる必要があります。

Q2. 空のリストが返ってくる (server list is empty)

原因: 認証情報が間違っているか、regions の指定が間違っているか、filters の条件が厳しすぎます。
対策: まず filters をコメントアウトして全取得できるか試し、AWS CLI (aws ec2 describe-instances) で同じ認証情報を使ってインスタンスが見えるか確認してください。

Q3. “ssh: connect to host … port 22: Connection timed out”

原因: プライベートIPに接続しようとしているのにVPNがない、またはセキュリティグループで22番が開いていません。
対策: パブリックIPを使う場合は ansible_host: public_ip_address に変更してください。また、セキュリティグループの設定を確認しましょう。


まとめ:クラウドネイティブな運用への第一歩

お疲れ様でした!
これで、サーバーが勝手に増減するクラウド環境でも、Ansibleを使いこなす準備が整いました。

今回の重要ポイント:

  • Dynamic Inventoryは、API経由でリアルタイムなサーバーリストを作る。
  • amazon.aws.aws_ec2 プラグインが現在のデファクトスタンダード。
  • keyed_groups を使えば、タグベースで自動的にグループ分けができる。
  • ansible.cfg でプラグインを有効化することを忘れずに。

「IPアドレスの管理」という不毛な作業から開放されたあなたは、より本質的な「ロジックの構築」に集中できるはずです。

次回、応用講座 第2回は「ロジックを極める。Loop制御、Block例外処理、Jinja2フィルタの魔術」です。
loopwhen はもう知っているかもしれませんが、リストの要素を加工する map フィルタや、複雑なJSONデータを解析する json_query、そしてエラー発生時のリカバリフローなど、Playbookを「プログラミング」する高度なテクニックを紹介します。
Ansible沼の深淵へようこそ。お楽しみに!

▼ クラウド自動化を実践する ▼

AWS環境で試す
「VPS」で自分専用環境

おすすめVPSを見る

クラウド×自動化スキルを年収に
「ITエンジニア転職」

転職エージェントを見る

コメント