Deploy a containerized application on Fargate
This document provides a high-level overview of how applications are deployed on AWS ECS Fargate in BYM.
AWS ECS (Elastic Container Service) is a managed container orchestration service that runs Docker containers without requiring you to manage EC2 instances. BYM uses the Fargate launch type, which allows AWS to handle the underlying infrastructure while developers focus on the application itself.
Architecture Overview
A typical ECS Fargate deployment consists of the following components:
Amazon ECR (Elastic Container Registry)
Amazon ECR stores the Docker images used by the application.
- Acts as a private Docker registry
- Stores versioned container images
- Images are typically built and pushed through GitHub Actions
Application Load Balancer (ALB)
The Application Load Balancer provides a single entry point to the application.
- Receives incoming HTTP/HTTPS traffic
- Performs health checks
- Distributes traffic across running ECS tasks
- Supports TLS termination and routing rules
ECS Cluster
An ECS Cluster is the logical container environment where ECS services and tasks run.
- Groups related ECS services
- Provides capacity management through AWS Fargate
- Enables centralized monitoring and management
ECS Service (Fargate)
The ECS Service manages the application's running containers.
- Maintains the desired number of running tasks
- Automatically replaces failed tasks
- Supports rolling deployments
- Integrates with the Application Load Balancer
Environment Variables
Environment variables are used to configure the application at runtime.
Typical examples include:
- Application settings
- API endpoints
- Feature flags
- Database connection information
- AWS resource identifiers
Sensitive values such as passwords and secrets should be stored in AWS Secrets Manager or AWS Parameter Store and injected into the container at runtime.
Architecture Diagram
flowchart TD
user@{ label: "Users" }
subgraph AWS["AWS Product Account"]
alb@{ label: "Application Load Balancer" }
subgraph ECS["ECS Cluster"]
service@{ label: "ECS Service" }
task@{ label: "Fargate Task" }
end
env@{ label: "Environment Variable/ Parameter Store / Secrets Manager" }
rds@{ label: "PostgreSQL RDS (Optional)" }
alb B@-.->|Route Traffic| service
service C@-.->|Run Tasks| task
env E@-.->|Inject Configuration| task
task F@-.->|Optional DB Connection| rds
end
subgraph ECR["AWS Shared Account"]
ecr@{ label: "Amazon ECR" }
ecr D@-.->|Pull Image| task
end
user A@-.->|HTTPS| alb
A@{ animation: fast }
B@{ animation: fast }
C@{ animation: fast }
D@{ animation: fast }
E@{ animation: fast }
F@{ animation: fast }
%% --- COLOR CLASSES ---
classDef user fill:#E3F2FD,stroke:#1E88E5,stroke-width:2px,color:#0D47A1
classDef ecs fill:#E8F5E9,stroke:#43A047,stroke-width:2px,color:#1B5E20
classDef alb fill:#FCE4EC,stroke:#D81B60,stroke-width:2px,color:#880E4F
classDef ecr fill:#E0F7FA,stroke:#00ACC1,stroke-width:2px,color:#006064
classDef env fill:#F3E5F5,stroke:#8E24AA,stroke-width:2px,color:#4A148C
classDef rds fill:#FFF8E1,stroke:#F9A825,stroke-width:2px,color:#E65100
%% --- APPLY CLASSES ---
class user user
class alb alb
class service ecs
class task ecs
class ecr ecr
class env env
class rds rds
Deployment Overview
| Repository | Responsibility |
|---|---|
| SharedKontoInfrastruktur | Shared AWS resources such as ECR repositories |
Application repository (for example KatteApiService) |
Application code, Docker image build, image publishing, and deployment workflows |
Infrastructure repository (for example KattehotellInfrastruktur) |
Runtime infrastructure such as ALB, ECS services, Parameter Store, and Secrets Manager |
👉 Deployment Flow (Start here)
This example demonstrates how to deploy the Kattehotell API service to Amazon ECS Fargate.
The deployment process spans multiple repositories, each with a specific responsibility. Follow the steps below in order.
1. SharedKontoInfrastruktur
Create shared AWS resources:
2. Application repository
Build and publish the application container image to Amazon ECR.
3. ProduktInfrastruktur repository
In your product's infrastructure repository, provision the ECS Fargate service and configure it to use the ECR repository, Secrets Manager secrets, Parameter Store values, and environment variables as shown below.
Deploy runtime infrastructure:
3.1 Configure Parameter Store and Secrets Manager (Optional)
- Configure Parameter Store
- Configure Secrets Manager
3.2 Configure shared resources
data "aws_ssm_parameter" "vpc_information" {
name = "/bym/vpc"
}
data "aws_route53_zone" "route53_zone" {
provider = aws.route53
name = "test.bymoslo.net" # Change based on the target environment
}
locals {
vpc = jsondecode(data.aws_ssm_parameter.vpc_information.insecure_value)
route53_domain = "test.bymoslo.net" # Change based on the target environment
kattehotell_ssm_parameters = module.ssm_parameters.parameters_arn # Optinal
kattehotell_secretsmanager = module.secretsmanager.secrets_arn # Optional
}
3.3 Create Application Load Balancer (ALB)
Create the Application Load Balancer that receives incoming traffic and route requests to the ECS service.
3.4 Create PostgreSQL RDS (Optional)
PostgreSQL RDS is optional. Stateless applications can be deployed without a database and might use other AWS services instead.
If an RDS instance is created:
- Add a
POSTGRESQL_CONNECTION_STRINGsecret in AWS Secrets Manager, create a PR, and merge the changes. - Ask Team Cloud to create a service user for the database.
- Once the service user has been created, Team Cloud updates the value of
POSTGRESQL_CONNECTION_STRINGwith the database connection string.
3.5 Configure ECS Service Variables
Configure environment variables, SSM parameters, and Secrets Manager references to inject into the containers.
locals {
aspnetcore_environment = {
test = "testing"
prod = "production"
}[var.environment]
##########
# api-service variables
############
api_service_variables = {
secretsmanager_secrets = {
POSTGRESQL_CONNECTION_STRING = local.kattehotell_secretsmanager["KATTEHOTELL_POSTGRESQL_CONNECTION_STRING"]
MY_NEW_SECRET = local.kattehotell_secretsmanager["MY_NEW_SECRET"]
...
} # Optional: Add Secrets manager if needed
ssm_secrets = {
SVARUT_BASEURL = local.kattehotell_ssm_parameters["SvarUt/BaseUrl"]
...
} # Optional: Add SSM Parameter Store values if needed
environment_variable = {
ASPNETCORE_ENVIRONMENT = local.aspnetcore_environment
...
}
}
}
3.6 Deploy ECS Fargate service
module "application" {
source = "git@github.com:BYM-IKT/terraform-byks-module.git?ref=v12"
account_id = var.account_id
environment = var.environment
application_name = "kattehotell"
team = "team-x"
has_rds = false # Add this line if you don't need RDS
ecs_services = {
api = {
port = <service-port-number>
cpu = 256 # CPU units
memory = 512 # Memory in MiB
desired_count = 1 # Number of running tasks
ecr_uri = data.terraform_remote_state.shared_kattehotell_ecr.outputs.kattehotell_ecr_repo.ecr_ur["api"].ecr_url
image_tag = var.environment
secretsmanager_secrets = local.api_service_variables.secretsmanager_secrets # Optional
ssm_secrets = local.api_service_variables.ssm_secrets # Optional
environment_variables = local.api_service_variables.environment_variable
}
}
depends_on = [
module.alb,
module.rds # Optional, if we need RDS
]
}
Note
During initial setup (before the Deployment workflow exists), set image_tag to latest to enable image publishing.
Once the Deployment workflow is implemented, switch to environment-specific tags (dev, test, prod) for all image publishing.
The ECS service always pulls the image defined by the configured image_tag.
Warning
Do not change the cpu, memory, or desired_count values without consulting Team Cloud. These settings must align with platform standards, cost considerations, and performance requirements.
4. Application repository
Update the GitHub Actions workflow to deploy the application:
- Run the ECS deployment workflow (select the ECS Fargate tab)
Note
Image tagging
Use standard image tags (dev, test, and prod) whenever possible. Only use custom tags when there is a specific deployment or operational requirement.
Deployment order
The ECS deployment workflow should only be executed after the ECS infrastructure has been fully provisioned in Step 3. Running the workflow before the infrastructure is ready will cause the deployment stage to fail.