Open CDK Guide


Purpose

Why This Guide?

The AWS CloudDevelopment Kit (CDK) is a framework built on top of CloudFormation that makes it delightful for users to manage AWS Infrastructure as Code (IaC). When everything is going right, the CDK will make you feel like a devops wizard. That being said, the cloud is complicated, CloudFormation coverage of AWS is incomplete, and the CDK itself (and IaC in general) is still a young framework with little in the way of established best practices.

This guide is an opinionated set of tips and best practices for working with the CDK. It is meant to be a living document, updated on an ongoing basis by the community as the CDK and practices around it mature.

This guide assumes that you are familiar with CDK concepts or have gone through the getting started documentation

Before using the guide, please read the license and disclaimer.

Contributions

Trying to keep up with AWS is a Sisyphean task and this guide is far from complete. If you have something to add, please submit a pull request to our github repo and help define conventions of the CDK.

Credits

This guide was started by Kevin S Lin, an early adopter of the CDK. It is heavily inspired in format and layout from the og-aws guide.

Below are a list of awesome folks who have helped out on the project:

Legend


Why CDK?

Before diving into best practices, a question that naturally arises when considering a new IaC in 2019 is why. AWS already has CloudFormation and there are many third party solutions (eg. Terraform, Troposphere, etc). This section exists to highlight reasons for considering.


Tips and Best Practices

Constructs

Stacks

Structure

- bin/
    - create-serviceA.ts
    - create-serviceB.ts
- lib
    - serviceA/
    - serviceB/
    - common/
- functions/
    - func1/
    - func2

Naming

const app = new cdk.App();
const stage = app.node.tryGetContext('stage')
const infra = new InfraStack(app, `fooOrg-fooApp-prod`, {...})
// a bucket defined inside InfraStack (eg. new Bucket(this, userImages))
// will have the following name -> fooOrg-fooApp-dev-userImages87437600-kke5zcq506k7

Tagging

import {TAGS} from './tags'
const infra = new InfraStack(app, "fooOrg-fooApp-dev", {...})
let {KEYS: K, VALUES: V} = TAGS
Tag.add(infra, K.APP, V.APP.FOO_APP)
Tag.add(infra, K.STAGE, V.STAGE.DEV)

Config

Patterns

export function createBucket({scope, id, bucketProps = {}, accessLogBucket}: {
  scope: Construct|App,
  id: string,
  bucketProps?: BucketProps
  accessLogBucket?: IBucket
}) {
  bucketProps = _.defaults({}, bucketProps, {
    encryption: BucketEncryption.KMS_MANAGED,
    blockPublicAccess: BlockPublicAccess.BLOCK_ALL
  })
  const bucket = new Bucket(scope, id, bucketProps)

  if (!_.isUndefined(accessLogBucket)) {
    let logFilePrefix = `${id}/`
    addS3AccessLogs({srcBucket: bucket, destBucket: accessLogBucket, logFilePrefix})
  }
  return bucket
}

Tools and Libraries

Collection of tools and libraries that make it easier to work with CDK

Deployments

Limitations

Get Help

Further Reading

Legal

Disclaimer

The authors and contributors to this content cannot guarantee the validity of the information found here. Please make sure that you understand that the information provided here is being provided freely, and that no kind of agreement or contract is created between you and any persons associated with this content or project. The authors and contributors do not assume and hereby disclaim any liability to any party for any loss, damage, or disruption caused by errors or omissions in the information contained in, associated with, or linked from this content, whether such errors or omissions result from negligence, accident, or any other cause.

License

Creative Commons License

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.