🐟

[AWS Copilot] Backend Service with VPCEndpoint

2022/02/15に公開

これは何?

  • AWS公式が提供しているコンテナデプロイCLI AWS Copilotを使ったWeb APIの構築手順をざっくりとまとめたものです。
  • 本資料では AWS Fargate をプライベートサブネットに配置しながら、各AWSリソースとのやりとりをVPCEndpoint経由で行う構成を採用しています。

AWS構成図

Figure1
Figure1:AWS構成図

予備知識

1. AWS Copilotとは

嬉しいこと

  • Fargate を利用したい場合に、Fargate とそれに付随するインフラリソースを自動かつ適切なアーキテクチャで構築をすることができます。
  • 最小の手順では Dockerfile だけ自前で用意すれば、いくつかのコマンドを実行することでAWS上に動くものを作成可能です。

Application, Environment, Service

  • AWS Copilot にて構築するアーキテクチャは以下の3つの要素を持ちます。
  • 開発者は用途に合わせて各要素に対する命名と Service の種類を選択します。
Name Description
Application 提供するサービスや全体のシステム
Environment システムをデプロイする環境
Service システムを構成するコンポーネントの種類

Figure2
Figure2:Application,Environment,Serviceの関係性

Backend Service

  • Backend ServiceAWS Copilot が提供する Service の1つです。
  • 本タイプを選択した場合、 Fargate は、インターネットからアクセスできず、同一VPCに配置されたリソースからのアクセスのみを許可する構成になります。[1]
  • 用途としては直接ユーザがアクセスしないバックエンドアプリケーションなどがあります。
    Figure3
    Figure3:Backend Service

2. AWS CloudMapとは

  • AWS CloudMapはAWSが提供するサービスディスカバリーです。
  • 役割を簡単に説明すると、各種AWSリソースの接続先情報(ARNやIPアドレスなど)を任意の名前で一限管理することができます。
  • また今回のようなコンピューティングサービスではスケールイン・アウトに伴うIPアドレスの増減を動的に反映することが可能です。
    Figure4
    Figure4:AWS Cloud Map

今回の構成

アーキテクチャ図(再掲)

Figuew1
Figure1:AWS構成図

各リソースの簡単な役割

名称 説明
Cognito APIGatewayを実行するユーザの管理
APIGateway アプリケーションを実行するための外部エンドポイント
CloudMap APIGatewayにFargateのPrivate IPを共有する
VPC Link APIGatewayからVPCリソースへアクセスするための口
CloudWatchLogs Fargateのアプリケーションログを出力
ECR コンテナイメージの管理
DynamoDB サンプルアプリケーションで用いるストレージ
Fargate サンプルアプリケーションの実行

構成のポイント

プライベートサブネット に AWS Fargateを配置する

  • AWS Copilot にて Backend Service を選んだ場合、デフォルトでは Fargate はパブリックサブネットに構築されます。[2]
  • ただ要件によってはFargateをプライベートサブネットに配置した方が良い場合があります。[3]
    • セキュリティ要件でプライベートサブネットに配置しなければならない場合
    • Fargate 上で動かすタスクにてセンシティブなデータを扱う場合

NATGatewayを使わずにVPCEndpointを使う

  • インターネットへのアウトバウンドが、他のAWSリソースへのアクセスで完結する場合に限り、NATGatewayではなくVPCEndpoint を利用した方が安く済むことがあります。
  • NATGateway を使わざる負えない時でもデータ転送量の観点からS3DynamoDB へのアクセスは VPCEndpoint(Gateway型) を使った方が料金を抑えられます。

料金体系

  • バージニア北部基準
対象 稼働時間 (USD/h) データ転送量 (USD/GB)
NATGateway 0.045 0.045
VPCEndpoint(Gateway型) - 0.010
VPCEndpoint(Interface型) 0.010 0.010

構築手順

https://zenn.dev/kzen/articles/8930bc11f10eff

解説

Applicationの構築 (copilot app init)

  • アプリケーション名を命名します。
  • 内部処理で SSM ParameterStore にアプリケーション名が登録されます。
SSM Parameter Name
/copilot/applications/my-app

Figure5
Figure5:Application

Environmentの構築 (copilot env init)

  • 環境名を命名します。
  • AWSリソースとして VPC(とその他ネットワークリソース)ECS Clusterなどが構築されます。
    Figure6
    Figure6:Environment

--import-vpc, --import-private-subnets

  • 今回は事前に構築したVPCを使うためimportオプションを利用します。
  • 実行ログでは No existing subnets と出力されますが特に処理への影響はありません。
log
Note: No existing subnets were found in VPC vpc-xxx.
If you proceed without at least two public subnets, you will not be able to deploy Load Balanced Web Services in this environment.

Service定義の作成 (copilot svc init)

  • コンポーネントの種類と名前を指定します。
  • また合わせて、Fargateで使用するDockerfileを指定します。
  • 成果物として copilot の設定ファイルである manifast.yml が生成されます。
    Figure7
    Figure7:Service

manifast.yml

  • copilot にてデプロイする Fargate の設定ファイルです。
  • CPUやメモリを始め、タスクの数やネットワークタイプなどを指定します。

アドオンの追加

  • copilot svc init では選択した Service の種類に沿ってあらかじめ決められたAWSリソースを構築します。
  • それ以外のAWSリソースを構築したい場合、アドオン機能を使うことで追加できます。
  • なおアドオンするリソースは Service を親Stackとした NestedStack として生成されます。
    Figure8
    Figure8:Stack構成

ストレージ アドオンの追加 (copilot storage init)

  • copilot にて公式に提供されているアドオンコマンドの一つです。
  • 現時点ではAuroraDynamoDBS3 が対応しています。
  • 生成されるテンプレートにはストレージ本体の他、Fargate からアクセスするための IAMポリシーの定義が含まれます。
    Figure9
    Figure9:copilot storage init

カスタムリソース アドオンの追加

  • アドオンコマンドで対応していないものを構築したい場合、addons 配下に直接テンプレートを配置することで一緒にデプロイすることが可能です。
  • 今回は APIGateway(HTTP) の構築に使っています。
    Figure10
    Figure10:customResource

カスタムパラメータの追加

  • v1.13.0 で追加された機能です。
  • 初期状態では親Stackからは App(アプリケーション名)Env(環境名)Name(サービス名) の3種類のみが渡されます。
  • これ以外のパラメータを使いたい場合は、addons.parameters.yml を作成することで追加できます。
  • 今回は親Stackで生成される CloudMap のARNを APIGateway(HTTP) のテンプレートで利用しています。
    Figure11
    Figure11:addons.parameters.yml

serviceのデプロイ (copilot svc deploy)

  • copilot svc init およびアドオンで追加したリソースをデプロイします。
  • 各種AWSサービスの構築の他に、Dockerイメージ のビルド、ECRへのプッシュも、このタイミングにて実行されます。

所感

  • 全体的に今、何をやっているかが分かりやすく使いやすい印象でした。
  • copilot storage initでIAMポリシー定義の生成と環境変数の払い出しが自動的にできるのが、アプリケーション連携において、とても配慮されているように感じました。
  • 機能的には今のままでも問題ないですが、将来自前で書くカスタムリソースが CDK で書けるようになると copilot で完結しやすいかもしれません。
    • (Cognito に関しては CDKHigh Level Construct を利用したかったので別Stackに今回は切り出しました。)

備考

  • 今回構築した VPCEndpoint を使った構成は将来的に manifast.yml のネットワークタイプの一つとして提供される予定らしいです。[4]

参考にしたもの

GitHub

https://github.com/aws/copilot-cli/discussions/2378
https://github.com/aws/copilot-cli/issues/2848

AWS Copilot関連

https://aws.github.io/copilot-cli/ja/docs/overview/

AWS CDK関連

https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_ec2.Vpc.html
https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_cognito-readme.html

AWS関連

https://aws.amazon.com/jp/vpc/pricing/
https://aws.amazon.com/jp/privatelink/pricing/
https://aws.amazon.com/jp/ec2/pricing/on-demand/
https://aws.amazon.com/jp/blogs/compute/task-networking-in-aws-fargate/

アプリケーション側

https://nestjs.com/
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-dynamodb/index.html
https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/modules/_aws_sdk_lib_dynamodb.html

脚注
  1. Fargateはパブリックサブネットに配置されますが、①付与されているセキュリティグループにてインバウンドを遮断していること、②前段に入り口となるAWSリソース(ALBなど)がないことから外部からのアクセスはできません。 ↩︎

  2. なぜこうした挙動(配慮)になっているかはIssue:2848にて説明されています。 ↩︎

  3. Task Networking in AWS Fargate ↩︎

  4. 2848#issuecomment-921940983 ↩︎

Discussion

ログインするとコメントできます