{"id":3816,"date":"2022-04-19T15:20:34","date_gmt":"2022-04-19T08:20:34","guid":{"rendered":"http:\/\/vticloud.io\/?p=3816"},"modified":"2022-05-06T16:31:47","modified_gmt":"2022-05-06T09:31:47","slug":"3816-2","status":"publish","type":"post","link":"https:\/\/vticloud.io\/en\/3816-2\/","title":{"rendered":"CI CD Docker: How to create a CI CD Pipeline with Jenkins, containers and Amazon ECS"},"content":{"rendered":"<p><\/p>\n<p style=\"text-align: justify;\">If you\u2019re still\u00a0building and delivering your software applications the traditional way then you are missing out on a major innovation in the Software Development Process or Software Development Life Cycle. To show you what I\u2019m talking about, in this article I will share \u201cHow to create a CI CD Pipeline with Jenkins, Containers and Amazon ECS\u201d that deploys your application and overcomes the limitations of the traditional software delivery model. This innovation greatly affects deadlines, time to market, quality of the product, etc. I will take you through the whole step-by-step process of setting up a CI CD Docker pipeline for a sample Nodejs application.<\/p>\n<h3 id=\"h-table-of-contents\" class=\"has-black-color has-text-color\" style=\"text-align: justify;\">Table of contents<\/h3>\n<ul class=\"has-black-color has-medium-font-size has-text-color\" style=\"text-align: justify;\">\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-ci-cd-docker-tool-stack\"><span style=\"color: #000000;\">CI CD Docker Tool Stack<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-architecture\"><span style=\"color: #000000;\">Architecture<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-ci-cd-workflow-and-phases\"><span style=\"color: #000000;\">CI CD workflow and phases<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-deployment-strategy\"><span style=\"color: #000000;\">Deployment strategy<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-dockerize-node-js-app\"><span style=\"color: #000000;\">Dockerize Node.js app<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-setup-github-repositories\"><span style=\"color: #000000;\">Setup Github Repositories<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-setup-the-aws-infrastructure\"><span style=\"color: #000000;\">Setup the AWS Infrastructure<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-setup-jenkins-on-the-ec2-instance\"><span style=\"color: #000000;\">Setup Jenkins on the EC2 Instance<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-configure-the-jenkins-server\"><span style=\"color: #000000;\">Configure the Jenkins Server<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-deploy-the-nodejs-application-to-the-ecs-cluster\"><span style=\"color: #000000;\">Deploy the Nodejs Application to the ECS Cluster<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-cleanup-the-resources-we-created\"><span style=\"color: #000000;\">Cleanup the resources we created<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-summary\"><span style=\"color: #000000;\">Summary<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-conclusion\"><span style=\"color: #000000;\">Conclusion<\/span><\/a><\/li>\n<li><a href=\"https:\/\/www.clickittech.com\/devops\/ci-cd-docker\/#h-faqs\"><span style=\"color: #000000;\">FAQs<\/span><\/a><\/li>\n<\/ul>\n<p style=\"text-align: justify;\">A CI CD Pipeline or Continuous Integration Continuous Delivery Pipeline is a set of instructions to automate the process of Software tests, builds, and deployments. Here are a few benefits of implementing CI CD in your organization.<\/p>\n<ol style=\"text-align: justify;\">\n<li><strong>Smaller Code Change<\/strong><br \/>\nThe ability of CI CD Pipelines to allow the integration of a small piece of code at a time helps developers to recognize any potential problem before too much work is completed.<\/li>\n<li><strong>Faster Delivery<\/strong><br \/>\nMultiple daily releases or continual releases can be made a reality using CI CD Pipelines.<\/li>\n<li><strong>Observability<\/strong><br \/>\nHaving automation in place that generates extensive logs in each stage of the development process helps to understand if something goes wrong.<\/li>\n<li><strong>Easier Rollbacks<\/strong><br \/>\nThere are chances that the code that has been deployed may have issues. In such cases, it is very crucial to get back to the previous working release as soon as possible. One of the biggest advantages of using the CI CD Pipelines is that you can quickly and easily roll back to the previous working release.<\/li>\n<li><strong>Reduce Costs<br \/>\n<\/strong>Having automation in place for repetitive tasks frees up the Developer and Operation guys\u2019 time that could be spent on Product Development.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">These are just a few benefits of having CI CD Pipelines for builds and deployments. On this video you can continue learning the CI CD benefits and why use a CI CD in place.<\/p>\n<p style=\"text-align: justify;\">Now, before we proceed with the steps to set up a CI CD Pipeline with Jenkins, Containers, and Amazon ECS, let\u2019s see in short what tools and technologies we will be using.<\/p>\n<h2 id=\"h-ci-cd-docker-tool-stack\" style=\"text-align: justify;\">CI CD Docker Tool Stack<\/h2>\n<ol style=\"text-align: justify;\">\n<li><strong>Github<br \/>\n<\/strong>It is a web-based application or a cloud-based service where people or developers collaborate, store and manage their application code using Git. We will create and store our sample Nodejs application code here.<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li><strong>AWS EC2 Instance<br \/>\n<\/strong>AWS EC2 is an Elastic Computer Service provided by Amazon Web Services used to create Virtual Machines or Virtual Instances on AWS Cloud. We will create an EC2 instance and install Jenkins and other dependencies in it.<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li><strong>Java<br \/>\n<\/strong>This will be required to run Jenkins Server.<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li><strong>AWS CLI<br \/>\n<\/strong>aws-cli i.e AWS Command Line Interface is a command-line tool used to manage AWS Services using commands. We will be using it to manage AWS ECS Task and ECS Service.<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"5\">\n<li><strong>Nodejs and Npm<br \/>\n<\/strong>Nodejs is a back-end JavaScript runtime environment and Npm is a package manager for Node. We will be creating a CI CD Docker Pipeline for the Nodejs application.<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"6\">\n<li><strong>Docker<br \/>\n<\/strong>Docker is an open-source containerization platform used for developing, shipping, and running applications. We will use it to build Docker Images of our sample Nodejs application and push\/pull them to\/from AWS ECR.<strong><br \/>\n<\/strong><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"7\">\n<li><strong>Jenkins<br \/>\n<\/strong>Jenkins is an open-source, freely available automation server used to build, test, and deploy software applications. We will be creating our CI CD Docker Pipeline to build, test and deploy our Nodejs application on AWS ECS using Jenkins<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"8\">\n<li><strong>AWS ECR<br \/>\n<\/strong>AWS Elastic Container Registry is a Docker Image Repository fully managed by AWS to easily store, share, and deploy container images. We will be using AWS ECR to store Docker Images of our sample Nodejs application.<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"9\">\n<li><strong>AWS ECS<br \/>\n<\/strong>AWS Elastic Container Service is a container orchestration service fully managed by AWS to easily deploy, manage, and scale containerized applications. We will be using it to host our sample Nodejs application.<\/li>\n<\/ol>\n<h2 id=\"h-architecture\" style=\"text-align: justify;\">Architecture<\/h2>\n<p style=\"text-align: justify;\">After the CI CD Docker Pipeline is successfully set up, we will push commits to our Github repository and in turn, Github Webhook will trigger the CI CD Pipeline on Jenkins Server. Jenkins Server will then pull the latest code, carry out unit tests, build a docker image and push it to AWS ECR. After the image is pushed to AWS ECR, the same image will be deployed in AWS ECS by Jenkins.<\/p>\n<h2 id=\"h-ci-cd-workflow-and-phases\" style=\"text-align: justify;\">CI CD workflow and phases<\/h2>\n<h3 id=\"h-workflow\" style=\"text-align: justify;\">Workflow<\/h3>\n<p style=\"text-align: justify;\">CI and CD Workflow allows us to focus on Development while it carries out the tests, build, and deployments in an automated way.\u00a0<\/p>\n<ol style=\"text-align: justify;\">\n<li><strong>Continuous Integration<\/strong><br \/>\nThis allows the developers to push the code to the Version Control System or\u00a0 Source Code Management System, build &amp; test the latest code pushed by the developer and generate &amp; store artifacts.<\/li>\n<li><strong>Continuous Delivery<\/strong><br \/>\nThis is the process that lets us deploy the tested code to the Production whenever required.\u00a0<\/li>\n<li><strong>Continuous Deployment<br \/>\n<\/strong>This goes one step further and releases every single change without any manual intervention to the customer system every time the production pipeline passes all the tests.\u00a0<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-phases\" style=\"text-align: justify;\">Phases<\/h3>\n<p style=\"text-align: justify;\">The primary goal of the automated CI CD pipeline is to build the latest code and deploy it. There can be various stages as per the need. The most common ones are mentioned below.<\/p>\n<ol style=\"text-align: justify;\">\n<li><strong>Trigger<br \/>\n<\/strong>The CI CD pipeline can do its job on the specified schedule when executed manually or triggered automatically on a particular action in the Code Repository.\u00a0\u00a0\u00a0<\/li>\n<li><strong>Code Pull<\/strong><br \/>\nIn this phase, the pipeline pulls the latest code whenever the pipeline is triggered.<\/li>\n<li><strong>Unit Tests<\/strong><br \/>\nIn this phase, the pipeline performs tests that are there in the codebase, this is also referred to as unit tests.<\/li>\n<li><strong>Build or Package<\/strong><br \/>\nOnce all the tests pass, the pipeline moves forward and builds artifacts or docker images in case of dockerized applications.<\/li>\n<li><strong>Push or Store<\/strong><br \/>\nIn this phase, the code that has been built is pushed to the Artifactory or Docker Repository in case of dockerized applications.<\/li>\n<li><strong>Acceptance Tests<br \/>\n<\/strong>This phase or stage of the pipeline validates if the software behaves as intended. It is a way to ensure if the software or application does what it is meant to do.<\/li>\n<li><strong>Deploy<br \/>\n<\/strong>This is the final stage in any CI CD pipeline. In this stage, the application is ready for delivery or deployment.<\/li>\n<\/ol>\n<h2 id=\"h-deployment-strategy\" style=\"text-align: justify;\">Deployment strategy<\/h2>\n<p style=\"text-align: justify;\">A deployment strategy is a way in which containers of the micro-services are taken down and added. There are various options available; however, we will only discuss the ones that are available and supported by ECS<\/p>\n<h3 id=\"h-rolling-updates\" style=\"text-align: justify;\">Rolling updates<\/h3>\n<p style=\"text-align: justify;\">In rolling updates, the scheduler in the ECS Service replaces the currently running tasks with new ones. The tasks in the ECS cluster are nothing but running containers created out of the task definition. Deployment configuration controls the number of tasks that Amazon ECS adds or removes from the service. The lower and the upper limit on the number of tasks that should be running is controlled by minimumHealthyPercent and maximumPercent respectively.\u00a0<\/p>\n<ol style=\"text-align: justify;\">\n<li><strong>minimumHealthyPercent example<\/strong>: If the value of\u00a0<strong>minimumHealthyPercent<\/strong>\u00a0is 50 and the desired task count is 4, then the scheduler can stop 2 existing tasks before starting 2 new tasks<\/li>\n<li><strong>maximumPercent example<\/strong>: If the value of\u00a0<strong>maximumPercent<\/strong>\u00a0is 4 and the desired task is 4 then the scheduler can start 4 new tasks before stopping 4 existing tasks.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">\u00a0<\/p>\n<p style=\"text-align: justify;\">If you want to learn more about this, visit the official documentation\u00a0<a href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/deployment-type-ecs.html\">here<\/a>.<\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-blue-green-deployment\" style=\"text-align: justify;\">Blue\/Green Deployment<\/h3>\n<p style=\"text-align: justify;\">Blue\/Green deployment strategy enables the developer\u00a0 to verify a new deployment before sending traffic to it by installing an updated version of the application as a new replacement task set.<\/p>\n<p style=\"text-align: justify;\">There are primarily 3 ways in which traffic can shift during blue\/green deployment.<\/p>\n<ol style=\"text-align: justify;\">\n<li><strong>Canary<\/strong>\u00a0\u2014 Tra\ufb03c is shifted in two increments, percentage of tra\ufb03c shifted to your updated task set in the \ufb01rst increment and the interval, in minutes, before the remaining tra\ufb03c is shifted in the second increment.<\/li>\n<li><strong>Linear<\/strong>\u00a0\u2014 Tra\ufb03c is shifted in equal increments, the percentage of tra\ufb03c shifted in each increment and the number of minutes between each increment.<\/li>\n<li><strong>All-at-once<\/strong>\u00a0\u2014 All tra\ufb03c is shifted from the original task set to the updated task set all at once.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">To learn more about this, visit the official documentation\u00a0<a href=\"https:\/\/docs.aws.amazon.com\/AmazonECS\/latest\/developerguide\/deployment-type-bluegreen.html\">here<\/a>.<\/p>\n<p style=\"text-align: justify;\">Out of these 2 strategies, we will be using the rolling-updates deployment strategy in our demo application.<\/p>\n<h2 id=\"h-dockerize-node-js-app\" style=\"text-align: justify;\">Dockerize Node.js app<\/h2>\n<p id=\"h-now-let-s-get-started-and-make-our-hands-dirty\" style=\"text-align: justify;\">Now, let\u2019s get started and make our hands dirty.<\/p>\n<p style=\"text-align: justify;\">The Dockerfile for the sample Nodejs application is as follows. There is no need to copy-paste this file, it is already available in the sample git repository that you cloned previously.<\/p>\n<p style=\"text-align: justify;\">Let\u2019s just try to understand the instructions of our Dockerfile.<\/p>\n<ol style=\"text-align: justify;\">\n<li>FROM node:12.18.4-alpine<br \/>\nThis will be our base image for the container.<\/li>\n<li>WORKDIR \/app<br \/>\nThis will be set as a working directory in the container.<\/li>\n<li>ENV PATH \/app\/node_modules\/.bin:$PATH<br \/>\nPATH variable is assigned a path to \/app\/node_modules\/.bin.<\/li>\n<li>COPY package.json .\/<br \/>\nPackage.json will be copied in the working directory of the container.<\/li>\n<li>RUN npm install<br \/>\nInstall dependencies.<\/li>\n<li>COPY . .\/<br \/>\nCopy files and folders with dependencies from the host machine to the container.<\/li>\n<li>EXPOSE 3000<br \/>\nAllow to port 300 of the container.<\/li>\n<li>CMD [\u201cnode\u201d, \u201c.\/src\/server.js\u201d]<br \/>\nStart the application<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">\u00a0<\/p>\n<p style=\"text-align: justify;\">This is the Docker file that we will use to create a docker image.<\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h2 id=\"h-setup-github-repositories\" style=\"text-align: justify;\">Setup Github Repositories<\/h2>\n<h3 id=\"h-create-a-new-repository\" style=\"text-align: justify;\">Create a new repository<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Go to\u00a0<a href=\"https:\/\/github.com\/\">https:\/\/github.com\/<\/a>, create an account if you don\u2019t have it already else log in to your account and create a new repository. You can name it as per your choice; however, I would recommend using the same name to avoid any confusion.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/zLnw3IRJPS--1hKgke2G8DYLdwdWVqaS9AQZUTDGMWfuPwoqdixgZkT4jdgRGjlPSeEwqP6EoDHswzL76CJHM1fdW9_kny2p-Ykckuu-7rddmKLUOkxxfRiKAgSSfAYj3zo4U93H\" width=\"624\" height=\"316\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>You will get the screen as follows, copy the repository URL and keep it handy. Call this URL as a Github Repository URL and note it down in the text file on your system.\u00a0<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/P9AW7BF77F3RiJfkFU0nCisVIwIqq1-YXnsR5BvPEx4G0RsPGqrnnBhaHAIACbcSUGs0huo48igfIKjjTFi6bfXbor2O4y4agLu43b8oOHEIyZjbf0yBOgQjgzbHsd82ms9mYx2S\" width=\"624\" height=\"149\" \/><\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><strong>Note<\/strong>: Create a new text file on your system and note down all the details that will be required later.<\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-create-a-github-token\" style=\"text-align: justify;\">Create a Github Token<\/h3>\n<p style=\"text-align: justify;\">This will be required for authentication purposes. It will be used instead of a password for Git over HTTPs, or can be used to authenticate to the API over Basic Authentication.<\/p>\n<ol style=\"text-align: justify;\">\n<li>Click on the user icon in the top-right, go to \u201cSettings\u201d, then click on the \u201cDevelopers settings\u201d option in the left panel.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/Ov9yPJwlNGNbyfsRtUX8mK7h941RXKqK46IRs1caah8eoCIn3Mmxz_0bx6tVog5Pk8LYJcxLgi7-opvnDJoHqRnOCNj4Mudc4TILbhK1QPth8tD7kzd7mK9sKtaKkJfHLZ8KBBEV\" width=\"624\" height=\"316\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Click on the\u00a0 \u201cPersonal access tokens\u201d options and \u201cGenerate new token\u201d to create a new token.<br \/>\n<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/6uwEt77FR-jvIQKflPXciaIAyjyiCRUWcudFzlo4vWNxUv9p26jGBC7hgFO1t4v6J5q---TYT9ImVBaDjvwNYPFkzo-O1wrymH_XNQwXucI2YgTHjGDt0QUSgP2mWb2p-obLmI0J\" width=\"624\" height=\"108\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>Tick the \u201crepo\u201d checkbox, the token will then have \u201cfull control of private repositories\u201d<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/7SXV0I0vappUyLrkzr1d05tgNzHXusuz30BPy1vOr0iYRFO0nzEaxngAKmDg9kMw9XV8UrAL2qvccL5zZ492wNW1nblzpKXpMjL6reWX7tPxuazX6QjilhbY_ODgMvvrjbgLeZxt\" width=\"624\" height=\"344\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>You should see your token created now.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/rg2UZN9TZPfiEw595dEaSBef0ylwMgUmsKSwKvEnfoWE_jOZLGA2dmrMlNSbw0ffQSEASKFW5SsTyvaLlpW3rcm5cSHTOo9RchYcIE26wHDnHQBEWLDECdWqY2DWBXCE-av9hSTb\" width=\"624\" height=\"108\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-clone-the-sample-repository\" style=\"text-align: justify;\">Clone the sample Repository<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Check your present working directory.<br \/>\npwd<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">\u00a0<\/p>\n<p style=\"text-align: justify;\"><strong>Note:<\/strong>\u00a0You are in the home directory, i.e. \/home\/ubuntu.<\/p>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Clone my sample repository containing all the required code.<br \/>\ngit clone\u00a0<a href=\"https:\/\/github.com\/shivalkarrahul\/nodejs.git\">https:\/\/github.com\/shivalkarrahul\/nodejs.git<\/a><\/li>\n<li>Create a new repository. This repository will be used for CI CD Pipeline setup.<br \/>\ngit clone\u00a0<a href=\"https:\/\/github.com\/shivalkarrahul\/demo-nodejs-app.git\">https:\/\/github.com\/shivalkarrahul\/demo-nodejs-app.git<\/a><\/li>\n<li>Copy all the code from my\u00a0<a href=\"https:\/\/github.com\/shivalkarrahul\/nodejs.git\">nodejs<\/a>\u00a0repository to the newly created\u00a0<a href=\"https:\/\/github.com\/shivalkarrahul\/demo-nodejs-app.git\">demo-nodejs-app<\/a>\u00a0repository.<br \/>\ncp -r nodejs\/* demo-nodejs-app\/<\/li>\n<li>Change your working directory.<br \/>\ncd demo-nodejs-app\/<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">\u00a0<\/p>\n<p style=\"text-align: justify;\"><strong>Note:<\/strong>\u00a0For the rest of the article, do not change your directory. Stay in the same directory, here it is \/home\/ubuntu\/demo-nodejs-app\/, and execute all the commands from there.\u00a0<\/p>\n<ol style=\"text-align: justify;\" start=\"6\">\n<li>ls -l<\/li>\n<li>git status<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/cjEDXnO-iW8CU-Jpppxjtx-VrB5uB5d3prnglzdrkMy98XH3k9yuJtxsLIv4W9q3VN4yeOw9e4QLHOY7QZuv-nkey1YZpu6f14zu0Rlp0G1S_MXlTZTPj0BmtP9qopcaXAl4Ageu\" width=\"624\" height=\"337\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-push-your-first-commit-to-the-repository\" style=\"text-align: justify;\">Push your first commit to the repository<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Check your present working directory, it should be the same. Here it is \/home\/ubuntu\/demo-nodejs-app\/<br \/>\npwd<\/li>\n<li>Set a username for your git commit message.<br \/>\ngit config user.name \u201cRahul\u201d<\/li>\n<li>Set an email for your git commit message.<br \/>\ngit config user.email \u201c&lt;<a href=\"mailto:test@email.com\">test@email.com<\/a>&gt;\u201d<\/li>\n<li>Verify the username and email you set.<br \/>\ngit config \u2013list<\/li>\n<li>Check the status, see files that have been changed or added to your git repository.<br \/>\ngit status<\/li>\n<li>Add files to the git staging area.<br \/>\ngit add<\/li>\n<li>Check the status, see files that have been added to the git staging area.<br \/>\ngit status<\/li>\n<li>Commit your files with a commit message.<br \/>\ngit commit -m \u201cMy first commit\u201d<\/li>\n<li>Push the commit to your remote git repository.<br \/>\ngit push<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/QMdsRu-NzzU05lDGLUUPSBFFmqijPD3KpKgIk7J3tEc50UHkECQLqgM1W_7pNJG1y3LpdPHLuFPQvKRmTP3dTNmmPoMSJAJvK0tzmacBODx4-uomobSfBHpgnANV8gxyY76h8VVg\" width=\"624\" height=\"392\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h2 id=\"h-setup-the-aws-infrastructure\" style=\"text-align: justify;\">Setup the AWS Infrastructure<\/h2>\n<h3 id=\"h-create-an-iam-user-with-a-programmatic-access\" style=\"text-align: justify;\">Create an IAM User with a Programmatic Access<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Create an IAM user with programmatic access in your AWS account and note down the access key and secret key in your text file for future references. Provide administrator permissions to the user.<br \/>\nWe don\u2019t need admin access; however, to avoid permission issues and for the sake of the demo, let\u2019s proceed with administrator access.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/Jis1Oa7crIcN0zx2G5RlsrFDtD5VcHouZIOwKLkvcL99NeI5t5fh-Lmn6uDj_-PWikR3_hxXRnxNsIUy9mthewj23HEVGWhqmUvrL-StgB35w0Xb48p1mWglyX2mZUJ5xfrYsu76\" width=\"624\" height=\"243\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-create-an-ecr-repository\" style=\"text-align: justify;\">Create an ECR Repository<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Create an ECR Repository in your AWS account and note its URL in your text file for future references.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/BvXsvV-vN3euWSoCBanfo-RgKPyifIIleMVNXZ_D5xHpY561pe5kmOPdan9Jd7Jya4GSe4HWVxTFPbApeK-fZyBODqvOUR7vyA-GpAF3eyjBeG-dYbfZ3FS0UfqG3EQIaIN-Xigh\" width=\"624\" height=\"177\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-create-an-ecs-cluster\" style=\"text-align: justify;\">Create an ECS Cluster<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Go to ECS Console and click on \u201cGet Started\u201d to create a cluster.\u00a0<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/GzA4RDcDTDRTXWMcHgsepRh5CIvN7BBzOrggXdR0_U3gFXr858UUwcjusH60rznrMvNdSGndeE0Iurw8VPaf0vN2QukTkI4G1YTypOFqIObs17cY2WfIxSzR_wZ_CzpL-FXdxL1E\" width=\"624\" height=\"179\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Click on the \u201cConfigure\u201d button available in the \u201ccustom\u201d option under \u201cContainer definition\u201d.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/3jgDLzmWArhXfknGjvOj_mhFSR0PrYqDyJLIGVbR2MBi3fu6Ln8XwlzWLzCmMZmHTGTfL4z8G4eceICBwvcmT02QVxL2FWxdMXIMAsy03a_ApVUKrUNp-L-pTXag0wI9NSYI4Wvy\" width=\"624\" height=\"369\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>Specify a name to the container as \u201cnodejs-container\u201d, the ECR Repository URL in the \u201cImage\u201d text box, \u201c3000\u201d port in the Port mappings section, and then click on the \u201cUpdate\u201d button. You can specify any name of your choice for the container.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/ptfDEDhQSeH9lBuUi81ODIYj7I2cXfurTIn7chpPxAhrpfpM2Pl47HCxKi5uXteRMCbNhpRcLeq1PUqmFrFc6UHm3EJUPrOBR8yYUuIZoX9yfObLXeZQA2lyUpg2mzr6TsTWPHZ2\" width=\"624\" height=\"388\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>You can now see the details you specified under \u201cContainer definition\u201d. Click on the \u201cNext\u201d button to proceed<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/Qae5BWDT6VD9AeLC_HTJq3aWY3Iy3kcr-M3F0cElUTq5rBzYW478HycBq7KCoPpnzgyvEgNj2SQgn5pf-btiUlDHukqfgmT58Tlz_UT_sj0nzqo-MPanmVW1AKVioHqSZtNvz6J0\" width=\"624\" height=\"372\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"5\">\n<li>Select \u201cApplication Load Balancer\u201d under \u201cDefine your service\u201d and then click on the \u201cNext\u201d button.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/_zLXQqjdk49VCQjs5ILlHBrOnDb-Mr7-r7S05mi3HM2oiLF_jdTVN9NGNioXFwNtbqsDgolrLiGwkdm1bbl9icy9ZqmHaixBCHA4Sjq0xOO1OCa2omLQ3MBy0s8vD_mf2QCzk4Ls\" width=\"624\" height=\"371\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"6\">\n<li>Keep the cluster name as \u201cdefault\u201d and proceed by clicking on the \u201cNext\u201d button. You can change the cluster name if you want.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/TlTQdFgW6XT6-HwUoKlAZuWoi9DUoDbpYBYJfTTebIDpKfZ50wmDsjUK2WHtlx6KEc_EKNXLMD4o0h-M_5uEE8QilV05jtn6Y4CNsmnmCsGB99WBViEiMqFqbst8Xa8oS-u63noJ\" width=\"624\" height=\"335\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"7\">\n<li>Review the configuration and it should look as follows. If the configurations match, then click on the \u201cCreate\u201d button. This will initiate the ECS Cluster creation.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/OpI0CGAN_whlGa4vW--f4vOxnaNOmwV6PjbgtRm9PYr92eKLv6cfmUXIpQ_UFWMQ6jEBrX_nibFZfT4rDG37JcvPKxG6IRzSktaqqTFAexyCgX9dGjkFCCC6Tp-aW220lrEAverz\" width=\"624\" height=\"369\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"8\">\n<li>After a few minutes, you should have your ECS cluster created and the Launch Status should be something as follows.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/CcOZslY_KzPMC_ZOF-54PaAjZLTC1xunZahAHgXEhgQeQ5Ifb1Hj6dmzDZshhsvbDjR3Sf6D756TTezlRXOPS-_Ckt7aXxCKlp88DRWBheZXowhtsXI9RudcDgSUvsYktILc8jUI\" width=\"624\" height=\"276\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-create-an-ec2-instance-for-setting-up-the-jenkins-server\" style=\"text-align: justify;\">Create an EC2 Instance for setting up the Jenkins Server<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Create an EC2 Instance with Ubuntu 18.04 AMI and open its Port 22 for your IP and Port 8080 for 0.0.0.0\/0 in its Security Group. Port 22 will be required for ssh and 8080 for accessing the Jenkins Server. Port 8080 is where Github Webhook will try to connect to on Jenkins Server, hence we need to allow it for 0.0.0.0\/0<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h2 id=\"h-setup-jenkins-on-the-ec2-instance\" style=\"text-align: justify;\">Setup Jenkins on the EC2 Instance<\/h2>\n<p style=\"text-align: justify;\">After the instance is available, let\u2019s install Jenkins Server on it along with all the dependencies.<\/p>\n<h3 id=\"h-pre-requisites-of-the-ec2-instance\" style=\"text-align: justify;\">Pre-requisites of the EC2 Instance<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Verify if the OS is Ubuntu 18.04 LTS<br \/>\ncat \/etc\/issue<\/li>\n<\/ol>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Check the RAM, minimum of 2 GB is what we require.<br \/>\nfree -m<\/li>\n<\/ol>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>The User that you use to log in to the server should have sudo privileges. \u201cubuntu\u201d is the user available with sudo privileges for EC2 instances created using \u201cUbuntu 18.04 LTS\u201d AMI.<br \/>\nwhoami<\/li>\n<li>Check your present working directory, it will be your home directory.\u00a0<br \/>\npwd<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/dfu3Wp7026M2VxfeNWLenCT7CR52Zq_hDnyvjCJpQ7rO5LPFXshgarRuQ4qIJmgmh0z2XVQMhAL3JqFkdvbbqc64tnsLLPScK1AJJg6mxnn0QBvacGcbGTMHA1j5OdW4INwklDq7\" width=\"624\" height=\"152\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-install-java-json-processor-jq-nodejs-npm-and-aws-cli-on-the-ec2-instance\" style=\"text-align: justify;\">Install Java, JSON Processor jq, Nodejs\/NPM and aws-cli on the EC2 Instance<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Update your system by downloading package information from all configured sources.<br \/>\nsudo apt update<\/li>\n<li>Search and Install Java 11<br \/>\nsudo apt search openjdk<br \/>\nsudo apt install openjdk-11-jdk<\/li>\n<li>Install jq command, the JSON processor.<br \/>\nsudo apt\u00a0 install jq<\/li>\n<li>Install Nodejs 12 and NPM<br \/>\ncurl -sL\u00a0<a class=\"vglnk\" href=\"https:\/\/deb.nodesource.com\/setup_12.x\" rel=\"nofollow\">https:\/\/deb.nodesource.com\/setup_12.x<\/a>\u00a0| sudo -E bash \u2013<br \/>\nsudo apt install nodejs<\/li>\n<li>Install aws cli tool.<br \/>\nsudo apt\u00a0 install awscli<\/li>\n<li>Check the Java version.<br \/>\njava \u2013version<\/li>\n<li>Check the jq version.<br \/>\njq \u2013version<\/li>\n<li>Check the Nodejs version<br \/>\nnode \u2013version<\/li>\n<li>Check the NPM version<br \/>\nnpm \u2013version<\/li>\n<li>Check the aws cli version<br \/>\naws \u2013version<\/li>\n<\/ol>\n<figure class=\"wp-block-image\" style=\"text-align: justify;\"><img class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/Ly61UeMSgWV4xwRb-xKuQNo4qoHdwTOTw4iwGsEBx_V2O6i_8p2NlA4bckqFYVxGcEmtRIX9BulvlR7QzgbPABhdgZ0boopd8a13BvI8GxJ-CQhWuKFYiHPQ7uHnPAKCtJNZtjmn\" alt=\"\" \/><\/figure>\n<p style=\"text-align: justify;\">Note: Make sure all your versions match the versions seen in the above image.\u00a0<\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-install-jenkins-on-the-ec2-instance\" style=\"text-align: justify;\">Install Jenkins on the EC2 Instance<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Jenkins can be installed from the Debian repository<br \/>\nwget -q -O \u2013\u00a0<a class=\"vglnk\" href=\"http:\/\/pkg.jenkins-ci.org\/debian\/jenkins-ci.org.key\" rel=\"nofollow\">http:\/\/pkg.jenkins-ci.org\/debian\/jenkins-ci.org.key<\/a>\u00a0| sudo apt-key add -sudo sh -c \u2018echo deb\u00a0<a class=\"vglnk\" href=\"http:\/\/pkg.jenkins-ci.org\/debian\" rel=\"nofollow\">http:\/\/pkg.jenkins-ci.org\/debian<\/a>\u00a0binary\/ &gt; \/etc\/apt\/sources.list.d\/jenkins.list\u2019<\/li>\n<li>Update the apt package index<br \/>\nsudo apt-get update<\/li>\n<li>Install Jenkins on the machine<br \/>\nsudo apt-get install jenkins<\/li>\n<li>Check the service status if it is running or not.<br \/>\nservice jenkins status<\/li>\n<li>You should have your Jenkins up and running now. You may refer to the official documentation\u00a0<a href=\"https:\/\/www.jenkins.io\/doc\/book\/installing\/linux\/\">here<\/a>\u00a0if you face any issues with the installation.\n<p><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/a9dWCAqyU7b0kjkPGudAu87u0FRArya6BYCyB8u_Wke8fZznvMf85TPKr4Mz6F1_nLfqRIfsRlIkeRpV1WblNdINoRjspHbBFxvx-ifHi7CgFynKUSNh_pTw7nlxAe-_8J4OY15f\" width=\"624\" height=\"384\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-install-docker-on-the-ec2-instance\" style=\"text-align: justify;\">Install Docker on the EC2 Instance<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Install packages to allow apt to use a repository over HTTPS:<br \/>\nsudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release<\/li>\n<li>Add Docker\u2019s official GPG key:<br \/>\ncurl -fsSL\u00a0<a class=\"vglnk\" href=\"https:\/\/download.docker.com\/linux\/ubuntu\/gpg\" rel=\"nofollow\">https:\/\/download.docker.com\/linux\/ubuntu\/gpg<\/a>\u00a0| sudo gpg \u2013dearmor -o \/usr\/share\/keyrings\/docker-archive-keyring.gpg<\/li>\n<li>Set up the stable repository<br \/>\necho \u201cdeb [arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg]\u00a0<a class=\"vglnk\" href=\"https:\/\/download.docker.com\/linux\/ubuntu\" rel=\"nofollow\">https:\/\/download.docker.com\/linux\/ubuntu<\/a>\u00a0 $(lsb_release -cs) stable\u201d | sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null<\/li>\n<li>Update the apt package index<br \/>\nsudo apt-get update<\/li>\n<li>Install the latest version of Docker Engine and containerd,<br \/>\nsudo apt-get install docker-ce docker-ce-cli containerd.io<\/li>\n<li>Check the docker version.<br \/>\ndocker \u2013version<\/li>\n<li>Create a \u201cdocker\u201d group, this may exit.<br \/>\nsudo groupadd docker<\/li>\n<li>Add \u201cubuntu\u201d user to the \u201cdocker\u201d group<br \/>\nsudo usermod -aG docker ubuntu<\/li>\n<li>Add \u201cjenkins\u201d user to the \u201cdocker\u201d group<br \/>\nsudo usermod -aG docker jenkins<\/li>\n<li>Test if you can create docker objects using \u201cubuntu\u201d user.<br \/>\ndocker run hello-world<\/li>\n<li>Switch to \u201croot\u201d user<br \/>\nsudo -i<\/li>\n<li>Switch to \u201cjenkins\u201d user<br \/>\nsu jenkins<\/li>\n<li>Test if you can create docker objects using \u201cjenkins\u201d user.<br \/>\ndocker run hello-world<\/li>\n<li>Exit from \u201cjenkins\u201d user<br \/>\nexit<\/li>\n<li>Exit from \u201croot\u201d user<br \/>\nexit<\/li>\n<li>Now you should be back in \u201cubuntu\u201d user. You may refer to the official documentation\u00a0<a href=\"https:\/\/docs.docker.com\/engine\/install\/ubuntu\/\">here<\/a>\u00a0if you face any issues with the installation.<br \/>\n<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/VVSAVxJAwezEIzAJvnliAklnhkcMPy_3hSKrkaqru1ts5Y2R5T2X8GtEFIyiubaqWidTOs3Hfr570z0vhYib0y1NItGpHmBWr_LhxIbY9Tdezpads84W8BnTYiTBxLnW2bDJc3ZV\" width=\"624\" height=\"507\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h2 id=\"h-configure-the-jenkins-server\" style=\"text-align: justify;\">Configure the Jenkins Server<\/h2>\n<ol style=\"text-align: justify;\">\n<li>After Jenkins has been installed, the first step is to extract its password.<br \/>\nsudo cat \/var\/lib\/jenkins\/secrets\/initialAdminPassword<br \/>\n<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/fL5JfcHtll1kXFPzBOeOSSYwKvIPuDRzC5Bkb-RCDQ7B6uoLYab8xp2qi1FQZLz5pcfe30G1cip9O2b291a7rEk97SspetLZgzBE2_P7zP5ros8NhhVEDsMyzjxZXvUr7iy7muw_\" width=\"624\" height=\"43\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Hit the URL in the browser<br \/>\nJenkins URL: http:\/\/&lt;public-ip-of-the-ec2-instace&gt;:8080<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/7lEQJqv-l9i7szXSeZomh--BPH3qvkM-vFoS7oZcPpiukSZj3fd-t5YwhNgh-yVQ3GcNSQVKjjzL285zujU-HQxwL3WnVWw7-NuUlMiyE7PwmCg1HgdZTiSJLenuG71F40vs0EpM\" width=\"624\" height=\"360\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>Select the \u201cInstall suggested plugins\u201d option<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/nGl0Rinoe2DaRJpSol32OCPgQfSu7Sv3mJhZ5Qpv-GbX1DwONXQjwDiKZ2aI4ap6VqeoDzSsLGlpJ-Sjg0_J5FMuX5PsTjBxbf50bPAXcZkPLDMnKibJQun3nJ-HBb8MdX1xSjcK\" width=\"624\" height=\"205\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>Specify user-name, password for the new admin user to be created. You can use this user as an admin user.<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/_474Y7Tv_6jxDAvXsCo2Lw2-RwnGs4rh_HM0z2OUSIYevC6pK14ZWmdyr56TNWcH6pFrIg08YzGuyLs8E1sjBkQ9UozZjOE71jJS0CCH8EIz6b36jJGTHZRDgswvBLkY-tcKE5aU\" width=\"624\" height=\"360\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"5\">\n<li>This URL field will be auto-filled, click on the \u201cSave and Finish\u201d button to proceed.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/FbhWwtKe0r7oIqufDeX5Lj057x_gm-FvQz4A6nrwMbukVRiEoBWdn9u1_vkIStU70IGJ4UlFAZprNWg7OUa7G3b8QYYqQtD32BfJCF1u25L00nAwMl-wXCp2clyYbac0P2gLy2fM\" width=\"624\" height=\"359\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"6\">\n<li>Your Jenkins Server is ready now.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/vNsGnwRwOnzWQZPF6XTJIgEEorF8XMylXdx7exYVLPIFywSuEmuwYr1MugHV1zOpz_eGFFQPGNL_UI-EpdVcAwqRwYj8_UKSid_x47AeWBi08G-C_-Dn7L_sg094glt2W7ZPORLe\" width=\"624\" height=\"128\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"7\">\n<li>Here is how its Dashboard looks like.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/NiARjD8n5NmlPzL6sjC7cS70nY_lTSGpV4YV7p-oOMBuXktqIYkwABlB49ZhxhJbnBCamdaqG1dVpgI4riJDMgRJdPVat7Tr52jBl_x9SkxW4i6O3DzBrFnAK-JYpbpMABW4Occt\" width=\"624\" height=\"256\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-install-plugins\" style=\"text-align: justify;\">Install Plugins<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Let\u2019s install all the plugins that we will need. Click on \u201cManage Jenkins\u201d in the left panel.<img loading=\"lazy\" src=\"https:\/\/lh5.googleusercontent.com\/Zqu_wmobVsvakq05TrBCRnCOljeLJwOmS1ymSUfsdCGP1GIEprZIiZuJBkrn-wtRQpUnasgmFR3k4nXvHvmV2aSJbIl2Uqgt71YTvfFk32-kXyqu0kKbGcQFJCLSDWk-E2U6GjhZ\" width=\"624\" height=\"184\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Here is a list of plugins that we need to install\n<ol>\n<li><a href=\"https:\/\/plugins.jenkins.io\/aws-credentials\/\">CloudBees AWS Credentials<\/a>:<br \/>\nAllows storing Amazon IAM credentials, keys within the Jenkins Credentials API.<\/li>\n<li><a href=\"https:\/\/plugins.jenkins.io\/docker-workflow\">Docker Pipeline<\/a>:<br \/>\nThis plugin allows building, testing, and using Docker images from Jenkins Pipeline.<\/li>\n<li><a href=\"https:\/\/plugins.jenkins.io\/amazon-ecr\">Amazon ECR<\/a>:<br \/>\nThis plugin provides integration with AWS Elastic Container Registry (ECR)<br \/>\nUsage:\u00a0<\/li>\n<li><a href=\"https:\/\/plugins.jenkins.io\/pipeline-aws\/\">AWS Steps<\/a>:<br \/>\nThis plugin adds Jenkins pipeline steps to interact with the AWS API.<\/li>\n<\/ol>\n<\/li>\n<\/ol>\n<p style=\"text-align: justify;\">\u00a0<\/p>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>In the \u201cAvailable\u201d tab, search all these plugins and click on \u201cInstall without restart\u201d.<br \/>\n<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/LT2BLcI_Wffisr0bNr4lh_uMokWhbavkhQmGJg8qdh8p3NHWNpeX07Ql75Dl2t6RHXDw3CaPkj4_Z6z3MRkz60Q4NTo3yEUyBKuA2S-PCbpOSxoQQOY4562vTTSQUsb7x4QymBFj\" width=\"624\" height=\"273\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>You will see the screen as follows after the plugins have been installed successfully.<br \/>\n<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/pvhbmuohFMg_usIhtwYJ8pqzQJ9gbbIflA8FdsbWJ8X283aU_wJ5qtZgpC2GYnORqrrgSFYqLytAzXHt-OO_p18BP0hxGbHe3xQv9_H4wH284K6BX3WT9ppHkZrSV062VfJObrjZ\" width=\"624\" height=\"341\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-create-credentials-in-jenkins\" style=\"text-align: justify;\">Create Credentials in Jenkins<\/h3>\n<ol style=\"text-align: justify;\">\n<li><a href=\"https:\/\/plugins.jenkins.io\/aws-credentials\/\">CloudBees AWS Credentials<\/a>\u00a0plugin will come to rescue here. Go to \u201cManage Jenkins\u201d, and then click on \u201cManage Credentials\u201d.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/NKeSusP6EdG7PCbMExEaLO1zLQmqlE-hmFnH2HsQFf10dhR0LC4jT9Z-M0hMgCqBUypKivVA51fUKTRzPRkaNkH99zZQylT6Q-ETwwKwOeXRjWfljVYkU_h6_FGCO82XdlzOOMfq\" width=\"624\" height=\"281\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Click on \u201c(global)\u201d \u201cAdd credentials\u201d.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/dHrFwFlJLYNglMkjt7eKq7T_BWmD7jrZVftE79kFtPgtbKQHNJWVpJMend_FzFuf7IhCSuHTrs7kx3FXh_MQ9T8nicK_eYJ9MEVFn8Wd6EGaYfiJKk040GwqVptWPyF8SaC68n_j\" width=\"624\" height=\"185\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>Select Kind as \u201cAWS Credentials\u201d and provide ID as \u201cdemo-admin-user\u201d. This can be provided as per your choice,\u00a0 keep a note of this ID in the text file. Specify the Access Key and Secret Key of the IAM user we created in the previous steps. Click on \u201cOK\u201d to store the IAM credentials.\u00a0<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/Tws_2jBEXFLNma-KM8Vqz7I0RSAdhUKj2MrbE9pw-o4UU2QeCk-o2pIvQDhEeSzH1hjG5OyHQ8MxrjNHclL_eWFaq5BFfRFEyWwSdeMMwmGm-Q8JJi_U5_b2NJh4G36bjfW2W72n\" width=\"624\" height=\"287\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>Follow the same step and this time select Kind as \u201cUsername with password\u201d to store the Github Username and Token we created earlier. Click on \u201cOk\u201d to store the Github credentials.<br \/>\n<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/a_YqFmczbC-YptXlNzF36ETdm8TFw2IPcwxVQEXdxI06QMgHcdd7gDN0EZ_f7vo6ThwU-Ezww3MTDRKNzNb4w-JuLR-p0FGAjrhxZfxzo1l9VeI1Ifd3EgGX5y1V-Er6WZhw783D\" width=\"624\" height=\"271\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"5\">\n<li>You should now have IAM and Github credentials in your Jenkins.<br \/>\n<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/osqSLxElPjjNrDeJ1EWmLxju48cfCo0Bqr5m5rVr9CUlqk5vV1Dm0yi3GiIztExAupGBBRfQk9tGlFzN3iCGACxUge9LJMf9UmbF94Kt8LzcpjamoA9Jf82zZ8a4ABNAklMILsJS\" width=\"624\" height=\"168\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-create-a-jenkins-job\" style=\"text-align: justify;\">Create a Jenkins Job<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Go to the main dashboard, and click on \u201cNew Item\u201d to create a Jenkins Pipeline.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/F54uboyilvmxiS9a0qPMDAEj18be_sPWJiRCcNZC2RUFvjyyVcPrN9pPScYKl47w3si0256JSkkRPIVcRamC0YbNgJuYZ6yM2TfEw48lckqj-o6hd0F9pMzT2yN7zzdQrlpMvrUt\" width=\"624\" height=\"83\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Select the \u201cPipeline\u201d and name it as \u201cdemo-job\u201d or provide a name of your choice.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/29TJNtNgokuPTdWfeB-xbO_kvpIm4oYmptqi3KYUM0OwQDvzYU9rEbufXdLKPan9uHFRDrnDr3k3g26DgqAvv8M6FxP9GtwmQifZpdvWJlVz6hmUWBG2m32ZIJNU8xgkXdFNG9GM\" width=\"624\" height=\"197\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>Tick the \u201cGithub project\u201d checkbox under the \u201cGeneral\u201d tab, provide the Github Repository URL of the one we created earlier. Also, tick the checkbox \u201cGithub hook trigger for GitScm polling\u201d under the \u201cBuild Trigger\u201d tab.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/tASQWsNskRn6w8ybtCSs5uNtPG3glanHXqCGsd2vc02LsAjfjZaym0r4lJBy-kYYfQd8KlAqIpfy-sbUKZLDSk1ZSkBO-OTv1bpkVL6dbBx4vTmf8jjoVOpRhVpuBdkELEafKowz\" width=\"624\" height=\"327\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>Under the \u201cPipeline\u201d tab, select \u201cPipeline script from the SCM\u201d definition, specify our repository URL and select the credential we created for Github. Check the branch name if it matches the one you will be using for your commits. Review the configurations and click on \u201cSave\u201d to save your changes to the pipeline.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/oMTL52RyqVY0dO5Mr5yV_Is1JiVZLsZZXq-y0v6ZxqF6pA004E39kytBCQuvDNb2PuSLlmFP0pYlFsURih51XwF1qsK7W_JrcTqO3iGN1JsKwhUuww0LUDkzwsPVkNn2BTqS3rLT\" width=\"624\" height=\"368\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"5\">\n<li>Now you can see the pipeline we just created.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/MCcU924vHTcTxE4OpsPFN0iEjyfinPtZtxVgxI28hhY30UCgcG8HyPbzyyd4EaqhIBf7L8-Xxg1QVE11bKb5Gcp6iZArqx0yz9FHjNqc6OxzFO31b2gYA0yOafu2CM6qZVKhhBoo\" width=\"624\" height=\"129\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-integrate-github-and-jenkins\" style=\"text-align: justify;\">Integrate Github and Jenkins<\/h3>\n<p style=\"text-align: justify;\">The next step is to integrate Github with Jenkins so that whenever there is an event on the Github Repository, it can trigger the Jenkins Job.<\/p>\n<ol style=\"text-align: justify;\">\n<li>Go to the settings tab of the repository, click on \u201cWebhooks\u201d in the left panel. You can see the \u201cAdd webhook\u201d button, click on it to create a webhook.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/rlAMirKJnwoiyQFmi7uEN9rnZEnRWbeiHyoGVagUqtJecB6r61wn81_gMBpV9-4h3FZq8QHGM7FUJwRXRDquWU8DjD1FQJepqLIggeCP6iP688WhCn1GH6TPUTqTVHWlH8vjusHz\" width=\"624\" height=\"169\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Provide the Jenkins URL with context as \u201c\/github-webhook\/\u201d. The URL will look as follows.<br \/>\nWebhook URL: http:\/\/&lt;Jenkins-IP&gt;:8080\/github-webhook\/<br \/>\nYou can select the events of your choice; however, for the sake of simplicity I have chosen \u201cSend me everything\u201d. Make sure the \u201cActive\u201d checkbox is checked. Click on \u201cAdd webhook\u201d to create a webhook that will trigger the Jenkins job whenever there is any kind of event in the Github Repository.<br \/>\n<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/Iy2Rpq_UpcTML9LNAkJmmaX840LRBLjbxvLc92tj8x9iBL2qNGQhDZvCBxSVNFfThXouu-WLdPSow2f5jBQFtKOAN_dgEeRYe4tiLqNKyb3r--Tkx1YUaQtYTOJSAXh8-gTfpGfB\" width=\"624\" height=\"301\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>You should see your webhook. Click on it to see if it has been configured correctly or not.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/DQCyxDjY0_yVaTYD-dKAqNBVqLD4BuYATZmbp1g_0LxWrqVqYhRjhojt9EtXzGnfeEPFy61f_MfWoXHpQFZ0ZYjSTIjmqPgbhHD4RrfIp-eTnNuLP0w8kS6VHiV3lhA30G-M6NK9\" width=\"624\" height=\"153\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>Click on the \u201cRecent Deliveries\u201d tab and you should see a green tick mark. The green tick mark shows that the webhook was able to connect to the Jenkins Server.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/afrZvBRrBoB1OUNrVNM_NH3dyO7f54MS8hqzeef1eE1W2NRj9qhdPoE_coM-w7fWtvBA7G35LoeiCcfy3gS0uKNo9dlaGgoTrWq08OBozacJhDLOaowPC4c0D1DlBs_x-qPbGfzt\" width=\"624\" height=\"171\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h2 id=\"h-deploy-the-nodejs-application-to-the-ecs-cluster\" style=\"text-align: justify;\">Deploy the Nodejs Application to the ECS Cluster<\/h2>\n<p style=\"text-align: justify;\">Before we trigger the Pipeline from Github Webhook, lets try to manually execute it.<\/p>\n<h3 id=\"h-build-the-job-manually\" style=\"text-align: justify;\">Build the Job Manually<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Go to the Job we created and Build it.<img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/-ah6zYeHnDQcCCg9fc9BYRLUawv_FEUJRqdwC0PwcgUB0MyT_0a21L5n_uj1GmzkwDuPjSKJLAyfFe8yyua1wDmUp_nCyhQZDNW9uPxOnj0PByQik0Yswy93rkYbkUfEHWAMKR1L\" width=\"624\" height=\"132\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>If you see its logs, you will see that it failed. The reason is, we have not yet assigned values to variable we have in our Jenkinsfile<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh3.googleusercontent.com\/_frmVI0xYOPDRx-_Cz22VK9K08FJ_plQqeN-ODQuhB_PX8XrUsM-qKvucCv1GotHrOAw_h9Bl17JieC_KjVOP89W_Elw26OgHDjQEK1qpFkzL-8Jq1asufazOpr8D8zshfPPbVuv\" width=\"624\" height=\"371\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-push-your-second-commit\" style=\"text-align: justify;\">Push your second commit<\/h3>\n<p style=\"text-align: justify;\"><strong>Reminder Note:<\/strong>\u00a0For the rest of the article, do not change your directory. Stay in the same directory i.e. \/home\/ubuntu\/demo-nodejs-app and execute all the commands from here.\u00a0<\/p>\n<p style=\"text-align: justify;\"><strong>Assign values to the variable in the Jenkinsfile<\/strong><\/p>\n<ol style=\"text-align: justify;\">\n<li>To overcome the above error, you need to make some changes to the Jenkinsfile. We have variables in that file and we need to assign values to those variables to deploy our application to the ECS cluster we created. Assign correct values to the variables having \u201cCHANGE_ME\u201d.<br \/>\ncat Jenkinsfile<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh6.googleusercontent.com\/Otuyil_Eqcj0yXpeW2L6s5vEFOl37W7LxGHXHvbi2JxsTXgpMQshONePRd_sowxOeAFXUX3dFSWaToSWlcfbZVEiHXTLMcIXYRuo-QGtaLbYyr2Ks3hR3Nm9Z3AHusZYScNBcr8s\" width=\"624\" height=\"147\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Here is the list of variables for your convenience.<br \/>\nWe have the following variables in the Jenkinsfile.<\/p>\n<ol>\n<li>AWS_ACCOUNT_ID=\u201dCHANGE_ME\u201d<br \/>\nAssign your AWS Account Number here.<\/li>\n<li>AWS_DEFAULT_REGION=\u201dCHANGE_ME\u201d<br \/>\nAssign the region you created your ECS Cluster in<\/li>\n<li>CLUSTER_NAME=\u201dCHANGE_ME\u201d<br \/>\nAssign the name of the ECS Cluster that you created.<\/li>\n<li>SERVICE_NAME=\u201dCHANGE_ME\u201d<br \/>\nAssign the Service name that got created in the ECS Cluster.<\/li>\n<li>TASK_DEFINITION_NAME=\u201dCHANGE_ME\u201d<br \/>\nAssign the Task name that got created in the ECS Cluster.<\/li>\n<li>DESIRED_COUNT=\u201dCHANGE_ME\u201d<br \/>\nAssing the number of tasks you want to be created in the ECS Cluster.<\/li>\n<li>IMAGE_REPO_NAME=\u201dCHANGE_ME\u201d<br \/>\nAssign the ECR Repositoy URL<\/li>\n<li>IMAGE_TAG=\u201d${env.BUILD_ID}\u201d<br \/>\nDo not change this.<\/li>\n<li>REPOSITORY_URI = \u201c${AWS_ACCOUNT_ID}.dkr.ecr.${AWS_DEFAULT_REGION}.amazonaws.com\/${IMAGE_REPO_NAME}\u201d<br \/>\nDo not change this.<\/li>\n<li>registryCredential = \u201cCHANGE_ME\u201d<br \/>\nAssign the name of the credentials you created in Jenkins to store the AWS Access Key and Secret Key<\/li>\n<\/ol>\n<\/li>\n<li>Check the status to confirm that the file has been changed.<br \/>\ngit status<br \/>\ncat Jenkinsfile<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh5.googleusercontent.com\/8rZvsHLigsF0UGgmpFOL8-kABHWoY91WVul3CYf7UXoEqQpSE4IPMGO5Ql9YcQzvmRdQZGP3P-lo1Zm1WWSNoyhctZESjrOFLIhMS40bm2yWtOKl_sBN5P8Hk6eLW6jrISVTgBkQ\" width=\"624\" height=\"211\" \/><\/p>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>Add a file to the git staging area, commit it and then push to the remote Github Repository.<br \/>\ngit status<br \/>\ngit add Jenkinsfile\u00a0<br \/>\ngit commit -m \u201cAssigned environment specific values in Jenkinsfile\u201d<br \/>\ngit push<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/cY6xfIMHKaQwm45ddecWi3aJRnKOfiI7I8eyL9NDS6XEnj0zJjz0UdyC2WkQqYaQAVRRz_1Dt0GQ7m6qcR0dao-nXaCqbV5SfNAWBOWwcc4nLBNK9y7na0Hmwl-_5iOPkwE1Jc2q\" width=\"624\" height=\"263\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-error-on-jenkins-server\" style=\"text-align: justify;\">Error on Jenkins Server<\/h3>\n<p style=\"text-align: justify;\">After pushing the commit, the Jenkins Pipeline will get triggered. However, you will see an error \u201c<strong><em>Got permission denied while trying to connect to the Docker daemon socket at unix:\/\/\/var\/run\/docker.sock<\/em><\/strong>\u201d in your Jenkins Job. The reason for this is, a \u201cjenkins\u201d user that is used by the Jenkins Job is not allowed to create docker objects. To give permission to a \u201cjenkins\u201d user, we added it to the \u201cdocker\u201d group in the previous step; however, we did not restart the Jenkins service after that.\u00a0<\/p>\n<p style=\"text-align: justify;\">I kept this deliberately so that I could show you the need to add the \u201cjenkins\u201d user to the \u201cdocker\u201d group in your EC2 Instance.<\/p>\n<figure class=\"wp-block-image\" style=\"text-align: justify;\"><img src=\"https:\/\/lh6.googleusercontent.com\/7RaCkj-_tCyzVirkMYxUuAFTH0-q1SNQgy6oyq_lrYXPoHfpgvP28ox-6VddUGLzPW3-AcKtcXHZVnyNTMF48v462PpVAHcYJ6fhf8DghiAjC5K_w9NmNMs2AMQ7M2ucRJyHmz9L\" alt=\"\" \/><\/figure>\n<p style=\"text-align: justify;\">Now you know what needs to be done to overcome the above error.<\/p>\n<ol style=\"text-align: justify;\">\n<li>Restart the Jenkins service.<br \/>\nsudo service\u00a0 jenkins restart<\/li>\n<li>Check if the Jenkins service has started or not.<br \/>\nsudo service\u00a0 jenkins status<img loading=\"lazy\" src=\"https:\/\/lh5.googleusercontent.com\/ZVaTd6jpzx2p5US0cpzSgFQvIRlxyWubXLgGrhnO4q00jLPVCu6M2fdDMSRLWJj91hqKtMRVULxiZ32sLKhUSigivUzFVpZZhv8R6_MWSRNMR2ynDTU9IfrPZSLJMN1oJjoq0Im0\" width=\"624\" height=\"191\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-push-your-third-commit\" style=\"text-align: justify;\">Push your third commit<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Make some changes in README.md to commit, push and test if the Pipeline gets triggered automatically or not.<br \/>\nvim README.md<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Add, commit and push the file.<br \/>\ngit status<br \/>\ngit diff README.md<br \/>\ngit add README.md<br \/>\ngit commit -m \u201cModified README.md to trigger the Jenkins job after restarting the Jenkins service\u201d<br \/>\ngit push<br \/>\n<img loading=\"lazy\" src=\"https:\/\/lh5.googleusercontent.com\/_4kDTfHacLFSpMs6WqQM7aqyR63VSVoiGiewneiOH4uo66yXJPqslZRoP5TTirR3xN_VyOdIaOM374xaQZBfIpW-l54j9Mkq3-BYLPOc9ToF0EweVxlex-HiBZZ8rgZxWrMLjCKu\" width=\"624\" height=\"276\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>This time you can observe that the job must have got triggered automatically. Go to the Jenkins job and verify the same.<br \/>\n<img loading=\"lazy\" src=\"https:\/\/lh6.googleusercontent.com\/ELkmgfAmMy7yQ1gyNe8ymq0XGPO0D8fYt1ehSkDyBF806BlDl54I-4R8LsNI-rI0uvEhHNLPEOMamUr3chhRD3pP6Hj7qiMj814a3mLQNJy67Y0OuRnF9I_EInjwHymDkeMTDIre\" width=\"624\" height=\"339\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"4\">\n<li>This is how the Stage View looks like. It shows us the stages that we have specified in our Jenkinsfile.<br \/>\n<img loading=\"lazy\" src=\"https:\/\/lh6.googleusercontent.com\/xcEFDCiYcmjLgtQFWaKpR8RtDrHbV4q0s3ws7hiIWr3akwmdBOY3VmcXmKx0UjUVaMjFRgNUbuyzihOEnRBxfyR8GjWFKD9C1WAssTwVGXsIctEu6EWFnGdODL1EvEbmnsfG-UWP\" width=\"624\" height=\"188\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-check-status-of-the-task-in-the-ecs-cluster\" style=\"text-align: justify;\">Check Status of the Task in the ECS Cluster<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Go to the Cluster, click on the \u201cTasks\u201d tab, and then open the running \u201cTask\u201d.\u00a0<img loading=\"lazy\" src=\"https:\/\/lh3.googleusercontent.com\/ECzDGWksOLnNFBLHhDj0yU7mtZ3D-XaS6LkPO2pNDyUc_w2DjUqU0nkR3np7qDi5K-MfxBhRIsJqFBSVlWrJRWndY62mMjDHb1Ln2dsivrvlavSUa-Or5ztYVqk7_u-BaxmXk5n9\" width=\"624\" height=\"256\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"2\">\n<li>Click on the \u201cJSON\u201d tab and verify the image, the image tag should match with the Jenkins Build number. In this case, it is \u201c6\u201d and it matches with my Jenkins Job Build number.<\/li>\n<\/ol>\n<figure class=\"wp-block-image\" style=\"text-align: justify;\"><img src=\"https:\/\/lh5.googleusercontent.com\/lNbSk74uhhu6YJWnCGDw1Owg5j6bbKHEgYMPN8DjPDjm4cX4afktK8jEYp73KOaTMAkzjDhFzv7s4qdfVRSP1CadJmnCbf1WBKZ8Ne8abUQsU_CXF9slwW7i_5CSne8_j7leHtzF\" alt=\"\" \/><\/figure>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"3\">\n<li>Hit the ELB URL to check if the Nodejs application is available or not.You should get the message as follows in the browser after hitting the ELB URL.<img loading=\"lazy\" src=\"https:\/\/lh3.googleusercontent.com\/qzDU0d_j-gegJ9OLeDzORKtAMMF-xKNgAKHaPjz4oPNDoEA-g4fiGGqsDWktWsQDhzIBRSCTleepJ4yw1dl_FhdnANDIIunc5Z_3woiAh9c8lSmXhzwu2KgodB7VFOF4u5xFAFNc\" width=\"624\" height=\"49\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h3 id=\"h-push-your-fourth-commit\" style=\"text-align: justify;\">Push your fourth commit<\/h3>\n<ol style=\"text-align: justify;\">\n<li>Open the \u201csrc\/server.js\u201d file and make some changes in the display message to test the CI CD Pipeline again.<br \/>\nvim src\/server.js<\/li>\n<li>Check the files that have been changed. In this case, only one file can be seen as changed.<br \/>\ngit status<\/li>\n<li>Check the difference that your change has caused in the file.<br \/>\ngit diff src\/server.js<\/li>\n<li>Add the file that you changed to the git staging area.<br \/>\ngit add src\/server.js\u00a0<\/li>\n<li>Check the status of the local repository.<br \/>\ngit status<\/li>\n<li>Add a message to the commit.<br \/>\ngit commit -m \u201cUpdated welcome message\u201d<\/li>\n<li>Push your change to the remote repository.<br \/>\ngit push<\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><img loading=\"lazy\" class=\"aligncenter\" src=\"https:\/\/lh4.googleusercontent.com\/WT2JY7kQD7KiLWkd-OYHs4dmL89bScNOedIRvwppQSwkl2gEQlOdK1cSJVwJRAUZitzCTYRo6KN4OPVVloN5yquA1XoKOSysJyvatp2AKh5iP5ChPMcjsCSFhfoqi4bfIjZwpGbe\" alt=\"\" width=\"624\" height=\"363\" \/><\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"8\">\n<li>Go to the Task, this time you will see 2 tasks running. One with the older revision and one with the newer revision. You see 2 tasks because of the rolling-update deployment strategy configured by default in the cluster.<br \/>\n<img loading=\"lazy\" src=\"https:\/\/lh3.googleusercontent.com\/wS6w4DNal2dFIqZilV_HU0vcQJTXKYDjwdUcndNFc9isCbx2ap-2Ma9VAzr0vnA8Y5UZFQL8O5YiIib3zuESjZGPYPSmYsVZ9Ww6daGOjHIJLEFzE8zEPcI7JK8772K1K2EXeE4E\" width=\"624\" height=\"135\" \/><\/li>\n<\/ol>\n<p style=\"text-align: justify;\">Note: Your revision numbers may differ.<\/p>\n<ol style=\"text-align: justify;\" start=\"9\">\n<li>Wait for around 2-3 minutes, and you should only have one task running with the latest revision.<br \/>\n<img loading=\"lazy\" src=\"https:\/\/lh4.googleusercontent.com\/cou7TeIBsyIRecJtgl8xcKYXw2WcHBqoFKMwjEn5sGoA6Fmge6QXyHabI1m992wEUH_LqV6uD2_yK9acsTqUZXRg7kT7gGtT_ZHLvJgVItWokz_TRpdQeF8CfxSDlwOn5C4OmmhE\" width=\"624\" height=\"128\" \/><\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<ol style=\"text-align: justify;\" start=\"10\">\n<li>Again hit the ELB URL and you should see your changes. In this case, we had changed the display message.<br \/>\n<img loading=\"lazy\" src=\"https:\/\/lh3.googleusercontent.com\/QiKdRWxEq0L2M6KVAra2dxzSysEOM4m-lRZWW--b5za6uyqctyq61Lsh0XGgIsQkOCAj64c_bqg-Dktl1yG-ZdNxllPI_jom9CSD32JkBDBuB6MwPXgsxvZ8TvS3eigj5wqFdNnS\" width=\"624\" height=\"49\" \/><\/li>\n<\/ol>\n<p style=\"text-align: justify;\"><strong>Congratulations<\/strong>! You have a working Jenkins\u00a0<strong>CI CD Pipeline<\/strong>\u00a0to deploy your Nodejs containerized application on AWS ECS whenever there is a change in your source code.<\/p>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h2 id=\"h-cleanup-the-resources-we-created\" style=\"text-align: justify;\">Cleanup the resources we created<\/h2>\n<p style=\"text-align: justify;\">If you were just trying out to set up a CI CD pipeline to get familiar with it or for POC purposes in your organization and no longer need it, it is always better to delete the resources you created while carrying out the POC. As part of this CI CD pipeline, we created a few resources. We created the below list to help you delete them.<\/p>\n<ol style=\"text-align: justify;\">\n<li>Delete the Github Repository<\/li>\n<li>Delete the Github Token<\/li>\n<li>Delete the IAM User<\/li>\n<li>Delete the EC2 Instance<\/li>\n<li>Delete the ECR Repository<\/li>\n<li>Delete the ECS Cluster<\/li>\n<li>Deregister the Task Definition<\/li>\n<\/ol>\n<div class=\"wp-block-spacer\" style=\"text-align: justify;\" aria-hidden=\"true\">\u00a0<\/div>\n<h2 id=\"h-summary\" style=\"text-align: justify;\">Summary<\/h2>\n<p style=\"text-align: justify;\">And finally, here is the summary of what you have to do to set up a CI CD Docker pipeline to deploy a sample Nodejs application on AWS ECS using Jenkins.\u00a0<\/p>\n<ol style=\"text-align: justify;\">\n<li>Clone the existing sample Github Repository<\/li>\n<li>Create a new Github Repository and copy the code from the sample repository in it<\/li>\n<li>Create a Github Token\u00a0<\/li>\n<li>Create an IAM User<\/li>\n<li>Create an ECR Repository<\/li>\n<li>Create an ECS Cluster<\/li>\n<li>Create an EC2 Instance for setting up the Jenkins Server<\/li>\n<li>Install Java, JSON processor jq, Nodejs, and NPM on the EC2 Instance<\/li>\n<li>Install Jenkins on the EC2 Instance<\/li>\n<li>Install Docker on the EC2 Instance<\/li>\n<li>Install Plugins<\/li>\n<li>Create Credentials in Jenkins<\/li>\n<li>Create a Jenkins Job<\/li>\n<li>Integrate Github and Jenkins<\/li>\n<li>Check the deployment<\/li>\n<li>Cleanup the resources<\/li>\n<\/ol>\n<figure class=\"wp-block-image size-large\" style=\"text-align: justify;\"><\/figure>\n<h2 id=\"h-conclusion\" style=\"text-align: justify;\">Conclusion<\/h2>\n<p style=\"text-align: justify;\">A CI CD Pipeline serves as a way of automating your software applications\u2019 builds, tests, and deployments. It is the backbone of any organization with a DevOps culture. It has numerous benefits for software development and it boosts your business greatly.\u00a0\u00a0<\/p>\n<p style=\"text-align: justify;\">In this blog, we demonstrated the steps to create a Jenkins CI CD Docker Pipeline to deploy a sample Nodejs containerized application on AWS ECS. We saw how Github Webhooks can be used to trigger the Jenkins pipeline on every push to the repository which in turn deploys the latest docker image to AWS ECS.<\/p>\n<p style=\"text-align: justify;\">CI CD Pipelines with Docker are best for your organization to improve code quality and deliver software releases quickly without any human errors. We hope this blog helped you to learn more about the integral parts of the CI CD Docker Pipeline.<\/p>\n<h2 id=\"h-faq\" style=\"text-align: justify;\">FAQ<\/h2>\n<div class=\"schema-faq wp-block-yoast-faq-block\">\n<div id=\"faq-question-1632242778901\" class=\"schema-faq-section\" style=\"text-align: justify;\"><strong class=\"schema-faq-question\">What is a CI CD Pipeline?<\/strong><\/p>\n<p class=\"schema-faq-answer\">In simple words, a CI CD Pipeline is a set of instructions executed in order to deliver a newer version of your software application.<\/p>\n<\/div>\n<div id=\"faq-question-1632242820313\" class=\"schema-faq-section\" style=\"text-align: justify;\"><strong class=\"schema-faq-question\">Why should I use a CI CD Pipeline?<\/strong><\/p>\n<p class=\"schema-faq-answer\">To avoid human errors, enhance code quality, improve release cycles, add technical and business values, improve customer satisfaction, and much more.\u00a0<\/p>\n<\/div>\n<div id=\"faq-question-1632242839561\" class=\"schema-faq-section\" style=\"text-align: justify;\"><strong class=\"schema-faq-question\">Which are the basic stages of any CI CD Pipeline?<\/strong><\/p>\n<p class=\"schema-faq-answer\">Any basic CI CD Pipeline typically includes \u2013 Pull, Test, Build, Push and Deploy stages.<\/p>\n<\/div>\n<div id=\"faq-question-1636391551439\" class=\"schema-faq-section\" style=\"text-align: justify;\"><strong class=\"schema-faq-question\">Does setting up a CI CD Pipeline need any Programming knowledge?<\/strong><\/p>\n<p class=\"schema-faq-answer\">Not really. If you are working with a tool like Jenkins that has GUI, you can simply create a CI CD Pipeline by making some configurations on the UI. You may need some basic understanding of scripting to automate your tasks or execute commands.<\/p>\n<\/div>\n<div id=\"faq-question-1636391571148\" class=\"schema-faq-section\" style=\"text-align: justify;\"><strong class=\"schema-faq-question\">What is a CI CD Docker Pipeline?<\/strong><\/p>\n<p class=\"schema-faq-answer\">A CI CD Pipeline that tests, builds, and deploys Docker Containers of your applications is referred to as CI CD Docker Pipeline.\u00a0<\/p>\n<\/div>\n<div id=\"faq-question-1636391576241\" class=\"schema-faq-section\"><strong class=\"schema-faq-question\">Why should I use CI CD Pipeline with Docker?<\/strong><\/p>\n<p class=\"schema-faq-answer\" style=\"text-align: justify;\">One can use CI CD Pipeline with Docker to specifically automate the Software Development process and improve release cycles of microservices-based applications.<\/p>\n<\/div>\n<\/div>\n<p><\/p>","protected":false},"excerpt":{"rendered":"<p>If you\u2019re still\u00a0building and delivering your software applications the traditional way then you are missing out on a major innovation in the Software Development Process or Software Development Life Cycle. To show you what I\u2019m talking about, in this article I will share \u201cHow to create a CI CD Pipeline with Jenkins, Containers and Amazon [&hellip;]<\/p>\n","protected":false},"author":21,"featured_media":3824,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[13],"tags":[],"_links":{"self":[{"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/posts\/3816"}],"collection":[{"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/comments?post=3816"}],"version-history":[{"count":14,"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/posts\/3816\/revisions"}],"predecessor-version":[{"id":3902,"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/posts\/3816\/revisions\/3902"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/media\/3824"}],"wp:attachment":[{"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/media?parent=3816"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/categories?post=3816"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vticloud.io\/en\/wp-json\/wp\/v2\/tags?post=3816"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}