Setup branch deployments with Gitlab CI and AWS CDK

Kishan Nirghin
3 min readNov 11, 2021

This post will cover the basics of setting up branch deployments (or feature deployments) with Gitlab CI and AWS CDK.

Note: this post covers the usage of Gitlab CI for setting up the pipelines and not CDK pipelines.

Setting up branch deployments with Gitlab CI and AWS CDK can be split up into 2 parts. Part 1 which covers the theory of setting up branch deployments with AWS CDK and part 2 which focusses on automating these principles using Gitlab CI.

Setting up branch deployments using AWS CDK

Some basics first: AWS facilitates CDK deployments through Stacks. Stacks are a collection of resources within AWS CloudFormation. CDK specifications are declarative, meaning that the config solely contains the desired state. AWS compares the desired state with the previous desired state to compute the differences. Updates to the modified resources are performed accordingly.

In pseudo-code this principle will read as:

# Create a stack with name "myStack"
s = cdk.Stack(id = "myStack")
# Add a lambda function function to myStack
s.addLambdaFunction(id = "myLambda", src = code)

The declarative lines above will create a stack and add a Lambda function to it. Subsequent updates to this stack can be performed by updating the configuration file, e.g. by adding an additional bucket to the stack:

# Create a stack with name "myStack"
s = cdk.Stack(id = "myStack")
# Add a lambda function function to myStack
s.addLambdaFunction(id = "myLambda", src = code)
# Add a S3 bucket to myStack
s.addS3Bucket(id = "bucket1")

AWS uses identifiers under the hood to figure out when to update which resource. Since the id in the above example remained the same AWS interprets this as an update. Creating a new stack therefore is as simple as changing the stack identifier in the config file:

s = cdk.Stack(id = "anotherStack")
s.addS3Bucket(id = "bucket1")

This will leave the previous stack (id=myStack) untouched and create a new stack (id=anotherStack) right next to it. These principles and behaviour of CDK (more specifically AWS Cloudformation) can be used to setup branch deployments.

Summary (tldr;) - we can deploy new stacks to AWS without updating the previous one by ensuring that the stack id is unique.

In the example above one can use dynamic stack ids by passing this value as a command-line argument: cdk deploy -c stackName="DynamicStackName".

Setting up branch deployments with Gitlab CI

The challenge that holds now it to run cdk deploy -c stackName="<name>" with a different value for <name> for each branch. An easy solution would be to use the CI_COMMIT_BRANCH environment variable which is automatically set by Gitlab and to our disposal.

branch_deploy:
script:
cdk deploy -c stackName=${CI_COMMIT_BRANCH}

Setting up branch deployments is as simple as the above. The next step in maturity would be to cleanup the AWS Stack whenever this branch gets merged or abandoned. For this we can setup a Gitlab environment. Gitlab environments describe where code is deployed, and in our case: what to do when the environment closes.

branch_deploy:
environment:
name: $CI_COMMIT_BRANCH
on_stop: stop_branch_deploy
script:
- cdk deploy -c stackName=${CI_COMMIT_BRANCH}

Which will call the stop_branch_deploy step whenever the environment closes: branch is merged, or branch is abandoned.

stop_branch_deploy:
environment:
name: $CI_COMMIT_BRANCH
action: stop
script:
- cdk destroy -c stackName=${CI_COMMIT_BRANCH}

Voilà, this is really all there is to it when setting up branch deployments. Another benefit of using Gitlab environments is that it has nice integrations with the GitLab web interface. Under deployments > environments in the main menu an overview of the deployed environments will be kept.

Summary (tldr;) - Setup the deploy job including an environment to be able to automatically clean it up when the environment closes.

Conclusion

Setting up branch deployments using Gitlab CI and AWS CDK is rather easy once you get a grip and understanding of the behaviour and principles of the tools.

This post goes over the theoretical concepts only. A (more elaborate and) running example that utilises theses principles can be found here:

That wraps it up. Thanks for reading until the very end, if you succeeded with the help of this post let me know by adding a clap.

P.S. Feel free to reach out to me for questions or remarks at kishan@itslogical.nl

--

--