Taking Continuous Delivery to the Next Level: GitLab CI/CD + AWS

Introducing GitLab with AWS: how to build your Continuous Delivery from scratch.

Overview

Outcome

A system that, for every project on GitLab, sets up automatically a continuous delivery pipeline for you.

Amazon S3

Create the bucket

Why “stage”? Well, since we need custom subdomains, we have to map a wildcard domain name to our CloudFront distribution; it’s better to circumscribe this behavior, and leave free the first level subdomain.

Creating the S3 Bucket

Configure the bucket for website hosting

Change the Bucket policies

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AddPerm",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::stage.yourdomain.com/*"
}
]
}

IAM

Create a group

Create the user

GitLab CI/CD

In order to avoid configuring every future project, you can put the keys in a group, so that all projects inside it can have access to them.

Create the group

Create the environment variables

Create a pilot project

Create the .gitlab-ci.yml

variables:
S3_BUCKET: "stage.yourdomain.com"
BUILD_COMMAND: "npm run build"
DIST_DIR: "./dist"
stages:
- build
- deploy
build:
stage: build
image: debian:latest
...
deploy:
stage: deploy
image: python:latest
...
aws s3 sync ${DIST_DIR} s3://${S3_BUCKET}/${CI_PROJECT_NAME}/${CI_COMMIT_REF_NAME} --delete

Start the pipeline

Route 53

Create an hosted zone

Certificate Manager

Request a certificate

CloudFront

Create the CloudFront Distribution

Add the alias record on Route 53

Lambda@Edge

Whitelist the Host header

Create the Lambda@Edge

The function code

Create the trigger

GitLab Environments

With Environments you have full control of your project delivery.

Configuring environments

deploy:master:
<<: *deploy
only:
- master
...
deploy:branches:
<<: *deploy
only:
- branches
- tags
except:
- master
...
...
environment:
name: ${CI_COMMIT_REF_NAME}
url: https://${CI_PROJECT_NAME}.${S3_BUCKET}
on_stop: clean
aws s3 rm s3://${S3_BUCKET}/${CI_PROJECT_NAME}/${CI_COMMIT_REF_NAME} --recursive

Invalidate the cache

aws cloudfront create-invalidation --distribution-id ${DISTRIBUTION_ID} --paths "/*"

Create the environments

Conclusion

Creative Technologist