CI/CD with AWS codeDeploy and CodePipeline

In last article we learnt to prepare our git collaboration before implementing CI/CD. In this article we will learn how to setup CI/CD with AWS. We can also use AWS codeCommit instead of Github but we will use Github for simplicity in this article. Flow of the deployment will go like below:
Dev Team -> Git Commit -> Codepipeline prepare build -> CodeDeploy pushes changes to EC2 server

We will use following AWS services:
1. AWS EC2 Instance: Instance to deploy code
2. AWS CodeDeploy: AWS service to setup automatic deployments
3. AWS CodePipeline: AWS service to create chained actions for CI/CD
4. AWS S3: A bucket will be used to prepare build before deployment

Setting up Roles and permissions in AWS:
All AWS services are handled by some users with certain roles to access like we need some user with permitted access to EC2 instance to manage auto deployment through CodeDeploy. Here are the roles that need to be created:
1. CodeDeployRole:
This role will be used to trigger CodeDeploy Service. To create this role go to AWS IAM Console, click on Roles, create New Role, Choose AWS Service, Select CodeDeploy, Select CodeDeploy for use case also, review permission and create. Alternatively, you can create a policy as following and attach to a role named CodeDeployRole

2. EC2S3Role:
This Role will be used to access build from S3 created by CodeDeploy. To create this role go to AWS IAM Console, click on Roles, create New Role, Choose AWS Service, Select EC2, Select AmazonS3ReadOnlyAccess for permission, review permission and create. Alternatively, you can create a policy as following and attach to a role named EC2S3Role

3. AWS-CodePipeline-Service:
This Role will be used by CodePipeline to create build and submit it to codeDeploy. This can be created during Pipeline setup. Alternative way is to copy JSON from here and create new policy and attach this policy to this AWS-COdePipeline-Service Role.

Create EC2 Instance, setup environment and install CodeDeploy Agent:
Create a new EC2 instance and chose EC2S3Role and setup application environment or if you already have some running instance then attach EC2S3Role to that particular instance so that it can read S3 to pull build. There should be some tag attached to the EC2 which will be used by Codedeploy to identify instance.  Also install CodeDeploy agent on the instance and make sure it is running. This agent will be responsible for auto deployment from CodeDeploy service running in CodePipeline deployment.

Setup CodeDeploy from AWS console:
As I said this will be responsible for auto deployment in the pipeline setup. We have to create an application and under that application we can add deployment groups according to our requirements. For example if we have 3 environment then we can create 3 deployment groups
1. Development
2. Staging
3. Live
To create a codeDeploy, navigate to Services, select CodeDeploy, select Custom deployment, Give the name to this application, Give the group name(Let’s use Development now and you can add more groups later), select in-place deployment, under Amazon EC2 Instance tab select the instance tag, select role as CodeDeployRole we created earlier and create application.

Create Deploy Configuration file on Github repository:
It is necessary to add a codeDeploy configuration file on the github repository so that when a build is pushed from pipeline to codeDeploy then codeDeploy can know on which location on the EC2 instance it need to copy code and what necessary commands to run to reflect changes. You can put appspec.yml file on root of repository and create a folder named Deploy where you can put shell script  files with necessary commands which need to be run after or during deployment. Following is the sample Appspec.yml

Create the CodePipeline:
Finally, we have everything ready to setup a complete pipeline. To create this, navigate to Services, select CodePipeline, click on get started, give the name to pipeline(According to your environment), select github as Source and authorize, chose branch ,select No Build, select CodeDeploy Group according to environment, select service Role for pipeline or create new, review and finish. Your pipeline is ready. If you have 3 environments then you can create 3 pipeline(Development, Staging and Live) and chose appropriate CodeDeploy Group. You can also add additional.  You can also add additional confirmation step for Live so that it needs your approval to push changes on live server. Create a SNS using your email then go to live pipeline, edit pipeline, add new step, chose confirmation, chose SNS you created earlier then save.

Test the pipeline:
Now pipeline is ready, as soon as you merge any pull request in any environment then concerned pipeline will trigger and deploy the code on the appropriate server. You can also click on trigger button to manually start pipeline. For live pipeline, if you have added additional confirmation step then you will be notified to your email for the build and you have to approve that in aws console to push the changes to live server. Rest other environments, deployment will be fully automatic.

At first, this may look a bit difficult but once you try, it will look too easy.