Sharing private CDK constructs with AWS CodeArtifact

Aug 18, 2020

One of the things I love about the AWS CDK is the fact that it makes it super easy to create and share constructs for use in multiple stacks. This addresses a set of challenges I see across customers who are creating and re-using sections of CloudFormation templates. Copy/pasting of your JSON or YAML templates is hard to manage in terms of versioning, and it can then be easily lost in the broader template you paste it in to. Nested Templates can help with this, but still leaves you needing to work on a good versioning and distribution strategy - and of course you’re still missing the benefits of working with the CDK at this point. If you’re writing CDK stacks and working with a CDK based language, you will want a solution that can work with in that workflow.

AWS CodeArtifact

Authoring custom constructs

I won’t go in to the specifics of how to author your own constructs here because there is good documentation on creating custom constructs already, and it covers how to do this in different languages too. The concept here though is that you create your custom construct that is made up of one or more other CDK constructs that you want to re-use, expose properties that need to be configured by the consuming application, and then publish the construct. The question of “where do I publish a construct that isn’t designed to be public?” is one that I have been asked from time to time, and this is where AWS CodeArtifact comes in to it.

What is AWS CodeArtifact?

AWS CodeArtifact is a fully managed artifact repository service that makes it easy for organizations of any size to securely store, publish, and share software packages used in their software development process. This is exactly the problem we are looking to solve here - we have custom CDK constructs we want to share, and sharing them without needing to manage our own artifact repository platforms is an ideal solution. CodeArtifact supports standard tooling for NPM, Maven and PyPi so we can share packages easily without making big changes to our workflow. I’m going to talk to how this works with NodeJS in this post as that’s what I code with, but the high level processes are the same between languages.

Creating your construct package

Fortunately for us, it’s very easy to set up a construct library (as opposed to creating a normal CDK app). The CDK CLI has an option on what template to use when you run the init command, if you don’t specify a template you get the default ‘app’ template, but there are a couple of options - the lib template creates a library ready to share a construct from.

npx cdk init lib --language=typescript

Once you have this created, you can go through and create your constructs as you need. You’ll want to pay particular attention to the package.json file at this point though before you publish your module, as the settings here dictate how it presents itself to CodeArtifact. Specifically the name and version attributes, as they will be how people find your package, but use all the relevant metadata here. Also, adding a readme file will help people who are browsing the CodeArtifact UI in the AWS console as well - this is an ideal place to put documentation on how your construct works.

Publishing to CodeArtifact

Before you push your module to CodeArtifact you’ll want to go through the getting started with CodeArtifact guide and make sure you are connected to your new repository. When you run the aws codeartifact login command you’ll have a new NPM config file stored at ~/.npmrc. You can move this to be a project specific config, or leave it there if it should be global for the current user. Once this config is published the process of publishing your module is very straightforward. This can be done by running npm publish - that’s it! At this point you can go to your CodeArtifact repo and see your module.

A custom construct being shown in CodeArtifact

Using the construct from CodeArtifact

Now that you have published your module, it’s time to use it. To get started, create yourself a new CDK app and then install your module. In the screenshot above you can see mine is called @brfarn/construct so to install that I would run:

npm install @brfarn/construct --save

As long as CodeArtifact is configured and logged in, NPM will do the rest - it will find the package and install it as normal. If you crack open the package-lock.json file you’ll also find that the URLs of the packages are all now pointing to your CodeArtifact repo and not the public NPM registry. Using the custom construct becomes as easy as using any other CDK construct:

import * as brfarn from '@brfarn/construct'

...

new brfarn.Construct(this, "TestConstruct", {})

When the CDK synthesises your template (either in a pipeline or with cdk deploy or cdk synth you will see the output template contains all the constructs you created in your custom module, as well as anything else you put in to your stack.

Sharing an versioning

This is all well and good for a single version, but now how do you go about managing versions? The good news here is that this is easy as well. If I decide I need to change the shared construct I simply update it and publish it again with a new version number - this is something that you would ideally do in a release pipeline where you can run your tests first and publish at the end. It also means you can give CodeBuild permission to push to CodeArtifact instead of individual developers, which helps the security posture of your artifact repository.

After your new versions are published then you can use npm outdated to see if there are newer versions of packages available, and then npm update will install the latest versions for you to use in your stack. This is standard NPM stuff here, nothing CodeArtifact specific is happening here. This is one of the great benefits of CodeArtifact - all the benefits of a managed, highly available service, that comes to you with the standard tools you work with already.

Wrapping up

Almost every discussion I have with customers these days involves the CDK in some way, shape or form - and this is a good thing. The maturity it brings to the Infrastructure as Code space is very easy to see, and having services like CodeArtifact to enable secure and simple sharing of constructs will make code reusability a simple task no matter the size of team or organisation.

 

Comments

You're signed in as | Sign out

Submitting comment...

There are no comments on this post yet. Be the first to leave one!