Skip to content

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)

3.2 Configure shared resources

locals.tf
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_STRING secret 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_STRING with the database connection string.

3.5 Configure ECS Service Variables

Configure environment variables, SSM parameters, and Secrets Manager references to inject into the containers.

ecs_locals.tf
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

main.tf
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:

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.