Deploying FastAPI Application to ECS Fargate
This article will introduce how to deploy a FastAPI application to ECS Fargate. The architecture is depicted in the following diagram.
You can check the source code in the following repository.
The following knowledge is required to understand the source code:
- FastAPI
- Terraform
- GitHub Actions
- AWS
- Docker
Cloning the Source Code
Clone the source code with the following command:
$ git clone https://github.com/ryuseikakujo/fastapi-on-fargate.git
Setup
Perform the setup steps below:
- Setting Environment Variables
- Creating an ECR Repository
- Pushing the Docker Image to ECR
- Creating a Terraform Backend
- Creating Infrastructure Resources with Terraform
- Configuring GitHub Actions Secrets
Setting Environment Variables
Set the environment variables with the following command:
$ export AWS_PROFILE=xxxxx
$ export AWS_ACCOUNT_ID=xxxxx
Creating an ECR Repository
Create an ECR repository. In the example below, I create a repository named my-app
.
$ cd infrastructure/provisioning
$ sh ecr.sh
Enter app name: my-app
The ECR repository namely my-app will be created.
Pushing the Docker Image to ECR
Push the Docker image to the created ECR repository. When prompted for the app name, enter my-app
(the name of your ECR repository).
$ cd api
$ sh local-push-to-ecr.sh
Enter app name: my-app
Creating a Terraform Backend
Create a backend for managing the Terraform state. This will create S3 and DynamoDB. Note that when prompted for Enter unique S3 bucket name for Terraform Backend:
, you need to choose a globally unique name. For example, a name like my-app-tfstate
might not be unique.
$ 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
Creating Infrastructure Resources with Terraform
First, modify the bucket
and dynamodb_table
in the infrastructure/terraform/backend.tf
file.
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"
}
Next, modify 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>"
}
Then, apply Terraform with the following commands:
$ cd infrastructure/terraform
$ terraform init
$ terraform apply
The following resources will be created:
- VPC
- Subnets
- Internet Gateway
- NAT Gateway
- Security Group
- ECS
- Cluster
- Task Definition
- Service
- ECS CloudWatch Log
- IAM Roles
- Role for pushing images to ECR via GitHub Actions with OIDC
- ECS task execution role
- ALB
- S3
- Bucket for collecting ALB logs
FastAPI will run on ECS Fargate in the private subnets and the traffic will be balanced by ALB.
Configuring GitHub Actions Secrets
To perform ECS delivery with GitHub Actions defined in .github/workflows/cd_ecs.yml
, configure the following Secrets on GitHub:
AWS_IAM_ROLE_ARN
: ARN of the IAM role for GitHub ActionsECR_REPO_NAME
: ECR repository nameTASK_DEFINITION_FAMILY_NAME
: ECS task definition nameECS_CLUSTER_NAME
: ECS cluster nameECS_SERVICE_NAME
: ECS service name
When committed to the main
branch, GitHub Actions will push the Docker image to ECR and update the ECS task definition.
References