エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

AWS上の旧インフラをVPC移行した話

こんにちは、エンジニアリンググループ AI・機械学習チームの安田です。最近rustでTCP/IPスタックを作って遊んでます。

この記事はエムスリーSREがお届けするブログリレーの13日目です。

今回は先日実施した、AWS上でVPCの異なる環境へインフラ移行をした話をします。

その中で、

  • ほとんど同じ名前のリソースの移行
  • MLのモデル等大きなデータを移行
  • AWSアカウントの違うシステムでの短い停止時間でのシステム移行

の点に注力したのでご紹介します。

押さえるべきポイント

本記事でお伝えしたい、移行時に引っ掛かりそうなポイントです。

  • ほとんどのリソースはAWSアカウントユニークだが、S3はAWS全体でユニーク
  • NSレコードのTTLは長い
  • Route53のALBのAレコードは、サジェストされない値を直接書き込める
  • ACMはRoute53での証明書発行時、CNAMEレコードを参照するがAレコードは不要

背景

AI・機械学習チームでは日々新しいプロダクトを開発しています。プロダクトを作る中でインフラ構成も改善しているのですが、そうすると初期のほうに作成したプロダクトと最近のプロダクトのインフラ構成の乖離が大きくなっていきます。その負債が返済必要な程度に大きくなったために今回本作業を実施しました。

具体的には、

  • 複数あるAWSアカウントの利用方法統一
  • 独立したVPCから共通の(VPN・TGWが通った)VPCへの移行
  • terraform構成の抜本的な変更

に取り組みました。

実施概要

現状説明

まず、作業実施前のインフラ及びアプリケーションについて説明します。

f:id:sora_sakaki:20210125234555p:plain
作業実施前のインフラ

本アプリケーションはレコメンドAPIで、ざっくり以下のような内容になっています。

  • Batch, APIのECSクラスタが存在する
  • 1つのVPCに本アプリケーションのみが存在する
  • 計算結果はAuroraDB(MySQL)に、学習モデルはS3に存在する
  • DBの書き換えはBatchのみで実施する
  • 運用のためのスクリプト群がLambdaに存在する

また、環境としては

  • dev
  • QA
  • perf(負荷試験環境)
  • prod

の4環境存在します。

今回の変更

f:id:sora_sakaki:20210125234638p:plain
作業実施後のインフラ

今回の変更では以下のような変更を実施します。

  • それぞれの環境が利用するAWSアカウントを変更する
  • ほかのアプリケーションと共通のVPCを利用する

また、変則的なAWSアカウントの変更があるので具体的に以下に示します。

f:id:sora_sakaki:20210126000912p:plain
AWSアカウントの変更

これによって

  • 今回対象のプロダクトが全く存在しないアカウントへ移行
  • 今回対象のプロダクトの別環境のものが存在するアカウントへ移行

の2つのパターンが混在しています。

移行のポイント1: ほとんど同じ名前のリソースの移行

大抵のAWSリソースはAWSアカウントごとに名前がユニークであることを求められます。この上で以下の2点の注意が必要でした。

  • ジェネラル的な名前のリソースの他プロダクトとの名前重複
  • 旧perf・新prodが共通のAWSアカウントであるための名前重複

今回、旧perf/prod以外は概ね困らなかったのですが、prodに関しては旧perfと一部名前がかぶったため、リソース名に-perf/-prodと環境名を入れる修正を実施しました。

しかし、S3だけはAWS全体でユニークである必要があるため、新旧で名前を変える必要があります。この点が今回のようなインフラ移行で注意が必要な点です。

移行のポイント2: MLのモデル等大きなデータを移行

移行すべきデータは以下の2つがあります。

  • MLモデル(S3上のファイル)
    • 100GB程度
    • 移行中更新されなかったためコピーするだけ
  • 計算済みデータ(RDS上のデータ)
    • 100GB程度
    • オンライン更新されなかったため、いいタイミングで全コピー+差分更新

それぞれスマートな方法は以下の通りですが、今回諸々の都合でできなかったため以下に実際に実施した苦肉の策を書きます。

S3のMLモデル移行

S3のMLモデル移行の課題は以下の点です。

  • 同じアカウントではないのでS3コンパネでのS3間の転送ができない
  • データ転送量が多いのでAWS上で完結させたい(金額的にも)
  • アカウントをまたいだIAM/権限を作るのが面倒

今回は、コピー先S3へアクセスできるIAMが存在したためそちらを利用しごり押しで対応しました。

  • コピー元AWSアカウントにて、コピー元S3へアクセスできるIAMロールを利用してEC2へダウンロードする
  • コピー先のIAMを先ほどのEC2へ適用し、コピー先S3へアップロードする
RDSのデータ移行

RDSのデータ移行の課題は以下の点です。

  • データ転送量が多いのでAWS上で完結させたい
  • Batch更新ではあるものの、データ復元にかなり時間がかかる

今回は以下の手順を取りました。

  1. 移行の少し前に全データをコピーして新DBを作る
  2. 移行時に差分更新を実施する

1の全データをコピーして新DBを作る方法は2つあります。

今回はterraformの都合スナップショットは難しかったためSQLとしてdumpしてS3経由で新DBを作りました。

2の差分更新については、Batch実行で生成が可能だったため新規で差分データを生成する形で対応しました。

移行のポイント3: AWSアカウントの違うシステムでの短い停止時間でのシステム移行

基本戦略は以下の通りです。

  1. DNS切り替え以外の部分はインフラ・アプリケーションを構築し動作する状況にする
  2. DBやS3上のモデル等はなるべく事前に移行しておく
  3. 最後にDNSを切り替える

この上で問題になりそうな点は

  • AWSアカウント間でRoute53を移行しないといけない
  • ALB・ACMがRoute53と依存関係にある

この2点です。

AWSアカウント間でRoute53を移行しないといけない

今回は以下の順番で進めました。

  1. 空っぽのRoute53レコードを新アカウントで用意する
  2. 既存のAレコードをコピーする
  3. 親のNS設定を旧レコードのNSからここで作成した新レコードのNSに差し替える
  4. 全部おわったら新レコードのAレコードを変更する

ポイントは2点で

  • Route53のALBを参照するAレコード作成時、別アカウントのALBが設定できないように見えてできる
  • NSの切り替えにはAレコードと違いかなり時間がかかる
    • もちろんデフォルト設定の場合

前者は以下にコンパネのAレコード作成画面を示します。画像中の赤い丸部分がALBを指定する箇所になります。

f:id:sora_sakaki:20210126022354p:plain
Route53のAレコード作成画面

こちらはアカウント中のALBがインクリメンタルサーチできる窓となっていまして、同一アカウントのALBであれば候補から選択すれば設定可能です。しかし別アカウントのALBは候補に表示されません。

ところが、この枠は普通に値を書き込むことが可能なため、別アカウントのALBを指定したい場合は該当ALBのDNS名をコピーしてくればそのまま適用可能です。

後者はAレコードやCNAMEレコードと違い、NSレコードはデフォルトでTTLがかなり長いため、実施時に時間的余裕を見る必要があります。普段変更する機会が多くなかったので留意点でした。

ALB・ACMがRoute53と依存関係にある

こちらはterraformの作り次第なのですが、勘違いしやすいと思うポイントです。

どういうことかというと、ALBは構築時に証明書が必要になります。その証明書を発行するACMは発行時にRoute53へレコードを作成しドメイン所有者の確認します。しかし、今回のようにダウンタイムを短くしたい場合Route53の設定は最後に変更したいため、ALBの作成が行えない(気がする)ということです。

実はこれは勘違いで、

  • ALBにはACMの証明書が必要
  • ACMの証明書発行にはRoute53のCNAMEレコードが必要
  • ALBは構築後にRoute53のAレコード更新が必要

このように証明書発行に必要なレコードはAレコードではなくCNAMEレコードなので問題なく証明書のみの発行が可能です。また、旧インフラのACMのためのCNAMEレコードは不要です。CNAMEレコードは証明書発行時のみ確認するため、発行済みであれば移行時等に一時的に存在しなくても問題がないためです。

まとめ

全体を通して、最終的に以下のようなフローでインフラ移行を実施しました。

  1. Route53を建てる
  2. Route53に旧Aレコードを設定する
  3. 親のNS設定を新Route53へ変更する
  4. 一晩休み
  5. 新インフラをAレコード以外作成する
  6. S3, RDSのdumpデータを新S3へコピーする
  7. RDSのdumpデータを新RDSへ流し込む
  8. 一晩休み
  9. データや各種アプリケーションの動作確認
  10. DNSの切り替え

結果としては障害らしい障害もなく無事移行できました。

本記事で記載したものは、検証時に見つけた中でも目立ったものです。実際は細かい依存関係の解決や名前衝突の解決などが沢山あったため十分な事前検証の重要性を再確認しました。

変則的なインフラ移行が必要な方の参考になると幸いです。

We are hiring!

エムスリーではクラウド基盤の技術が活躍できる場面はたくさんあるので、興味のある方はぜひ応募してみてください!

jobs.m3.com