駑馬十駕

1年間運用されたEC2を処す ~デフォルトVPC脱却編~

AWS

スポットでとあるスタートアップで約1年間AWS上で運用されているLaravelアプリケーションのインフラをスケールできるよう改善して欲しいという依頼をされたので見てみることに。

これが中々どうして手強いのものでした。

その会社さんはエンジニアリソースが限られており、インフラに明るいエンジニアがいないのでIaCやコンテナ運用は厳しいという前提があることを頭に入れて頂いた上で読み進めて頂けると幸いです。

結構ざっくり書いてあるので所々抜けている記述があると思いますが備忘録なので許してください...

調査編

Part1

WordPressを生業としていたCTOの方がインフラを作られたという情報を念頭に置いた上でAWSのコンソール画面で見てみることに。そこにはデフォルトVPC上のパブリックサブネットにEC2がポツンと1台立たずんでいるだけでした。

Laravelアプリケーションを運用しているならS3やRDSはないのか...?

と疑問に思い、作成したご本人であるCTOに聞いてみましたがそもそもS3RDSは知らないとのこと。では画像やMySQLのデータはどこに保存しているのですか?と聞いてみたらEBSに全て突っ込んでいるという解答を頂きました。バックアップは一切取得していないそうです。EBS消失したらどうするんだろう。

また、AWS操作のログを知りたくなったのでCloudtrailで操作ログを見てみたらルートアカウントで操作されていました。IAM...

Part2

さて、コンソールからではEC2インスタンス内に何が入っているか分からないのでSSH接続して入ってみました。するとなぜか事前に共有されていた情報とは違い

合計6つのLaravelアプリケーションが1台のEC2上に相乗りしていました

DBに至ってはEC2インスタンス内のMySQLになぜか10個くらいDBが入っていました(正確には数えていません)。

ヒアリングの結果、サービスの歴史的経緯から本体のLaravelアプリケーションの亜種が5つ相乗りしており、EC2に来たリクエストをapacheで振り分けていました。経験未熟な自分はこの現実を見てゴールが何か分からなくなりました。しかし正体不明の野良バッチなどがなかったのは不幸中の幸いと言うべきでしょうか。

ゴール策定編

混乱しても仕方がないので、状況を整理してどうして欲しいのかを話し合いました。 決まったのは、

  • 6つのLaravelアプリケーションのうち1つは完全に独自仕様なので別インスタンスで運用したい
  • 残りの5つは近い将来統合する予定なので統合できるよう稼働させて欲しい
  • デフォルトVPCを脱却して専用のネットワーク環境をとりあえずいい感じに作って欲しい
  • 大事なデータが入ったEC2上のMySQLを何とかセキュアに運用できるようにして欲しい

というものでした。正直インフラ(AWS?)の基礎知識をもった人がいなかったので、誘導尋問っぽくなった感は否めませんが、自分の中ではベストな提案をできたと思っています。

検証編

まず実験できる環境が必要だと判断し、ステージング環境を作ることにしました。VPCからサブネット・セキュリティグループ・ルートテーブルなど一式作る必要があったので若干時間がかかりました。本番環境で稼働しているEC2からAMIを作成し、ステージング環境のVPC上で作成したAMIからEC2を起動して実験しました。AMIを作成するとき再起動しないにチェックをつけないとオリジナルのEC2が再起動してしまうので気をつけて下さい。

EC2上のMySQLを処してRDSへ移行するため、mysqldumpでデータをダンプできること・RDSへインポートできることを確認しました。レコード数が大したことなかったのでDMSは使いませんでした。

移行編

移行当日(深夜)はユーザに一切EC2にアクセスされて欲しくないので全段にELBを挟んでユーザにはELB側でメンテナンス画面を出し、自分達のIPアドレスからはEC2を含むターゲットグループにリクエストを流すという方法を取りました。

[AWS]ALBだけでメンテナンス画面を表示させる

ドメインレジストラにはRoute53ではなく某国産ドメインレジストラを使っており、AレコードでEC2のElastic IPを指定していました。terraform applyで一発!という手段は取れない事が確定したので、温かみのある手動操作でAレコードを消してCNAMEでELBのDNSを入力して反映を待ちます。ELBのIPアドレスは可変なのでちゃんとDNSを指定しましょう!

メンテナンス画面が表示される事を確認出来たところで

  1. 本番EC2からAMIを取得して新規で作成したVPC上にEC2を1台ずつ起動
  2. mysqldumpでsqlデータをダンプ
  3. 事前に立てておいたRDSにダンプしたデータをインポート
  4. Laravelの.env内のDBに関する環境変数をRDSの値に書き換え
  5. ELBのターゲットグループに新規で立てたEC2を入れる
  6. 疎通できているか画面をチェック
  7. ELB側で固定で返していたメンテナンス画面表示のルールを削除

という感じの流れで行いました。記憶を掘り起こして書いてるので間違ってるかもです。

感想編

本番環境を操作するのは神経をすり減らしますね。また、自分のようなインフラに明るくないエンジニアが移行作業を完遂できたのはELBあってこそだなと痛感しました。ELBマジ感謝。

お察しの通りまだアプリケーションの構成としてはELB, EC2, RDSの構成になっており、EC2のMAZ対応が出来ていないのでこの後はElastic Beanstalkへの移行というミッションが控えています。頑張ります!