Traffine I/O

日本語

2023-07-15

FastAPIアプリケーションをECS Fargateにデプロイ

FastAPIアプリケーションをECS on Fargateにデプロイ

この記事では、FastAPIをFargateにデプロイする方法を紹介します。アーキテクチャは以下の図の通りです。

Fast API on ECS Fargate architecture

ソースコードは以下のレポジトリから確認することができます。

https://github.com/ryuseikakujo/fastapi-on-fargate

ソースコードの理解には以下の知識が必要になります。

  • FastAPI
  • Terraform
  • GitHub Actions
  • AWS
  • Docker

ソースコードのクローン

以下のコマンドでソースコードをクローンします。

bash
$ git clone https://github.com/ryuseikakujo/fastapi-on-fargate.git

セットアップ

以下の手順でセットアップを行います。

  1. 環境変数の設定
  2. ECRレポジトリの作成
  3. DockerイメージをECRにプッシュ
  4. Terraformのバックエンドを作成
  5. インフラのリソースをTerraformで作成
  6. GitHub ActionsのSecretsの設定

環境変数の設定

以下のコマンドで環境変数の設定を行います。

bash
$ export AWS_PROFILE=xxxxx
$ export AWS_ACCOUNT_ID=xxxxx

ECRレポジトリの作成

ECRレポジトリを作成します。以下では、my-appという名前のレポジトリを作成します。

bash
$ cd infrastructure/provisioning

$ sh ecr.sh
Enter app name: my-app
The ECR repository namely my-app will be created.

DockerイメージをECRにプッシュ

以下のコマンドで作成したECRにDockerイメージをプッシュします。app nameを尋ねられるので、my-app(ECRレポジトリの名前)を入力します。

bash
$ cd api

$ sh local-push-to-ecr.sh
Enter app name: my-app

Terraformのバックエンドを作成

Terraformのステートを管理するためのバックエンドを作成します。S3とDynamoDBが作成されます。ここで、Enter unique S3 bucket name for Terraform Backend: と尋ねられた際に、グローバルでユニークな名前にする必要があることに注意してください。以下の例のような、my-app-tfstateという名前だとユニークでない可能性があります。

bash
$ cd infrastructure/provisioning

$ sh backend.sh
Enter unique S3 bucket name for Terraform Backend: my-app-tfstate
Enter dynamodb name for Terraform Backend: my-app-tfstate
Enter Cloudformation stack name for Terraform Backend: my-app-tfstate

インフラのリソースをTerraformで作成

まずはinfrastructure/terraform/backend.tfファイルのbucketdynamodb_tableを変更します。

infrastructure/terraform/backend.tf
  backend "s3" {
-   bucket = "my-app-tfstate" # This should be the name you defined at step 3.
+   bucket = "<Your s3 bucket name>" # This should be the name you defined at step 3.
    key = "terraform.tfstate"
-   dynamodb_table = "my-app-tfstate" # This should be the name you defined at step 3.
+   dynamodb_table = "<Your dynamodb table name>" # This should be the name you defined at step 3.
    region = "ap-northeast-1"
  }

次に、infrastructure/terraform/variables.tfを変更します。

infrastructure/terraform/variables.tf
  variable "aws_account_id" {
-   default = "123456789012"
+   default = "<Your account id>"
  }

  variable "app_name" {
    type    = string
-   default = "my-app"
+   default = "<Your app name>"
  }

  variable "vpc_cidr" {
    type    = string
    default = "10.0.0.0/16"
  }

  variable "azs" {
    type    = list(string)
    default = ["ap-northeast-1a", "ap-northeast-1c"]
  }

  variable "public_subnet_cidrs" {
    default = ["10.0.0.0/24", "10.0.1.0/24"]
  }

  variable "private_subnet_cidrs" {
    default = ["10.0.10.0/24", "10.0.11.0/24"]
  }

  variable "github_org" {
-   default = "my-org"
+   default = "<Your github organization name>"
  }

  variable "github_repo" {
-   default = "my-repo"
+   default = "<Your github repository name>"
  }

そして以下のコマンドでTerraformをapplyします。

bash
$ cd infrastructure/terraform

$ terraform init

$ terraform apply

以下のリソースが作成されます。

  • VPC
  • サブネット
  • Internet Gateway
  • NAT Gateway
  • Security Group
  • ECS
    • Cluster
    • タスク定義
    • Service
  • ECSのCloudWatch Log
  • IAMロール
    • GitHub Actions経由でOIDCでECRにイメージをプッシュするためのロール
    • ECSタスク実行ロール
  • ALB
  • S3
    • ALBのログを収集するバケット

FastAPIはプライベートサブネットにあるECS Fargateで起動し、ALBでトラフィックがバランシングされます。

GitHub ActionsのSecretsの設定

.github/workflows/cd_ecs.ymlで定義しているGitHub ActionsによるECSのデリバリーを行うには、以下のSecretsをGitHub上で設定します。

  • AWS_IAM_ROLE_ARN: ARN of IAM role for GitHub Actions
  • ECR_REPO_NAME: ECR repo name
  • TASK_DEFINITION_FAMILY_NAME: ECS task definition name
  • ECS_CLUSTER_NAME: ECS cluster name
  • ECS_SERVICE_NAME: ECS service name

mainブランチにコミットされると、GitHub ActionsがECRにDockerイメージをプッシュし、ECSタスク定義の更新を行うようになります。

参考

https://towardsaws.com/deploy-scalable-docker-service-with-amazon-ecs-on-ec2-instances-510178097190
https://y-ohgi.com/introduction-terraform/
https://github.com/ryuseikakujo/fastapi-on-fargate

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!