[アップデート] システムのリファクタリングを後押しするプロキシ層を提供「AWS Migration Hub Refactor Spaces」がプレビューリリースされました #reinvent

2021.12.01

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

re:Invent期間中に発表された新サービス「AWS Migration Hub Refactor Spaces」について紹介します。

AWS Migration Hub Refactor Spacesは現在パブリックプレビューですので、どなたでもお試しいただけます。また、本記事の内容はパブリックプレビュー版をもとに執筆していますので、将来的に仕様が変更される可能性がある点はご注意ください。

AWS Migration Hub Refactor Spaces

Strangler Fig パターン

古いシステムをリファクタリングしたいと思いながらも、まとまった時間、お金、リソースも確保が厳しいなぁ。一気にリプレースするのはやっぱリスクがあるよね。ベストではないけど何とか使えてるし、しばらくこのままで、、、リファクタリングが進められない悩みは多くのユーザーが抱えていることかと思います。

一方で少ない成功事例に共通したモデルとして紹介されているのが「Strangler Fig」というパターンです。

Strangler Fig は和訳すると「絞め殺しの木」となんともおぞましい名前が付けられていますが、公式ブログでより拝借いたしました以下写真のように宿主となる木を覆うように根を這わせ、最終的に宿主の木を包み込んで置き換わってしまう植物とのことです。

(引用元:Preview – AWS Migration Hub Refactor Spaces Helps to Incrementally Refactor Your Applications

古いシステムは一気にリファクタリングするのではなく、周辺システムから徐々に新しいシステムへと作り変え、最終的に古いシステムが「絞め殺される」まで数年かけてゆっくりとリファクタリングしていくことから「Strangler Fig」と名付けられたようです。

AWS Migration Hub Refactor Spaces はプロキシだ!

こちらも公式ブログの画像引用ですが、例えばフロントはCloudFront+S3で提供されおり、APIのエンドポイントはレガシーなEC2/RDSのシステムで実装されています。

(引用元:Preview – AWS Migration Hub Refactor Spaces Helps to Incrementally Refactor Your Applications

ここから/cart機能の一部のみをマイクロサービスとしてLambdaに切り出すとした場合、既存アプリケーションと新しいサービスをつなぐネットワークを整備する必要がある、という課題に直面します。また各マイクロサービス毎に権限管理、コスト管理を容易にするためにAWSアカウントを分離することも珍しくありませんので、マルチアカウントでトラフィックのルーティング制御も必要になります。

(引用元:Preview – AWS Migration Hub Refactor Spaces Helps to Incrementally Refactor Your Applications

そこでリリースされたのが「AWS Migration Hub Refactor Spaces」です。ちなみにAWS Migration Hubという名前がついていますが、今のところ従来のAWS Migration Hubとの関連性はあまり無いように思います。

AWS Migration Hub Refactor Spacesはこの複雑なトラフィックのルーティングをAmazon API Gateway、Network Load Balancer、AWS Transit Gateway、AWS Resource Access Managerなどの既存サービスを駆使し、ユーザーにこれらのリソースを意識させることなくプロキシ層を提供するサービスです。

(引用元:Preview – AWS Migration Hub Refactor Spaces Helps to Incrementally Refactor Your Applications

AWSインフラ構築に携わっている人であれば、これらのリソースを使ってマルチアカウントのトラフィック制御することがどれだけ複雑で面倒な作業であるか想像するのは難しくないと思いますが、開発者はAWS Migration Hub Refactor Spaceの管理画面から作成できたアプリケーション部分のみ、例えば/cartをLambda関数や新たなVPCリソースに向けるように設定するだけで、裏でAPI Gatewayのメソッド定義が行われてデプロイされたり、Transit GatewayのVPC関連付けやルーティング設定が行われます。

フロントエンドアプリは従来のエンドポイントをAWS Migration Hub Refactor Spacesでデプロイされたプロキシ用のAPI GatewayのエンドポイントURLに一度切り替えてしまえば、あとはプロキシ内のトラフィック制御によってリリースされた新しいサービスへと切り替わっていきます。

リージョン

以下の10リージョンで既に利用かのうです

  • バージニア
  • オレゴン
  • オハイオ
  • シンガポール
  • シドニー
  • 東京
  • アイルランド
  • フランクフルト
  • ロンドン
  • ストックホルム

(つд⊂)ゴシゴシ(゚Д゚)オオサカ ナインヤケド?

料金

現在はプレビュー中のためAWS Migration Hub Refactor Spacesに対する課金は発生しません。ただし、AWS Migration Hub Refactor Spacesで作成される各種既存サービスには料金が発生しますのでご注意ください。

プレビュー期間終了後は、以下の料金が発生します。

Environments

  • 1環境あたり 0.028 USD/時間

APIリクエスト

  • 0.000002ドル/リクエスト(1.00 USD/100マンリクエスト)

やってみた

今回は東京リージョンで検証しています。

AWS Migration Hub Refactor Spacesでは「AWS Migration Hub Refactor Spaces管理者用」「既存サービス用」「新サービス用」のように3アカウントに分けることを推奨されていますが、今回は検証環境の都合上「AWS Migration Hub Refactor Spaces管理者用」「既存サービス/新サービス」の2アカウントで検証としました。

事前に既存サービスとしてEC2で雑なAPIエンドポイントを作成済みです。

テスト用API

$ curl -X GET http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/hoge
[GET]/hoge on EC2
$ curl -X POST http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/hoge
[POST]/hoge on EC2
$ curl -X GET http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/fuga
[GET]/fuga on EC2
$ curl -X POST http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/fuga
[POST]/fuga on EC2

最終的にGET /hogeのみをLambda関数に移行することを想定して進めます。

EnvironmentおよびApplicationの作成

Migration Hubの管理コンソールを開き[Refactor Spaces]-[App Refactor]-[Enviromnets]-[Create Enviromnent]をクリックします。任意のEnvironment nameを入力し[Next]へ。

EnvironmentはVPCで構成されるマルチアカウントのネットワークファブリックになります。Environmentの作成によって内部的にはTransit Gatewayが作成されています。

任意のApplication Nameを入力。Proxyとして利用するVPCを選択します。Proxy endpoint typeはパブリックから接続する環境であればRegional、VPC内からのみであればPrivateを選択します。

Applicationの設定によって指定したVPCにNetwork Load Balancerが設置され、Proxy endpoint typeの設定はそのままAPI Gatewayのエンドポイントタイプになります。

このEnvironmentを共有する他のアカウントを招待します。Organization、Oranization unit(OU)だけでなくAWSアカウントを指定してOrganization外部のアカウントを招待することも出来ます。今回はAWSアカウント指定でOrganization外部のアカウントで検証しています。

この設定によりEnvironmentおよびTransitGatewayがAWS Resource Access Managerによって他のアカウントと共有可能になります。

設定値を確認して[Create & share environment]をクリック

EnvironmentおよびApplicationの作成が完了すると、Transit GatewayおよびAPI Gatewayが自動的に作成されていることが解ります。

Applicationの詳細を確認すると指定したProxy VPC内にNetwork Load Balancerも自動的に作成されていることも確認できました。

共有設定の承認

先ほどリソース共有で指定したアカウントに切り替え、Refactor Spacesの管理画面を開くと以下のように共有設定の承認通知が届いていますので[Accept share]で承認します。

Serviceの作成

既存サービス提供側のAWSアカウントに切り替え、Refactor Spacesの管理画面から[Quick actions]-[Create service]を開きます。先ほど作成したEnvironmentおよびApplicationを選択し、任意のService nameを入力します。

既存サービスで提供しているVPCを選択し、エンドポイントURLを入力します。ヘルスチェックパスが異なる場合は特定のヘルスチェックパスを設定します。Set this service as the applications's default route.にチェックを入れると、このアプリケーションが特定のパスパターンにマッチしない場合のデフォルトとしてリクエストを受けます。

なお、AWS Resource Access ManagerでTransit GatewayをEnvironment内で共有していますので、異なるアカウントであってもVPC CIDR重複は許されないようですのでお気をつけください。

Serviceの登録が完了し、Routeのヘルスチェックが正常に確認されるとProxyのエンドポイントURLが有効になります。フロントエンドサービスからはこのエンドポイントURLに対してリクエストするように切り替えを行ってください。

Routeのヘルスチェックが確認されると裏ではAPI Gatewayのメソッドの作成やデプロイが自動的に行われています。

またTransit Gatewayの関連付けやルート設定も自動的に行われています。

既存サービスへのリクエストの確認

パブリックな環境からProxyエンドポイントに対してリクエストを行っています。この時点ではすべてEC2にリクエストが流れていることが確認できました。

すべてEC2へリクエストが流れている確認

$ curl -X GET https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge
[GET]/hoge on EC2
$ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge
[POST]/hoge on EC2
$ curl -X GET https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/fuga
[GET]/fuga on EC2
$ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/fuga
[POST]/fuga on EC2

GET /hoge のみ Lambda に変更

新サービス提供側のAWSアカウントに切り替え、Refactor Spacesの管理画面から[Quick actions]-[Create service]を開きます。先ほど作成したEnvironmentおよびApplicationを選択し、任意のService nameを入力します。

Lambdaを選択し、リクエスト先のLambda関数を指定します。今回はGET /hogeのみを対象に指定しました。

登録が完了すると以下のようになります。

API Gatewayを確認すると/hogeに対するリソースパスが作成されて自動的にデプロイされています。

/hogeのリソースパスが作成されたことで、これまでCatch-allの/{proxy+}に流れていたPOST /hogeなどGET以外のリクエストはANY /hogeにリクエストが流れることになります。しかしながらANY /hogeのエンドポイントURLはデフォルトのままですので、このままでは期待した動作をしません。

これまでPOST /hogeのターゲット

/{proxy+}:
    x-amazon-apigateway-any-method:
      parameters:
      - name: "proxy"
        in: "path"
        required: true
        schema:
          type: "string"
      x-amazon-apigateway-integration:
        httpMethod: "ANY"
        uri: "http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/{proxy}"

GET /hogeのみLambdaに向けた状態だと以下のようになります。

失敗するPOST /hogeのターゲット

/hoge:
    x-amazon-apigateway-any-method:
      parameters:
      - name: "proxy"
        in: "path"
        required: true
        schema:
          type: "string"
      x-amazon-apigateway-integration:
        httpMethod: "ANY"
        uri: "http://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000"

上記のままリクエストすると以下のように405エラーになります

$ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge/
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>

ANY /hoge のサービスを追加

これを回避するためには明示的にANY /hogeのエンドポイントURLをhttp://ec2-xx-xx-xx-xx.ap-northeast-1.compute.amazonaws.com:5000/hogeとして登録する必要があります。

設定は以上で完了です。

動作確認

期待したとおりGET /hogeのみLambdaに切り替わったことが確認できました。

GET /hogeのみLambdaに流れている確認

$ curl -X GET https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge
"Hello from Lambda!"
$ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/hoge
[POST]/hoge on EC2
$ curl -X GET https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/fuga
[GET]/fuga on EC2
$ curl -X POST https://u3yjwzfxi4.execute-api.ap-northeast-1.amazonaws.com/prod/fuga
[POST]/fuga on EC2

検証は以上です!

私はインフラ屋なのでRefactor Spacesの各設定に対して対向となるサービスの設定画面を逐次確認していますが、基本的にRefactor Spacesで設定するだけで開発者はAPI GatewayやTransit Gatewayなどの設定画面を操作することなくマルチアカウントのトラフィック制御ができると思います。すごい!

まとめ

  • 古いシステムのリファクタリングは周辺から徐々に置き換えていく「Strangler Fig」パターンが成功事例の共通点
  • 徐々にリファクタリングするには複雑なトラフィックを制御するプロキシが必要
  • AWS Migration Hub Refactor Spacesはそのプロキシを以下のサービスをラップして作成、設定してくれる
    • API Gateway
    • Network Load Balancer
    • Transit Gateway
    • RAM
  • 開発者はRefactor Spacesの管理画面から切り替えるパスとターゲットを登録するだけで、自動的にこれらのサービスの設定、デプロイが行われる

参考