FastAPIアプリケーションをECS on Fargateにデプロイ
この記事では、FastAPIをFargateにデプロイする方法を紹介します。アーキテクチャは次の図の通りです。
ソースコードは次のレポジトリから確認することができます。
ソースコードの理解には次の知識が必要になります。
- FastAPI
- Terraform
- GitHub Actions
- AWS
- Docker
ソースコードのクローン
次のコマンドでソースコードをクローンします。
$ git clone https://github.com/ryuseikakujo/fastapi-on-fargate.git
セットアップ
次の手順でセットアップを行います。
- 環境変数の設定
- ECRレポジトリの作成
- DockerイメージをECRにプッシュ
- Terraformのバックエンドを作成
- インフラのリソースをTerraformで作成
- GitHub ActionsのSecretsの設定
環境変数の設定
次のコマンドで環境変数の設定を行います。
$ export AWS_PROFILE=xxxxx
$ export AWS_ACCOUNT_ID=xxxxx
ECRレポジトリの作成
ECRレポジトリを作成します。以下では、my-app
という名前のレポジトリを作成します。
$ 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レポジトリの名前)を入力します。
$ 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
という名前だとユニークでない可能性があります。
$ 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
ファイルのbucket
とdynamodb_table
を変更します。
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
を変更します。
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
します。
$ 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 ActionsECR_REPO_NAME
: ECR repo nameTASK_DEFINITION_FAMILY_NAME
: ECS task definition nameECS_CLUSTER_NAME
: ECS cluster nameECS_SERVICE_NAME
: ECS service name
main
ブランチにコミットされると、GitHub ActionsがECRにDockerイメージをプッシュし、ECSタスク定義の更新を行うようになります。
参考