Streamlined CI/CD Integration with AWS ECS

devopsadventurer

Marc Khaled

Posted on April 30, 2024

Streamlined CI/CD Integration with AWS ECS

Introduction

AWS offers a suite of developer tools to automate the software release process, making it faster and more reliable. Three key components of this suite are AWS CodeBuild, AWS CodeCommit, and AWS CodePipeline. Each tool serves a specific purpose in the CI/CD (Continuous Integration and Continuous Deployment) process, working together to streamline code updates from development to production.

AWS CodeCommit

What is it?
AWS CodeCommit is a fully managed source control service that hosts secure Git-based repositories. It enables developers to collaboratively store, manage, and version control their code in the cloud, facilitating continuous integration and delivery workflows.

Key Features:

  • Secure: Provides secure repositories, ensuring code integrity and safety.
  • Scalable: Handles large projects and integrates seamlessly with the AWS ecosystem.
  • Integration: Supports CI/CD pipelines and development processes by integrating with other AWS services like CodeBuild and CodePipeline.

AWS CodeBuild

What is it?
AWS CodeBuild is a fully managed build service that compiles source code, runs tests, and produces software packages ready to deploy. It eliminates the need for you to manage, patch, and scale your own build servers. CodeBuild scales automatically to meet peak build requests, and you pay only for the build time you consume.

Key Features:

  • Fully Managed: No servers to provision and manage. It scales automatically.
  • Continuous Scaling: Handles varying levels of build volumes automatically.
  • Integration: Easily integrates with AWS CodePipeline, allowing for the automation of the build and testing phase in the CI/CD process.

AWS CodePipeline

What is it?
AWS CodePipeline is a continuous integration and continuous delivery service for fast and reliable application and infrastructure updates. CodePipeline automates the build, test, and deploy phases of your release process every time there is a code change, based on the release model you define.

Key Features:

  • Automation: Automates the build, test, and deploy phases of your release process.
  • Modular Design: Easily integrates with third-party services like GitHub or integrates with AWS services like AWS CodeBuild and AWS CodeDeploy.
  • Fast Delivery: Enables fast and reliable application and infrastructure updates.

How They Work Together

  1. CodePipeline: This tool models and visualizes the software release process by defining a series of stages—such as source, build, and deploy—each consisting of actions.
  2. In the build stage, CodeBuild compiles the code, runs tests, builds a Docker image, and pushes it to Amazon ECR, automatically deploying the application to ECS.
  3. CodeCommit: Acts as the source control service, hosting the application's code repository and facilitating integration into the CI/CD process.

AWS Repositories

ECR

Amazon Elastic Container Registry (ECR) is a cloud service provided by AWS that allows developers to store, manage, and deploy Docker container images. It's designed to simplify the development to production workflow, offering secure, scalable, and reliable registry services. ECR integrates seamlessly with Amazon Elastic Container Service (ECS) and AWS Lambda, facilitating the easy deployment of applications on a variety of AWS services. Additionally, it supports private repositories, ensuring that container images are safely stored and shared within an organization.

Navigate to the ECR service and create the following repository:

Visibility settings Private
Repository name cicd

Image description

Image description

Image description

CodeCommit

Amazon CodeCommit is a fully managed source control service that hosts secure Git-based repositories. It enables developers to collaboratively store, manage, and version control their code in the cloud, facilitating continuous integration and delivery workflows. CodeCommit is designed to scale effortlessly, handle large projects, and integrate with AWS's ecosystem, offering a seamless experience for CI/CD pipelines and development processes. Its high availability and secure infrastructure make it an ideal choice for enterprise-level code management.

Navigate to the CodeCommit service and create repository:

Image description

Image description

Cloning the CodeCommit Repository to your Local Machine

Interacting with CodeCommit from your local machine requires the setup of:

  • an IAM user with AWSCodeCommitPowerUser permissions.
  • SSH keys configured and uploaded to AWS.

IAM Permissions Setup

AWS Identity and Access Management (IAM) is a web service that helps you securely control access to AWS resources. With IAM, you can centrally manage permissions that control which AWS resources users can access. You use IAM to control who is authenticated (signed in) and authorized (has permissions) to use resources.

Navigate to the IAM Service and select the user that is supposed to receive access to the repository.

  • Attach to the user the AWSCodeCommitPowerUser policy.

SSH Keys Setup

SSH access allows secure communication between your computer and a Git repository, like AWS CodeCommit, without using passwords. By generating SSH keys and configuring them in Git Bash, you establish a secure channel for pushing and pulling code. This method uses a private key, stored on your machine, and a public key, stored on AWS, to authenticate your actions securely.

On your local machine, create an SSH keypair

# Generates a pair of SSH keys, comprising a private key for the user's machine and a public key to share with remote systems for secure access.
ssh-keygen 
Enter fullscreen mode Exit fullscreen mode

Press enter to choose the default answer to the 3 prompts generated:

Enter file in which to save the key (/c/Users/mjk67/.ssh/id_rsa): —> Press Enter
Enter Passphrase: —> Press Enter
Enter Passphrase: —> Press Enter

Image description

Navigate to .ssh directory and print the public key content (id_rsa.pub):

cd .ssh
cat id_rsa.pub

# Below is an example of the public key content
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDbdPT7OUHS/o94u/hCoPvsYu2ImfCESZHsvZKRlqHe8nxDM3VriO8R
DznXHM92akDNxq3FtzPou49e/qf7GR5aikB8iGxyxadmjlbkDpZPaZiP0c8DSHYQngpFDIqnVWW4vusmFMh+FlvEWoSb
V3hf5ENpho4kYh9/qEKGMkZ2n6lF2Le17Q5TbdHH2PdnZlnzZ9q7REsrJ/yQXOSspRT023/dokqvWZ/23DgjtoDxIl5p
To4Jb7yjBbLm8lb1JLgBmSdcmXOlloWBm5+Fo86YUvBCsx5m3vRHHS1zsZFRbyd+NY6dQD8l1DDj8lGLoIPf9GfeJ3WD
vTV0hvsfnOnmLjmRmBu/1O1kW4Gwimqd4WgdOfedAixm8USW2JHtcbJI5ovhP9AVmoaW1kF/aX42wLhdR+NOBDLndQhh
MYBhJGXlK/uZsvMBeV8fcvCq07wcZ5z508xHHJ94EP+BysD+AcRirzRrwvd6DpHijl2c2fsf09sgNbUfly7Dcs3G/Gs=
mjk67@MJKX

Enter fullscreen mode Exit fullscreen mode

Image description

The user's profile in the IAM service contains a section called “SSH Public keys for AWS CodeCommit", under the Security Credentials tab. Copy the public key and upload it there.

Image description

Once successfully uploaded, a Key ID is generated. Copy the SSH Key ID APKAWO3HCQZE7WM5OFNA

Image description

In the Bash emulator on your local machine, run the following commands to create a config file in the ~/.ssh directory:

nano ~/.ssh/config
Enter fullscreen mode Exit fullscreen mode

Add the following lines to the file, where the value for User is the SSH key ID copied earlier, and the value for IdentityFile is the path to and name of the private key file:

Host git-codecommit.*.amazonaws.com
  User APKAWO3HCQZEYAJAVT3R
  IdentityFile /c/Users/mjk67/.ssh/id_rsa
Enter fullscreen mode Exit fullscreen mode

Image description

Finally, clone the repository to your machine.

git clone ssh://git-codecommit.eu-west-1.amazonaws.com/v1/repos/CICD
Enter fullscreen mode Exit fullscreen mode

Image description

Image description

NodeJS

Node.js is an open-source, cross-platform JavaScript runtime environment that enables developers to execute JavaScript code server-side. Built on Chrome's V8 JavaScript engine, Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, ideal for building scalable network applications. It comes with a vast ecosystem of libraries and tools, facilitated through the npm package manager, making development fast and flexible. Node.js shines in real-time applications, microservices architectures, and command-line tools, among other uses.

Navigate to any code editor and create a NodeJS app with the following files:

App.js

This is the source for a basic Express.js web server:

  • Imports the Express.js library.
  • Initializes an Express application.
  • Sets up a route that responds to GET requests on the root URL (/) with "Hello, World!".
  • Starts the server on a specified port (environment variable PORT or 80 by default), listening for incoming requests.
const express = require('express');
const app = express();
const PORT = process.env.PORT || 80;

app.get('/', (req, res) => {
  res.send('Hello, World!');
});

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Enter fullscreen mode Exit fullscreen mode

Package.json

This file describes your Node.js application and its dependencies:

  • Defines the app name, version, and description.
  • Specifies the entry point (app.js) and the command to start the application (npm start which executes node app.js).
  • Lists the dependencies required by the application, in this case, Express.js.
{
  "name": "hello-world-app",
  "version": "1.0.0",
  "description": "A simple Node.js app",
  "main": "app.js",
  "scripts": {
    "start": "node app.js"
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}

Enter fullscreen mode Exit fullscreen mode

Dockerfile

This Dockerfile outlines the steps to containerize your Node.js application:

  • It starts with a Node.js 14 base image.
  • Sets the working directory inside the container.
  • Copies package.json and package-lock.json (if available) to the container.
  • Runs npm install to install dependencies.
  • Copies the rest of the application source code into the container.
  • Exposes port 80 for network access.
  • Specifies the command to start the app (node app.js).
FROM node:14
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 80
CMD ["node", "app.js"]
Enter fullscreen mode Exit fullscreen mode

buildspec.yml

This file is used by AWS CodeBuild to define the build process:

  • It logs into ECR (Elastic Container Registry) to enable Docker to push images.
  • Builds a Docker image named hello-world-app and tags it as latest.
  • Pushes the image to the specified ECR repository URI.
  • Updates and stabilizes ECS service.
version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin 444208416329.dkr.ecr.eu-west-1.amazonaws.com/cicd

  build:
    commands:
      - echo Building the Docker image...
      - docker build -t hello-world-app .
      - docker tag hello-world-app:latest 444208416329.dkr.ecr.eu-west-1.amazonaws.com/cicd
      - echo Pushing the Docker image...
      - docker push 444208416329.dkr.ecr.eu-west-1.amazonaws.com/cicd

  post_build:
    commands:
      - bash -c "if [ \"$CODEBUILD_BUILD_SUCCEEDING\" == \"0\" ]; then exit 1; fi"
      # Update ECS service
      - aws ecs update-service --region eu-west-1 --cluster CICD-ECS-Cluster --service NodeJs-Service-3 --force-new-deployment
      # Wait for the service to be stable
      - aws ecs wait services-stable --region eu-west-1 --cluster CICD-ECS-Cluster --services NodeJs-Service-3
Enter fullscreen mode Exit fullscreen mode

Pushing the code to the CodeCommit Repository

Copy the previous code into the cloned CICD Repository

Image description

Image description

Image description

Image description

Note: Make sure to Ctrl+S

Execute the following commands in their respective order to push the to the CICD CodeCommit Repository

#Staging Changes
git add .
#Committing Changes
git commit -m "Initial commit with project files"
#Pushing to CodeCommit
git push
Enter fullscreen mode Exit fullscreen mode

Image description

To validate the Push we will check the CodeCommit Repository

Image description

CodeBuild

Amazon CodeBuild is a fully managed build service that compiles source code, runs tests, and produces software packages that are ready to deploy. With CodeBuild, there's no need to provision, manage, or scale your own build servers, as it scales continuously and processes multiple builds concurrently. It integrates with other AWS services like CodeCommit, CodeDeploy, and CodePipeline for an end-to-end continuous integration and delivery (CI/CD) experience. Moreover, CodeBuild is cost-effective, charging by the minute for the compute resources used during the build process.

Navigate to the CodeBuild service and Create a project with the following Parameters:

Project name CodeBuild-CICD
Source Provider AWS CodeCommit
Repository CICD
Reference type Branch
Branch Master
Provisioning mode On-demand
Environment image Managed image
Compute EC2
Operating system Ubuntu
Runtime(s) Standard
Image aws/codebuild/standard:7.0
Image version Always user the lastest image fro this runtime version
Service role New Service Role
Role name codebuild-CodeBuild-CICD-service-role
Build specifications Use a buildspec file
Buildspec name buildspec.yml

Image description

Image description

Image description

Image description

Image description

Now click on Start Build

[Container] 2024/04/10 21:42:11.101664 Running on CodeBuild On-demand
[Container] 2024/04/10 21:42:11.101677 Waiting for agent ping
[Container] 2024/04/10 21:42:11.303090 Waiting for DOWNLOAD_SOURCE
[Container] 2024/04/10 21:42:17.760602 Phase is DOWNLOAD_SOURCE
[Container] 2024/04/10 21:42:17.762056 CODEBUILD_SRC_DIR=/codebuild/output/src135744690/src/git-codecommit.eu-west-1.amazonaws.com/v1/repos/CICD
[Container] 2024/04/10 21:42:17.762497 YAML location is /codebuild/output/src135744690/src/git-codecommit.eu-west-1.amazonaws.com/v1/repos/CICD/buildspec.yml
[Container] 2024/04/10 21:42:17.764072 Not setting HTTP client timeout for source type codecommit
[Container] 2024/04/10 21:42:17.764175 Processing environment variables
[Container] 2024/04/10 21:42:17.906865 No runtime version selected in buildspec.
[Container] 2024/04/10 21:42:17.951330 Moving to directory /codebuild/output/src135744690/src/git-codecommit.eu-west-1.amazonaws.com/v1/repos/CICD
[Container] 2024/04/10 21:42:17.952931 Unable to initialize cache download: no paths specified to be cached
[Container] 2024/04/10 21:42:17.999724 Configuring ssm agent with target id: codebuild:3f186abc-8078-4feb-b514-6577bf544cb1
[Container] 2024/04/10 21:42:18.019828 Successfully updated ssm agent configuration
[Container] 2024/04/10 21:42:18.020220 Registering with agent
[Container] 2024/04/10 21:42:18.055085 Phases found in YAML: 3
[Container] 2024/04/10 21:42:18.055121  BUILD: 3 commands
[Container] 2024/04/10 21:42:18.055127  POST_BUILD: 2 commands
[Container] 2024/04/10 21:42:18.055130  PRE_BUILD: 2 commands
[Container] 2024/04/10 21:42:18.055469 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
[Container] 2024/04/10 21:42:18.055484 Phase context status code:  Message: 
[Container] 2024/04/10 21:42:18.152405 Entering phase INSTALL
[Container] 2024/04/10 21:42:18.156311 Phase complete: INSTALL State: SUCCEEDED
[Container] 2024/04/10 21:42:18.156336 Phase context status code:  Message: 
[Container] 2024/04/10 21:42:18.185686 Entering phase PRE_BUILD
[Container] 2024/04/10 21:42:18.186330 Running command echo Logging in to Amazon ECR...
Logging in to Amazon ECR...

[Container] 2024/04/10 21:42:18.191333 Running command aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin 444208416329.dkr.ecr.eu-west-1.amazonaws.com/cicd
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

[Container] 2024/04/10 21:42:30.642947 Phase complete: PRE_BUILD State: SUCCEEDED
[Container] 2024/04/10 21:42:30.642968 Phase context status code:  Message: 
[Container] 2024/04/10 21:42:30.675019 Entering phase BUILD
[Container] 2024/04/10 21:42:30.675570 Running command echo Building the Docker image...
Building the Docker image...

[Container] 2024/04/10 21:42:30.680678 Running command docker build -t hello-world-app .
#0 building with "default" instance using docker driver

#1 [internal] load build definition from Dockerfile
#1 transferring dockerfile: 150B done
#1 DONE 0.0s

#2 [internal] load .dockerignore
#2 transferring context: 2B done
#2 DONE 0.0s

#3 [internal] load metadata for docker.io/library/node:14
#3 DONE 1.0s

#4 [internal] load build context
#4 transferring context: 33.08kB done
#4 DONE 0.0s

#5 [1/5] FROM docker.io/library/node:14@sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa
#5 resolve docker.io/library/node:14@sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa 0.0s done
#5 sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 0B / 50.45MB 0.1s
#5 sha256:b253aeafeaa7e0671bb60008df01de101a38a045ff7bc656e3b0fbfc7c05cca5 0B / 7.86MB 0.1s
#5 sha256:3d2201bd995cccf12851a50820de03d34a17011dcbb9ac9fdf3a50c952cbb131 0B / 10.00MB 0.1s
#5 sha256:a158d3b9b4e3fa813fa6c8c590b8f0a860e015ad4e59bbce5744d2f6fd8461aa 776B / 776B done
#5 sha256:2cafa3fbb0b6529ee4726b4f599ec27ee557ea3dea7019182323b3779959927f 2.21kB / 2.21kB done
#5 sha256:1d12470fa662a2a5cb50378dcdc8ea228c1735747db410bbefb8e2d9144b5452 7.51kB / 7.51kB done
#5 sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 15.73MB / 50.45MB 0.4s
#5 sha256:b253aeafeaa7e0671bb60008df01de101a38a045ff7bc656e3b0fbfc7c05cca5 7.86MB / 7.86MB 0.4s done
#5 sha256:3d2201bd995cccf12851a50820de03d34a17011dcbb9ac9fdf3a50c952cbb131 9.44MB / 10.00MB 0.4s
#5 sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 20.97MB / 50.45MB 0.5s
#5 sha256:3d2201bd995cccf12851a50820de03d34a17011dcbb9ac9fdf3a50c952cbb131 10.00MB / 10.00MB 0.4s done
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 0B / 191.85MB 0.5s
#5 sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 0B / 51.88MB 0.5s
#5 sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 25.84MB / 50.45MB 0.6s
#5 sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 11.53MB / 51.88MB 0.6s
#5 sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 31.46MB / 50.45MB 0.7s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 10.49MB / 191.85MB 0.7s
#5 sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 19.92MB / 51.88MB 0.7s
#5 sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 39.85MB / 50.45MB 0.8s
#5 sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 26.21MB / 51.88MB 0.8s
#5 sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 50.45MB / 50.45MB 1.0s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 35.92MB / 191.85MB 1.0s
#5 sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 48.23MB / 51.88MB 1.0s
#5 sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 50.45MB / 50.45MB 1.0s done
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 46.14MB / 191.85MB 1.1s
#5 sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 51.88MB / 51.88MB 1.1s
#5 sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 51.88MB / 51.88MB 1.1s done
#5 extracting sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 0.1s
#5 sha256:5f32ed3c3f278edda4fc571c880b5277355a29ae8f52b52cdf865f058378a590 0B / 35.24MB 1.2s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 65.01MB / 191.85MB 1.4s
#5 sha256:5f32ed3c3f278edda4fc571c880b5277355a29ae8f52b52cdf865f058378a590 18.87MB / 35.24MB 1.4s
#5 sha256:6f51ee005deac0d99898e41b8ce60ebf250ebe1a31a0b03f613aec6bbc9b83d8 4.19kB / 4.19kB 1.3s done
#5 sha256:0c8cc2f24a4dcb64e602e086fc9446b0a541e8acd9ad72d2e90df3ba22f158b3 0B / 2.29MB 1.4s
#5 sha256:5f32ed3c3f278edda4fc571c880b5277355a29ae8f52b52cdf865f058378a590 25.17MB / 35.24MB 1.5s
#5 sha256:0c8cc2f24a4dcb64e602e086fc9446b0a541e8acd9ad72d2e90df3ba22f158b3 2.29MB / 2.29MB 1.5s done
#5 sha256:0d27a8e861329007574c6766fba946d48e20d2c8e964e873de352603f22c4ceb 0B / 450B 1.5s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 87.03MB / 191.85MB 1.7s
#5 sha256:5f32ed3c3f278edda4fc571c880b5277355a29ae8f52b52cdf865f058378a590 35.24MB / 35.24MB 1.7s done
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 98.57MB / 191.85MB 1.9s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 110.10MB / 191.85MB 2.1s
#5 sha256:0d27a8e861329007574c6766fba946d48e20d2c8e964e873de352603f22c4ceb 450B / 450B 2.0s done
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 139.46MB / 191.85MB 2.4s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 153.09MB / 191.85MB 2.6s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 163.58MB / 191.85MB 2.8s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 174.06MB / 191.85MB 2.9s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 191.85MB / 191.85MB 3.1s
#5 sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 191.85MB / 191.85MB 3.4s done
#5 extracting sha256:2ff1d7c41c74a25258bfa6f0b8adb0a727f84518f55f65ca845ebc747976c408 2.6s done
#5 extracting sha256:b253aeafeaa7e0671bb60008df01de101a38a045ff7bc656e3b0fbfc7c05cca5
#5 extracting sha256:b253aeafeaa7e0671bb60008df01de101a38a045ff7bc656e3b0fbfc7c05cca5 0.3s done
#5 extracting sha256:3d2201bd995cccf12851a50820de03d34a17011dcbb9ac9fdf3a50c952cbb131 0.1s
#5 extracting sha256:3d2201bd995cccf12851a50820de03d34a17011dcbb9ac9fdf3a50c952cbb131 0.2s done
#5 extracting sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 0.1s
#5 extracting sha256:1de76e268b103d05fa8960e0f77951ff54b912b63429c34f5d6adfd09f5f9ee2 2.3s done
#5 extracting sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 0.1s
#5 extracting sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 5.2s
#5 extracting sha256:d9a8df5894511ce28a05e2925a75e8a4acbd0634c39ad734fdfba8e23d1b1569 5.5s done
#5 extracting sha256:6f51ee005deac0d99898e41b8ce60ebf250ebe1a31a0b03f613aec6bbc9b83d8
#5 extracting sha256:6f51ee005deac0d99898e41b8ce60ebf250ebe1a31a0b03f613aec6bbc9b83d8 done
#5 extracting sha256:5f32ed3c3f278edda4fc571c880b5277355a29ae8f52b52cdf865f058378a590
#5 extracting sha256:5f32ed3c3f278edda4fc571c880b5277355a29ae8f52b52cdf865f058378a590 1.3s done
#5 extracting sha256:0c8cc2f24a4dcb64e602e086fc9446b0a541e8acd9ad72d2e90df3ba22f158b3 0.1s
#5 extracting sha256:0c8cc2f24a4dcb64e602e086fc9446b0a541e8acd9ad72d2e90df3ba22f158b3 0.1s done
#5 extracting sha256:0d27a8e861329007574c6766fba946d48e20d2c8e964e873de352603f22c4ceb done
#5 DONE 14.9s

#6 [2/5] WORKDIR /usr/src/app
#6 DONE 0.5s

#7 [3/5] COPY package*.json ./
#7 DONE 0.1s

#8 [4/5] RUN npm install
#8 0.663 npm WARN saveError ENOENT: no such file or directory, open '/usr/src/app/package.json'
#8 0.667 npm notice created a lockfile as package-lock.json. You should commit this file.
#8 0.670 npm WARN enoent ENOENT: no such file or directory, open '/usr/src/app/package.json'
#8 0.675 npm WARN app No description
#8 0.680 npm WARN app No repository field.
#8 0.685 npm WARN app No README data
#8 0.692 npm WARN app No license field.
#8 0.693 
#8 0.814 up to date in 0.209s
#8 0.815 found 0 vulnerabilities
#8 0.815 
#8 DONE 0.9s

#9 [5/5] COPY . .
#9 DONE 0.1s

#10 exporting to image
#10 exporting layers 0.0s done
#10 writing image sha256:b3b3c6f2da0cb1cd7b84321e4c3a5757b5c65ab47f60847f3f1205b4abbd0c73 done
#10 naming to docker.io/library/hello-world-app done
#10 DONE 0.1s

[Container] 2024/04/10 21:42:48.452444 Running command docker tag hello-world-app:latest 444208416329.dkr.ecr.eu-west-1.amazonaws.com/cicd

[Container] 2024/04/10 21:42:48.473176 Phase complete: BUILD State: SUCCEEDED
[Container] 2024/04/10 21:42:48.473201 Phase context status code:  Message: 
[Container] 2024/04/10 21:42:48.508299 Entering phase POST_BUILD
[Container] 2024/04/10 21:42:48.508925 Running command echo Pushing the Docker image...
Pushing the Docker image...

[Container] 2024/04/10 21:42:48.514184 Running command docker push 444208416329.dkr.ecr.eu-west-1.amazonaws.com/cicd
Using default tag: latest
The push refers to repository [444208416329.dkr.ecr.eu-west-1.amazonaws.com/cicd]
9ce5dc06c6ed: Preparing
f8056483e6c0: Preparing
5f70bf18a086: Preparing
d3e13bd793d6: Preparing
0d5f5a015e5d: Preparing
3c777d951de2: Preparing
f8a91dd5fc84: Preparing
cb81227abde5: Preparing
e01a454893a9: Preparing
c45660adde37: Preparing
fe0fb3ab4a0f: Preparing
f1186e5061f2: Preparing
b2dba7477754: Preparing
3c777d951de2: Waiting
f8a91dd5fc84: Waiting
cb81227abde5: Waiting
e01a454893a9: Waiting
c45660adde37: Waiting
fe0fb3ab4a0f: Waiting
f1186e5061f2: Waiting
b2dba7477754: Waiting
f8056483e6c0: Pushed
5f70bf18a086: Pushed
9ce5dc06c6ed: Pushed
d3e13bd793d6: Pushed
0d5f5a015e5d: Pushed
cb81227abde5: Pushed
3c777d951de2: Pushed
fe0fb3ab4a0f: Pushed
f1186e5061f2: Pushed
f8a91dd5fc84: Pushed
b2dba7477754: Pushed
c45660adde37: Pushed
e01a454893a9: Pushed
latest: digest: sha256:82afd89fcd59b28114b657c3f8bd89e7f7409b746e7fff9a252350b85611e41e size: 3044

[Container] 2024/04/10 21:43:19.682208 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2024/04/10 21:43:19.682231 Phase context status code:  Message: 
[Container] 2024/04/10 21:43:19.725915 Set report auto-discover timeout to 5 seconds
[Container] 2024/04/10 21:43:19.726000 Expanding base directory path:  .
[Container] 2024/04/10 21:43:19.727531 Assembling file list
[Container] 2024/04/10 21:43:19.727543 Expanding .
[Container] 2024/04/10 21:43:19.729097 Expanding file paths for base directory .
[Container] 2024/04/10 21:43:19.729109 Assembling file list
[Container] 2024/04/10 21:43:19.729113 Expanding **/*
[Container] 2024/04/10 21:43:19.731389 Found 1 file(s)
[Container] 2024/04/10 21:43:19.731452 Report auto-discover file discovery took 0.005537 seconds
[Container] 2024/04/10 21:43:19.731980 Phase complete: UPLOAD_ARTIFACTS State: SUCCEEDED
[Container] 2024/04/10 21:43:19.731993 Phase context status code:  Message:
Enter fullscreen mode Exit fullscreen mode

To validate the build , if we check the ECR Repository the Docker Image should be present

Image description

ECS

Amazon ECS (Elastic Container Service) is a scalable, high-performance container orchestration service that supports Docker containers and allows for the easy running and management of containerized applications on AWS. ECS eliminates the need for you to install and operate your own container orchestration software, manage and scale a cluster of virtual machines, or schedule containers on those virtual machines. With simple API calls, you can launch and stop Docker-enabled applications, query the complete state of your cluster, and access many familiar features like security groups, load balancers, Amazon EBS volumes, and IAM roles. ECS can be used to host a variety of application architectures, from simple web apps to complex microservices. It integrates deeply with other AWS services, such as IAM for security and CloudWatch for logging and monitoring, providing a robust solution for deploying and managing containers at scale.

Navigate to the ECS Service and create a cluster with the following paramters:

Cluster name CICD-ECS-Cluster
Infrastructure AWS Fargate (serverless)
Monitoring Use Container Insights

Image description

Image description

Task Definition

Task Definitions in Amazon ECS are blueprints for your applications that describe how a container (or multiple containers) should run on ECS. They specify various parameters for the container, such as the Docker image to use, the required CPU and memory, the ports to open, and the environment variables to set. Task Definitions also support defining the roles, network configurations, and volumes for your containers, making it a key component in deploying scalable and flexible containerized applications on AWS.

Navigate to the Task Definition section in the ECS service and create a task definition with the following paramters:

Task Definition Family CICD-TD
Infrastructure Requirements Leave it as is
Container-1 Name Nodejs
Image URI http://444208416329.dkr.ecr.eu-west-1.amazonaws.com/cicd
Essential Container Yes
Port Mappings 80 (TCP) nodejs-port (HTTP)

Image description

Image description

Image description

Image description

Image description

ECS Cluster Service

The Amazon ECS Cluster Service is a key component within the ECS ecosystem that manages the orchestration and lifecycle of tasks and services. When you define a service in ECS, you set a desired number of instances of a task definition that should be running concurrently. The ECS service scheduler ensures that the specified number of tasks are always running and rebalances tasks across your cluster to meet the desired state. This includes handling task failures by restarting failed tasks and integrating with Elastic Load Balancing to distribute traffic to the tasks. The service is ideal for long-running applications and services, and it supports both rolling updates and blue/green deployments to enable you to release new versions with minimal impact.

Navigate to the CICD-ECS-Cluster and create a service with the following parameters:

Task definition CICD-TD
Service name NodeJs-Service
Desired tasks 1
VPC Default
Subnet eu-west-1a
Security Group Create New Security Group
Security group name CICD-SG
Inbound rules HTTP

Image description

Image description

Image description

Navigate to : NodeJs-Service-3 —> Tasks —> b8fab0bc17174ecca37aea8f0946bac0 —>Networking

Image description

Copy the Public IP

Image description

Hit the IP on your local web browser

Image description

CodePipeline

Amazon CodePipeline is a continuous integration and continuous delivery (CI/CD) service that automates the build, test, and deployment phases of your release process. It models complex workflows with multiple stages, actions, and transitions between these stages, facilitating rapid and reliable application updates. CodePipeline integrates with pre-built plugins and custom tooling, allowing you to orchestrate every step from code to deployment. This service is designed to enable developers to consistently deliver features and updates while maintaining high quality and speed.

Navigate to the CodePipeline service and create a Pipeline with the following parameters:

Pipeline name CICD-NodeJs-Pipeline
Pipeline type V2
Execution mode Queued (Pipeline type V2 required)
Service role New service role
Role name AWSCodePipelineServiceRole-eu-west-1-CICD-NodeJs-Pipeline
Source provider AWS CodeCommit
Repository name CICD
Branch Name master
Build provider AWS CodeBuild
Project name CICD-CodeBuild
Deploy Skip Deploy Stage

Note: Make sure that the CodeBuild Role has ECS Permissions

Image description

Image description

Image description

Image description

Pipeline Testing

To ensure the pipeline's functionality is intact, we will modify the output from Hello World to Hello Universe and commit this updated code to the CodeCommit repository. Upon detecting the update, CloudWatch will automatically initiate the pipeline, which, in turn, will execute the deployment process to update the ECS service with these new changes. This automated sequence demonstrates the seamless integration of AWS services in facilitating continuous delivery and deployment.

Image description

Image description

Image description

Conclusion

AWS's suite of CI/CD tools offers a comprehensive solution for software release processes, from code compilation to deployment. By leveraging CodeBuild, CodeCommit and CodePipeline, developers can automate the release cycle, ensuring faster, more reliable releases, reducing manual effort, and minimizing the risk of human error

💖 💪 🙅 🚩
devopsadventurer
Marc Khaled

Posted on April 30, 2024

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related