Creating a CI/CD Jenkins Pipeline that runs automatically the Production Stage via Amazon ECS- Fargate, and Amazon ECR.

Creating a CI/CD Jenkins Pipeline that runs automatically the Production Stage via Amazon ECS- Fargate, and Amazon ECR.

In this article, we will create a CI/CD (continuous integration/continuous delivery and deployment) production pipeline, using Jenkins as a CI/CD automation software, GitHub as a source code management, Amazon ECR(Elastic Container Registry) as an image (artifact) repository, Docker as an image builder, Amazon ECS(Elastic Container Service)-Fargate as a container orchestration service.

When running the pipeline, we’ll use the Nodejs application as an artifact.

1. Preparing a necessary environment

a. Create a public GitHub repository.

b. Add a Nodejs application to the public GitHub repository for testing.

c. Install the Jenkins server.

d. configure AWS CLI on our instance

e. Install necessary plugins in Jenkins (Docker, Docker-pipeline, Amazon ECR Plugin).

f. Set up AWS Credentials in Jenkins so that it facilitates the Docker push to the ECR repository.

  • go to the manage Jenkins, Credentials, system, Global Credentials, kind
username with password
  • scope
Global (jenkins,nodes, items, all child items. etc)
  • username
username of AWS Account
  • password
password of AWS Account
  • ID
AWS-ID

2. Creating role: “AmazonEC2ContainerRegistryFullAccess**” for ECR**

Create IAM Role for ECR, Here, In this step we need to create IAM role with below permission Attach Permission Policies: AmazonEC2ContainerRegistryFullAccess and attach IAM Role with our running instance

  • Create repository in Amazon ECR

3. Create a Job with a pipeline

  • put to your GitHub repository URL in the GitHub project

  • Setting environment

      pipeline{
          agent any
          environment {
              AWS_ACCOUNT_ID= "***********"
              AWS_DEFAULT_REGION= "ap-south-1"
              IMAGE_REPO_NAME="project-02"
              IMAGE_TAG="latest"
              REPOSITORY_URI="public.ecr.aws/b4u1h2a4/project-02"
    
          }
      }
    
    • Code for logging into AWS ECR
    stages{
            stage ("logging into AWS ECR") {
                steps{
                    script{
                        sh """aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"""
                    }
                }
            }
        }
  • Code for clone code from github repository
pipeline{
    agent any
    stages{
        stage ("Code Clone"){
            steps{
                echo "Clone code from Github repo"
                git url:"<https://github.com/thesamiksha/node-todo-cicd.git>", branch:"master"
            }
        }
    }
}
  • Code for build image

      stage ("build") {
                  steps{
                      echo "building docker image"
                      script{
                          dockerImage = docker.build "${IMAGE_REPO_NAME}:${IMAGE_TAG}"
                      }
                  }
              }
    
    • code for pushing docker image into AWS ECR
    stage("pushing to ECR") {
                steps{
                    echo "pushing docker image into AWS ECR"
                    script{
                        sh """ docker tag ${IMAGE_REPO_NAME}:${IMAGE_TAG} ${REPOSITORY_URI}:$IMAGE_TAG"""
                        sh """ docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_REPO_NAME}:${IMAGE_TAG}"""
                    }
                }
            }
  • Full stage code for login into ECR, Clone code, Build image, Pushing into ECR
    pipeline{
    agent any
        environment {
            AWS_ACCOUNT_ID= "***********"
            AWS_DEFAULT_REGION= "ap-south-1"
            IMAGE_REPO_NAME="project"
            IMAGE_TAG="latest"
            REPOSITORY_URI="${AWS_ACCOUNT_ID}.dkr.ecr.ap-south-1.amazonaws.com/project"

        }
        stages{
            stage ("logging into AWS ECR") {
                steps{
                    echo "logging into AWS ECR"
                    script{
                        sh """aws ecr get-login-password --region ${AWS_DEFAULT_REGION} | docker login --username AWS --password-stdin ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com"""
                    }
                }
            }
            stage ("clone code"){
                steps{
                    echo "clonning code from git-hub"
                    git url:"<https://github.com/thesamiksha/node-todo-cicd.git>", branch:"master"
                }
            }
            stage ("build") {
                steps{
                    echo "building docker image"
                    script{
                        dockerImage = docker.build "${IMAGE_REPO_NAME}:${IMAGE_TAG}"
                    }
                }
            }
            stage("pushing to ECR") {
                steps{
                    echo "pushing docker image into AWS ECR"
                    script{
                        sh """ docker tag ${IMAGE_REPO_NAME}:${IMAGE_TAG} ${REPOSITORY_URI}:$IMAGE_TAG"""
                        sh """ docker push ${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com/${IMAGE_REPO_NAME}:${IMAGE_TAG}"""
                    }
                }
            }

        }
    }

4. Deploy to the ECS cluster

An ECS (Elastic Container Service) cluster is a container management service provided by Amazon Web Services (AWS). It is designed to simplify the deployment and management of containerized applications using Docker containers.

  • Creating an ECS cluster using fargate

Create an ECS cluster with a unique name.

  • Creating a task definition file

  • Task definition

It is a blueprint or configuration that describes how a containerized application should run. It defines various parameters and settings for one or more containers that are part of a task. It is used to launch and run tasks within an ECS cluster.

Create a task definition file and name (project-02-task)

  • Creating role: “ecsTaskExecutionRole” for ECS

  • Here, In this step, we need to create a role with the below permission Attach Permission Policies: ecsTaskExecutionRole

Sign in to the AWS Management Console and open the IAM console at https://console.aws.amazon.com/iam/.

In the navigation pane of the IAM console, choose “Roles”, and click on the “Create role” button

  • In Image URI we have to paste our (ECR private repository)

  • Our Node-todo app is running in port 8000 so, in our case container port is 8000, You can customize with our own

  • leave everything as default and create

Create a service

Replace the subnets with your default subnet id and Replace the security group name with the Jenkins server security groups id. (Control and make sure that the 8000 port is open in Jenkins server security groups.)

  • Desire task

This specifies how many instances of a task should be running at any given time to meet your application's requirements for scalability and availability.

Finally, Our service has been successfully deployed.

  • Code for deploying our node-app to the server

    
      stage("deploy"){
                  steps{
                      echo " deploying from ecs fragate"
                      script{
                          def ecsClusterName = "project-02-cluster"
                          def ecsServiceName = "project-02-service"
                          sh "aws ecs update-service --cluster ${ecsClusterName} --service ${ecsServiceName} --force-new-deployment"
                      }
                  }
              }
    

We can see that it works for our application by pasting the public IP of the container into our web browser. Note: Don’t forget to add 8000 (port number).