AWS 上でマルチアカウントで複数サービスをホストする場合のアーキテクチャパターン (2)

#はじめに
AWS 上でマルチアカウントで複数サービスをホストする場合のアーキテクチャパターンを紹介します。
この記事は2つ目で、[最初の記事](https://qiita.com/asahi0301/items/cde60e5196fd5d14e4ff)ではシングルアカウントでのパターンについて紹介しています。

#マルチアカウントの場合
シングルアカウントパターンで紹介した構成がマルチアカウントでも可能なのかまず見てみましょう。

## ALBがフロントパターン
まずはこちらです。
現時点では、ALBのアカウント間共有の機能はないので、ALBをアカウントAが持つ、App1をアカウントBが持つ、App2をアカウントCが持つ...といったことはできないです
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/86d61539-4c85-9870-4562-2b78e330b556.png)

## HTTP APIがフロントパターン
次にこちらです。
HTTP API と 内部ALBの連携機能は、同一アカウント内のリソースである必要があるので、API GatewayをアカウントAが持つ、内部ALBをアカウントBが持つ...といったことはできなさそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/511b81d8-9614-c6dc-2a06-512b99bd7800.png)

## REST APIがフロントパターン
次にこちらです。
REST API と 内部NLBの連携機能も同様に、同一アカウント内のリソースである必要があるので、API GatewayをアカウントAが持つ、内部NLBをアカウントBが持つ...といったことはできなさそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/b0cf5e0d-3dbb-7ace-aee4-e92776f4d2df.png)


分が悪くなって来ました。

次を見てみましょう。

## REST APIがフロントで 外部ALBをバックエンドに持つパターン
お、これはマルチアカウントできそうですね。
API GatewayをアカウントAで作成し、ALBはアカウントBで作成する。 
API GatewayとALBとの接続は Publicにすると、API Gatewayだけを管理するアカウントと、ALBとそれに紐付くリソースを管理するアカウントに分けることができそうです。（ALBのアクセス制限は最初の記事を参照してください）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/eadd47cf-6d33-0d34-9fcf-9a52d5d3b56f.png)

ただし、冒頭で述べたように、ALBのアカウント共有機能はないため、この構成図だと App1とApp2は必ず同一アカウントになってしまいます。
それをどうにかする方法を少し考えてみたいと思います。


### パスごとにALBを持つパターン
こちらだと、API Gateway、App1用のALB、App2用のALBをそれぞれ別アカウントで持つということができそうです。
（参考までにLambda(App3)も別アカウントに持ちたい場合は、フロントのAPI Gatewayの後ろに「ALB - Lambda」か「API Gateway - Lambda」になるかなと思います。あまりイケている気がしないですが、、）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/811249ea-f65b-bfdf-9099-38fa8db34308.png)


これを増やしていく、つまり、path3用のALB、path4用のALB...と増やしていけば、フロントをAPI Gatewayに統一し、バックエンドをそれぞれ別アカウントで作成するといったことはできそうです。

##どうしても API Gateaway - ALB間の public接続が許容できない場合
REST APIの機能は必須だけど、ALBを使いたい。でも、public接続が許容できないというのも少なからずあると思います。
その場合のマルチアカウントパターンについて考えてみたいと思います。

### Appごとにアカウントを分けたい場合
構成図のうち、API gateway、内部NLBとリバースプロキシ(nginxなど)を作成するフロントアカウントと、ELBとAppを持つアプリケーションアカウントに別れます。そして、アプリケーションの数だけアプリケーションアカウントが存在することになります。
複数のVPC間は、VPC peeringもしくは Transit Gatewayで互いに接続します。

こうすることで、API Gatwayから実際のアプリケーションまでの経路は、VPCから外に出ないprivateな通信になります。
考慮が点としては、アプリケーションが増えるごとに、nginxの設定を追加変更する必要がある点です。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/c1dc18d8-f6e4-bffb-983b-31866919febc.png)



### Appごとにアカウントを分けない場合
Appごとにアカウントを分けなくてもいい、つまり、フロント用アカウントとアプリ用アカウントさえ別れていればOKな場合は、
前述の「アプリケーションが増えるごとに、nginxの設定を追加変更する必要がある」という手間はなくなります。

具体的には構成図のように、nginxをシンプルなリバースプロキシ(来たリクエストは全て単一のALBに流す)として設定し、実際のルーティングはALBに任せることで、アプリケーションが増えても、基本的にはNginxの設定を変更する必要はなく、アプリケーション用アカウントのALB周りだけイジればいいことになります。

アプリごとにアカウントを分けなくてもいい場合は、意外とシンプルになるのではないでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/687ea204-df4d-ad4b-891d-0b8aa58e8aaf.png)

## (余談) API Gatewayではなく、ELBをフロントに置くパターン
考え方は全く同じですが、アプリ用のアカウントをどうするかで、同様に以下の2パターンがあるかなーと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/0ea95392-d5f7-9028-1bb4-86c2239f3c21.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/1375982d-aea3-ba14-ac75-d92314d2884f.png)


# まとめ
フロントとアプリケーションでAWSアカウントを分けたい場合は、現時点でのAWS側の制約などもあり、なかなか一筋縄ではいかなそうです。
個人的には、API Gatewayが必須かどうか、アプリケーション用のAWSアカウントの分け方をどうするかで取りうる選択が変わってきそうです。

API Gatewayの機能は魅力的なので、使いたい人は多いのではないかと個人的には思っています。
なので、アプリケーション用のアカウントを分けたい場合はこのパターン(再掲)。ただし、アプリケーション追加時のNginxの設定変更をどうにかして頑張ることを許容する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/c1dc18d8-f6e4-bffb-983b-31866919febc.png)


アプリケーション用のアカウントを分けなくてもいい場合はこのパターン(再掲)、というのがいいのではないかと思っています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/107953/687ea204-df4d-ad4b-891d-0b8aa58e8aaf.png)


# 次の話
今回は、/path1 や /path2 でアプリケーションを分けたい。つまり、ルーティングが主目的だったため、ALBやAPI Gatewayでルーティングさせるアーキテクチャをメインで紹介しましたが、通常のルーティング以外に、リトライや接続数制限、サーキットブレーカーといった機能も求めたくなってしまうこともあるかもしれません。
その場合は、ALBでは対応できないため、AWSのサービスであれば、App Meshを使うことになるかと思います。
次回は、App Meshを使ったマルチアカウントパターンについて紹介したいと思います。