Many organizations have been shifting to DevOps practices, which is the combination of cultural philosophies, techniques, and tools. Collectively, they increase your organization’s ability to deliver applications and services at high velocity. For example, evolving and improving products faster than organizations using traditional software development and infrastructure management processes to automate deployments on AWS.
An integral part of DevOps is adopting the culture of continuous integration and delivery/deployment (CI/CD). A commit or change to code passes through various automated stage gates, from building and testing to deploying applications from development to production environments.
To illustrate, we will build a CI/CD pipeline in this blog using automate deployments on AWS native tools to understand conceptually CI/CD pipeline, which is highly recommended.
Architecture Diagram of Automated Deployments on AWS:
This blog will brainstorm the thought process and the reasoning behind choosing the tools to build CI/CD pipeline. We will make a simple web application hosted on the EC2 server and use all AWS native services on the AWS platform. A quick brief about what is essential in choosing the right tools for CI/CD implementation:
The first step in any implementation should be security. Application architecture, hardware, network, and data should collectively contribute to building a secure environment.
Architecture should allow multiple and concurrent implementations. At the same time, it should enable rigorous testing for applications built to be First time Right. Microservice architecture is best for achieving these goals.
However, different applications may have different suited architectures like Service Oriented architecture (SOA) and Lambda Architecture.
Services and tools:
- Source Control repository: AWS CodeCommit
- Build: AWS CodeBuild
- Deployment: AWS CodeDeploy
- Notification: AWS SNS
- Hosting webserver: EC2 AMI
- CI/CD Pipeline: AWS Codepipeline
Stage 1: Source Control repository (AWS CodeCommit)
AWS Code Commit is serverless. Data is encrypted at rest and has SSH, or HTTPS endpoints enabled for data in transit. It offers data durability, data availability, automatic scaling, and more critical data is stored away from computing resources. At the same time, it is pretty inexpensive.
Diagram explaining the Flow of AWS CodeCommit:
We will set up a code repository to automate deployments on AWS and push code from the local machine to the code commit repository. We will use the AWS region as us-east-1 (N. Virginia) for all services throughout the blog.
- Create repository: Login to your AWS management console and search for code commit. On the homepage, click “Create repository.” Fill in the below details and click create. We can use the CodeCommit console, AWS CLI, or GIT client to push code to CodeCommit. In this blog, we will use GIT bash.
- Clone Repository: In the AWS console, choose Clone URL on the top right of the page, and then choose Clone HTTPS. The address to clone your GIT repository is copied to your clipboard. Open GIT bash and type in command GIT clone followed by URL copied earlier. It will prompt credentials to connect to AWS via GIT for the first time.
- Push Code to Repository: Download code from GitHub. Just follow the screenshots. Place code in folder DemoCICD. As a best practice, we should create a branch and merge code to branch, but to make this article simpler, we will merge code to master for now. Shift to the current directory and use the command below to add new files.
Once new files are added, use the below command to commit changes.Now push files to the AWS CodeCommit repository using the below commandCheck repository in AWS. All files should be copied. Appspec.yml contains settings for CodeDeploy. Buildspec.yml has settings for CodeBuild
Pre-requisite for Build:
EC2 instance to host application and deploy Code Deploy agent- We will launch an EC2 Linux instance to host a web application. Then we will deploy Code Deploy agent in order to deploy the build artifact to the machine.
Launch EC2 instance:
- Open the Amazon EC2 console
- From the console dashboard, choose Launch instance
- On Step 1: Choose an Amazon Machine Image (AMI), locate Amazon Linux 2 AMI (HVM), SSD Volume Type, and then choose Select.
- Then, on Step 2: Choose an Instance Type page, choose t2.micro type (the free tier eligible), and then choose Next- Configure Instance Details.
- Finally, on Step 3: Configure Instance Details page, do the following:
In Auto-assign Public IP, choose Enable.
In the IAM role, choose the IAM role you created in the previous procedure (for example, DemoCICDEC2InstanceRole)
- Expand Advanced Details, and in the User data field, enter the script below, which will be executed at the time of launch installation.
- Click Add Storage -> click Add Tags -> Create a tag with key as “purpose” and value as Demo CI/CD.” We will identify EC2 instances for deployment with these tags. Configure Security Group
- Under Configure Security Group, choose to assign a security group: “Create a new security group.” The security group name is “SG-EC2-CICD”. Add SSH (to access the instance via putty) and HTTP (to access web application) type of port and in source choose “My IP” Click “Review and Launch” Download key file and then press “Launch.”
Building Package and Project: AWS CodeBuild:
We will create a building project that will automate deployments on AWS CodeBuild will use to run the build in this step. Sign in to the AWS management console and search CodeBuild. Choose the same AWS region (N. Virginia). Click create build and fill in the details below:
Project Name: BuildCICD. Fill in the Description and create a tag as per best practice.
Source: Source provider — AWS CodeCommit, Repository — DemoCICD, Reference type — Branch, Branch master
Environment: select Managed image, operating system as Amazon Linux 2, runtime — standard, image- amazonlinux2–86_64-standard:1.0 (or suitable for your use case), service role — New Service role
Buildspec — select a buildspec file (we will discuss this shortly)
Leave everything else the same and click create build project
BuildSpec: A buildspec is a collection of commands and related settings that the codeBuild service uses to run a build. Either you can include a buildspec.yml file as part of the source code or enter build commands while building a project. We have uploaded buildspec.yml file to the code repository.
It can have different phases like install, pre_build, build, and post_build.
Deployment with AWS CodeDeploy:
CodeDeploy is a fully managed service used to fully automate software deployment. It can be used to deploy code to AWS EC2 or on-premises servers, AWS Fargate, and AWS Lambda.
Create an application in CodeDeploy:
- Firstly, open the CodeDeploy console
- Secondly, if the Applications page does not appear, choose Applications on the AWS CodeDeploy menu.
- Thirdly, choose Create application. In the application name, enter CICDDemoApplication.
- Fourthly, in Compute platform, choose EC2/On-premises.
- Finally, choose Create application.
Deployment Group: In the deployment group, we will define deployment-related settings. On the page that displays your application, choose to Create a deployment group.
In the Deployment group name, enter DemoCICDDeploy.
In Service Role, choose the service role you created earlier (for example, CodeDeploy).
Under Deployment type, choose In-place.
Following that, under Environment configuration, choose Amazon EC2 Instances. Enter the name you used to tag the instance (example: MyCodePipelineDemo). Afterwards, under Deployment configuration, choose CodeDeployDefault.OneAtaTime.
Then, under Load Balancer, clearly Enable load balancing. You do not need to set up a load balancer or choose a target group for this article.
Choose Create deployment group.
We have completed configuring all services required for building a pipeline. Now, we will make a plug-and-play CI/CD pipeline using the above-created services.
AWS Code pipeline is a fully managed serverless service that helps in automating the entire software delivery release. It is a pipeline wherein we can call all other services like Codebuild, CodeCommit, manual approvals, testing, deployment, etc., in any order and any number of times. Additionally, it is entirely serverless, works on a pay-as-you-go cost model with a fully secured & configurable workflow, and enables one place monitoring and rapid software delivery.
- Sign in to the AWS Management Console and open the CodePipeline console
- Choose Create pipeline. Give pipeline name as “DemoCICD.” Fill in the details as mentioned below:
Provide Build provider as AWS Code Build and fill in the details as mentioned below and click Next.
Choose the deploy provider as CodeDeploy and fill in the rest of the details like below.
Click next and review the changes. If all looks fine, then click Create pipeline. This will start the pipeline for the very first time. If everything is set correctly, it should succeed. Now, this is Continuous deployment. The pipeline will automatically trigger if you commit any changes. Since we have created a web server, you can try accessing the website using EC2 instance public IP.
SNS- Manual Approval:
Let’s create a new step to add manual approval. For this, click Edit on the pipeline page. We will add approval after the build stage. For this, click on + Add Stage after the build stage. Give name as “Production-Sign-off.” Under the Production-Sign-off, click Add action group. I have already created an SNS to send me an email for approval.
Click done. With this, we have successfully added a manual approval stage. To auto-trigger the entire pipeline, we will just modify index.html in our local and push it to CodeCommit.
We have successfully built a complete CI/CD pipeline using automate deployments on AWS CodeCommit, AWS CodeBuild, AWS CodeDeploy, AWS SNS, EC2, and AWS Code pipeline. Using this solution, you can easily set up and manage an entire CI/CD pipeline in AWS accounts using the native AWS suite of CI/CD services. In this, a commit or change to code passes through various automated stage gates all the way from building and testing to deploying applications, from development to production environments much faster.