DevOps On AWS: CodePipeline In Action

Kelvin Onuchukwu - Jun 2 '23 - - Dev Community

This post was originally published at Practical Cloud.
View the original post here.

This is the second part of a three series project on designing and deploying a three-tier architecture on AWS. Here is the link to the first part of this project.

DevOps on AWS is the implementation of the DevOps philosophy on the AWS Cloud platform. This includes implementing an effective CI/CD solution that provides components such as Load Balancing, Content Delivery, Storage, Security, Database, Caching and Scaling.
AWS provides a set of tools for implementing DevOps which includes,but may not be limited to:

  • AWS CodeCommit: This is a cloud version control service that is quite secure and highly scalable.
  • AWS CodeBuild: This is a fully managed build and continuous integration service in the cloud. It provides similar capability to Jenkins. It is also highly scalable, offering continuous scaling and high availability.
  • AWS CodeDeploy: This is a deployment service that automatically deploys applications to EC2 instances, On-premises servers, Lambda functions and ECS.
  • AWS CodePipeline: This is a managed continuous delivery service that can be used to automate a release pipeline. AWS also offers other supplementary services such as CodeStar, Device Farm, etc which can help improve the quality of your DevOps experience on AWS.

In this project, we'll be making use of CodePipeline as the continuous delivery service for automating the deployment of our three-tier application to AWS.

  • We'll be using GitHub, instead of CodeCommit for source control.
  • We'll use CodeBuild for building and testing our application code. CodeBuild will also be used to execute our terraform scripts in order to provision environments for the application. At this stage we'll also add a manual step, which involves sending SNS notifications to the user after a "terraform plan". If we are happy with the plan, then we go ahead to approve, which takes it to the next step.
  • CodeDeploy will then be used to deploy the Flask application to our EC2 instances.

Lets Go!

Step 1: Fork The Application repository

This is a very important first step. CodePipeline will listen for changes to our application. To follow through with the rest of the project, you'll need to have the repository in your GitHub account. Here is the link to the project on GitHub. Fork the repository.

Step 2: Provision The Environment

Clone the repository to your local computer.
Navigate into the terraform directory. Edit the backend.tf file and add your own backend.
Run terraform plan. if you like the plan, then run terraform apply. After the apply is successfully executed, you should see your bastion host's IP address and your application's DNS address on your screen.

Step 3: Create A Build Project

This is where we integrate our source control.
CodeBuild enables us to perform testing and other necessary builds and integrations. It is our build server of choice for this project.
On the CodeBuild Console, create a project. Choose a suitable name and description. Enable build badge.
Build badges are images provided through a public URL which displays the status of our latest build.
AWS CodeBuild

Your source provider should be GitHub. Connect to your GitHub account. Source version is master (The master branch).
Codebuild connect to GitHub

Choose Ubuntu as your operating system. Choose the standard runtime and select "create a new service role".
CodeBuild

Because I want CodeBuild to have private access to my servers, I will click on "Additional configuartion".
Under VPC, Ill select the project-x-vpc that I provisioned using terraform.
Leave every other setting as is. Click on create build project.
N.B: The secret sauce for CodeBuild is the buildspec file at the root of the application's repository. This is where I define what happens during the build phase. CodeBuild cannot run without a buildspec file. By default, this file must be named buildspec.yml though you can change this behaviour.

Step 4: Create An IAM Role For CodeDeploy

CodeDeploy will require IAM permissions in order to access the application servers.
Go to the IAM Console, click on "Roles", click on "Create role".
We will create a service roles which CodeDeploy will assume to gain access to our EC2 servers.

IAM role for CodeDeploy
Click on Next.
Iam for codedeploy

Since our AutoScaling group will be originally launched from a launch template, we will need to add extra permissions.
Click on Add permissions, Attach policy, Create policy
Our json policy willl look like this:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "ec2:CreateTags",
                "ec2:RunInstances",
                "iam:PassRole"
            ],
            "Resource": "*"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Click on Next. Review and create your policy. It should look like this:
Iam Policy

Now go back and attach this permission, it should look like this:
CodeDeploy Role
Click Next, Review and create your role.

Step 5: Configure CodeDeploy

AWS CodeDeploy is a deployment service that automates the continuous deployment of application updates/versions to your servers.
Click on CodeDeploy drop down on the Left hand side of your screen. Click on "Applications". Click on "Create Application".
Application in CodeDeploy is a mechanism by which it manages revisions, deployment configurations and deployment groups.
Choose a name for your application and select a platform. Click on "Create application".
CodeDeploy

Click on "Create deployment group".
Choose a name for your group. Select the CodeDeploy service role we created in step 4.
Create A CodeDeployment Group

Now because I want MINIMUM downtime, I'll be using a blue/green deployment type. You can visit here to get more information about blue/green deployments.
code deploy

Select the project-x-asg auto scaling group and also choose terminate after 5 minutes. Under Application Load Balancer, select your provisoned project-x-lb-tg target group as the target group of choice.
code deploy

Click on "advanced options". Enable deployment rollbacks on failures. Create your deployment group.
Code deploy

We don't need any triggers for this deployment group. you typically use triggers if you are simply automating your deployment. But since this is a CI/CD pipeline, we'll leave everything to CodePipeline to orchestrate.

N.B: The secret sauce for CodeDeploy is the appspec file at the root of the application's repository. This is where I define what happens during the deploy phase. CodeDeploy cannot run without an appspec file. By default, this file must be named appspec.yml though you can change this behaviour.
Also note that the only reason this would work is because I already included instructions for installing the CodeDeploy as part of the user data on the logic tier servers. Therefore they will be automatically provisoned by terraform. If you were to use a different environment, remeber to install the CodeDeploy agent on your servers. You can find instructions on how to do that here.

Step 6: Create A Pipeline

AWS Codepipeline acts as our continuous delivery service. It is the glue that holds our entire together and also orchestrates it. CodePipeline will seamlessly handle the integration of source control, CodeBuild and Codedeploy.

Go to the Pipeline Console, click on "Create Pipeline".
AWS pipeline console

Choose a name for your pipeline. Click on Next.
Creating an AWS CodePipeline

Under source stage, select GitHub from the drop down. Authorize access to GitHub.
Creating a pipeline

CodePipeline allows us to choose either Jenkins or CodeBuild as our build provider. We are going to choose CodeBuild.
Under project name, select the build project we created in step 3.
Creating a pipleine

On the Add Deploy stage, we will use CodeDeploy as our deploy provider. Then we will select the application name and deployment group we created earlier on in step 5.
CodePipeline
Review and create your pipeline.

Aaaaaaaaaaaaaaaaaaannnnnnndd............Done!!!
We have successfully created a CI/CD pipeline on AWS using AWS CodePipeline.

Before You Go..
Let's take this a notch further by adding a manual approval feature through which manual approval must be given before the application is deployed.

Step 7: Create An SNS Topic

For manual the manual approval stage, we want to be able to send an email notification to the team lead that the buid is successful and about to deploy. The team lead must then review the artifacts and/or log outputs from the build and make a decision whether to continue to deploy or not.

Go to the AWS SNS console, create a topic.
Choose a standard topic. Give a name and display name to your topic. create the topic.
Image description

Step 8: Modify The Pipeline

Now we have to include an action group after the build stage to enable a manual approval feature.

Go to the pipeline, click on Edit.
Image description

On the Build Stage, click on Edit.
Here, we will add an action group just after the build.
An Action Group is a set of one or more actions through which you can further refine your pipeline workflow. There are six types of actions - source, build, test, deploy, approval and invoke. Read more about them here.
Your pipelie should now look like this:
Pipeline
Without the red lines of course!

That's it. I hope you enjoyed it. Happy Clouding!!!

. . . . . . . . . . . . . . . . . .