AWS App Runnerでインターネットに接続する際の注意点

結論、NATが必要です。

ただ、App Runnerからインターネットにアクセスする際に「なんでNATが必要になるのか？」となったのでまとめました。

ある案件でコンテナサービスでApp Runnerを使用することにしました。
「AWS App Runnerについて簡潔に教えて」GPTに聞いてみました。

>AWS App Runnerは、AWSが提供する完全に管理されたアプリケーション実行サービスです。AWS App Runnerを使用すると、コンテナ化されたアプリケーションやコードリポジトリからのコードベースのアプリケーションを簡単にデプロイ、実行、スケーリングすることができます。
>AWS App Runnerでは、ユーザーがアプリケーションのソースコードやコンテナイメージを指定し、それを基に自動的にデプロイメントパイプラインを構築します。また、リアルタイムの監視、ログ収集、自動スケーリングなどの機能も提供されます。
>AWS App Runnerは、開発者やチームがアプリケーションのデプロイメントに関連する複雑さを最小限に抑えることができるため、迅速かつ効率的なアプリケーションの実行が可能です。また、コンテナオーケストレーションやサーバーレスの利点を享受しながら、インフラストラクチャの管理に時間を費やすことなくアプリケーションの開発に集中することができます。
>AWS App Runnerは、Webアプリケーション、API、バッチジョブなど、さまざまなタイプのアプリケーションの実行に使用できます。

要は、コンテナ化されたウェブアプリケーションやAPIを開発者が簡単かつ迅速にデプロイできるフルマネージド型サービスです。
開発者はGitのソースコードか、ECRをプッシュするだけであとはApp Runnerが自動デプロイまでしてくれます。（VPCとか、AutoScallingとかALBとか全部いらない）

というわけで今回最初に作成した構成（一部）がこちら↓（赤枠だけ見てください）
![スクリーンショット 2023-12-18 13.44.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655825/2fc07a3e-2ab7-385c-22f3-5c2563944dad.png)


App Runnerが2022年2月のアップデートでVPCコネクタを使用することでVPC内のリソースとプライベートなアクセスができるようになったことは知っていました。↓
https://dev.classmethod.jp/articles/aws-app-runner-supports-privately-accessible-services-amazon-vpc/
<br>
（それまではインターネットからの公開アクセス専用でありプライベートアクセスに制限することはできなかったらしい。（プライベートサブネットにアクセスできなかったためRDS等をパブリックサブネットに配置しなきゃいけなかった））
<br>
なので、App RunnerからVPCコネクタ経由でプライベートサブネットのAuroraやElastiCacheにアクセス！さらに外部APIのコールが必要があったので、そのままApp Runnerから外部APIをコール！としていました。
<br>
しかしこのままでは厳密には、App Runnerは外部API（図の右上にあるAdmin API　NOMOSHOP API）をコールすることはできません。
<br>
App RunnerでVPCコネクタを使用する場合、全てのアウトバウンド通信はVPC経由になるので直接外部のAPIをコールすることができないのです。

というわけでどうすればいいのか、以下に記載します。
<br>

## App Runnerからインターネットにアクセスするには？

「App Runnerはフルマネージド型サービスで、開発者はGitのソースコードか、ECRをプッシュするだけ」
この説明に頼りすぎて内部的に何が行われているのかを理解していませんでした。
<br>

結論、App Runnerがインターネットにアクセスするには、NATゲートウェイとインターネットゲートウェイが必要になります。

正確には **「App Runnerの内部のVPCにアタッチされているENIのプライベートIPアドレスを介して、各 FargateタスクにプライベートアクセスするのでVPCネットワーキングモードで使用する場合、NATゲートウェイとインターネットゲートウェイが必要になります」** 
<br>

順に説明していきます。
<br>

### パブリックネットワーキングモードとVPCネットワーキングモード
https://aws.amazon.com/jp/blogs/news/deep-dive-on-aws-app-runner-vpc-networking/

 **パブリックネットワーキングモード** 
2022年2月のアップデートがあるまではこちらの方法でしか使用することができませんでした。App Runnerは内部にVPCを所有しています。

![スクリーンショット 2023-12-18 13.53.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655825/6a9fe0f2-8c83-9c17-fa95-76e24610076f.png)


・インバウンド通信はApp Runner VPC内部のNLB、ENIを経由して最終的にアプリケーションコンテナに到達します。
・アウトバウンド通信はApp Runner VPC 内部の ENI、NAT Gateway、Internet Gateway を通ってインターネットに出ていきます
<br>

この図にあるように独自のVPCは登場しません。そしてアウトバウンド通信はインターネットから出て行くので、アプリケーションコンテナからアクセスできるのはインターネット経由で疎通できるサービスに限られます。つまり **S3 や DynamoDB にはインターネット経由で通信できるのでアクセスできますが、独自のVPC内部のプライベートサブネットにあるリソース（Auroraや ElastiCache）にアクセスすることはできません** でした。上述した「プライベートサブネットにアクセスできない」はこのことです。

 
<br>
<br>
<br>
 
 
 **VPCネットワーキングモード** 
一方、こちらは2022年のアップデートで対応されたVPCサポートによるものになります。

![スクリーンショット 2023-12-18 13.54.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655825/1f7a26f2-5648-e5fe-1d66-ed0e3675073f.png)

・インバウンド通信がENIに到達するまではパブリックネットワーキングモードと同じです。
・アウトバウンド通信はAWS Hyperplane というものを用いてFargate ENIから独自のVPC内部のENIへルーティングされます。
 **→つまりこの先は独自のVPC内部のルーティングに依存してきます！** 

↑この部分に気づけませんでした...。
<br>

パブリックネットワーキングモードの場合は、図にあるようにApp Runnerが管理しているVPCにNAT Gateway やInternet Gatewayがあるのでお客様側で用意する必要はありませんでした。
<br>
一方 VPCネットワーキングモードの場合は、アウトバウンド通信は全てお客様のVPCに行ってしまうので、そこからインターネットに出ていこうと思った時にルートテーブルの設定をしたりNAT Gateway、Internet Gatewayなどのリソースを作成する必要があるのです。（図のCustomerの部分にNATゲートウェイやInternet Gatewayがありますね）
<br>

というわけで、修正したAWS構成時がこちら↓
![スクリーンショット 2023-12-18 13.57.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3655825/a1573203-5f78-784e-31de-142669269b61.png)



これで外部APIにインターネット経由で接続することができました！
便利な分ブラックボックスになっている部分が多くて構造を理解するのが大変ですね...
<br>
<br>

結論...
 **App RunnerでVPCコネクタを使用する場合にインターネットにアクセスしたいときはNATが必要！** 
App Runnerを使用することがあるときはこの言葉を思い出してください。



## 参考
https://dev.classmethod.jp/articles/aws-app-runner-supports-privately-accessible-services-amazon-vpc/

https://aws.amazon.com/jp/blogs/news/deep-dive-on-aws-app-runner-vpc-networking/