1.4.2 • Published 13 days ago

@routineless/nx-aws-cdk v1.4.2

Weekly downloads
-
License
MIT
Repository
github
Last release
13 days ago

License: MIT NPM Version codecov Typescript Semantic Release Commitizen friendly

@routineless/nx-aws-cdk

Nx plugin for aws cdk application development.

Table of Contents

Install

To install this plugin to existing nx workspace run:

npm install -D @routineless/nx-aws-cdk

After installation you need to add @routineless/nx-aws-cdk to your nx.json plugins section:

{
  "targetDefaults": {...},
  "namedInputs": {...},
  "plugins": [
    "@routineless/nx-aws-cdk"
  ]
}

Usage

Right now this plugin supports nx integrated repos only.

Preset

@routineless/nx-aws-cdk can be used to generate aws cdk app with create-nx-workspace.

You can generate nx workspace using preset.

npx create-nx-workspace nx-aws-cdk-workspace --preset @routineless/nx-aws-cdk

Same can be achieved by running:

npx create-aws-cdk-app nx-aws-cdk-workspace

This command will create a workspace with cdk application and optionaly initial lambda function app. It utilizes cdk-application and aws-lambda generators to generate applications.

├── apps
│   ├── <lambdaApp>
│   │   ├── infra
|   |   |   └── src
|   |   |       └── index.ts
|   |   └── runtime
|   |       └── src
|   |           └── main.ts
│   └── <cdkApp>
│       ├── cdk.json
│       └── src
│           ├── main.ts
│           └── stacks
├── libs
└── nx.json

Available Options

nametypedefaultrequiredaliasdescription
infraAppNamestringinfrafalseiName of cdk application.
lambdaAppNamestringfalselName of lambda application. If not provided lambda application will not be generated during workspace creationg.
unitTestRunnerstringjestfalseuWill add corresponing unit test executors and files. Available options jest, none.

Cdk application generator

After installing @routineless/nx-aws-cdk and adding it to your nx.json plugins section or generating workspace using preset you can add cdk application to your nx workspace by running:

npx nx g cdk-application infra

Note: --setAsRoutinelessInfraApp=true will set generated app as routineless infra app and all generated lambda functions will be added to this application.

Generated application structure:

├── cdk.json
├── jest.config.ts
├── project.json
├── src
│   ├── assets
│   ├── environment.spec.ts
│   ├── environment.ts
│   ├── main.ts
│   └── stacks
│       ├── persistance.spec.ts
│       └── persistance.ts
├── tsconfig.app.json
├── tsconfig.json
└── tsconfig.spec.json

Stacks directory contains all cdk stacks and has generated persistance stack with simple S3 bucket for demonstration purposes. Cdk application configuration is defined in cdk.json file. Generated project will have inferred cdk and localstack targets.

You can see them by runnint npx nx show project <projectName>:

...
"localstack": {
  "executor": "@routineless/nx-aws-cdk:localstack",
  "options": {},
  "configurations": {}
},
"cdk": {
  "executor": "@routineless/nx-aws-cdk:cdk",
  "dependsOn": ["build"],
  "options": {},
  "configurations": {}
}
...

All stacks that should be managed withing generated cdk application should be described in the main.ts file.

nametypedefaultrequiredaliasdescription
namestringtrueName of cdk application.
tagsstringfalsetTags to apply for generated application.
unitTestRunnerstringjestfalseuWill add corresponing unit test executors and files. Available options jest, none.
setAsRoutinelessInfraAppbooleanfalsefalseiWill configure generated cdk app to be infra app where other generated applications will be added.

Lambda application generator

Lambda generator will generate nx application for lambda runtime and infrastructure code that can be used by cdk. It also can add lambda to existing cdk application if it is configured as routineless infra app.

npx nx g aws-lambda foo-lambda

Generated application structure:

├── infra
|   ├── src
|   │   ├── index.spec.ts
|   │   └── index.ts
|   ├── .eslintrc.json
|   ├── jest.config.ts
|   ├── project.json
|   ├── tsconfig.json
|   ├── tsconfig.lib.json
|   └── tsconfig.spec.json
|
└── runtime
    ├── src
    │   ├── main.spec.ts
    │   └── main.ts
    ├── .eslintrc.json
    ├── jest.config.ts
    ├── project.json
    ├── tsconfig.json
    ├── tsconfig.app.json
    └── tsconfig.spec.json

Runtime code is located in src/runtime/main.ts file. Infrastructure code is located in src/infra/index.ts file.

nametypedefaultrequiredaliasdescription
namestringtrueName of cdk application.
tagsstringfalsetTags to apply for generated application.
unitTestRunnerstringjestfalseuWill add corresponing unit test executors and files. Available options jest, none.
directorystringfalsecA directory name where to generate lambda application. Can be provided using -d alias.
addLambdaToInfraAppbooleantruefalseaAdds generated lambda to configured cdk infrastrucure app.

Lambda runtime executor

Lambda runtime executor is responsible for preparing your lambda runtime code for deployment.

Executor has two main modes bundled and unbundled. Bundled mode will create a single file that will contain all runtime dependencies and your lambda code. Unbundled mode will keep your lambda and internal dependencies projects structure and bundle third party dependencies in a separate file that will be placed in output node_modules directory.

Important: Unbundled mode supports only esm format and is in experimental stage. If you encounter any issues building and deploying your project fall back to bundled mode.

Basic configuration can be described in project.json file as:

    "build": {
      "executor": "@routineless/nx-aws-cdk:lambda-runtime",
      "outputs": ["{options.outputPath}"],
      "defaultConfiguration": "development",
      "options": {
        "outputPath": "dist/apps/<lambda-project>/runtime",
        "tsConfig": "apps/<lambda-project>/runtime/tsconfig.app.json"
      },
      "configurations": {
        "development": {
          "bundle": false
        },
        "production": {
          "minify": false
        }
      }
    },
nametypedefaultrequiredaliasdescription
tsConfigstringtrueThe path to tsconfig file.
outputPathstringtrueThe output path of the generated files.
mainstringfalseThe path to the entry file, relative to project.
bundlebooleantruefalseWhether to bundle the main entry point and additional entry points. Set to false to keep individual output files. Esm format supported only.
formatstringesmfalsefModule format to output.
outputFileNamestringfalseName of the main output file. Defaults same basename as 'main' file.
additionalEntryPointsstring[][]falseList of additional entry points.
assetsstring[][]falseList of static assets.
externalstring[]"@aws-sdk/*"falseMark one or more module as external. Can use wildcards, such as '@aws-sdk/'.
deleteOutputPathbooleantruefalseDelete the output path before building.
metafilebooleanfalsefalseGenerate a meta.json file in the output folder that includes metadata about the build. This file can be analyzed by other tools.
minifybooleanfalsefalseMinifies outputs.
skipTypeCheckbooleanfalsefalseSkip type-checking via TypeScript. Skipping type-checking speeds up the build but type errors are not caught.
generatePackageJsonbooleanfalsefalseGenerates a package.json with dependencies that were excluded and needs to be installed.
thirdPartybooleantruefalseIncludes third-party packages in the bundle (i.e. npm packages).
targetstringesnextfalseThe environment target for outputs.
esbuildOptionsobjectfalseAdditional options to pass to esbuild. See https://esbuild.github.io/api/. Cannot be used with 'esbuildConfig' option.
esbuildConfigstringfalsePath to a esbuild configuration file. See https://esbuild.github.io/api/. Cannot be used with 'esbuildOptions' option.

Cdk executor

Cdk executor is responsible for cdk commands execution. It can be used to bootstrap, deploy, destroy and executing other cdk commands. General usage pattern is npx nx cdk <cdk-project-name> <cdk command> ...args.

In order to use cdk executor you need a valid cdk.json configuration in the root of your application. By default cdk target will be inferred by @routineless/nx-aws-cdk, you can add additional target or override default one by adding cdk target to your project.json file:

"cdk": {
  "executor": "@routineless/nx-aws-cdk:cdk",
  "configurations": {
    "development": {
      "env": "dev",
      "resolve": true
    },
    "production": {
      "env": "prod",
      "resolve": true
    }
  },
  "dependsOn": ["build"]
},
"cdk-new": {
  "executor": "@routineless/nx-aws-cdk:cdk",
  "dependsOn": ["build"],
  "options": {
    "env": "new"
  }
}

Using production configuration by providing -c production to your cdk command will utilize lambda runtime production configuration that will minify output bundle.

Or you can update targetDefaults section in your nx.json file to apply default options to all cdk targets:

...
"targetDefaults": {
  "cdk": {
    "options": {
      "region": "us-east-2"
    }
  }
}
...

Local setup

By default all infrastructure would be deployed to your localstack. It requires docker to be installed and running on your machine.

Then you can run cdk diff against localstack environment:

npx nx cdk <cdk-project-name> diff

You can deploy your application by running:

npx nx cdk <cdk-project-name> bootstrap
npx nx cdk <cdk-project-name> deploy --all

You can inspect deployed resources using awslocal cli. Note that awslocal uses us-east-1 region by default. If you have configured another default region in your ~/.aws/config file you need to provide --region flag to awslocal commands or define DEFAULT_REGION env variable to have the same value.

pip install awscli-local
awslocal lambda list-functions
awslocal lambda invoke --function-name <functionName> '/dev/stdout'

Then you can destroy your infrastructure by running:

npx nx cdk <cdk-project-name> destroy --all

All commands can be run with --watch flag to enable watch mode.

Note: Insert gif demo here

AWS setup

In order to deploy cdk application to aws account you need to have configured aws credentials and provide --env <env> flag to cdk executor. Env flag can be anything except local as it is reserved for localstack environment.

npx nx cdk <cdk-project-name> diff --env dev
npx nx cdk <cdk-project-name> bootstrap --env dev
npx nx cdk <cdk-project-name> deploy --all --env dev
// In order to prevent aws cli from sending output to vi you can provide --no-cli-pager
// or run aws configure set cli_pager ""
aws lambda list-functions
aws lambda invoke --function-name <functionName> '/dev/stdout'
npx nx cdk <cdk-project-name> destroy --all --env dev

You can provide --profile <profile> flag to cdk executor to use specific aws profile. Same can be achieved by setting AWS_PROFILE env variable. Bu default all stacks will resolve their region and account using aws pseudo parameters that will be resolved during deployment. You can provide specific account region information using --region <region> and --account <account> flags. You can use --resolve flag to try to resolve account/region information from aws config, it will fallback to pseudo parameters if resolution failes.

AWS_ENV=dev npx nx cdk <cdk-project-name> diff --resolve
nametypedefaultrequiredaliasenv variabledescription
accountnumberfalseaAWS_ACCOUNTAWS account id to deploy cdk application.
regionstringfalserAWS_REGIONAWS region to deploy cdk application.
envstringlocalfalseeAWS_ENVEnvironment name that will be used in result stack names to distinguish different environments.
watchbooleanfalsefalsewWatch mode. Will execute provided command on every change detected in cdk app and its dependencies.
resolvebooleanfalsefalseRResolve mode. Will try to resolve aws account/region info from local context during build time instead of relying on aws pseudo parameters.

Localstack executor

Localstack executor is responsible for starting and shutting down localstack docker container. It is used intarnally by cdk executor in local mode.

This executor will be inferred as a localstack target to any project that contains cdk.json in its root directory. You can check it by running npx nx show project <projectName>.

"localstack": {
  "executor": "@routineless/nx-aws-cdk:localstack",
  "options": {},
  "configurations": {}
}

You can use localstack container by running:

// Start localstack container
npx nx localstack <projectName> start
// Stop localstack container
npx nx localstack <projectName> stop

By default cdk executor will start localstack during its first local run and will leave it running for subsequent commands executions. In order to release resources you need to stop it yourself after you are done with local testing.

You can override default localstack options by adding localstack target to your project.json file:

"localstack": {
  "executor": "@routineless/nx-aws-cdk:localstack",
    "options": {
      "containerName": "my-project-localstack",
      "composeFile": "path/to/localstack/docker-compose.yml",
      "preserveVolumes": true
    }
}

Or by updating targetDefaults section in your nx.json file to apply default options to all localstack targets:

"targetDefaults": {
  "localstack": {
    "options": {
      "containerName": "my-project-localstack",
      "debug": true
    }
  },
}
nametypedefaultrequiredaliasdescription
commandstringtruecLocalstack commands. Accepts 'start', 'stop'.
containerNamestringlocalstack_mainfalsenLocalstack container name.
composeFilestringfalsefCustom localstack docker-compose file path relative to workspace root.
volumeMountPathstringjestfalsevPath to mount localstack data. By default data will not be exposed and stored withing docker named volume.
debugbooleanfalsefalseEnable localstack debug mode.
preserveVolumesbooleanfalsefalsepPreserve localstack docker volumes on shutting down.

Maintainers

@KozelAnatoliy

License

MIT © 2023 Anatoli Kozel