セキュリティポリシーのため、接続先のIPは固定にして欲しいと言われたら~AWS Route53のラウンドロビン方式でバランシングしてみた~

今年も始まりましたアドベントカレンダー！
[昨年](https://qiita.com/advent-calendar/2016/brightvie)は残念ながら完走することが出来ず...(完走どころではない...)

今年は完走目指して執筆出来ればと思います！

# はじめに

弊社では、介護・医療をはじめとするシステム開発をメインにしながら、
託児所・美容院子育て支援アプリの開発やスマホ向けソーシャルゲームの開発など幅広いシステムの開発を手がけております。

基本的には現場の方や施設の方と一緒にお話をしていく中で課題を解決しながら一緒になってモノづくりをしていくスタイルですが、
予算やセキュリティ上の制約など様々な要望にもなるべくお答えしながらシステムの構築を行っております。

弊社ではAWSを基本的には利用しており、構成も定番の構成（ELB -> EC2 -> RDSなど）を用いることが多いですが、
他システムと連携する際や連携デバイスのセキュリティ上の制約などにより、
弊社側のAPIのドメインのDNS設定は問題ないが、
他システムのFirewallの設定で固定のIPアドレスの設定が必要などの場合があります。

そのため、ELBが利用できないシーンがいくつかあったりしたので、
その時のインフラ構築メモを記載したいと思います。


# セキュリティ上の制約

ELB経由でEC2にアクセスする場合、DNSに設定するレコードはIPアドレスではなくCNAMEでドメインを登録する必要があるかと思います。
その際に、IPアドレスが固定にならないため他システムのFirewallの設定が出来ないなどのセキュリティ上の制約がありました。


このシステムでは負荷はそこまで多くないため、負荷分散を積極的に考慮する必要はなかったのですが、
さすがにIPアドレスを固定にして1台のサーバで受けるということは怖すぎるので、
いくつか解決策があるなかで、弊社はRoute53のラウンドロビン形式でのバランシングを取り入れました。

# Route53のラウンドロビンを利用

Route53には、同じドメインに対して複数のIPアドレスを設定して分散アクセスを実現したり、
IPアドレスごとにリクエストを振り分ける重み付けが出来る機能があったり、
IPアドレスの死活監視を行ってくれたりと
簡単に導入出来る便利な機能があったので、弊社ではこちらの方法を採用しました。

<img width="901" alt="システム連携イメージ.png" src="https://qiita-image-store.s3.amazonaws.com/0/17346/880e088b-17ef-5352-4b44-d61c98b5c674.png"　style="border: 1px solid black;">

図にすると上記のような感じです。


# やったこと

参考資料に記載の通りなので細かい手順はそちらを見て頂きつつ、
気をつける点や弊社で行った設定などを記載しておきます。

参考)
- [Route53 で DNS ラウンドロビン](https://qiita.com/nagizero/items/385ed12c60f229a4df9c)
- [Route53のヘルスチェックでHTTPポート監視してみる](https://i-think-it.net/aws-route53-http-port-check/)

## 手順1. Route53のヘルスチェック設定

Route53の左メニューの「Health checks」より、サーバ毎にヘルスチェックの設定を行います。

ここでは主に下記の設定を行う

- IPアドレスかドメイン名か、どちらを死活監視に利用するかを選択
- HTTP/HTTPS/TCPのそれぞれ何を利用するのか
- IPアドレスやポートを設定

### TCPを設定した場合ポートが開放されているかどうかをチェックする

当初TCPポートでのヘルスチェックを行っていたのですが、
このヘルスチェックはポートが開放されているかどうかのみをチェックするため、サーバがダウンしているときは検知可能ですが、
例えば80ポートでApacheが起動しているときにサーバは起動しているがApacheが落ちているときには検知されません。

<img width="731" alt="Route53 TCPとHTTPのヘルスチェック" src="https://qiita-image-store.s3.amazonaws.com/0/17346/c43b55b7-719c-683a-72a9-953176c52026.png">


今回は、サービスが正常に稼働しているサーバに対してアクセスを振り分けたいという意図があるため
ヘルスチェックで利用するのはTCPではなくHTTP（またはHTTPS）で実施しました。


## 手順2. ドメインの登録とラウンドロビンの設定

次にドメインの登録とアクセスを振り分けるための重み付けを行います。
Route53の左メニューの「Hosted zones」より、ドメインを登録する「Hosted Zone」を選択し
、
「Create Record Set」ボタンよりドメインの登録を行います。

アクセスを振り分けるための設定は、「Routing Policy」を選択することが可能です。

フェイルオーバー方式やトラフィック量によってなど様々な振り分ける設定を選択可能ですが、
今回は単純に比率で振り分けることができればいいので、「Weighted」を選択します。

<img width="640" alt="Route53_ラウンドロビン設定.png" src="https://qiita-image-store.s3.amazonaws.com/0/17346/b0e07aa7-d393-7928-4d6e-1bfc2995db8d.png">

上記の例だと、同一ドメインで「test-web01」と「test-web02」のサーバに対して1対1の比率でアクセスを振り分けるという設定になるかと思います。


参考)

   - [Route 53のルーティング系の設定(simple/weighted/latency)](https://cloudpack.media/690)
   - [ルーティングポリシーの選択 | AWS公式ドキュメント](http://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/routing-policy.html)



## 手順3. ヘルスチェックの登録

最後に各設定項目にヘルスチェックの機能を設定します。

各ドメインの設定の「Associate with Health Check」を「Yes」に設定し、
手順1で作成したヘルスチェックの設定項目を紐付けることで完了です。

<img width="320" alt="Route53ヘルスチェックの設定.png" src="https://qiita-image-store.s3.amazonaws.com/0/17346/eff00cc0-8d9e-2bc5-a4a3-53985c9369ce.png">


あとはサーバをダウンさせたりプロセスを落としたりした時にDNSが正常に切り替わるのか確認を行えば完了です。

# まとめ

他にも良い方法があるかと思いますが、スタートアップとして取り組んでいる中
インフラ専任の人もいないため、上記のようなすぐに出来る方法で対応を行いました。

現状だとサーバを増やすたびにIPを追加しなければいけないので、
負荷分散を目的とするのであれば有効ではない方法だと思います。

本来であれば、

- Route53でバランシングした先で更に負荷分散を実施する
- VIPを活用したバランシング

などなどもっと規模が大きくなってきた際には、インフラ専任の人と一緒にシステム構築が出来たらなぁという夢を見ながら日々開発を頑張っていきたいと思います。

# 明日の予告

さて、明日は[弊社社長](https://qiita.com/felicidadept)の登場です！（おそらくQiita初投稿！！）
社長はエンジニア出身でありながら経営や営業、マーケティングやデザインなども一人でこなしつつ、
数多くの現場改善やシステム導入など幅広いスキルを活かして活躍されている自慢の社長です！

Ionicまわりのお話ということで楽しみですね。