はじめに
AWS 上で以下のような構成を検証していたところ、
ALB のリソースマップで backend EC2 が Health checks failed となり、
ALB 経由でトラフィックが流れない問題に遭遇した。
CloudFront
→ API Gateway
→ VPC Link
→ NLB
→ ALB
→ EC2(ASG)
本記事は、その原因特定から解決までの流れをまとめた備忘録である。
発生していた事象
- ALB のターゲットグループで EC2 が Unhealthy
- ALB リソースマップに Health checks failed と表示
- ネットワーク構成(VPC / SG / ネットワークACL)は一見問題なさそう
ヘルスチェック設定の確認
ALB のターゲットグループ設定は以下の通り。
| 項目 | 設定 |
|---|---|
| Protocol | HTTP |
| Port | traffic-port |
| Path | / |
| Success codes | 200 |
一見すると特に問題のない設定。
EC2 側の状態確認
まず EC2 にログインして、ローカルで HTTP が動いているかを確認。
ss -lntp | grep :80
→ 80番ポートで LISTEN していない
この時点で、
- ALB がヘルスチェックできないのは当然
- SG 以前に EC2 側の問題の可能性が高い
と判断。
HTTP サーバ導入と疎通確認
EC2 はプライベートサブネットにあり、dnf install には NAT Gateway が必要だったため、
一時的に NAT Gateway を設定し、その後 Apache を導入。
sudo dnf install -y httpd
sudo systemctl start httpd
sudo systemctl enable httpd
再度確認。
curl http://localhost
すると次の応答が返却された。
HTTP/1.1 403 Forbidden
Server: Apache/2.4.66 (Amazon Linux)
なぜ HTTP が通っているのに Unhealthy なのか?
ここで重要なポイント。
- ALB のヘルスチェックは 200 系レスポンスのみを正常とみなす
-
403 Forbiddenは 「HTTP は通っているが異常応答」
つまり、
「通信できている ≠ ALB 的に Healthy」
という状態だった。
根本原因の特定
原因を整理すると以下の通り。
✅ セキュリティグループ
- app サーバの SG で HTTP(80) は許可されていた
- ネットワーク的な遮断はなし
❌ EC2 側の問題
- HTTP サーバが最初は 起動していなかった
- 起動後も
/に対して 403 Forbidden を返していた - 結果として ALB のヘルスチェック条件(200系)を満たしていなかった
解決方法
Apache の DocumentRoot に単純な index.html を配置。
sudo bash -c 'echo "ok" > /var/www/html/index.html'
sudo chmod 644 /var/www/html/index.html
確認:
curl -I http://localhost/
HTTP/1.1 200 OK
結果
- ターゲットグループの状態が
Unhealthy → Initial → Healthy - ALB リソースマップの
Health checks failed が解消 - ALB 経由で EC2 にリクエストが到達することを確認
まとめ(今回の学び)
本当の原因
EC2(app サーバ)で HTTP サービスが
正常応答(200 OK)を返していなかったこと
原因ではなかったもの
- ALB の設定ミス
- セキュリティグループ
- NLB / VPC Link / API Gateway
- CloudFront
教訓
- SG は「通信を許可する」だけ。アプリの稼働は保証しない
- ALB のヘルスチェックは 403 / 500 を一切許容しない
- 本番では以下がベストプラクティス
/health → 常に 200 OK を返す
ALB のヘルスチェック用エンドポイントと、
実際のアプリパスは分離すべき。
おわりに
今回のトラブルは、
「ALB が悪いように見えるが、実際は EC2 の中身ができていなかった」
という典型パターンだった。
ALB / NLB / API Gateway / ECS など、どの構成でも応用できる重要なポイントなので、今後のために記録として残しておく。