Today I'll be setting up an automated delivery process using AWS codepipeline. What is codepipeline? Codepipeline is AWS's take on a CI/CD platform like Gitlab CI, Jenkins, Bamboo, and Travis CI. Codepipeline is actually multiple AWS services lumped together to automate the delivery of software as fast as possible.

The AWS services I will be using are:

  1. CodeCommit
  2. CodeBuild
  3. CodeDeploy
  4. CodePipeline
  5. Elastic Beanstalk
  6. S3
  7. EC2

Prerequisites

Before I begin, I will need to make edits to a previous flask project. This project is what I will be using for codepipeline.

  1. Open the app.py file and make the edits below. Primarily change app to application and create a new route called /status, have it return the text "blue" when someone access that part of the site.
from flask import Flask, render_template

application = Flask(__name__)

@application.route('/')
def index():
    return render_template('index.html')

@application.route('/status')
def status():
    return "blue"
    
if __name__ == '__main__':
    application.run()

2. Once you have made the changes above, rename the app.py to application.py.

3. Create a python test application on Elastic Beanstalk! Head over to the Elastic Beanstalk console page and click on "Create New Application" on the top right corner. Next click on the "Actions" button and select "Create environment".

Choose the "Web server environment".

Give your domain a name or you can let AWS name it for you. Select "Preconfigured platform" and python as the environment. Finally choose "Sample application" under the application code. Go ahead and click on "Create environment". Give Elastic Beanstalk a few minutes to setup your environment. After a few minutes you should be able to reach your website via web browser.

Once everything is up and running you should see the following in your web browser.

Now that Elastic Beanstalk is pre-warmed, we can continue you with creating a pipeline.


Creating the Pipeline

  1. Create a new code repository in CodeCommit and give it a name. Mine will be called hello-kitty. For more details on setting up a repository in CodeCommit please see this.

2.  Setting up CodePipeline.

a. Click on "Create pipeline" and fill out the pipeline name keep everything else default. This should automatically create a role for codepipeline to access resources it needs to complete the pipeline.

b. Add codecommit as the source provider, the repository name you created in the prerequisite section, and the branch. Lastly select "Amazon CloudWatch Events" as the change detection options. What this will do is kick off the pipeline as soon as new changes are pushed to the repository.

c. The next stage to setup is the build stage. In this stage select "AWS CodeBuild" as the build provider and a region. Click on "Create project" to continue setting up the project.

d. This will open a new window and in this window give the project a name, select "Managed image", and "Amazon Linux 2" for the operating system.

e. "Standard" for the runtime, "aws/codebuild/amazonlinux2-x86_64-standard:1.0" for the image. You can leave "Always use the latest image for this runtime version". This will also create a new role name, you can leave it as the default.

f. Select "Use a buildspec file" under Build specifications and leave the logs at default.

g. Create a buildspec.yml in the root directory of your project folder. This buildspec file will contain the instructions needed by codebuild on how to create the flask app. Since this is a flask app we don't need any special file formats to run the app other than the code.

version: 0.2

phases:
  install:
    runtime-versions:
      python: 3.7

artifacts:
  files:
    - '**/*'

version denotes the buildspec version to use, in this case 0.2. The phases I'll be using for this build is the install phase. This will use the python 3.7 runtime in the pipeline's container for the code to use. Once it is complete, CodeBuild will package up all of the contents pulled into the container from CodeCommit and create an artifact which will stored in S3.

- '**/*' will take all of the files and folders and create an artifact.

3. Time to configure the deploy stage!

a. Under deploy provider select "AWS Elastic Beanstalk", next select your region. Next up is the application name of the Elastic Beanstalk project that was created in the prerequisite section.

b. Next select the Elastic Beanstalk environment name, mine is called HelloKitty-env. Click on the next button to continue.

c. In the next page, review the pipeline and when you're satisfied with the pipeline, go ahead and click on the create pipeline button.

d. As soon as you click on the "Create pipeline" button, you should see the pipeline being executed.

e. Under the build section click on the "Details" link. This will bring you to the logs created during the codebuild stage. Here you can see all the commands that occurred inside of the container while your code was being built.

f. As soon as the deploy stage is complete, refresh your browser and you will be greeted by Hello Kitty!

g. Let's check what the status page shows. On your browser go to yoursite.us-east-2.elasticbeanstalk.com/status and it should say "blue".

h. Time to test the automated deployment aspect codepipeline. To do this I'll change "blue" to "green" and then push my code to the codecommit repository.

from flask import Flask, render_template

application = Flask(__name__)

@application.route('/')
def index():
    return render_template('index.html')

@application.route('/status')
def status():
    return "green"
    
if __name__ == '__main__':
    application.run()

i. The new changes will trigger and execute the pipeline again.

j. Now if I go to yoursite.us-east-2.elasticbeanstalk.com/status it should say "green"!


Conclusion

Okay now that this basic pipeline is up and running, you maybe wondering what are the next steps from here?

Well, a minor addition I would put in place is a manual approval phase. This will allow various teams to discuss the build's efficacy and decide to either move to the deployment stage or reject the job. An amazing option for an organization following a change management process.

Go back to the pipeline and click on the "Edit" button.

In the "Build" stage, click on "Add action" and give the action a name. For the action provider select "Manual approval", if you have an SNS topic you can configure it here.

Now if you kick off the pipeline, it will continue and then stop right before the deploy stage. It will not continue to the deploy stage until someone clicks on the "Review" button to either reject or approve.