Skip to content

This repository contains the infrastructure as code to wrap your AWS CDK project with CI/CD around it.

License

Notifications You must be signed in to change notification settings

cdklabs/cdk-cicd-wrapper

CDK CI/CD Wrapper

Documentation · Changelog · Join the community

Apache 2.0 License Release badge Commit activity

Welcome to the CDK CI/CD Wrapper

The CDK CI/CD Wrapper gives you an easy way to deliver your CDK applications like a pro. This repository contains all the tools to build, deliver and test any CDK Applications through multiple stages, and AWS accounts to have high level of quality and confidence.

Getting Started

To set up the CI/CD pipeline in your existing AWS CDK project, follow these steps:

  1. Install the CDK CI/CD Wrapper pipeline package by running the following command:

    npm i @cdklabs/cdk-cicd-wrapper @cdklabs/cdk-cicd-wrapper-cli
  2. Open your entry file, typically located at bin/<your-main-file>.ts (where your-main-file is the name of your root project directory).

  3. Include the PipelineBlueprint.builder().synth(app) statement in your entry file, like so:

    import * as cdk from 'aws-cdk-lib';
    import { PipelineBlueprint } from '@cdklabs/cdk-cicd-wrapper';
    
    const app = new cdk.App();
    
    PipelineBlueprint.builder().synth(app);

    This will deploy the CI/CD pipeline with its default configuration without deploying any stacks into the staging accounts.

  4. Optional: If you want to include additional stacks in the CI/CD pipeline, modify your entry file as follows:

    import * as cdk from 'aws-cdk-lib';
    import { PipelineBlueprint, GlobalResources } from '@cdklabs/cdk-cicd-wrapper';
    
    const app = new cdk.App();
    
    PipelineBlueprint.builder().addStack({
    provide: (context) => {
       // Create your stacks here
       new YourStack(context.scope, `${context.blueprintProps.applicationName}YourStack`, {
          applicationName: context.blueprintProps.applicationName,
          stageName: context.stage,
       });
       new YourOtherStack(context.scope, `${context.blueprintProps.applicationName}YourOtherStack`, {
          applicationQualifier: context.blueprintProps.applicationQualifier,
          encryptionKey: context.get(GlobalResources.ENCRYPTION)!.kmsKey,
       });
    }}).synth(app);

    Note: Refer to the Developer Guide for more information on the PipelineBlueprint.

  5. The CDK CI/CD Wrapper expects to have the validate, lint, test, audit scripts defines. If you are missing any of the npm run scripts (e.g., ), or want to use the provided CLI tool for one or more actions, you can add the following definitions to your package.json file:

    1. Adding validate script
jq --arg key "validate" --arg val "cdk-cicd validate" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "validate:fix" --arg val "cdk-cicd validate --fix" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
    1. Adding lint script, we recommend using eslint and you can initalise it
npm init @eslint/config

jq --arg key "lint" --arg val "eslint . --ext .ts --max-warnings 0" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "lint:fix" --arg val "eslint . --ext .ts --fix" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
    1. Adding audit scripts
npm install --save -D concurrently
jq --arg key "audit" --arg val "concurrently 'npm:audit:*(\!fix)'" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "audit:deps:nodejs" --arg val "cdk-cicd check-dependencies --npm" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "audit:deps:python" --arg val "cdk-cicd check-dependencies --python" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "audit:deps:security" --arg val "cdk-cicd security-scan --bandit --semgrep --shellcheck" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "audit:license" --arg val "npm run license" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "audit:fix:license" --arg val "npm run license:fix" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "license" --arg val "cdk-cicd license" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
jq --arg key "license:fix" --arg val "cdk-cicd license --fix" '.scripts[$key] = $val' package.json | jq . > package.json.tmp; mv package.json.tmp package.json;
{
  ...
  "scripts": {
    "validate": "cdk-cicd validate",
    "validate:fix": "cdk-cicd validate --fix",
    "audit": "npx concurrently 'npm:audit:*(!fix)'",
    "audit:deps:nodejs": "cdk-cicd check-dependencies --npm",
    "audit:deps:python": "cdk-cicd check-dependencies --python",
    "audit:scan:security": "cdk-cicd security-scan --bandit --semgrep --shellcheck --ci",
    "audit:license": "npm run license",
    "audit:fix:license": "npm run license:fix",
    "license": "cdk-cicd license",
    "license:fix": "cdk-cicd license --fix",
    "lint": "eslint . --ext .ts --max-warnings 0",
    "lint:fix": "eslint . --ext .ts --fix",
    "test": "jest"
    ...
  }
  ...
}

Note: If you are using eslint for linting, ensure that the configuration files are present or generate them with npm init @eslint/config.

  1. Before deploying, run the following commands to ensure your project is ready:

    npm run validate:fix
    npm run audit:fix:license
    
    • npm run validate:fix will create the required package-verification.json file for you.
    • npm run audit:fix:license will generate a valid Notice file for you.
  2. Deploy all the stacks by running the following command:

    npx dotenv-cli -- npm run cdk deploy -- --all --region ${AWS_REGION} --profile $RES_ACCOUNT_AWS_PROFILE --qualifier ${CDK_QUALIFIER}

    Once the command finishes, the following CDK Stacks will be deployed into your RES Account:

    • PipelineRepository: Responsible for either creating the CodeCommit repository and setting up PullRequest automation for CodeGuru scanning and running a set of configured commands, or establishing the CodeStar connection between your AWS RES Account and the configured GitHub repository.
    • SSMParameterStack: Responsible for creating parameters in the SSM Parameter Store, such as Account IDs.
    • VPCStack: Responsible for enabling the running of the build stages of the pipeline in a VPC, with or without a proxy. By default, this stack is not created unless configured via npx {{ npm_cli }}@latest configure. Check here for more information on possible configurations.
    • EncryptionStack: Responsible for creating the KMS Key used to encrypt all created CloudWatch Log Groups.
    • PipelineStack: Responsible for creating the CodeCommit Repository and the CodePipeline with all the CodeBuild Steps.

Visit our documentation to learn more.

Use cases

The CDK CI/CD Wrapper is the next step on road to standardize and simplify the multi-stage CI/CD process that the successful aws-cdk-cicd-boot-sample started. Thus the use cases for the CDK CI/CD Wrapper are the same as for the aws-cdk-cicd-boot-sample.

  • Multi staged CI/CD pipeline for IaC projects

On top of that the CDK CI/CD Wrapper has arbitrary scripts that can be leveraged in any projects involving TypeScript, and/or Python.

  • CI/CD execution by AWS CodePipeline in VPC, Private VPC with NAT Gateway, or even through an HTTP Proxy
  • Security scanning on dependencies and on your project codebase as well
  • License management over NPM and Python dependencies
  • Support for private NPM registry to safely store your libraries
  • Customizable CI/CD pipeline to attach to your CDK applications which comes with built-in dependency injection
  • Workbench deployment feature which allows you to develop and experiment your solutions before it is introduced in the delivery pipeline, e.g: deploy and test one or multiple CDK stacks isolated from the ones deployed by the CI/CD pipeline

Intended usage

You should not fork this repository and expect to reproduce the same in your AWS Accounts, this repository is only used for preparing, testing and shipping all the packages used by the CDK CI/CD Wrapper. Using the CDK CI/CD Wrapper gives you the following benefits:

  • ✅ Automated Open Source License checking (we have provided a list of licenses which you don't want to have them present in your PRODUCTION workloads)
  • ✅ Pre/Post deploy hooks during the deployment in each of the stages (DEV/INT/PROD)
    • ✅ PRE -> Unit Tests
    • ✅ POST -> Functional Tests, Load Testing
  • ✅ Flexible definition of stages, the default (DEV/INT/PROD) stages can be extended with new custom stages like EXP.
  • ✅ Stacks deployment can be specified for each stages separately
  • ✅ Customizable CI steps to meet project requirements
  • ✅ Centrally store compliance logs in S3 Buckets which are pre-configured on a per-stage/environment basis
  • ✅ Build Lambda Layers for Python and scan dependencies in the CI/CD (in case of CVE findings, block the pipeline)

Security

See CONTRIBUTING for more information.

License

This project is licensed under the Apache-2.0 License.

Community

The CDK CI/CD Wrapper community can be found within the #cdk-cicd-wrapper channel in the cdk.dev community Slack workspace.

Contributors

Thanks goes to these wonderful people (emoji key):

All Contributors

Gezim Musliaj
Gezim Musliaj

💻
Milan Gyalai @ AWS
Milan Gyalai @ AWS

💻
Vladimir Dainovski
Vladimir Dainovski

💻