@aligent/nx-cdk 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +130 -0
- package/generators.json +15 -0
- package/package.json +20 -0
- package/src/generators/helpers/configs/nxJson.d.ts +4 -0
- package/src/generators/helpers/configs/nxJson.js +52 -0
- package/src/generators/helpers/configs/packageJson.d.ts +61 -0
- package/src/generators/helpers/configs/packageJson.js +65 -0
- package/src/generators/helpers/configs/tsConfigs.d.ts +12 -0
- package/src/generators/helpers/configs/tsConfigs.js +40 -0
- package/src/generators/helpers/utilities.d.ts +82 -0
- package/src/generators/helpers/utilities.js +100 -0
- package/src/generators/preset/files/.editorconfig.template +18 -0
- package/src/generators/preset/files/.git-hooks/pre-push.template +68 -0
- package/src/generators/preset/files/.github/CODEOWNERS.template +3 -0
- package/src/generators/preset/files/.github/dependabot.yml.template +7 -0
- package/src/generators/preset/files/.github/workflows/ci-cd.yml.template +27 -0
- package/src/generators/preset/files/.gitignore.template +62 -0
- package/src/generators/preset/files/.nvmrc.template +1 -0
- package/src/generators/preset/files/.prettierignore.template +10 -0
- package/src/generators/preset/files/.yarnrc.yml.template +6 -0
- package/src/generators/preset/files/LICENSE.template +21 -0
- package/src/generators/preset/files/README.md.template +77 -0
- package/src/generators/preset/files/application/README.md.template +61 -0
- package/src/generators/preset/files/application/_internal/log-group-defaults-injector.ts.template +100 -0
- package/src/generators/preset/files/application/_internal/microservice-checks.ts.template +58 -0
- package/src/generators/preset/files/application/_internal/nodejs-function-defaults-injector.ts.template +110 -0
- package/src/generators/preset/files/application/_internal/step-function-defaults-injector.ts.template +126 -0
- package/src/generators/preset/files/application/_internal/version-functions-aspect.ts.template +74 -0
- package/src/generators/preset/files/application/bin/main.ts.template +72 -0
- package/src/generators/preset/files/application/cdk.context.json.template +4 -0
- package/src/generators/preset/files/application/cdk.json.template +92 -0
- package/src/generators/preset/files/application/eslint.config.mjs.template +3 -0
- package/src/generators/preset/files/application/lib/service-stacks.ts.template +21 -0
- package/src/generators/preset/files/application/package.json.template +27 -0
- package/src/generators/preset/files/cdk-config.yml.template +16 -0
- package/src/generators/preset/files/eslint.config.mjs.template +54 -0
- package/src/generators/preset/files/prettier.config.mjs.template +3 -0
- package/src/generators/preset/files/rolldown.config.base.mjs.template +46 -0
- package/src/generators/preset/files/tsconfig.json.template +6 -0
- package/src/generators/preset/files/vitest.config.base.mjs.template +39 -0
- package/src/generators/preset/files/vitest.global.setup.mjs.template +109 -0
- package/src/generators/preset/preset.d.ts +4 -0
- package/src/generators/preset/preset.js +35 -0
- package/src/generators/preset/schema.d.ts +7 -0
- package/src/generators/preset/schema.json +32 -0
- package/src/generators/service/files/README.md.template +29 -0
- package/src/generators/service/files/eslint.config.mjs.template +20 -0
- package/src/generators/service/files/package.json.template +32 -0
- package/src/generators/service/files/rolldown.config.mjs.template +3 -0
- package/src/generators/service/files/src/index.ts.template +75 -0
- package/src/generators/service/files/src/infra/.gitkeep.template +0 -0
- package/src/generators/service/files/src/runtime/handlers/.gitkeep.template +0 -0
- package/src/generators/service/files/src/runtime/lib/utils/.gitkeep.template +0 -0
- package/src/generators/service/files/tests/__data__/.gitkeep.template +0 -0
- package/src/generators/service/files/vitest.config.mjs.template +18 -0
- package/src/generators/service/generator.d.ts +4 -0
- package/src/generators/service/generator.js +43 -0
- package/src/generators/service/schema.d.ts +4 -0
- package/src/generators/service/schema.json +20 -0
- package/src/index.d.ts +2 -0
- package/src/index.js +19 -0
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Script adapted from https://github.com/kaczor6418/git-hooks-example/blob/master/git-hooks/pre-commit
|
|
3
|
+
|
|
4
|
+
# Support using VSCode to commit
|
|
5
|
+
# This loads nvm.sh and sets the correct PATH before running hook
|
|
6
|
+
export NVM_DIR="$HOME/.nvm"
|
|
7
|
+
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
|
8
|
+
|
|
9
|
+
# Define colours for nicer CLI output
|
|
10
|
+
RED="\033[1;31m"
|
|
11
|
+
GREEN="\033[1;32m"
|
|
12
|
+
NO_COLOUR="\033[0m"
|
|
13
|
+
|
|
14
|
+
echo -e "${GREEN}Executing git hook $0 $@${NO_COLOUR}"
|
|
15
|
+
|
|
16
|
+
# Use the current Node version explicitly
|
|
17
|
+
nvm use
|
|
18
|
+
|
|
19
|
+
# Get the list of staged changes
|
|
20
|
+
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACM)
|
|
21
|
+
|
|
22
|
+
# Exclude files that shouldn't trigger pre-commit checks
|
|
23
|
+
# This is done here because `nx affected` doesn't look at task inputs
|
|
24
|
+
# when determining if a project is affected
|
|
25
|
+
EXCLUDED_FILES_REGEX='.*\.md$' # Ignore markdown files
|
|
26
|
+
EXCLUDED_FILES_REGEX+='|.*\/step-functions\/.*\.(yml|yaml)$' # Ignore step function yaml files
|
|
27
|
+
EXCLUDED_FILES_REGEX+='|^\/?([^\/]*)$' # Ignore all root-level files
|
|
28
|
+
AFFECTED_FILES=$(echo "$STAGED_FILES" | \
|
|
29
|
+
grep -vE "$EXCLUDED_FILES_REGEX" | \
|
|
30
|
+
paste -sd,)
|
|
31
|
+
|
|
32
|
+
echo -e "${GREEN}\nAffected files: $AFFECTED_FILES\n${NO_COLOUR}"
|
|
33
|
+
|
|
34
|
+
# Exit early if there are no affected files
|
|
35
|
+
if [ -z "$AFFECTED_FILES" ]; then
|
|
36
|
+
echo -e "${GREEN}No affected files found. Exiting pre-commit hook.${NO_COLOUR}"
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
# Prepare the affected commands for static analysis targets
|
|
41
|
+
AFFECTED_COMMAND="yarn nx affected --files=$AFFECTED_FILES --nxBail --tui=false"
|
|
42
|
+
commands=("$AFFECTED_COMMAND -t lint typecheck --parallel=3", "$AFFECTED_COMMAND -t test --configuration coverage")
|
|
43
|
+
failures=()
|
|
44
|
+
|
|
45
|
+
# Loop over commands, execute and push failure message if we see one
|
|
46
|
+
for cmd in "${commands[@]}"; do
|
|
47
|
+
$cmd
|
|
48
|
+
exit_code=$?
|
|
49
|
+
|
|
50
|
+
if [ "$exit_code" -eq 1 ]; then
|
|
51
|
+
failures+=("✖ Command ${RED}'${cmd}'${NO_COLOUR} failed with exit code ${exit_code} - see CLI output for errors")
|
|
52
|
+
elif [ "$exit_code" -eq 127 ]; then
|
|
53
|
+
failures+=("✖ Command ${RED}'${cmd}'${NO_COLOUR} failed with exit code ${exit_code} - check that the script exists in package.json")
|
|
54
|
+
elif [ "$exit_code" -ne 0 ]; then
|
|
55
|
+
failures+=("✖ Command ${RED}'${cmd}'${NO_COLOUR} failed with unexpected exit code ${exit_code}")
|
|
56
|
+
fi
|
|
57
|
+
done
|
|
58
|
+
|
|
59
|
+
# Report overall success or failure
|
|
60
|
+
if [ ${#failures[@]} -ne 0 ]; then
|
|
61
|
+
echo -e "\n🚩${RED} Couldn't commit changes dues to the following errors: ${NO_COLOUR}"
|
|
62
|
+
|
|
63
|
+
for report in "${failures[@]}"; do
|
|
64
|
+
echo -e $report;
|
|
65
|
+
done
|
|
66
|
+
|
|
67
|
+
exit 1
|
|
68
|
+
fi
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
name: CI/CD Pipeline
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches:
|
|
6
|
+
- '**'
|
|
7
|
+
push:
|
|
8
|
+
branches:
|
|
9
|
+
- staging
|
|
10
|
+
- production
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
code-quality:
|
|
14
|
+
name: 🕵️♀️ Code Quality Check
|
|
15
|
+
uses: aligent/workflows/.github/workflows/node-pr.yml@main
|
|
16
|
+
with:
|
|
17
|
+
skip-format: false
|
|
18
|
+
|
|
19
|
+
deploy:
|
|
20
|
+
name: Deploy to AWS
|
|
21
|
+
uses: aligent/workflows/.github/workflows/aws-cdk-deploy.yml@main
|
|
22
|
+
with:
|
|
23
|
+
cdk-stack-name: ${{ vars.STACK_NAME }}
|
|
24
|
+
aws-access-key-id: ${{ vars.AWS_ACCESS_KEY_ID }}
|
|
25
|
+
deploy: true
|
|
26
|
+
secrets:
|
|
27
|
+
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
|
2
|
+
# Ignore everything by default
|
|
3
|
+
*
|
|
4
|
+
|
|
5
|
+
# Project standard configurations
|
|
6
|
+
!**/*.md
|
|
7
|
+
!.git-hooks
|
|
8
|
+
!.git-hooks/*
|
|
9
|
+
!.github
|
|
10
|
+
!.github/*
|
|
11
|
+
!.github/**/*
|
|
12
|
+
!.editorconfig
|
|
13
|
+
!.gitignore
|
|
14
|
+
!.nvmrc
|
|
15
|
+
!.prettierignore
|
|
16
|
+
!cdk-config.yml
|
|
17
|
+
!eslint.config.mjs
|
|
18
|
+
!LICENSE
|
|
19
|
+
!nx.json
|
|
20
|
+
!package.json
|
|
21
|
+
!prettier.config.mjs
|
|
22
|
+
!rolldown.config.base.mjs
|
|
23
|
+
!tsconfig.json
|
|
24
|
+
!vitest.global.setup.mjs
|
|
25
|
+
!vitest.config.base.mjs
|
|
26
|
+
|
|
27
|
+
# Package manager
|
|
28
|
+
!.yarn
|
|
29
|
+
!.yarn/patches
|
|
30
|
+
!.yarn/plugins
|
|
31
|
+
!.yarn/plugins/*
|
|
32
|
+
!.yarn/plugins/**/*
|
|
33
|
+
!.yarn/releases
|
|
34
|
+
!.yarn/sdks
|
|
35
|
+
!.yarn/versions
|
|
36
|
+
!.yarnrc.yml
|
|
37
|
+
!yarn.lock
|
|
38
|
+
|
|
39
|
+
# Application
|
|
40
|
+
!application
|
|
41
|
+
!application/*
|
|
42
|
+
!application/**/*
|
|
43
|
+
!collection
|
|
44
|
+
!collection/*
|
|
45
|
+
!collection/**/*
|
|
46
|
+
!docs
|
|
47
|
+
!docs/*
|
|
48
|
+
!docs/**/*
|
|
49
|
+
!libs
|
|
50
|
+
!libs/*
|
|
51
|
+
!libs/**/*
|
|
52
|
+
!services
|
|
53
|
+
!services/*
|
|
54
|
+
!services/**/*
|
|
55
|
+
|
|
56
|
+
# Test and bundle artifacts
|
|
57
|
+
**/cdk.out
|
|
58
|
+
**/dist
|
|
59
|
+
**/coverage
|
|
60
|
+
|
|
61
|
+
# Environment files
|
|
62
|
+
*.env
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
v<%= nodeVersion %>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
nodeLinker: node-modules
|
|
2
|
+
|
|
3
|
+
plugins:
|
|
4
|
+
- checksum: e5e6e2885ab0e6521b70b0af7c6d8ca2c75dcae2403706fc4600a783b339a6530a476dafb9450c9436ca4050eb6bdee9b62e6e2cebfecf1e81dd709a2480dc07
|
|
5
|
+
path: .yarn/plugins/@yarnpkg/plugin-engines.cjs
|
|
6
|
+
spec: 'https://raw.githubusercontent.com/devoto13/yarn-plugin-engines/main/bundles/%40yarnpkg/plugin-engines.js'
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Aligent
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# <%= projectName %> Integrations
|
|
2
|
+
|
|
3
|
+
A monorepo containing integration services that support the <%= projectName %> project. This repository manages the deployment of microservices and their shared infrastructure using AWS CDK.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
<!-- Add an overview of the whole system -->
|
|
8
|
+
|
|
9
|
+
## Services
|
|
10
|
+
|
|
11
|
+
Services deployment are managed by the main [CDK Application](./application/README.md)
|
|
12
|
+
|
|
13
|
+
<!-- List services here with link to the service read me file -->
|
|
14
|
+
<!-- Eg: [User Management](../services/user-management/README.md) -->
|
|
15
|
+
|
|
16
|
+
## Project Structure
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
<%= folderName %>/
|
|
20
|
+
├── application/ # CDK Application & orchestration
|
|
21
|
+
│ ├── bin/main.ts # CDK App entry point (development/staging/production stages)
|
|
22
|
+
│ ├── lib/ # Service stack composition
|
|
23
|
+
│ └── cdk.json # CDK configuration
|
|
24
|
+
│
|
|
25
|
+
├── services/ # Microservices workspace
|
|
26
|
+
│
|
|
27
|
+
├── nx.json # Nx monorepo configuration
|
|
28
|
+
├── rolldown.config.base.mjs # Base Lambda bundling config
|
|
29
|
+
├── vitest.config.base.mjs # Base test configuration
|
|
30
|
+
└── eslint.config.mjs # ESLint configuration
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Getting Started
|
|
34
|
+
|
|
35
|
+
### Prerequisites
|
|
36
|
+
|
|
37
|
+
- Node.js <%= nodeVersion %> (see [.nvmrc](.nvmrc))
|
|
38
|
+
- Yarn 4.12.0+
|
|
39
|
+
- AWS CLI configured with appropriate credentials
|
|
40
|
+
|
|
41
|
+
### Installation
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Use correct Node version
|
|
45
|
+
nvm use
|
|
46
|
+
|
|
47
|
+
# Install dependencies
|
|
48
|
+
yarn install
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Contributing
|
|
52
|
+
|
|
53
|
+
We follow [trunk-based development framework](https://trunkbaseddevelopment.com/) as a start and will evolve depending on our need.
|
|
54
|
+
|
|
55
|
+
1. Create new branch from `main`
|
|
56
|
+
2. Make your changes following code standards
|
|
57
|
+
3. Ensure your changes pass linting, type checks and testes
|
|
58
|
+
4. Submit a pull request back to `main`
|
|
59
|
+
5. For deployment, submit a pull request from `main` to `staging` or `production`
|
|
60
|
+
|
|
61
|
+
## Adding New Services
|
|
62
|
+
|
|
63
|
+
To add a new service to the monorepo:
|
|
64
|
+
|
|
65
|
+
1. Use the Aligent CDK generator `@aligent/nx-cdk`
|
|
66
|
+
2. Add service infrastructure in
|
|
67
|
+
- `services/{service-name}/src/index.ts`
|
|
68
|
+
- `services/{service-name}/src/infra/`
|
|
69
|
+
3. Add Lambda handlers in `services/{service-name}/src/runtime/handlers/`
|
|
70
|
+
|
|
71
|
+
## License
|
|
72
|
+
|
|
73
|
+
MIT
|
|
74
|
+
|
|
75
|
+
## Support
|
|
76
|
+
|
|
77
|
+
For questions or issues, please contact the Aligent Microservices guild.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Application
|
|
2
|
+
|
|
3
|
+
This application manages the deployment of microservices and their shared infrastructure.
|
|
4
|
+
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
### Environment Parameters
|
|
8
|
+
|
|
9
|
+
Parameters are managed through the `parameters/.env.csv` file by default
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
# Pull down parameters from the playground environment to .env.csv
|
|
13
|
+
yarn nx run application:parameters
|
|
14
|
+
|
|
15
|
+
# Update parameters from .env.csv
|
|
16
|
+
yarn nx run application:parameters:import
|
|
17
|
+
|
|
18
|
+
# Custom filename and parameter path can be passed in as arguments
|
|
19
|
+
yarn nx run application:parameters --file .env.dev.csv --path /my/dev/path
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Deployment
|
|
23
|
+
|
|
24
|
+
### Using yarn script from workspace root (Recommended)
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Synthesize templates
|
|
28
|
+
yarn pg:synth
|
|
29
|
+
|
|
30
|
+
# Deploy to playground
|
|
31
|
+
yarn pg:deploy
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Direct Nx Commands
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
yarn nx run application:cdk <command> <args>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Testing
|
|
41
|
+
|
|
42
|
+
### Mock Services
|
|
43
|
+
|
|
44
|
+
The application may include mock services for testing integrations without external dependencies.
|
|
45
|
+
|
|
46
|
+
<!-- list mock services here -->
|
|
47
|
+
|
|
48
|
+
Change the value of the `/application/dev/url` SSM Parameter to switch between real and mock endpoints
|
|
49
|
+
|
|
50
|
+
### Local Development
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Type checking
|
|
54
|
+
yarn typecheck
|
|
55
|
+
|
|
56
|
+
# Testing
|
|
57
|
+
yarn test
|
|
58
|
+
|
|
59
|
+
# Linting
|
|
60
|
+
yarn lint
|
|
61
|
+
```
|
package/src/generators/preset/files/application/_internal/log-group-defaults-injector.ts.template
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { RemovalPolicy, type IPropertyInjector } from 'aws-cdk-lib';
|
|
2
|
+
import { LogGroup, RetentionDays, type LogGroupProps } from 'aws-cdk-lib/aws-logs';
|
|
3
|
+
|
|
4
|
+
interface Config {
|
|
5
|
+
duration: 'SHORT' | 'MEDIUM' | 'LONG';
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Property injector for CloudWatch Log Groups with configuration-aware defaults
|
|
10
|
+
*
|
|
11
|
+
* Applies configuration-specific retention policies and removal settings to log groups.
|
|
12
|
+
* Different configurations balance between cost optimization and data retention needs.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // Apply configuration-specific defaults
|
|
17
|
+
* PropertyInjectors.of(scope).add(
|
|
18
|
+
* new LogGroupDefaultsInjector({ duration: 'SHORT' }).withProps({
|
|
19
|
+
* logGroupName: '/custom/log/group',
|
|
20
|
+
* })
|
|
21
|
+
* );
|
|
22
|
+
*
|
|
23
|
+
* // Log groups automatically inherit configuration defaults
|
|
24
|
+
* new LogGroup(stack, 'MyLogGroup', {
|
|
25
|
+
* // retention and removal policy applied automatically
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*
|
|
29
|
+
* @see https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_logs.LogGroup.html
|
|
30
|
+
*/
|
|
31
|
+
export class LogGroupDefaultsInjector implements IPropertyInjector {
|
|
32
|
+
readonly constructUniqueId = LogGroup.PROPERTY_INJECTION_ID;
|
|
33
|
+
private readonly config: Config;
|
|
34
|
+
private defaultProps: LogGroupProps;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Creates a new LogGroupDefaultsInjector
|
|
38
|
+
*
|
|
39
|
+
* @param config - Configuration identifier used to select appropriate defaults.
|
|
40
|
+
*/
|
|
41
|
+
constructor(config: Config) {
|
|
42
|
+
const props = retentionProperties(config.duration);
|
|
43
|
+
this.config = { ...config };
|
|
44
|
+
this.defaultProps = { ...props };
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Creates a new injector instance with additional properties
|
|
49
|
+
*
|
|
50
|
+
* Returns a new injector that inherits the current configuration but includes
|
|
51
|
+
* additional properties that override the configuration defaults.
|
|
52
|
+
*
|
|
53
|
+
* @param props - Additional properties to merge with configuration defaults
|
|
54
|
+
* @returns A new injector instance with merged properties
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```typescript
|
|
58
|
+
* const customInjector = new LogGroupDefaultsInjector({ duration: 'SHORT' })
|
|
59
|
+
* .withProps({
|
|
60
|
+
* logGroupName: '/aws/lambda/custom',
|
|
61
|
+
* retention: RetentionDays.ONE_MONTH,
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
public withProps(props: LogGroupProps) {
|
|
66
|
+
const modifiedInjector = new LogGroupDefaultsInjector(this.config);
|
|
67
|
+
modifiedInjector.defaultProps = { ...this.defaultProps, ...props };
|
|
68
|
+
return modifiedInjector;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Injects configuration-appropriate defaults into log group properties
|
|
73
|
+
*
|
|
74
|
+
* Merges configuration-specific retention and removal policies with user-provided properties.
|
|
75
|
+
*
|
|
76
|
+
* @param originalProps - Properties provided when creating the log group
|
|
77
|
+
* @param context - CDK injection context containing construct information
|
|
78
|
+
* @returns Merged properties with injected defaults
|
|
79
|
+
*/
|
|
80
|
+
public inject(originalProps: LogGroupProps) {
|
|
81
|
+
return { ...this.defaultProps, ...originalProps };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Get duration-specific log group properties
|
|
87
|
+
*
|
|
88
|
+
* @param duration - The duration to get the log group properties for
|
|
89
|
+
* @returns The log group properties for the duration
|
|
90
|
+
*/
|
|
91
|
+
function retentionProperties(duration: 'SHORT' | 'MEDIUM' | 'LONG') {
|
|
92
|
+
switch (duration) {
|
|
93
|
+
case 'SHORT':
|
|
94
|
+
return { retention: RetentionDays.ONE_WEEK, removalPolicy: RemovalPolicy.DESTROY };
|
|
95
|
+
case 'MEDIUM':
|
|
96
|
+
return { retention: RetentionDays.SIX_MONTHS, removalPolicy: RemovalPolicy.DESTROY };
|
|
97
|
+
default:
|
|
98
|
+
return { retention: RetentionDays.TWO_YEARS, removalPolicy: RemovalPolicy.RETAIN };
|
|
99
|
+
}
|
|
100
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { CfnResource } from 'aws-cdk-lib';
|
|
2
|
+
import { NagMessageLevel, NagPack, rules, type NagPackProps } from 'cdk-nag';
|
|
3
|
+
import type { IConstruct } from 'constructs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Microservice Checks are a compilation of rules to validate infrastructure-as-code template
|
|
7
|
+
* against recommended practices using the cdk-nag library.
|
|
8
|
+
*
|
|
9
|
+
* @see https://github.com/cdk-patterns/cdk-nag/
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* const app = new App();
|
|
13
|
+
* const stack = new Stack(app, 'MyStack');
|
|
14
|
+
* Aspects.of(stack).add(new MicroservicesChecks());
|
|
15
|
+
*/
|
|
16
|
+
export class MicroserviceChecks extends NagPack {
|
|
17
|
+
constructor(props?: NagPackProps) {
|
|
18
|
+
super(props);
|
|
19
|
+
this.packName = 'Microservices';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public visit(node: IConstruct) {
|
|
23
|
+
if (node instanceof CfnResource) {
|
|
24
|
+
this.applyRule({
|
|
25
|
+
info: 'The Lambda function does not have an explicit memory value configured.',
|
|
26
|
+
explanation:
|
|
27
|
+
"Lambda allocates CPU power in proportion to the amount of memory configured. By default, your functions have 128 MB of memory allocated. You can increase that value up to 10 GB. With more CPU resources, your Lambda function's duration might decrease. You can use tools such as AWS Lambda Power Tuning to test your function at different memory settings to find the one that matches your cost and performance requirements the best.",
|
|
28
|
+
level: NagMessageLevel.ERROR,
|
|
29
|
+
rule: rules.lambda.LambdaDefaultMemorySize,
|
|
30
|
+
node: node,
|
|
31
|
+
});
|
|
32
|
+
this.applyRule({
|
|
33
|
+
info: 'The Lambda function does not have an explicitly defined timeout value.',
|
|
34
|
+
explanation:
|
|
35
|
+
'Lambda functions have a default timeout of 3 seconds. If your timeout value is too short, Lambda might terminate invocations prematurely. On the other side, setting the timeout much higher than the average execution may cause functions to execute for longer upon code malfunction, resulting in higher costs and possibly reaching concurrency limits depending on how such functions are invoked. You can also use AWS Lambda Power Tuning to test your function at different timeout settings to find the one that matches your cost and performance requirements the best.',
|
|
36
|
+
level: NagMessageLevel.ERROR,
|
|
37
|
+
rule: rules.lambda.LambdaDefaultTimeout,
|
|
38
|
+
node: node,
|
|
39
|
+
});
|
|
40
|
+
this.applyRule({
|
|
41
|
+
info: 'The Lambda function does not have tracing set to Tracing.ACTIVE.',
|
|
42
|
+
explanation:
|
|
43
|
+
'When a Lambda function has ACTIVE tracing, Lambda automatically samples invocation requests, based on the sampling algorithm specified by X-Ray.',
|
|
44
|
+
level: NagMessageLevel.ERROR,
|
|
45
|
+
rule: rules.lambda.LambdaTracing,
|
|
46
|
+
node: node,
|
|
47
|
+
});
|
|
48
|
+
this.applyRule({
|
|
49
|
+
info: 'The CloudWatch Log Group does not have an explicit retention policy defined.',
|
|
50
|
+
explanation:
|
|
51
|
+
'By default, logs are kept indefinitely and never expire. You can adjust the retention policy for each log group, keeping the indefinite retention, or choosing a retention period between one day and 10 years. For Lambda functions, this applies to their automatically created CloudWatch Log Groups.',
|
|
52
|
+
level: NagMessageLevel.ERROR,
|
|
53
|
+
rule: rules.cloudwatch.CloudWatchLogGroupRetentionPeriod,
|
|
54
|
+
node: node,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { type IPropertyInjector } from 'aws-cdk-lib';
|
|
2
|
+
import { Runtime, Tracing } from 'aws-cdk-lib/aws-lambda';
|
|
3
|
+
import { NodejsFunction, type NodejsFunctionProps } from 'aws-cdk-lib/aws-lambda-nodejs';
|
|
4
|
+
|
|
5
|
+
interface Config {
|
|
6
|
+
runtime: Runtime;
|
|
7
|
+
sourceMap?: boolean;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Property injector for Node.js Lambda functions with configuration-aware defaults
|
|
12
|
+
*
|
|
13
|
+
* Applies configuration-specific bundling and runtime settings to Lambda functions.
|
|
14
|
+
* Different configurations can optimize for different priorities such as build speed,
|
|
15
|
+
* bundle size, or debugging capabilities.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```typescript
|
|
19
|
+
* // Apply configuration-specific defaults
|
|
20
|
+
* PropertyInjectors.of(scope).add(
|
|
21
|
+
* new NodeJsFunctionDefaultsInjector({
|
|
22
|
+
* sourceMaps: true,
|
|
23
|
+
* esm: true,
|
|
24
|
+
* minify: true,
|
|
25
|
+
* }).withProps({
|
|
26
|
+
* timeout: Duration.seconds(30),
|
|
27
|
+
* memorySize: 256,
|
|
28
|
+
* })
|
|
29
|
+
* );
|
|
30
|
+
*
|
|
31
|
+
* // Functions automatically inherit configuration defaults
|
|
32
|
+
* new Function(stack, 'MyFunction', {
|
|
33
|
+
* code: Code.fromAsset('src/lambda'),
|
|
34
|
+
* handler: 'index.handler',
|
|
35
|
+
* // bundling and runtime config applied automatically
|
|
36
|
+
* });
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* @see https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_lambda_nodejs.NodejsFunction.html
|
|
40
|
+
*/
|
|
41
|
+
export class NodeJsFunctionDefaultsInjector implements IPropertyInjector {
|
|
42
|
+
public readonly constructUniqueId = NodejsFunction.PROPERTY_INJECTION_ID;
|
|
43
|
+
private readonly config: Required<Config>;
|
|
44
|
+
private defaultProps: NodejsFunctionProps;
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Creates a new NodeJsFunctionDefaultsInjector
|
|
48
|
+
*
|
|
49
|
+
* @param config - Configuration identifier used to select appropriate defaults. Uses production defaults if not specified.
|
|
50
|
+
*/
|
|
51
|
+
constructor(config: Config) {
|
|
52
|
+
this.config = { ...config, sourceMap: config.sourceMap || true };
|
|
53
|
+
this.defaultProps = { runtime: config.runtime, tracing: Tracing.ACTIVE };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Creates a new injector instance with additional properties
|
|
58
|
+
*
|
|
59
|
+
* Returns a new injector that inherits the current configuration but includes
|
|
60
|
+
* additional properties that override the configuration defaults.
|
|
61
|
+
*
|
|
62
|
+
* @param props - Additional properties to merge with configuration defaults
|
|
63
|
+
* @returns A new injector instance with merged properties
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```typescript
|
|
67
|
+
* const customInjector = new NodeJsFunctionDefaultsInjector({
|
|
68
|
+
* sourceMaps: false,
|
|
69
|
+
* })
|
|
70
|
+
* .withProps({
|
|
71
|
+
* timeout: Duration.minutes(5),
|
|
72
|
+
* memorySize: 1024,
|
|
73
|
+
* });
|
|
74
|
+
* ```
|
|
75
|
+
*
|
|
76
|
+
* TODO: Provide a nice way to inherit global properties from previous injectors
|
|
77
|
+
*/
|
|
78
|
+
public withProps(props: NodejsFunctionProps) {
|
|
79
|
+
const modifiedInjector = new NodeJsFunctionDefaultsInjector(this.config);
|
|
80
|
+
modifiedInjector.defaultProps = { ...this.defaultProps, ...props };
|
|
81
|
+
return modifiedInjector;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Injects configuration-appropriate defaults into Lambda function properties
|
|
86
|
+
*
|
|
87
|
+
* Merges configuration-specific defaults with user-provided properties,
|
|
88
|
+
* automatically configuring bundling options and runtime settings.
|
|
89
|
+
*
|
|
90
|
+
* @param originalProps - Properties provided when creating the function
|
|
91
|
+
* @returns Merged properties with injected defaults
|
|
92
|
+
*/
|
|
93
|
+
public inject(originalProps: NodejsFunctionProps) {
|
|
94
|
+
// The NodeJsFunction constructor pre-sets runtime to 16.x or LATEST depending on feature flags
|
|
95
|
+
// We assume that using this injector means you want to standardise the runtime across all lambdas
|
|
96
|
+
const props = {
|
|
97
|
+
...this.defaultProps,
|
|
98
|
+
...originalProps,
|
|
99
|
+
runtime: this.defaultProps.runtime,
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
// If source maps are enabled in our bundling, add the required NODE_OPTIONS flag to the environment
|
|
103
|
+
const environment = {
|
|
104
|
+
...props.environment,
|
|
105
|
+
...(this.config.sourceMap ? { NODE_OPTIONS: '--enable-source-maps' } : {}),
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
return { ...props, environment };
|
|
109
|
+
}
|
|
110
|
+
}
|