DEV Community

Cover image for Deploy a Microservices application on ECS
Jones Ndzenyuy
Jones Ndzenyuy

Posted on

Deploy a Microservices application on ECS

Introduction

The Elastic Compute Service - ECS can be a game changer for startups with low initial traffic and a vision to scale. It allows you to deploy Docker containers in an AWS managed environment, eliminating the need to manage the control plane. ECS is a free service, you only pay for the resources deployed. With its auto scaling feature, there's no need to worry about over provisioning infrastructure. You can start with the minimum resources and scale up as traffic grows.
In this article, I'll guide you step by step on how to deploy a microservices infrastructure on ECS. The Application consists of an Nginx server acting as a reverse proxy, intelligently routing traffic to downstream applications(Angular, Node and Java) based on user requests. The architecture of the application is as follows:

App Architecture

Re-architecting the Application to be deployed on ECS

The different services of the App communicates with each other, in ECS, we need to ensure that there is communication among services. ECS doesn't manage volumes like in EKS, so we need to deploy an RDS-MySQL database and a MongoDB Atlas DB, then configure our containers to access the external services via our network setup. To ensure there is communication between services, we will use ECS' Service Discover, which will register a private hosted zone and permit the services to discover each other and send API calls amongst them. Nginx should be configured to use the domain names that will be used in the private Hosted zone for communications and routing of traffic. The Architecture to be deployed is as follows:

Infra Architecture

How to build it

Create IAM Roles

  1. Github Actions via OIDC and attach policies

Go to Console -> Cloudformation and create a new deployment. Give the name of the stack github-iam-oidc, copy the code below into a yaml file and choose it for cloudformation to deploy it

  GitHubOrg:
    Description: Name of GitHub Username (case sensitive)
    Type: String
    Default: "YOUR-GITHUB-USERNAME"

  RepositoryName:
    Description: Name of GitHub Repository (case sensitive)
    Type: String
    Default: "THE-REPO_NAME-FOR-THI-PROJECT"

  OIDCProviderArn:
    Description: ARN of the GitHub OIDC Provider (Leave blank to create one)
    Type: String
    Default: "arn:aws:iam::997450571655:oidc-provider/token.actions.githubusercontent.com"

  OIDCAudience:
    Description: Audience supplied to configure-aws-credentials.
    Type: String
    Default: "sts.amazonaws.com"

Conditions:
  CreateOIDCProvider: !Equals 
    - !Ref OIDCProviderArn
    - ""

Resources:
  GithubOidc:
    Type: AWS::IAM::OIDCProvider
    Condition: CreateOIDCProvider
    Properties:
      Url: https://token.actions.githubusercontent.com
      ClientIdList:
        - !Ref OIDCAudience
      ThumbprintList:
        - "74f3a68f16524f15424927704c9506f55a9316bd"  # Replace with actual thumbprint

  Role:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Action: sts:AssumeRoleWithWebIdentity
            Principal:
              Federated: !If
                - CreateOIDCProvider
                - !Ref GithubOidc
                - !Ref OIDCProviderArn
            Condition:
              StringEquals:
                token.actions.githubusercontent.com:aud: !Ref OIDCAudience
              StringLike:
                token.actions.githubusercontent.com:sub: !Sub repo:${GitHubOrg}/${RepositoryName}:*

Outputs:
  RoleArn:
    Description: IAM Role ARN for GitHub Actions
    Value: !GetAtt Role.Arn

Enter fullscreen mode Exit fullscreen mode
  1. Update the policy in the created role Now search the IAM roles that is created(github-iam-oidc-XXX) and add policies that will permit us to push to ECR and deploy to ECS. Add an inline policy with name github-deploy-to-ecs, We will add the following policies:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ecs:CreateService",
                "ecs:DescribeServices",
                "ecs:DescribeClusters",
                "ecs:UpdateService",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchGetImage",
                "ecr:CompleteLayerUpload",
                "ecr:DescribeImages",
                "ecr:UploadLayerPart",
                "ecr:ListImages",
                "ecr:InitiateLayerUpload",
                "ecr:BatchCheckLayerAvailability",
                "ecr:PutImage",
                "ecs:DescribeTaskDefinition",
                "ecs:RegisterTaskDefinition",
                "ecs:ListTasks",
                "ec2:DescribeNetworkInterfaces",
                "ecs:DescribeTasks",
                "ecr:GetAuthorizationToken",
                "iam:PassRole"
            ],
            "Resource": [
                "*"
            ]
        }       
    ]
}
Enter fullscreen mode Exit fullscreen mode
  1. Create ecsTaskExecutionRole and give it admin access(just for this project)

Create ECR Repository

We have to create 4 different repositories for the the different containers. On the console, navigate to ECR and select create(do it for the 4 different containers), give the names to the different repos:

  • client
  • javaapi
  • nodeapi
  • nginx Leave the other settings as defaults and select create.

Image description

Create MySQL database in RDS

In the console navigate to RDS and create a MySQL database with the following settings:

Choose a database creation method: Standard create
Engine Options: MySQL
Engine version: select the latest
Templates: Free tier
Db instance identifier: books
Master username: root
password: give-your-password
Storage: 20Gb
VPC security group: create new
 - SG name: rds-sg
Enter fullscreen mode Exit fullscreen mode

Leave the rest as defaults and create the database. When created, record the db URL, username and password, Instance identifier.

Create MongoDB Atlas database

Navigate to https://cloud.mongodb.com, create a free account and create a free database.

db name: epoc
username: GIVE-YOUR-USERNAME
password: GIVE-YOUR-PASSWORD
Enter fullscreen mode Exit fullscreen mode

Under database clusters click on connect and select Drivers

Connect to Mongodb

Scroll down and copy the Connection string to be add to our environment variables. The string will be similar to:

mongodb+srv://ndzenyuyjones:<db_password>@epoc.fezqjvq.mongodb.net/?retryWrites=true&w=majority&appName=epoc
Enter fullscreen mode Exit fullscreen mode

Now we have to edit this string to include the DB name, and the password(replace with your password, then add the db name to the string(after mongodb.net/) Your string should be something like:

mongodb+srv://ndzenyuyjones:<db_password>@epoc.fezqjvq.mongodb.net/epoc?retryWrites=true&w=majority&appName=epoc
Enter fullscreen mode Exit fullscreen mode

Copy this to a variables file including the other values registered above. We will need them for deployment.

Clone Project Repository

Open git on your local machine and run the following to clone the project repository and initialize for usage in the steps ahead

git clone https://github.com/Ndzenyuy/day-1-deploy_microservices_to_ecs.git

cd day-1-deploy_microservices_to_ecs

sudo rm -rf .github
sudo rm -rf .git

Enter fullscreen mode Exit fullscreen mode

Initialise git and Create a folder with the following code

git init
mkdir .github/workflows
touch .github/workflows/nginx.yml .github/workflows/client.yml .github/workflows/nodeapi.yml .github/workflows/javaapi.yml
Enter fullscreen mode Exit fullscreen mode

It will create deployment files for the different services. Each of the pipelines will run only when there is a change in the folder containing the source files.

  1. open the nginx.yml file and paste the following
name: Deploy to ECS

on:
  push:
    paths:
      - "nginx/**"
  pull_request:
    paths:
      - "nginx/**"

  workflow_dispatch:

permissions:
  id-token: write
  contents: read

env:
  AWS_REGION: "us-east-1"
  AWS_GITHUB_ROLE: ${{ secrets.AWS_GITHUB_ROLE }}
  ECS_PROJECT: ${{ secrets.ECS_PROJECT }}

  ECR_REPOSITORY_NGINX: "nginx"
  ECS_NGINX_TASK: "nginx-task"
  ECS_CLUSTER: "ecs-task"
  ECS_SERVICE: "nginx-task-service"

jobs:
  build:
    name: Build and Push to ECR
    runs-on: ubuntu-latest

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

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_GITHUB_ROLE }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Get version from VERSION file
        id: get-version
        run: |
          if [ -f VERSION ]; then
            VERSION=$(cat VERSION)
          else
            echo "VERSION file not found. Exiting..."
            exit 1
          fi
          echo "Current version: $VERSION"
          echo version=$VERSION >> $GITHUB_OUTPUT

      # Build and push nginx image
      - name: Build and push Nginx image
        id: build-image-nginx
        uses: docker/build-push-action@v5
        with:
          context: ./nginx
          file: ./nginx/Dockerfile
          push: true
          provenance: false
          tags: |
            ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_NGINX }}:${{ steps.get-version.outputs.version }}
            ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_NGINX }}:latest

  deploy:
    needs: build
    name: Deploy to ECS-nginx task
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_GITHUB_ROLE }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download task definition
        run: |
          aws ecs describe-task-definition \
          --task-definition ${{ env.ECS_NGINX_TASK }} \
          --query taskDefinition \
          --region ${{ env.AWS_REGION }} > task-definition.json

      - name: Get version from VERSION file
        id: get-version
        run: |
          if [ -f VERSION ]; then
            VERSION=$(cat VERSION)
          else
            echo "VERSION file not found. Exiting..."
            exit 1
          fi
          echo "Current version: $VERSION"
          echo version=$VERSION >> $GITHUB_OUTPUT

      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ env.ECR_REPOSITORY_NGINX }}
          image: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_NGINX }}:${{ steps.get-version.outputs.version }}

      - name: Deploy to ECS
        id: deploy-ecs
        uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          wait-for-service-stability: true
Enter fullscreen mode Exit fullscreen mode
  1. angular.yml
name: Angular CI/CD

on:
  push:
    paths:
      - "client/**"
  pull_request:
    paths:
      - "client/**"

  workflow_dispatch:

permissions:
  id-token: write
  contents: read

env:
  MONGO_URI: ${{ secrets.MONGO_URI }}
  MYSQL_HOST: ${{ secrets.MYSQL_HOST }}
  MYSQL_USER: ${{ secrets.MYSQL_USER }}
  MYSQL_PASS: ${{ secrets.MYSQL_PASS }}
  MYSQL_DB: ${{ secrets.MYSQL_DB }}

  AWS_REGION: ${{ secrets.AWS_REGION }}
  AWS_GITHUB_ROLE: ${{ secrets.AWS_GITHUB_ROLE }}
  ECS_PROJECT: ${{ secrets.ECS_PROJECT }}

  ECR_REPOSITORY_CLIENT: "client"
  ECR_REPOSITORY_JAVA: "javaapi"
  ECR_REPOSITORY_NODEAPI: "nodeapi"
  ECR_REPOSITORY_NGINX: "nginx"

  ECS_ANGULAR_TASK: "angular-task"
  ECS_CLUSTER: "ecs-task"
  ECS_SERVICE: "angular-task-service"

jobs:
  build-angular:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_GITHUB_ROLE }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      #Angular
      - name: Build and push Angular image
        id: build-image-angular
        uses: docker/build-push-action@v5
        with:
          context: ./client
          file: ./client/Dockerfile
          push: true
          provenance: false
          tags: |
            ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_CLIENT }}:${{ github.run_number }}
            ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_CLIENT }}:latest

  deploy:
    needs: build-
    name: Deploy to ECS-angula task
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_GITHUB_ROLE }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download task definition
        run: |
          aws ecs describe-task-definition \
          --task-definition ${{ env.ECS_ANGULAR_TASK }} \
          --query taskDefinition \
          --region ${{ env.AWS_REGION }} > task-definition.json

      - name: Get version from VERSION file
        id: get-version
        run: |
          if [ -f VERSION ]; then
            VERSION=$(cat VERSION)
          else
            echo "VERSION file not found. Exiting..."
            exit 1
          fi
          echo "Current version: $VERSION"
          echo version=$VERSION >> $GITHUB_OUTPUT

      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ env.ECR_REPOSITORY_CLIENT }}
          image: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_CLIENT }}:${{ steps.get-version.outputs.version }}

      - name: Deploy to ECS
        id: deploy-ecs
        uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          wait-for-service-stability: true
Enter fullscreen mode Exit fullscreen mode
  1. javaapi.yml
name: Java-api CI/CD

on:
  push:
    paths:
      - "javaapi/**"
  pull_request:
    paths:
      - "javaapi/**"

  workflow_dispatch:

permissions:
  id-token: write
  contents: read

env:
  MONGO_URI: ${{ secrets.MONGO_URI }}
  MYSQL_HOST: ${{ secrets.MYSQL_HOST }}
  MYSQL_USER: ${{ secrets.MYSQL_USER }}
  MYSQL_PASS: ${{ secrets.MYSQL_PASS }}
  MYSQL_DB: ${{ secrets.MYSQL_DB }}

  AWS_REGION: ${{ secrets.AWS_REGION }}
  AWS_GITHUB_ROLE: ${{ secrets.AWS_GITHUB_ROLE }}
  ECS_PROJECT: ${{ secrets.ECS_PROJECT }}

  ECR_REPOSITORY_CLIENT: "client"
  ECR_REPOSITORY_JAVA: "javaapi"
  ECR_REPOSITORY_NODEAPI: "nodeapi"
  ECR_REPOSITORY_NGINX: "nginx"

  ECS_JAVA_TASK: "java-task"
  ECS_CLUSTER: "ecs-task"
  ECS_SERVICE: "java-task-service"

jobs:
  build-javaapi:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_GITHUB_ROLE }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

        # Java API
      - name: Build and push Java image
        id: build-image-java
        uses: docker/build-push-action@v5
        with:
          push: true
          provenance: false
          tags: |
            ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_JAVA }}:${{ github.run_number }}
            ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_JAVA }}:latest

  deploy:
    needs: build-javaapi
    name: Deploy to ECS-javaapi task
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_GITHUB_ROLE }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download task definition
        run: |
          aws ecs describe-task-definition \
          --task-definition ${{ env.ECS_JAVA_TASK }} \
          --query taskDefinition \
          --region ${{ env.AWS_REGION }} > task-definition.json

      - name: Get version from VERSION file
        id: get-version
        run: |
          if [ -f VERSION ]; then
            VERSION=$(cat VERSION)
          else
            echo "VERSION file not found. Exiting..."
            exit 1
          fi
          echo "Current version: $VERSION"
          echo version=$VERSION >> $GITHUB_OUTPUT

      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ env.ECR_REPOSITORY_JAVA }}
          image: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_JAVA }}:${{ steps.get-version.outputs.version }}

      - name: Deploy to ECS
        id: deploy-ecs
        uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          wait-for-service-stability: true
Enter fullscreen mode Exit fullscreen mode
  1. nodeapi.yml
name: Node-api CI/CD

on:
  push:
    paths:
      - "nodeapi/**"
  pull_request:
    paths:
      - "nodeapi/**"

  workflow_dispatch:

permissions:
  id-token: write
  contents: read

env:
  MONGO_URI: ${{ secrets.MONGO_URI }}
  MYSQL_HOST: ${{ secrets.MYSQL_HOST }}
  MYSQL_USER: ${{ secrets.MYSQL_USER }}
  MYSQL_PASS: ${{ secrets.MYSQL_PASS }}
  MYSQL_DB: ${{ secrets.MYSQL_DB }}

  AWS_REGION: ${{ secrets.AWS_REGION }}
  AWS_GITHUB_ROLE: ${{ secrets.AWS_GITHUB_ROLE }}
  ECS_PROJECT: ${{ secrets.ECS_PROJECT }}

  ECR_REPOSITORY_CLIENT: "client"
  ECR_REPOSITORY_JAVA: "javaapi"
  ECR_REPOSITORY_NODEAPI: "nodeapi"
  ECR_REPOSITORY_NGINX: "nginx"

  ECS_NODEAPI_TASK: "node-task"
  ECS_CLUSTER: "ecs-task"
  ECS_SERVICE: "node-task-service"

jobs:
  build-nodeapi:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v4

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_GITHUB_ROLE }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

        # Node API
      - name: Build and push Node.js image
        id: build-image-node
        uses: docker/build-push-action@v5
        with:
          context: ./nodeapi
          file: ./nodeapi/Dockerfile
          push: true
          provenance: false
          tags: |
            ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_NODEAPI }}:${{ github.run_number }}
            ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_NODEAPI }}:latest

  deploy:
    needs: build-nodeapi
    name: Deploy to ECS-javaapi task
    runs-on: ubuntu-latest
    steps:
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_GITHUB_ROLE }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Login to Amazon ECR
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2

      - name: Checkout code
        uses: actions/checkout@v4

      - name: Download task definition
        run: |
          aws ecs describe-task-definition \
          --task-definition ${{ env.ECS_NODEAPI_TASK }} \
          --query taskDefinition \
          --region ${{ env.AWS_REGION }} > task-definition.json

      - name: Get version from VERSION file
        id: get-version
        run: |
          if [ -f VERSION ]; then
            VERSION=$(cat VERSION)
          else
            echo "VERSION file not found. Exiting..."
            exit 1
          fi
          echo "Current version: $VERSION"
          echo version=$VERSION >> $GITHUB_OUTPUT

      - name: Fill in the new image ID in the Amazon ECS task definition
        id: task-def
        uses: aws-actions/amazon-ecs-render-task-definition@v1
        with:
          task-definition: task-definition.json
          container-name: ${{ env.ECR_REPOSITORY_NODEAPI }}
          image: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY_NODEAPI }}:${{ steps.get-version.outputs.version }}

      - name: Deploy to ECS
        id: deploy-ecs
        uses: aws-actions/amazon-ecs-deploy-task-definition@v2
        with:
          service: ${{ env.ECS_SERVICE }}
          cluster: ${{ env.ECS_CLUSTER }}
          task-definition: ${{ steps.task-def.outputs.task-definition }}
          wait-for-service-stability: true
Enter fullscreen mode Exit fullscreen mode

Now Commit and push the project code to Github, create a repository in your github account. This will trigger Github actions to launch the different pipelines which will obviously fail because of the missing secrets and variables.

Github Secrets

On Github, navigate to the created repository in the previous steps, go to settings and check secrets and variables -> actions.
Now create repository secrets, put the values of the following as recorded when the different services where created for:

AWS_GITHUB_ROLE (the oidc role created with cloudformation)
AWS_REGION
MONGO_URI
MYSQL_DB
MYSQL_HOST
MYSQL_PASS
MYSQL_PORT
MYSQL_USER
Enter fullscreen mode Exit fullscreen mode

Image description

Re-run the failed workflows for at least the docker images be pushed to ECR

Create the task definitions

Navigate to ECS service on the console and select task definitions. Create task definitions for the different service-containers that we will be deploying.

  1. Nginx Task definition:
    Task definition family: nginx-task
    Infrastructure requirements: AWS Fargate
    container name: nginx
    Image URI: copy and paste the nginx image URI from ECR
    container port: 80
    use log collection = true
    create

  2. Angular task definition
    Task definition family: angular-task
    Infrastructure requirements: AWS Fargate
    container name: client
    Image URI: copy and paste the client image URI from ECR
    container port: 4200
    use log collection = true
    create

  3. Java task definition
    Task definition family: java-task
    Infrastructure requirements: AWS Fargate
    container name: java
    Image URI: copy and paste the java image URI from ECR
    container port: 9000
    environment variables:

    • MYSQL_PASS :
    • MYSQL_DB: (books)
    • MYSQL_HOST:
    • MYSQL_USER: root
    • MONGO_URI: use log collection = true create
  4. Node task definition
    Task definition family: node-task
    Infrastructure requirements: AWS Fargate
    container name: node
    Image URI: copy and paste the node image URI from ECR
    container port: 5000
    environment variables:

    • MONGO_URI: use log collection = true create

Create ECS Cluster

Navigate to the console and create a cluster under ECS service with the following parameters:
Cluster name: ecs-cluster
Leave the rest as defaults and create cluster.

Create ECS services

We have to now create services for each of the tasks. Go to create services and configure each with the following:

  1. Angular service
Task definition family: angular-task
revision: choose the latest
service name: angular-task-service
Compute options: Launch type
Desired tasks: 1
Service discovery: use service discovery
Configure namespace: create a new namespace
namespace name: ecs-microservice-ns
Service discovery name: client
Enter fullscreen mode Exit fullscreen mode

leave the rest as defaults and create

  1. Node Service
Task definition family: node-task
revision: choose the latest
service name: node-task-service
Compute options: Launch type
Desired tasks: 1
Service discovery: use service discovery
Configure namespace: select existing namespace
namespace name: ecs-microservice-ns
Service discovery name: nodeapi
Enter fullscreen mode Exit fullscreen mode

leave the rest as defaults and create

  1. Java Service
Task definition family: java-task
revision: choose the latest
service name: java-task-service
Compute options: Launch type
Desired tasks: 1
Service discovery: use service discovery
Configure namespace: select existing namespace
namespace name: ecs-microservice-ns
Service discovery name: javaapi
Enter fullscreen mode Exit fullscreen mode

leave the rest as defaults and create

  1. Nginx Service
Task definition family: nginx-task
revision: choose the latest
service name: nginx-task-service
Compute options: Launch type
Desired tasks: 1
Service discovery: use service discovery
Configure namespace: select existing namespace
namespace name: ecs-microservice-ns
Service discovery name: nginx
Load balancing: Use load balancing
Load balancer type: Aplication load balancer
Application Load Balancer: create a new ALB
Load balancer name: ecs-alb
listener: create new listener
target group: create a new target group
target group name: ecs-nginx-tg
Enter fullscreen mode Exit fullscreen mode

leave the rest as defaults and create

Image description

Image description

Image description

After some time, the different services will be created, check the load balancer DNS record and paste it on the browser, the app will appear as such:

Image description

The App is up and running. Congratulations !!!

Top comments (3)

Collapse
 
nevodavid profile image
Nevo David

This is the kind of guide I wish I had when I first touched ECS, thanks for breaking it all down like this.

Collapse
 
sphavix profile image
sphavix

Hi, Great article. Can you please share the link to Github source code I want to try the project as well?

Collapse
 
ndzenyuy profile image
Jones Ndzenyuy

Am happy you found it useful, Sorry for the delay in my reply, the repository github.com/Ndzenyuy/day-1-deploy_m...