先日、稼働しているRailsのWebアプリケーションをRails5.2から6.0に上げて本番デプロイしようとした際に、ヘルスチェックに失敗していてデプロイできない状態になっていたのですが、そのときに対応した内容を書いてみます。
何が起こったか
まず、AWS EC2インスタンスにデプロイしようとした際にタイムアウトが発生して、デプロイに失敗していました。 このタイムアウトの原因を探していたら、AWSのターゲットグループのヘルスチェックに失敗していることが分かりました。
// デプロイ失敗時のログ Deploying new task definition................................................................................................................................................................................................................................................................................................. Deployment failed due to timeout. Please see: https://github.com/fabfuel/ecs-deploy#timeout
なぜ、ヘルスチェックに失敗したか
Rails6で導入されたDNSリバインディング対策の機能で、ActionDispatch::HostAuthorization
というミドルウェアがブラウザからアクセスされた時のホストをチェックしてくれるようになりました。
github.com
外部からアクセスされるドメインは設定しておいたのですが、それ以外は設定していませんでした。
WebアプリはAWS ECS(EC2インスタンス)で運用、ターゲットグループのヘルスチェックを有効にしていていたのですが、このヘルスチェックはどうやらプライベートIPアドレスを使っているようで、ホストとして登録しておかないとアクセスできない状態になっていました。
ActionDispatch::HostAuthorization
でホストを許可するための指定の仕方
デフォルトでは、development環境で以下の3つが登録されていて、staging, production環境では設定がないのでホストを指定しておく必要があります。
Rails.application.config.hosts = [ IPAddr.new("0.0.0.0/0"), # All IPv4 addresses. IPAddr.new("::/0"), # All IPv6 addresses. "localhost" # The localhost reserved domain. ]
config/application.rb
や config/environments
の中で
config.hosts << 'my-web-app.com'
のように記載するとホストを指定するとアクセスが許可されるようになります。
具体的に設定した値
EC2などの仮想マシンはVPC内に構築しているので、VPCのIPV4 CIDRの設定を入れることでデプロイできるようになりました。
config.hosts <<IPAddr.new('10.0.0.0/16')
VPCにIPV4 CIDRを追加した時忘れそうなので、そのときまたデプロイできなくなりそう。。という懸念は残っています。 あと、IPアドレスをもう少し絞れたら嬉しいのですがそこまでは分からなかった。。。サブネットのCIDR使えば、もうちょっと範囲を絞れるかな。どなたか知っている方は教えてもらえると嬉しいです。