๐Ÿš€ Multi-Application CI/CD on AWS (Production-Style)

Published: (January 1, 2026 at 01:36 AM EST)
3 min read
Source: Dev.to

Source: Dev.to

Project Goal

  • Developers push code to GitHub.
  • GitHub Actions automatically:
    • Tests code
    • Builds Docker images
    • Pushes images to AWS ECR
    • Deploys to AWS ECS (Fargate) or EC2 + Docker
  • End users access apps via HTTPS (ALB + ACM)
  • Logs & monitoring via CloudWatch
  • Supports rolling / blueโ€‘green deployment

Highโ€‘Level Architecture

flowchart TD
    Developer -->|push| GitHubRepo[GitHub Repo (App1, App2, App3)]
    GitHubRepo --> GitHubActions[GitHub Actions (CI/CD)]
    GitHubActions -->|Test| Test
    GitHubActions -->|Docker Build| Build
    GitHubActions -->|Push to ECR| ECR[AWS ECR (Images)]
    ECR --> ECS[AWS ECS (Fargate)]
    ECS --> ALB[Application Load Balancer]
    ALB --> EndUsers[End Users (HTTPS)]

Repository Structure

multi-app-devops/
โ”œโ”€โ”€ app1/
โ”‚   โ”œโ”€โ”€ Dockerfile
โ”‚   โ””โ”€โ”€ src/
โ”œโ”€โ”€ app2/
โ”‚   โ”œโ”€โ”€ Dockerfile
โ”‚   โ””โ”€โ”€ src/
โ”œโ”€โ”€ app3/
โ”‚   โ”œโ”€โ”€ Dockerfile
โ”‚   โ””โ”€โ”€ src/
โ””โ”€โ”€ .github/
    โ””โ”€โ”€ workflows/
        โ””โ”€โ”€ deploy.yml

Each application is independent but deployed via the same pipeline logic.

Step 1: AWS Account & IAM

Attach the following managed policies to the CI/CD IAM user/role:

  • AmazonEC2FullAccess
  • AmazonECS_FullAccess
  • AmazonEC2ContainerRegistryFullAccess
  • CloudWatchFullAccess
  • IAMReadOnlyAccess

Create an Access Key for programmatic access.

Step 2: Networking (VPC)

  1. Create a VPC with two public subnets.
  2. Attach an Internet Gateway and configure a route table.
  3. Security groups:
    • ALB โ€“ inbound ports 80 and 443
    • ECS tasks โ€“ inbound ports 3000, 5000, 80 (as required by each app)

Step 3: Create ECR Repositories

Create one repository per application:

  • app1-ecr
  • app2-ecr
  • app3-ecr

Record the following for later use:

  • AWS Account ID
  • Region
  • Repository URI (e.g., 123456789012.dkr.ecr.us-east-1.amazonaws.com/app1)

Step 4: Dockerize Applications

Example Dockerfile (use the same pattern for each app):

# Dockerfile
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

Step 5: ECS Cluster (Fargate)

  1. Create an ECS cluster.
  2. Define a Task Definition for each app:
    • Container image โ†’ ECR URI
    • Port mapping โ†’ appโ€™s exposed port
    • CPU & memory settings
  3. Create a Service for each task definition:
    • Launch type: FARGATE
    • Attach the service to the ALB target group
    • Desired count: 2 (high availability)

Step 6: Application Load Balancer

Configure pathโ€‘based routing:

PathTarget Service
/app1app1-service
/app2app2-service
/app3app3-service

Step 7: GitHub Secrets

Add the following secrets to the repository:

  • AWS_ACCESS_KEY_ID
  • AWS_SECRET_ACCESS_KEY
  • AWS_ACCOUNT_ID
  • ECR_REPO_APP1 (full URI)
  • ECR_REPO_APP2 (full URI)
  • ECR_REPO_APP3 (full URI)

Step 8: GitHub Actions CI/CD Pipeline

.github/workflows/deploy.yml

name: CI-CD Pipeline

on:
  push:
    branches: [ "main" ]

env:
  AWS_REGION: us-east-1

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        run: |
          aws ecr get-login-password --region $AWS_REGION \
          | docker login --username AWS --password-stdin \
          ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.$AWS_REGION.amazonaws.com

      - name: Build & Push App1
        run: |
          docker build -t app1 ./app1
          docker tag app1:latest ${{ secrets.ECR_REPO_APP1 }}:latest
          docker push ${{ secrets.ECR_REPO_APP1 }}:latest

      - name: Deploy App1 to ECS
        run: |
          aws ecs update-service \
            --cluster devops-cluster \
            --service app1-service \
            --force-new-deployment

      # Repeat the build, push, and deploy steps for app2 and app3

Step 9: Monitoring & Logs

  • CloudWatch Logs โ€“ capture container stdout/stderr.
  • Metrics โ€“ CPU, memory, and network utilization per task.
  • Health checks โ€“ configured on the ALB target groups.

Step 10: Security & Best Practices

  • Use leastโ€‘privilege IAM policies.
  • Enable image scanning in ECR.
  • Enforce HTTPS with ACM certificates on the ALB.
  • Rotate IAM access keys regularly.

Step 11: Testing Flow

  1. Developer modifies code and pushes to main.
  2. GitHub Actions workflow triggers.
  3. Docker image is rebuilt and pushed to ECR.
  4. ECS service pulls the new image and performs a rolling deployment.
  5. End users receive the updated application without downtime.
Back to Blog

Related posts

Read more ยป