Ansibleで複数のAWSリージョンへ同じ構成を展開する|region指定とインベントリ分割の設計

宮崎智広 この記事の監修:宮崎智広(Linux実務・教育歴20年以上・受講者3,100名超)
HOMELinux技術 リナックスマスター.JP(Linuxマスター.JP)Ansible > Ansibleで複数のAWSリージョンへ同じ構成を展開する|region指定とインベントリ分割の設計
「TokyoとOregonで同じPlaybookを使いたいが、どこでリージョンを切り替えればいいのか分からない」
「インベントリをリージョンごとに分けるべきか、それとも変数で切り替えるべきか判断できない」

AWSのマルチリージョン展開をAnsibleで自動化しようとすると、最初に直面するのがインベントリとリージョン変数の設計問題です。特にモジュールに渡すリージョン指定と、インベントリの分割粒度の決め方は、後から変えると影響範囲が広く、最初から正しい設計を選んでおく必要があります。

この記事では、Ansibleで複数のAWSリージョンへ同じ構成を展開するためのインベントリ分割設計と、Playbookにおけるregion指定の方法を、実際のディレクトリ構成とサンプルを示しながら解説します。単一リージョン構成からの移行を考えている方にも、設計上の判断根拠が伝わるよう説明します。

この記事のポイント

・インベントリはリージョン別ディレクトリ型が運用しやすい
・group_varsにaws_regionを定義し全モジュールで参照する設計が基本
・AMI IDはリージョン固有のためgroup_varsで別管理が必須
・実行は -i inventory/ap-northeast-1 のようにリージョンを明示指定する


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

なぜ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

単一インベントリで完結する手軽さがありますが、同じlocalhostが複数グループに所属する構造は可読性が下がりがちです。展開対象リージョンが少ない(2つ程度)場合に限って採用を検討する程度にとどめましょう。

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が異なる

AMI IDはリージョン固有です。「同じAmazon Linux 2023」であっても、リージョンが変わればAMI IDが変わります。このリージョン固有の値をgroup_varsに集約することで、Playbook本体はどのリージョンでも同じコードを書けます。

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

リソース名に を含めることで、複数リージョンに同じPlaybookを適用しても名前が衝突しません。

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

インベントリのパスを切り替えるだけでリージョンが変わります。Playbook本体には一切手を加えません。

よくあるトラブルと対処法

「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は汎用性を保ちつつ、各リージョンの差分は変数ファイルだけに閉じ込めることができます。
現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、20年以上の運用経験を持つ現役エンジニアが基礎から教えます。
Ansible実践ハンズオンの詳細を見る >>

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

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

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

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

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

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

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

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

この記事を書いた人

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

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

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