2023-07-15

Deploying FastAPI Application to ECS Fargate

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.

Fast API on ECS Fargate architecture

You can check the source code in the following repository.

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

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:

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

Setup

Perform the setup steps below:

  1. Setting Environment Variables
  2. Creating an ECR Repository
  3. Pushing the Docker Image to ECR
  4. Creating a Terraform Backend
  5. Creating Infrastructure Resources with Terraform
  6. Configuring GitHub Actions Secrets

Setting Environment Variables

Set the environment variables with the following command:

bash
$ 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.

bash
$ 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).

bash
$ 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.

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

Creating Infrastructure Resources with Terraform

First, modify the bucket and dynamodb_table in the infrastructure/terraform/backend.tf file.

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"
  }

Next, modify 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>"
  }

Then, apply Terraform with the following commands:

bash
$ 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 Actions
  • ECR_REPO_NAME: ECR repository name
  • TASK_DEFINITION_FAMILY_NAME: ECS task definition name
  • ECS_CLUSTER_NAME: ECS cluster name
  • ECS_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

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

Ryusei Kakujo

researchgatelinkedingithub

Focusing on data science for mobility

Bench Press 100kg!