はじめに
本記事では、AWS ECS をプライベートサブネットで運用している際に Firebase Authentication がタイムアウトする問題について、
原因を切り分け、最終的に Redis Serverless(Valkey)の仕様に行き着いた過程と解決策を解説します。
Firebase 側の問題に見えて、実際は Redis の接続仕様が原因というケースは非常にハマりやすいため、同様の構成で困っている方の参考になれば幸いです。
この記事でわかる・できること
- ECS(プライベートサブネット)から Firebase Auth に接続できない原因の切り分け方法
- 「ECS Exec は成功するのにアプリは通信できない」理由
- ElastiCache Redis Serverless(Valkey)の罠仕様
- 問題を確実に解消するための実践的な解決策
この記事の対象者
- ECS + Rails API を使っている人
- Firebase Authentication をバックエンドで検証している人
- ElastiCache(特に Serverless / Valkey)を初めて使う人
- 「ネットワークは通っているはずなのに Timeout する」問題で詰まっている人
動作環境・使用するツールや言語
- OS:Amazon Linux(ECS Fargate)
- AWS:ECS Fargate(Private Subnet), ElastiCache
- 言語:Ruby 3.4.4
- フレームワーク:Rails 8.0.2
Firebase Authentication
redis / firebase_id_token gem
1. 発生した問題の概要
ECS(プライベートサブネット)上で稼働する Rails API において、
Firebase Authentication を使ったリクエストが常にタイムアウトしてしまいました。
ログ上では以下のようなエラーが出力されていました。
証明書の取得に失敗しました: Connection timed out
一見すると、
- Firebase 側の障害
- ECS からインターネットに出られない
- DNS / NAT / VPC Endpoint の設定ミス
などが疑われます。
2. ECS Exec は成功するのに、なぜアプリは通信できないのか
まず混乱しやすいポイントとして、ECS Exec は問題なく成功していました。
ECS Exec ✅ 成功
コンテナ内で curl htps://www.googleapis.com/...(Firebaseのドメイン) ✅ 成功
ここで多くの人がこう考えます。
「Firebase へは到達できている。じゃあ、どこのネットワークが悪い?」
しかし、これが 落とし穴でした。
3. Firebase Auth は「直接通信」だけでは完結しない
Rails で Firebase Authentication を扱う際、多くの場合、
- firebase_id_token gem
を利用します。
この gem で取得した公開鍵(証明書)をRedisにキャッシュする設計としていました。
処理は以下の流れになっています。
- Google から公開鍵(証明書)を取得
- Redis にキャッシュ
- 次回以降は Redis から読み込み
firebase_id_token gemを使った場合のplantUML図

つまり、
Redis に接続できないと Firebase Auth も失敗する
という構造です。
4. 真犯人は Redis Serverless(Valkey)の仕様
今回使用していた Redis は以下でした。
- ElastiCache Serverless
- エンジン:Valkey 8.x
- 転送中の暗号化:有効(必須)
Redis Serverless の重要な仕様
| 項目 | Redis Serverless |
|---|---|
| ポート | 6379 |
| TLS | 必須 |
| 平文接続 | ❌不可 |
| 対応クライアント | TLS 対応必須 |
Rails 側では以下のように初期化していました。
Redis.new(url: ENV["REDIS_URL"])
これは TLS 非対応(平文)接続です。
何が起きていたか
- TCP 接続は成立
- Redis 側は TLS を待つ
- クライアントは平文を送信
- お互いに一切応答せず timeout
結果として、以下の状態となっていました。
- redis.ping → Redis::TimeoutError
- Firebase 証明書キャッシュ失敗
- 認証エラー
5. なぜ気づきにくいのか(ハマりポイント)
この問題が厄介な理由は以下です。
- セキュリティグループ ✅ 正しい
- DNS ✅ 正常
- Google への curl ✅ 成功
- ECS Exec ✅ 成功
👉 「ネットワークは全部 OK」に見えます。
しかし実際は、
Redis Serverless の TLS 強制仕様
という サービス固有の制約が原因でした。
6. 解決策(確実に直す方法)
解決策は大きく分けて 2 つあります。
方法① Redis OSS(非Serverless)に切り替える(おすすめ)
MVP・個人開発ではこれが最短・最安定です。
ElastiCacheからRedis OSS キャッシュに移行します。
- 転送中の暗号化:OFF
- REDIS_URL だけで接続可能
Redis.new(url: ENV["REDIS_URL"])
設定がシンプルで移行コストも最小化できます。
方法② Redis Serverless を使い続ける場合
TLS を明示的に指定する必要があります。
Redis.new(
url: ENV["REDIS_URL"], # 接続先RedisのURL(環境変数REDIS_URLから取得)
ssl: true, # SSL(暗号化通信)を有効化
ssl_params: { # SSLの詳細パラメータ指定
verify_mode: OpenSSL::SSL::VERIFY_PEER
})
※ 本番では CA 証明書を使った検証が推奨です。
まとめ
今回の問題は、Firebase の障害でも、ECS のネットワーク設定でもなく、Rails の実装ミスでもありませんでした。
原因は 「Redis Serverless(Valkey)は TLS 必須」 という仕様です。
本記事のポイント
Redis Serverless は平文接続できない
MVP では Redis OSS の方が圧倒的に楽
「Timeout」はネットワーク以外が原因のことも多い
同じ構成で悩んでいる方の助けになれば幸いです。