「インベントリをリージョンごとに分けるべきか、それとも変数で切り替えるべきか判断できない」
AWSのマルチリージョン展開をAnsibleで自動化しようとすると、最初に直面するのがインベントリとリージョン変数の設計問題です。特にモジュールに渡すリージョン指定と、インベントリの分割粒度の決め方は、後から変えると影響範囲が広く、最初から正しい設計を選んでおく必要があります。
この記事では、Ansibleで複数のAWSリージョンへ同じ構成を展開するためのインベントリ分割設計と、Playbookにおけるregion指定の方法を、実際のディレクトリ構成とサンプルを示しながら解説します。単一リージョン構成からの移行を考えている方にも、設計上の判断根拠が伝わるよう説明します。
この記事のポイント
・インベントリはリージョン別ディレクトリ型が運用しやすい
・group_varsにaws_regionを定義し全モジュールで参照する設計が基本
・AMI IDはリージョン固有のためgroup_varsで別管理が必須
・実行は -i inventory/ap-northeast-1 のようにリージョンを明示指定する
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
なぜAnsibleでAWSのマルチリージョン展開を管理するのか
AWSでWebサービスやデータ処理基盤を運用する場合、東京リージョン(ap-northeast-1)だけでなく、海外ユーザー対応のためにバージニア(us-east-1)やシンガポール(ap-southeast-1)など複数リージョンに同じ構成を展開するケースは珍しくありません。手作業でリージョンごとにAWSコンソールを操作すると、設定の差異が生じやすく、変更のたびにすべてのリージョンを確認する必要があります。Ansibleでこれを自動化すると、「同じPlaybookを実行するだけで複数リージョンを統一した状態に保てる」という冪等性のメリットが最大限に活きます。
ただし、マルチリージョン対応で考慮すべき点が2つあります。
・リージョン変数の管理: Ansibleのモジュールはリージョンを明示指定することが多く、どこでこの変数を定義するかが設計の核心です
・リージョン固有リソースの扱い: AMI IDやVPCのCIDRなど、リージョンをまたぐと値が変わるパラメーターを正しく管理する必要があります
インベントリ設計の基本|リージョン分割の2つのアプローチ
インベントリをリージョン別に管理するアプローチは大きく2つあります。実務ではリージョン別ディレクトリ型を推奨します。1. リージョン別ディレクトリ型(推奨)
リージョンごとにインベントリディレクトリを用意する方法です。ディレクトリ内にhostsファイルとgroup_varsを置き、Playbook実行時に でターゲットリージョンを指定します。inventory/ ├── ap-northeast-1/ # 東京リージョン │ ├── hosts │ └── group_vars/ │ └── all.yml ├── us-east-1/ # バージニアリージョン │ ├── hosts │ └── group_vars/ │ └── all.yml └── ap-southeast-1/ # シンガポールリージョン ├── hosts └── group_vars/ └── all.yml
2. グループ変数型(単一インベントリ)
単一のinventoryファイルにリージョンをグループとして定義する方法です。# inventory/hosts [region_tokyo] localhost [region_virginia] localhost inventory/ └── group_vars/ ├── region_tokyo.yml # aws_region: ap-northeast-1 └── region_virginia.yml # aws_region: us-east-1
PlaybookにAWSリージョンを組み込む方法
1. group_varsでaws_regionを変数化する
各リージョンのgroup_vars/all.ymlに を定義します。この変数名はAnsibleの組み込み変数ではなく、自前で命名する慣習変数です。# inventory/ap-northeast-1/group_vars/all.yml aws_region: ap-northeast-1 ami_id: ami-0abc1234567890ef # Amazon Linux 2023(東京) # inventory/us-east-1/group_vars/all.yml aws_region: us-east-1 ami_id: ami-0def456789012abc # Amazon Linux 2023(バージニア)同じOSでもIDが異なる
2. モジュールのregionパラメーターで使う
amazon.awsコレクションのモジュールには パラメーターがあります。ここに を渡します。# playbooks/site.yml - name: Deploy infrastructure to AWS region hosts: localhost connection: local gather_facts: false tasks: - name: S3バケットを作成する amazon.aws.s3_bucket: name: "myapp-{{ aws_region }}-assets" region: "{{ aws_region }}" state: present - name: EC2インスタンスを起動する amazon.aws.ec2_instance: name: "webserver-{{ aws_region }}" region: "{{ aws_region }}" instance_type: t3.small image_id: "{{ ami_id }}" state: running
3. AWS_DEFAULT_REGIONとの使い分け
AWSモジュールは パラメーターを省略すると、環境変数 や の設定を参照します。しかしPlaybook内で明示的に を書くスタイルが推奨です。理由は次のとおりです。
・明示的な可読性: Playbookを読んだ人が「どのリージョンに作るのか」を追いやすい
・環境依存を避ける: 実行環境の .aws/config に左右されず、再現性が高まる
・複数リージョン混在時の誤操作防止: モジュールごとにリージョンが明示されていれば、意図しないリージョンへの誤適用に気づきやすい
ただし、 を モジュールで呼び出す場合などは でAWS_DEFAULT_REGIONを設定する方が整合が取れることもあります。
# shell/commandモジュールでawscliを使う場合のみ tasks: - name: Route53レコードをawscliで確認する shell: aws route53 list-hosted-zones --output json environment: AWS_DEFAULT_REGION: "{{ aws_region }}" register: route53_result
Playbookのregion設計を実機で試したい方は、>> Ansibleハンズオン講座の詳細を見る をご覧ください。
実践|マルチリージョン展開の構成例と実行手順
リージョン別ディレクトリ型を使った実際の構成例です。東京とバージニアの2リージョンにS3バケットとEC2インスタンスを展開する想定です。1. ディレクトリ構成
project/ ├── inventory/ │ ├── ap-northeast-1/ │ │ ├── hosts # 中身: localhost ansible_connection=local │ │ └── group_vars/ │ │ └── all.yml # リージョン固有変数 │ └── us-east-1/ │ ├── hosts │ └── group_vars/ │ └── all.yml ├── playbooks/ │ └── site.yml # 共通Playbook └── ansible.cfg
2. インベントリとgroup_vars
# inventory/ap-northeast-1/hosts [all] localhost ansible_connection=local # inventory/ap-northeast-1/group_vars/all.yml aws_region: ap-northeast-1 ami_id: ami-0abc123456789ef0 # Amazon Linux 2023 ap-northeast-1 instance_type: t3.small s3_bucket_prefix: myapp # inventory/us-east-1/group_vars/all.yml aws_region: us-east-1 ami_id: ami-0123456789abcdef0 # Amazon Linux 2023 us-east-1(IDが異なる) instance_type: t3.small s3_bucket_prefix: myapp
3. Playbook本体
# playbooks/site.yml --- - name: Deploy infrastructure to AWS hosts: localhost connection: local gather_facts: false tasks: - name: 対象リージョンを表示する debug: msg: "Deploying to region: {{ aws_region }}" - name: S3バケットを作成する amazon.aws.s3_bucket: name: "{{ s3_bucket_prefix }}-{{ aws_region }}-data" region: "{{ aws_region }}" versioning: true state: present - name: EC2インスタンスを起動する amazon.aws.ec2_instance: name: "webserver-{{ aws_region }}" region: "{{ aws_region }}" instance_type: "{{ instance_type }}" image_id: "{{ ami_id }}" state: running wait: true
4. 実行コマンド
# 東京リージョンのみに適用する $ ansible-playbook -i inventory/ap-northeast-1 playbooks/site.yml # バージニアリージョンのみに適用する $ ansible-playbook -i inventory/us-east-1 playbooks/site.yml # 両リージョンに連続適用する(シェルでループ) $ for region in ap-northeast-1 us-east-1; do ansible-playbook -i inventory/ playbooks/site.yml done # 実行結果(抜粋) PLAY [Deploy infrastructure to AWS] ************************** TASK [対象リージョンを表示する] ***************************** ok: [localhost] => { "msg": "Deploying to region: ap-northeast-1" } TASK [S3バケットを作成する] ********************************** changed: [localhost] TASK [EC2インスタンスを起動する] ***************************** changed: [localhost] PLAY RECAP *************************************************** localhost : ok=3 changed=2 unreachable=0 failed=0
よくあるトラブルと対処法
「AMI not found」エラーが出る
最も頻発するのがAMI IDのリージョン間違いです。AMI IDはリージョン固有のため、他のリージョンのIDをそのままコピーすると「InvalidAMIID.NotFound」エラーになります。対処: 各リージョンのgroup_vars/all.ymlに正しいAMI IDを記載する。同一OSのAMI IDはAWSコンソールの「AMI」画面でリージョンを切り替えて確認するか、 モジュールで動的に取得する方法を検討してください。
VPCやサブネットが見つからない
VPC IDやサブネットIDもリージョン固有です。他のリージョンのIDを流用すると「InvalidVpcID.NotFound」になります。対処: VPC IDとサブネットIDもAMI IDと同様にgroup_vars/all.ymlへ切り出します。もしくはPlaybook内で や を使って名前やタグからIDを動的解決する設計が安定します。
IAM権限が特定リージョンで不足している
IAMポリシーにリージョン条件()が設定されている場合、特定リージョンへのアクセスが拒否されます。対処: エラーメッセージに が含まれる場合は、まずIAMポリシーとSCPを確認します。Ansible側の問題ではなくAWS権限の問題のため、 コマンドで権限シミュレーションを行うと原因特定が速いです。
リソース名がリージョン間で重複する
グローバルに一意である必要があるリソース(S3バケット名など)は、リージョン識別子を名前に含めないと重複します。対処: 上記の例のように という命名規則を徹底します。
まとめ
Ansibleで複数のAWSリージョンへ同じ構成を展開する際のポイントを整理します。| 設計項目 | 推奨アプローチ |
|---|---|
| インベントリ構造 | リージョン別ディレクトリ型(-i で切り替え) |
| リージョン変数の定義場所 | 各リージョンのgroup_vars/all.yml |
| モジュールのリージョン指定 | region: "{{ aws_region }}" を明示記載 |
| AMI IDなどリージョン固有値 | group_vars/all.ymlにリージョンごと定義 |
| リソース命名 | 名前に{{ aws_region }}を含めて重複回避 |
| 実行コマンド | ansible-playbook -i inventory/リージョン名 site.yml |
リージョン別ディレクトリ型を採用することで、Playbook本体を変更せずにインベントリの指定だけで展開先リージョンを切り替えられます。group_varsにリージョン固有の変数(aws_region・ami_id・vpc_id)を集約することで、Playbookは汎用性を保ちつつ、各リージョンの差分は変数ファイルだけに閉じ込めることができます。
Ansible実践ハンズオンの詳細を見る >>
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
姓・名・メールの3つだけ/30秒/解除は3秒 / 詳細はこちら
- 前のページへ:roleが別のroleを呼ぶAnsibleの構成|meta/main.ymlのdependenciesと呼び出し順序の決め方
- この記事の属するカテゴリ:Ansibleへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は30秒、解除もいつでも可。
登録無料・いつでも解除できます