これまで、Ansible で、 aws_ec2 inventory plugin を対象ホストの指定だけに使っていたのですが、EC2 に付与したタグから環境の違いなども場合分けできるとわかって、もったいない使い方をしていたなと反省しきりです。
あらためて、このプラグインのグループの機能をまとめてみたいと思います。
aws_ec2 inventory plugin とは
amazon.aws.aws_ec2 は、Ansible 公式コレクション amazon.aws に同梱されている動的インベントリ(Dynamic Inventory)プラグインです。
静的な hosts ファイルの代わりに aws_ec2.yml という設定ファイルを準備しておくだけで、Ansible の実行時に AWS API(describe-instances)を呼び出し、最新の EC2 インスタンス一覧やそのメタデータ(タグ、IPアドレス、VPC ID、リージョンなど)を即座に取得してインベントリを自動生成することができます。
対象ホストをEC2インスタンス名で
デフォルトの状態では、インスタンス ID(i-0123456789abcdef0)や IPアドレスがホスト名(ansible_host)として扱われますが、 Ansible操作上は AWSコンソール上で設定した Name タグの値 で指定できると直感的で扱いやすくなります。
これを実現するのが設定ファイル内の hostnames パラメータです。
plugin: amazon.aws.aws_ec2
regions:
- ap-northeast-1
# ホスト名(ansible_host)決定の優先順位
hostnames:
- tag:Name # 最優先:Name タグの値(例: prd-web-01)
- private-ip-address # タグがない場合:プライベートIP
このように設定すると、 Playbook やコマンドの指定において EC2インスタンスにつけた名前、例えば prd-web-01 のような識別名で操作を実行できるようになります。
タグで環境を分ける group_vars
Dynamic Inventory の真価は、 EC2 に付与された タグ情報を利用して動的にグループを作成し、そのグループごとに group_vars で変数を適用できる 点にあります。
グループ作成には主に keyed_groups と groups の2つの手法を使い分けます。
keyed_groups の使い方
keyed_groups は、 EC2 の特定の属性(タグの値など)に基づいて、自動的にグループを生成・分類する機能です。タグの値が増えたり変更されたりしても、設定ファイルを変更する必要がありません。
-
用途 : 環境名(
Environmentタグ)やロール名(Roleタグ)の値ごとに全自動で網羅分類したいとき
keyed_groups:
# Environment タグの値 (prd, stg 等) からグループを動的生成
# 例: tag_prd, tag_stg
- key: tags.Environment
prefix: env
separator: "_"
# Role タグの値 (web, db 等) からグループを動的生成
# 例: role_web, role_db
- key: tags.Role
prefix: role
separator: "_"
groups の使い方
groups は、Jinja2 の条件式を使ってカスタムグループを定義する機能です。複数の条件(AND / OR)を組み合わせたり、部分一致で抽出したりする場合に使用します。
-
用途 : 「Nameタグに
webが含まれるもの」や「特定条件が重なったホストのみ」をグループ化したいとき
groups:
# Name タグに "web" という文字列が含まれるインスタンスをまとめる
web_servers: "'web' in tags.Name"
# 本番環境かつデータベースのホストを抽出する複合条件
prd_db_servers: "tags.Environment == 'prd' and tags.Role == 'db'"
具体的な構成例(ディレクトリ構造・設定ファイル・変数ファイル)
実際のプロジェクトで構成するディレクトリ構造の具体的な例です。
1. ディレクトリ構造
my_ansible_project/
├── ansible.cfg
├── site.yml
├── inventory/
│ └── aws_ec2.yml # Dynamic Inventory 設定ファイル
└── group_vars/
├── all.yml # 全ホスト共通の変数
├── env_prd.yml # keyed_groups で生成されたグループ用
└── web_servers.yml # groups で定義したカスタムグループ用
2. インベントリ設定ファイル (inventory/aws_ec2.yml)
ファイル名の末尾は必ず .aws_ec2.yml または .aws_ec2.yaml にする必要があります。
# プラグインの指定(必須)
plugin: amazon.aws.aws_ec2
# 対象リージョン
regions:
- ap-northeast-1
# 実行中のインスタンスのみ取得(接続エラー防止)
filters:
instance-state-name:
# EC2の Name タグを Ansible 上のホスト名にする
hostnames:
- tag:Name
- private-ip-address
# 1. keyed_groups による自動グループ化
keyed_groups:
# Environment タグによる自動グループ化 (env_prd 等)
- key: tags.Environment
prefix: env
separator: "_"
# 2. groups によるカスタムグループ化
groups:
# Name タグに "web" が含まれるホストを web_servers グループに指定
web_servers: "'web' in tags.Name"
3. 変数ファイル
3.1. 全ホスト共通変数 (group_vars/all.yml)
ansible_user: ec2-user
ansible_ssh_private_key_file: ~/.ssh/id_rsa_aws
3.2. 本番環境用変数 (group_vars/env_prd.yml)
keyed_groups: で生成された env_prd グループに対応する変数ファイルです。
is_production: true
log_level: ERROR
app_db_host: "prod-db.internal.local"
3.3. Webサーバーグループ用変数 (group_vars/web_servers.yml)
groups: で作成した web_servers グループに対応する変数ファイルです。
http_port: 80
https_port: 443
nginx_max_clients: 1024
動作確認コマンド
設定が完了したら、ansible-inventory コマンドで意図通りにホストが読み込まれ、グループ化されているか確認します。
# グループ階層構造の確認
ansible-inventory -i inventory/aws_ec2.yml --graph
実行結果イメージ
@all:
|--@env_prd:
| |--prd-web-01
| |--prd-web-02
|--@web_servers:
| |--prd-web-01
| |--prd-web-02
| |--dev-web-01
|--@ungrouped:
Playbook を実行するときは、次のように指定します。
ansible-playbook -i inventory/aws_ec2.yml site.yml
まとめ
-
amazon.aws.aws_ec2プラグインを使うと、EC2 の追加・削除に合わせてインベントリが自動更新される。 -
hostnamesに tag:Name を指定することで、EC2 インスタンス名で直感的に操作できる。 -
全自動の階層化には
keyed_groups、特定条件の抽出にはgroupsを使い分ける。 -
生成された動的グループ名と一致する
group_vars/<グループ名>.ymlを作成するだけで、環境に応じた変数を適用できる。
amazon.aws.aws_ec2 プラグインをぜひご活用ください。