Setting up CI/CD with AWS CodePipeline and CodeBuild for Angular 8 serverless website (AWS Cloudfront and S3)

6 min readNov 14, 2019

This article does not illustrate how to setup your CloudFront distribution with S3. Instead we will see how to setup your build environment and use AWS CodePipeline and CodeBuild with Github to track changes, build and deploy files for distribution to your website’s S3 bucket.

Very first thing, always create a virtual environment if you don’t install virtualenv.

my-MacBook-Pro:~ me$ pip3 install virtualenv

Collecting virtualenv

Downloading (3.4MB)

100% |████████████████████████████████| 3.4MB 5.7MB/s

Installing collected packages: virtualenv

Successfully installed virtualenv-16.7.7

Create and cd into your project directory.

my-MacBook-Pro:~ me$ mkdir proj

my-MacBook-Pro:~ me$ cd proj

Create the virtual environment inside the project directory and activate the virtual environment.

my-MacBook-Pro:proj me$ virtualenv proj_venv

Using base prefix ‘/usr/local/Cellar/python/3.7.0/Frameworks/Python.framework/Versions/3.7’

New python executable in /Users/me/me/proj_venv/bin/python3.7

Also creating executable in /Users/me/me/proj_venv/bin/python

Installing setuptools, pip, wheel…


my-MacBook-Pro:me my$ source proj_venv/bin/activate

(proj_venv) my-MacBook-Pro:proj me$

Important: Remember to add proj_venv to your project's .gitignore file so you don't include all of that in your source code.

Technologies we will use.

  1. I really loved my build and deploy experience for frontend with Angular and Bootstrap except I was disappointed that SPA’s don’t do very well with web crawlers and SEO. For this project I don’t care about that so much.
  2. Since I want this project’s backend to be absolutely serverless, I will be using AWS API Gateway and AWS Lambda and if required AWS DynamoDB (another article for those). Since this is a personal project this will keep costs down and also I get to learn some cool serverless technology. By the way for AWS Lambda code I will use either Python 3.6 or Go 1.13

Let’s install latest stable release version of Angular in our proj_venv virtual environment.

(proj_venv) my-MacBook-Pro:proj me$ npm install @angular/cli

Let’s check our Angular installation versions etc.

(proj_venv) my-MacBook-Pro:proj me$ ng — versionAngular CLI: 8.3.17Node: 10.9.0OS: darwin x64Angular:...Package                      Version------------------------------------------------------@angular-devkit/architect    0.803.17@angular-devkit/core         8.3.17@angular-devkit/schematics   8.3.17@angular/cli                 8.3.17@schematics/angular          8.3.17@schematics/update           0.803.17rxjs                         6.4.0

Great! we have all the latest version of Angular packages installed in our virtual environment.

Time to install MDBootstrap. This is really cool to quickly build a nice UI for your Angular web app. UI will automatically adhere to Google’s Material Design guidelines. MDB is Material Design on Bootstrap.

Follow the guide to installing MDB here.

Let’s create a new project.

ng new project --style=scss

Once the angular project folder is created. cd into it and install mdbootstrap pro or free version based on your choice.

Now let’s do ng serve --o

You should see your beautiful angular web app up and running at http://localhost:4200

Aah! Makes me happy…I guess this was the easy part.

Great! Now let’s setup git repo.

(proj_venv) my-MacBook-Pro:project me$ pwd/Users/me/me/project(proj_venv) my-MacBook-Pro:project me$ git remote add origin<user>/<project>.git(proj_venv) my-MacBook-Pro:project me$ git remote -vorigin<user>/<project>.git (fetch)origin<user>/<project>.git (push)

Create a repo on github with the same name as your project folder. project.git in this case. Stage all changes and commit using Atom. Then push it to the github repo. Verify updates in Github.

(proj_venv) my-MacBook-Pro:project me$ git push -u origin master

Everything on Github is now on sync with your local repo.

After you do some basic stuff in your Angular project let’s do a build for prod.

ng build --prod=true --aot

The files for your AWS S3 bucket will be in dist/ or dist/project/ folder inside your project depending on how you are setup.

I will leave building the actual Angular website to you, what we want to do after this, is to setup a simple CI/CD with AWS CodePipeline and AWS CodeBuild so every time we update our Angular project and merge the feature branch to the master branch of our Github repo, CodePipeline will automatically pull updates from our Github source repository and submit a build. CodeBuild will then build the files and push to your AWS S3 bucket that we will use with CloudFront distribution for our website.

It is important that you create the CodePipeline in the same region as your S3 bucket. S3 bucket Properties > Management will show you the region of the bucket in the endpoint URI under the Static Website box.

Login to your AWS console and search CodePipeline. Create Pipeline. Enter the name and let Pipeline create a new service role.

Now choose the custom location and specify your S3 bucket where you will host your website code. For now you can use the default AWS managed keys.

Now it’s time to connect your repo. We will use Github webhooks with CodePipeline.

Click on Connect to Github. Enter you credentials and authorize CodePipeline to pull source from Github.

Specify your source repo and the branch that you want CodePipeline to track and pull merges from. In most cases it will be master since you want your S3 bucket updated if you have merged tested code ready for release.

Now let’s move on to the next stage — Build. Here we will specify what CodePipeline should do when there are updates. Add a build stage and choose Build Provider AWS CodeBuild. Ideally choose the same region with CodePipeline and S3 bucket but CodeBuild still works if your Build Project is in a different region. Click on Create Project.

Specify Project Name and description.

Now let’s specify environment: Use Managed Image, I use Amazon Linux 2, standard runtime and make sure to specify in Image Version to always use latest image for the runtime. Then let Codebuild create a new service role. Create an S3Write policy for your S3 bucket and add to the CodeBuild role in IAM since CodeBuild will copy all files from dist/ to the AWS S3 bucket.

Now click insert build commands and click switch to editor.

yaml for the buildspec file.

version: 0.2phases:
nodejs: 10
- npm install
- npm install -g
# - command
# - command
- ng build --prod=true --aot
- aws s3 cp dist/<projfolder>/ s3://<yourbucketname> --recursive

Above buildspec file will spin up a machine with the AMI specified with nodejs 10 runtime version and install angular cli, build your angular proj with prod = true flag and after build completes successfully copy the files in dist/projectfolder/ to your website hosting bucket automatically.

All you need to do now is build your stuff and push to github repo and merge with the branch being tracked by CodePipeline setup.

Enable CloudWatch logs with the Log Name and Stream Name for CodeBuild to write logs to.

Click on Continue to CodePipeline.

Click Next.

Run the build.

You can click on the Details link under AWS Codebuild and will be able to see what CodeBuild is doing. It is fascinating that now we have a simple automated CI/CD for our simple Angular serverless website that will push distribution files to AWS S3 bucket which will be used with AWS Cloudfront and Route53 to serve globally to your users.

Hope this helps! Let me know if you have any questions.