【AWSマルチリージョン構成】構築で踏んだハマりどころ ― 実践的トラブルシューティング
前回の記事では、Active-Active 構成における3層(App / DB / Storage)のフェイルオーバー試験を行い、各レイヤーがどのように切り替わるかをレポートしました。
本記事では、その構成を実際に構築する中で踏んだ「ハマりどころ」を5つ厳選して取り上げます。いずれも、ドキュメントを読んだだけでは想定しにくい実践的なトラブルです。同様の構成に挑む方の参考になればさいわいです。
1. [ネットワーク] VPC の DNS 属性見落としによる PHZ 接続不可
事象
第2章で解説した Private Hosted Zone(PHZ)のスプリットビュー設定が完了し、EC2 からデータベースへの接続を試みたところ、NXDOMAIN エラーが返ってきて名前解決に失敗しました。
PHZ のレコード設定は正しいはずなのに、なぜか DNS レコードが引けない。Route 53 やレコードの設定内容を何度見直しても問題は見当たりませんでした。
原因と解決策
原因は、VPC の DNS 属性設定にありました。
VPC の DNS 設定には、以下の2つの独立した属性があります。
| 属性 | デフォルト値(カスタム VPC) | 役割 |
|---|---|---|
| enableDnsSupport | True(有効) | VPC 内の DNS 解決機能そのものの ON/OFF |
| enableDnsHostnames | False(無効) | VPC 内のインスタンスに DNS ホスト名を割り当てるかの ON/OFF |
PHZ を機能させるためには この両方が True になっている必要があります。デフォルト VPC では両方とも有効ですが、カスタム VPC を作成した場合、enableDnsHostnames はデフォルトで無効のままになります。
参考: カスタム VPC を作成した際の各属性のデフォルト値については、AWS 公式ドキュメント「VPC の DNS 属性」の enableDnsHostnames などの各項目にて仕様が明記されています。また、本トラブルの直接の原因である「PHZ を利用するための前提条件」については「プライベートホストゾーンを使用するときの Amazon VPC 設定」も合わせてご参照ください。
【画像配置予定】VPCのDNS属性設定画面、またはNXDOMAINエラーのスクショ
修正は AWS CLI 1コマンドで完了します。
# enableDnsHostnames を有効化
aws ec2 modify-vpc-attribute \
--vpc-id <vpc_id> \
--enable-dns-hostnames教訓
VPC まわりのネットワーク設定の「デフォルト値」は、デフォルト VPC を使い慣れているほど落とし穴になります。「PHZ は正しく設定したのに名前解決できない」という場合、まず疑うべき項目として覚えておくと時間の節約になります。Terraform などの IaC でリソースを定義する際も、この属性の明示的な指定を忘れずに組み込んでおくことを推奨します。
2. [Web/ALB] ALB HTTPS 終端によるリダイレクトループと「レイヤーの責務」
事象
ALB に ACM の証明書を適用し、リスナールールで HTTP → HTTPS リダイレクトを設定しました。ブラウザでサイトにアクセスすると、ページが表示されるどころか「ERR_TOO_MANY_REDIRECTS」の無限リダイレクトループが発生し、完全に接続不能な状態になりました。
原因
これは ALB と WordPress(アプリケーション)のそれぞれが、相手に認識させることなくリダイレクトをかけ続けることで発生する古典的で典型的な問題です。
本構成のリクエスト経路を整理すると、以下のようになります。
ユーザー (HTTPS) → ALB(HTTPS 終端)→ EC2/WordPress(HTTP で受信)【画像配置予定】ALBでのHTTPS終端による無限リダイレクトループのメカニズム図
ALB でHTTPS を終端するということは、ALB とユーザーの間は HTTPS で暗号化されますが、ALB とバックエンドの EC2 の間は HTTP(ポート 80)で通信します。これはまったく正常な動作です。
問題は WordPress 側の認識にあります。WordPress は ALB から HTTP でリクエストを受け取ると、「このリクエストは非セキュア(HTTP)で来ている」と認識します。WordPress には「HTTP でアクセスされたら HTTPS に転送する」という設定が入っているため、ALB に向けて HTTPS リダイレクトを返します。すると ALB は再度 HTTP に変換して WordPress に送り込み、WordPress はまた HTTPS にリダイレクト……というループが完成します。
解決策:アプリケーション側でプロトコルを正しく判断させる
この問題の解決は「各レイヤーが何を担うか」を正しく設計することです。ALB には X-Forwarded-Proto というリクエストヘッダーを付加する機能があります。このヘッダーには、ユーザーと ALB の間で使用された実際のプロトコル(https など)が記録されています。
WordPress 側でこのヘッダーを参照することで、「ALB からは HTTP で届いているが、ユーザーとの間は実際には HTTPS だ」と判断させることができます。wp-config.php に以下の定番コードを追加します。
// ALB HTTPS 終端環境下での HTTPS 判定
if ( isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https' ) {
$_SERVER['HTTPS'] = 'on';
}教訓:レイヤーごとの「セキュア通信状態」の責務を意識する
このトラブルは本構成固有のものではなく、ロードバランサを導入したほぼすべての構成で遭遇しうる「あるある」事例です。オンプレミス環境をクラウドに移行する際にも頻発します。
重要なのは、「システム全体としてどこからどこまでが HTTPS か」ではなく、「各レイヤーがセキュアな通信状態をどう認識しているか」を個別に把握する視点です。
- ロードバランサ(ALB): ユーザーとの HTTPS 終端を担う
- バックエンド(EC2): ALB からは HTTP で受け取ることを前提にしている
- アプリケーション(WordPress):
X-Forwarded-Protoヘッダーを元に通信状態を自ら判断する
これら各レイヤーの認識と責務が噛み合っていることを確認することが、HTTPS 化における基本的な設計の確認事項です。
3. [AMIビルド] efs-utils ビルド時の OOM と自前ビルドの落とし穴
事象
EC2 Image Builder を使って WordPress 稼働用のゴールデンイメージ(AMI)を作成していたところ、efs-utils のインストールステップで突如ビルドが失敗しました。ログを確認すると、Rust コンパイラが OOM(Out of Memory)によって強制終了(OOM キル)されていました。
【画像配置予定】OOMエラー発生時のビルドログ、またはCloudWatchメトリクスのスクショ
背景:なぜ efs-utils を自前ビルドするのか
efs-utils は AWS が開発した EFS マウントヘルパーです。Amazon Linux 2 / Amazon Linux 2023 であれば、yum install amazon-efs-utils の1コマンドで完結します。 Ubuntu の場合は公式パッケージが提供されていないため、GitHub リポジトリからソースを取得してビルドする必要があります。
「Ubuntuを使いたい」かつ「EFSを利用したい」という2つの要件が組み合わさった結果、efs-utils の自前ビルドが必要になりました。
EFS を使用しない構成や Amazon Linux を選択した場合は、このトラブルは発生しません。
原因と解決策
efs-utils は Rust で実装されており、Rust コンパイラのメモリ消費量は非常に大きくなります。Image Builder のデフォルト設定である t3.micro(1 GB RAM)では物理メモリが大幅に不足します。
このメモリ不足を解消するための現実的なアプローチとして、以下の2つの方法が考えられます。
- インスタンスサイズのスケールアップ(推奨):
ビルド用インスタンスをc5.xlarge(8 GB RAM)など、物理メモリに十分な余裕のあるサイズへ変更します。本構成では最終的にこのアプローチを採用し、最も安定してビルドを完了させることができました。 - スワップ領域の確保(代替案):
インスタンスサイズを維持したい場合、ビルド時にスワップ用の EBS ボリュームをアタッチし、スクリプト内でマウントしてスワップ領域として有効化することで、一時的に OOM を回避するアプローチも有効です。
教訓
efs-utils に限らず、Rust や Go で実装されたツールをソースからビルドするタスクは、コンパイラ自体のメモリ消費量が大きく、ビルドパイプラインのリソース要件を見誤りやすいポイントです。
AMI のビルド環境は「プロダクションよりも安価に済ませたい」という心理が働きがちです。しかし、ビルド用インスタンスは数十分程度の短時間で処理を終えて破棄される一時的なリソースであり、インスタンスサイズを上げても実際のコスト増はわずか数円〜数十円に過ぎません。
コンパイルを伴うビルドでは目先のコスト削減よりも処理の安定性を優先し、充分なメモリを持つインスタンスサイズを選定すること、あるいはスワップ領域の確保を標準手順に組み込んでおくことを推奨します。
【ワンポイントアドバイス】スポットインスタンスの活用
コストと安定性を両立させる強力なベストプラクティスとして、スポットインスタンスの利用があります。ビルド処理は20〜30分程度で完了するため、途中で中断されるリスクは低く、仮に中断されてもパイプラインを再実行するだけで済むため運用への実害はほぼありません。
EC2 Image Builder でスポットインスタンスを利用するには、標準の設定画面には項目がないため、「スポットインスタンスをリクエストするように設定した Launch Template(起動テンプレート)」を別途作成し、それを Image Builder のインフラストラクチャ設定に割り当てるという手法で実現可能です。
4. [CI/CD 連携] AMI 参照の「サイレントな不一致」と「テストの理想と現実」
事象
Image Builder でアプリケーションを修正した新しいゴールデンイメージ(AMI)を作成し、Auto Scaling Group のインスタンスリフレッシュを実行しました。しかし、新しく起動してきた EC2 インスタンスは、ミドルウェアが何も入っていない初期状態のUbuntuでした。
さらに困惑したのは、エラーが一切発生しなかったことです。Image Builder のビルドは成功し、インスタンスリフレッシュも正常完了の記録が残っています。しかし実態は古い(正確には間違った)AMI が使われていました。
原因
Launch Template(起動テンプレート)を作成するスクリプトの AMI 取得ロジックに問題がありました。そのスクリプトは、Image Builder で作成した独自の最新 AMI ではなく、SSM Parameter Store が提供する AWS 公式の最新 Ubuntu AMIを取得する設定になっていました。
【画像配置予定】誤ったAMIを取得しているIaCと、正しい成果物引き渡しフローの概念図
スクリプトの意図 : 独自ビルドの最新 AMI を起動テンプレートに適用する
スクリプトの実際の動作: SSM Parameter Store の公式 Ubuntu AMI を適用してしまっていたAMI ID は両方とも有効な ID のためエラーにはなりません。Launch Template の更新も成功し、インスタンスリフレッシュも成功します。しかしビルドの成果物とは無関係の「素の Ubuntu」が起動し続けます。
解決策:タグを用いた独自 AMI の動的検索
AMI 取得ロジックを、SSM Parameter Store の公式 AMI への参照から、「特定のプロジェクトタグが付与された、自アカウント所有の AMI の中で最新のもの」を動的に検索して取得する方式へ変更しました。
教訓:テストの理想と、現実的なパイプライン設計
「このような不整合はインフラテストで検知できるのではないか」という視点は正しいです。InSpec や Goss などのインフラテストツールを Image Builder のワークフローに組み込めれば、期待するパッケージやサービスが存在するかを自動確認し、こういったサイレントな不整合を防ぐことができます。
しかし実際には、Image Builder の成果物に対してフルのインフラテストスイートを維持・実行するのは、実装と運用の両面でコストが高く、小〜中規模の構成では現実的ではないケースも考えられます。
現実的な妥協点として有効なのは、パイプラインの「引き渡しポイント」を一元化・明示化するアプローチです。
- タグによる動的検索:
上記のように、独自ビルドの AMI には一意のプロジェクトタグを付与し、スクリプトはそのタグで検索する - SSM Parameter Store への書き出し:
Image Builder のビルド完了時に最新の AMI ID を独自の SSM パラメータパスに書き込み、デプロイスクリプトはそこを参照する
どちらの方式も、「CI/CD が生成した成果物(AMI)の ID を、IaC(起動テンプレート等)が確実に受け取る」という単純な原則を実現するための手段です。エラーが発生せず気付けないサイレントな不整合を防ぐために、この連携ポイントの設計には注意を払う必要があります。
5. [アーキテクチャ設計] ゴールデンイメージ(AMI)に何を焼き込むべきかの反省
事象
インフラが組み上がり、フェイルオーバー試験まで完了した状態で、改めて WordPress を本格的に使い始めたところ、管理画面からの画像アップロードで「レスポンシブな画像サイズを生成できません」というエラーが発生しました。
調査の結果、画像のリサイズ処理に必要な PHP 拡張モジュール(php-gd)がゴールデンイメージに含まれていなかったことが原因でした。
対処自体は単純です。稼働中インスタンスへの緊急パッチ(SSM Run Command でのパッケージインストール)でサービスを即時復旧し、その後、ビルドスクリプトに不足パッケージを追記して AMI を再ビルドしました。
本質的な課題:Immutable インフラの代償
この一連の対応を通じて改めて痛感したのは、Immutable(不変)なインフラを採用したことのトレードオフです。
パッケージが1つ足りないだけで、踏むべき手順は以下のようになります。
- ビルドスクリプトに不足パッケージを追記
- Image Builder パイプラインを再実行(ビルド完了まで 20〜30 分)
- AMI が配布されるまで待機
- Auto Scaling Group のインスタンスリフレッシュを実行(全インスタンス入れ替え)
apt install php-gd 1コマンドで済む修正に、これだけの工程を要します。
もちろん、これは Immutable インフラが持つ「インフラの状態を AMI という単一の成果物で管理し、常に再現性を保証する」という価値と表裏一体のコストでもあります。
教訓:アプリケーションソース配置のジレンマと分離設計
この「AMI再ビルドの重さ」は、インフラ環境の修正時だけでなく、アプリケーション(WordPress本体や設定ファイル)の更新時にも重くのしかかります。
今回のプロジェクトではオートスケーリング時の「起動速度」と「再現性」を担保するため、以下のような設計を採用していました。
- AMIビルド時:
WordPress のソースコードをダウンロードし、AMI 内の/opt/wordpressにシード(種)として焼き込む - インスタンス起動時:
UserDataで、AMI 内のシードを共有ストレージ(EFS)へrsyncで展開する
【画像配置予定】「AMI焼き込み方式」と「S3/起動時展開方式」のデプロイフロー比較図
この「AMI にアプリケーションを含める」アプローチは、起動時に外部からギガバイト単位のダウンロードを行う必要がなくなり、オートスケーリングを高速化できるという明確なメリットがありました。しかし一方で、WordPress のバージョンアップやコード修正のたびに、数十分の AMI ビルドパイプラインを回さなければならないという「運用の重さ」の要因にもなります。
実運用では、以下の代替アプローチを検討すべきです。
- S3 + 起動時展開(推奨)
アプリケーションのソースコード群をアーカイブ化して S3 に配置しておき、インスタンス起動時にaws s3 cpなどで取得して展開する方法です。数秒〜十数秒で完了するためスケールアウトを阻害せず、AMI の再ビルドなしにアプリケーションだけを更新できます。 - EFS への完全分離
ソースコードも含めてすべて EFS 上に永続化しておき、インスタンスは起動時にマウントするだけとする方法です。配置や更新は最速ですが、EFS のネットワークオーバーヘッドにより PHP の実行速度が低下するトレードオフがあるため、Opcache などのチューニングとセットで導入する必要があります。
Immutable インフラは強力ですが、OS/ミドルウェアとアプリケーションコードでは更新のライフサイクルが異なります。
本件を通して、「インフラ層は AMI に焼き込み、アプリケーション層は S3 や CodeDeploy 等から独立してデプロイする」というように、ライフサイクルに応じた分離設計を行うことが、アジリティの高い運用への鍵となるという結論に至りました。
まとめ
本記事では、マルチリージョン Active-Active 構成の実構築で踏んだ5つのトラブルを紹介しました。
| # | カテゴリ | ハマりどころ | キーポイント |
|---|---|---|---|
| 1 | ネットワーク | VPC DNS 属性による PHZ 接続不可 | カスタム VPC では enableDnsHostnames がデフォルト無効 |
| 2 | Web/ALB | HTTPS 終端によるリダイレクトループ | 各レイヤーのセキュア通信の認識を合わせる |
| 3 | AMIビルド | efs-utils OOM | Rust の自前ビルドは重い。ビルド環境のリソース確保を怠らない |
| 4 | CI/CD 連携 | AMI 参照のサイレントな不一致 | パイプライン間の成果物引き渡しポイントを明示化する |
| 5 | アーキテクチャ | ゴールデンイメージへの過剰な焼き込み | AMI の粒度設計(基盤のみ)と動的プロビジョニングの分離 |
次回の記事では、本環境を「本番導入」へ近づけるために検討すべき改善ポイントと、今回あえてシンプルにした箇所について整理する予定です。


