Spring boot on AWS: CodeCommit, CodeBuild, and CodeDeploy - without Code pipeline

Though AWS has lauched CodeCommit but it has not got lot of traction and many organizations are still using GitHub or BitBucket.  Though an spring boot application can be deployed using Jenkins  or Bitbucket pipeline in AWS; another option is using developer tools provided by AWS.  For everything today, choice is somewhere between two extreme options (in respect to cloud): At one end is using cloud only as infrastructure provider and at other end is Serverless. The choosen option is based on context such as Organizations nature of business, Cost, comfort and familiarity with cloud, and volume.

Jenkins can be setup on EC2 instances and made run always - anyone (who has access) can initiate a build. Cost will be of continously running EC2 instances but running a build is free.  Whereas Serverless (such as CodeBuild) has no cost for running server (EC2 instances, etc.) but running each build has cost associated.

Getting Started

  1. Create user groups: Developers, Reviewers, etc. and define their roles such as who has only development environment access and who has more
  2. Define the Git flow like flow with branches: Master, Release, Hot-fix, Develop, and feature branches
  3. Merging feature branch into develop need pull request for manual code review
  4. Create CodeBuild project using Console or CLI (create-project.json).  CodeBuild picks source (code + buildspec.yml) from S3 bucket, runs the build, and saves generated packed in output bucket.  Run a full build and unit tests every time someone creates a pull request. 
  5. CodeDeploy (refers appspec.yml) will deploy the package using In-place or Blue-green option 

Though spring-boot can be deployed on EC2 instance, or Elastic Beanstalk, or ECS, or as Lambda function; i prefer EC2 instance.

If we manage everything in AWS then we can use:
  • CodeCommit as Source repository
  • CodeBuild for building the project
  • CoddDeploy for deploying the project
The purpose here is to not use Code pipeline to understand individual services and not use AWS console to get familiar with commands.

Step 1. Create new repository -
aws codecommit create-repository --repository-name MyDemoRepo --repository-description "My demonstration repository"

Step 2. Create new Spring boot project either in STS or on "https://start.spring.io/"
To verify the package run command: mvn clean install
run the spring boot application from cmd using - mvn spring-boot:run

Step 3. Setup for HTTPS Users Using Git Credentials

Step 4. Create new folder and clone the repository in this folder:
git clone https://git-codecommit.ap-xxxxx-1.amazonaws.com/v1/repos/MyDemoRepo

Step 5. Copy the spring boot project (src and pom.xml) in the folder and run git commands:
git add .
git commit -m "message"
git push

Verify the code in AWS console inside Code Deploy

Step 6. Add buildspec.yml file to project
Ref - https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html
Ref - https://docs.aws.amazon.com/codebuild/latest/userguide/getting-started.html to write a buildspec file for Java project
git commit push the buildspec.yml file.

Step 7.  Create an S3 bucket where build package will be uploaded.

Step 8. Create a CodeBuild role
Ref - https://docs.aws.amazon.com/codebuild/latest/userguide/setting-up.html#setting-up-service-role
Role should have access to CodeDeploy, Cloudwatch, and S3

Step 9. Create create-project.json
Ref - https://docs.aws.amazon.com/codebuild/latest/userguide/getting-started.html
Ref - https://docs.aws.amazon.com/codebuild/latest/userguide/create-project.html#create-project-cli
Ref - https://noise.getoto.net/2017/08/02/create-multiple-builds-from-the-same-source-using-different-aws-codebuild-build-specification-files/
Once file is ready, execute following from cli:
aws codebuild create-project --cli-input-json file://create-project.json

Step 10. Run the build. 
aws codebuild start-build --project-name codebuild-demo-project
If build is succeesful then verify the package (build) generated is stored in destination S3 bucket. 

Step 11. Launch an EC2 instance on which application will be deployed.
While launching the application put some tag.  CodeDeploy uses the tag - If 15 EC2 instances are tagged then CodeDeploy will deploy on 15 instances.
During launch of ec2, assign an IAM role.  CodeDeploy needs IAM role which was used to launch ec2 instance.  If no role is assigned then in code deploy logs following might come -
InstanceAgent::Plugins::CodeDeployPlugin::CommandPoller: Missing credentials - please check if this instance was started with an IAM instance profile

Configure EC2 -
Install jdk (this step is optional here - we can either install at this stage or we can add a scipt that will be invoked from our appspec.yml file)
yum install java-1.8.0 -y
yum remove java-1.7.0-openjdk -y
Install maven (Ref - https://gist.github.com/sebsto/19b99f1fa1f32cae5d00#gistcomment-2394990)
sudo wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
sudo sed -i s/\$releasever/7/g /etc/yum.repos.d/epel-apache-maven.repo
sudo yum install -y apache-maven
mvn --version

Step 12. Install CodeDeploy on EC2 instance
sudo yum update
sudo yum install ruby
sudo yum install wget
cd /home/ec2-user
wget https://aws-codedeploy-eu-central-1.s3.amazonaws.com/latest/install
chmod +x ./install
sudo ./install auto
sudo service codedeploy-agent status

Step 13. Add AppSpec file the spring boot application - 

Step 14.  Create Code deploy
aws deploy create-application --application-name SimpleDemoApp

Create Code Deploy deployment group 
aws deploy create-deployment-group --application-name SimpleDemoApp --deployment-group-name SimpleDemoDG --deployment-config-name CodeDeployDefault.AllAtOnce --ec2-tag-filters Key=app,Value=boot,Type=KEY_AND_VALUE --service-role-arn arn:aws:iam::32771XXXX792:role/myCodeDeploy

Create deployment 
aws deploy create-deployment --application-name SimpleDemoApp --deployment-config-name CodeDeployDefault.AllAtOnce --deployment-group-name SimpleDemoDG --s3-location bucket=shekupcode,bundleType=zip,key=deploy.zip

The configuration files used in above project can be found on GitHub

The code deployment logs on ec2 can be found here -
less /var/log/aws/codedeploy-agent/codedeploy-agent.log

The above steps invole manual orchetration.  We can use comething like AWS lambda to automate the steps:

Integrating Lambda with third party tools can be a challenge.  Instead better approach will be using Code Pipeline.