Continuous integration and delivery (CI/CD) using AWS CDK Pipelines with Bitbucket

mohammedismaeel

Mohammed Ismaeel

Posted on October 12, 2021

Continuous integration and delivery (CI/CD) using AWS CDK Pipelines with Bitbucket

When starting a new project the first problem we face is planning our infrastructure. In this post I'm giving a simple example of how we can create an automated pipeline using AWS CDK and Bitbucket repository. Before diving into Prerequisites and Steps.
let me first unravel the title of this post: “Continuous integration and delivery with AWS CDK Pipelines”

Continuous Delivery

I will assume you already have heard about the term Continuous Delivery and there is many definitions out there but the simplest is CD is a set of tools and processes that helps DevOps teams to ship higher quality software, faster.

AWS CDK vs the world

The official definition for AWS CDK is an open source software development framework to define your cloud application resources (Infrastructure) using familiar programming languages (TypeScript, JavaScript, Python, Java and C#).

Why CDk vs the world?

Basically we can compare the CDK with Serverless framework, AWS SAM, and Terraform. All these frameworks are used to develop, test and deploy your project, I will not go in all details and differences between them!
The main benefits of using AWS CDK are:

  • Easy to use, because we will use the same programing language we use in our project, CDK can be integrated in your IDE, and you don't need to learn Yml or Terraform.
  • Component reusability and sharing, just like any other software library

For more details check this post by my friend Sebastian Bille
And another good post from A Cloud Guru

AWS CodeBuild vs Bitbucket Pipelines

I had a job interview recently, and as a part of the interview process I had to do some code test. They asked to create a pipeline using AWS CodeBuild with Bitbucket? My first reaction was why you want to use CodeBuild instead of Bitbucket Pipelines?
The answer I got wasn't satisficing, The main differences I found after some search are:

  • Integration with AWS services
  • Price, Bitbucket Pipelines offer product package options than AWS offers pay-as-you-go
  • Authentication with AWS, CodeBuild has IAM Role integration which gives temporary AWS credentials

If you want to find out more about this topic please check the following articles:

Getting started

The focus of this post will be on creating pipelines-as-code, so for demonstration purposes we will create and deploy a simple react-app

Prerequisites

  • NodeJS install latest Nodejs version
  • npm or yarn should be installed globally
  • AWS CDK install with npm install -g aws-cdk or yarn global add aws-cdk
  • AWS CLI
  • AWS Account
  • Bitbucket Account

Steps

1. Create Bitbucket repo

  • Create a public or private repository in Bitbucket and name it myapp
  • Clone Bitbucket repo to your machine

2. Creating react-app

  • Create a simple react-app in the same directory of your Bitbucket repository
npx create-react-app my-app
cd my-app
yarn start
Enter fullscreen mode Exit fullscreen mode
  • Commit react-app code to Bitbucket

3. Configure AWS CLI

  • Generate an Access Key and Secret Access Key for your AWS account.
$ > export AWS_ACCESS_KEY_ID="…"
$ > export AWS_SECRET_ACCESS_KEY="…"
$ > export AWS_SESSION_TOKEN="…"
Enter fullscreen mode Exit fullscreen mode

4. Create infrastructure folder

  • Create a new folder outside the src folder and name it infra
  • Navigate to the infra folder
  • Init the CDK project
  cdk init myApp --language typescript
Enter fullscreen mode Exit fullscreen mode

5. Deploy infrastructure

Before the deployment we need to update infr.ts under /lib start by:

  • Add the following dependencies
import * as CDK from "@aws-cdk/core";
import * as CodeBuild from "@aws-cdk/aws-codebuild";
import * as CodePipeline from "@aws-cdk/aws-codepipeline";
import * as CodePipelineAction from "@aws-cdk/aws-codepipeline-actions";
import * as S3 from "@aws-cdk/aws-s3"; 
Enter fullscreen mode Exit fullscreen mode
  • Create pipeline and pipeline artifacts

    // AWS CodeBuild artifacts
    const outputSources = new CodePipeline.Artifact();
    const outputWebsite = new CodePipeline.Artifact();

    // AWS CodePipeline pipeline
    const pipeline = new CodePipeline.Pipeline(this, "Pipeline", {
      pipelineName: "MyWebsite",
      restartExecutionOnUpdate: true,
    });
Enter fullscreen mode Exit fullscreen mode
  • Add checkout stage in this stage we will clone sources from bitbucket repository we will need to create a connectionArn in this step please follow the documentation in Create a connection to Bitbucket to get your connectionArn.
// AWS CodePipeline stage to clone sources from bitbucket repository
    pipeline.addStage({
      stageName: "Source",
      actions: [
        new CodePipelineAction.CodeStarConnectionsSourceAction({
          actionName: "Checkout",
          owner: "repository owner name",
          repo: "repository name",
          output: outputSources,
          branch: "master",// the branch you deploy from
          connectionArn:
                  //Paste the generated `connectionArn` here 

        }),
      ],

    });
Enter fullscreen mode Exit fullscreen mode
  • Add Build stage to build our website, we will add a simple ./infra/lib/pipeline.yml file to run CodeBuild project
version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 12
    commands:
      - yarn install
  build:
    commands:
      - yarn build

artifacts:
  base-directory: ./build
  files:
    - '**/*'

cache:
  paths:
    - './node_modules/**/*'

Enter fullscreen mode Exit fullscreen mode
 // AWS CodePipeline stage to build website and CDK resources
    pipeline.addStage({
      stageName: "Build",
      actions: [
        // AWS CodePipeline action to run CodeBuild project
        new CodePipelineAction.CodeBuildAction({
          actionName: "Website",
          project: new CodeBuild.PipelineProject(this, "BuildWebsite", {
            projectName: "MyWebsite",
            buildSpec: CodeBuild.BuildSpec.fromSourceFilename(
              "./infra/lib/build.yml"
            ),
          }),
          input: outputSources,
          outputs: [outputWebsite],
        }),
      ],
    });
Enter fullscreen mode Exit fullscreen mode
  • The last stage will be adding deployment stage, we want to deploy the react-app to S3 bucket, and every time we make a new changes it will be deployed the S3 bucket
 // Amazon S3 bucket to store website
const bucketWebsite = new S3.Bucket(this, "Files", {
      websiteIndexDocument: "index.html",
      websiteErrorDocument: "error.html",
      publicReadAccess: true,
    });

    // AWS CodePipeline stage to deploy website and CDK resources
    pipeline.addStage({
      stageName: "Deploy",
      actions: [
        // AWS CodePipeline action to deploy website to S3
        new CodePipelineAction.S3DeployAction({
          actionName: "Website",
          input: outputWebsite,
          bucket: bucketWebsite,
        }),
      ],

    });
Enter fullscreen mode Exit fullscreen mode

Resources:

AWS Cloud Development Kit
Easily deploying infrastructure as code via AWS CDK

Wrapping Up

You can do almost the same thing using GitHub actions, you will need create a new connection check this Create a connection to GitHub
We can create deferent pipelines for deferent stages like Dev, QA, Prod
The link to my Bitbucket repository is here

Please let me know in the comments if this post was helpful and what I can do better next time!

Please follow me on Twitter at @The_Al_Sanad where I Will frequently write about serverless, devOps!

💖 💪 🙅 🚩
mohammedismaeel
Mohammed Ismaeel

Posted on October 12, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related