@guardian/cdk 50.12.3 → 51.0.0

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.
Files changed (71) hide show
  1. package/lib/bin/commands/new-project/index.d.ts +1 -0
  2. package/lib/bin/commands/new-project/index.d.ts.map +1 -1
  3. package/lib/bin/commands/new-project/index.js +3 -1
  4. package/lib/bin/commands/new-project/index.js.map +1 -1
  5. package/lib/bin/commands/new-project/utils/app.d.ts +1 -0
  6. package/lib/bin/commands/new-project/utils/app.d.ts.map +1 -1
  7. package/lib/bin/commands/new-project/utils/app.js +6 -3
  8. package/lib/bin/commands/new-project/utils/app.js.map +1 -1
  9. package/lib/bin/commands/new-project/utils/imports.js +4 -4
  10. package/lib/bin/commands/new-project/utils/imports.js.map +1 -1
  11. package/lib/bin/index.js +7 -0
  12. package/lib/bin/index.js.map +1 -1
  13. package/lib/constructs/cloudwatch/alarm.d.ts +4 -0
  14. package/lib/constructs/cloudwatch/alarm.d.ts.map +1 -1
  15. package/lib/constructs/cloudwatch/alarm.js.map +1 -1
  16. package/lib/constructs/cloudwatch/ec2-alarms.d.ts +11 -1
  17. package/lib/constructs/cloudwatch/ec2-alarms.d.ts.map +1 -1
  18. package/lib/constructs/cloudwatch/ec2-alarms.js +33 -1
  19. package/lib/constructs/cloudwatch/ec2-alarms.js.map +1 -1
  20. package/lib/{experimental/constructs → constructs}/root.d.ts +4 -4
  21. package/lib/constructs/root.d.ts.map +1 -0
  22. package/lib/{experimental/constructs → constructs}/root.js +7 -7
  23. package/lib/constructs/root.js.map +1 -0
  24. package/lib/patterns/ec2-app/base.d.ts +5 -1
  25. package/lib/patterns/ec2-app/base.d.ts.map +1 -1
  26. package/lib/patterns/ec2-app/base.js +9 -1
  27. package/lib/patterns/ec2-app/base.js.map +1 -1
  28. package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/deployments/autoscaling.d.ts +1 -1
  29. package/lib/riff-raff-yaml-file/deployments/autoscaling.d.ts.map +1 -0
  30. package/lib/riff-raff-yaml-file/deployments/autoscaling.js.map +1 -0
  31. package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/deployments/cloudformation.d.ts +1 -1
  32. package/lib/riff-raff-yaml-file/deployments/cloudformation.d.ts.map +1 -0
  33. package/lib/riff-raff-yaml-file/deployments/cloudformation.js.map +1 -0
  34. package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/deployments/lambda.d.ts +1 -1
  35. package/lib/riff-raff-yaml-file/deployments/lambda.d.ts.map +1 -0
  36. package/lib/riff-raff-yaml-file/deployments/lambda.js.map +1 -0
  37. package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/group-by.d.ts +1 -1
  38. package/lib/riff-raff-yaml-file/group-by.d.ts.map +1 -0
  39. package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/group-by.js +1 -1
  40. package/lib/riff-raff-yaml-file/group-by.js.map +1 -0
  41. package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/index.d.ts +1 -1
  42. package/lib/riff-raff-yaml-file/index.d.ts.map +1 -0
  43. package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/index.js +6 -6
  44. package/lib/riff-raff-yaml-file/index.js.map +1 -0
  45. package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/types.d.ts +1 -1
  46. package/lib/riff-raff-yaml-file/types.d.ts.map +1 -0
  47. package/lib/riff-raff-yaml-file/types.js.map +1 -0
  48. package/lib/tsconfig.tsbuildinfo +1 -1
  49. package/package.json +1 -1
  50. package/lib/experimental/constructs/index.d.ts +0 -2
  51. package/lib/experimental/constructs/index.d.ts.map +0 -1
  52. package/lib/experimental/constructs/index.js +0 -18
  53. package/lib/experimental/constructs/index.js.map +0 -1
  54. package/lib/experimental/constructs/root.d.ts.map +0 -1
  55. package/lib/experimental/constructs/root.js.map +0 -1
  56. package/lib/experimental/riff-raff-yaml-file/deployments/autoscaling.d.ts.map +0 -1
  57. package/lib/experimental/riff-raff-yaml-file/deployments/autoscaling.js.map +0 -1
  58. package/lib/experimental/riff-raff-yaml-file/deployments/cloudformation.d.ts.map +0 -1
  59. package/lib/experimental/riff-raff-yaml-file/deployments/cloudformation.js.map +0 -1
  60. package/lib/experimental/riff-raff-yaml-file/deployments/lambda.d.ts.map +0 -1
  61. package/lib/experimental/riff-raff-yaml-file/deployments/lambda.js.map +0 -1
  62. package/lib/experimental/riff-raff-yaml-file/group-by.d.ts.map +0 -1
  63. package/lib/experimental/riff-raff-yaml-file/group-by.js.map +0 -1
  64. package/lib/experimental/riff-raff-yaml-file/index.d.ts.map +0 -1
  65. package/lib/experimental/riff-raff-yaml-file/index.js.map +0 -1
  66. package/lib/experimental/riff-raff-yaml-file/types.d.ts.map +0 -1
  67. package/lib/experimental/riff-raff-yaml-file/types.js.map +0 -1
  68. /package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/deployments/autoscaling.js +0 -0
  69. /package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/deployments/cloudformation.js +0 -0
  70. /package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/deployments/lambda.js +0 -0
  71. /package/lib/{experimental/riff-raff-yaml-file → riff-raff-yaml-file}/types.js +0 -0
@@ -5,6 +5,7 @@ interface NewProjectProps {
5
5
  app: string;
6
6
  stack: string;
7
7
  stages: string[];
8
+ regions: string[];
8
9
  yamlTemplateLocation?: string;
9
10
  packageManager: PackageManager;
10
11
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/commands/new-project/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAW7D,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5C,UAAU,eAAe;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,cAAc,CAAC;CAChC;AAsED,eAAO,MAAM,aAAa,UAAiB,eAAe,uBA+EzD,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/bin/commands/new-project/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAW7D,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,CAAC;AAE5C,UAAU,eAAe;IACvB,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,cAAc,EAAE,cAAc,CAAC;CAChC;AAuED,eAAO,MAAM,aAAa,UAAiB,eAAe,uBAgFzD,CAAC"}
@@ -38,7 +38,7 @@ function validateConfig(config) {
38
38
  }
39
39
  }
40
40
  function getConfig(props) {
41
- const { init, app, stack, stages, yamlTemplateLocation, packageManager } = props;
41
+ const { init, app, stack, stages, regions, yamlTemplateLocation, packageManager } = props;
42
42
  const rootDir = (0, git_1.gitRootOrCwd)();
43
43
  const cdkDir = (0, path_1.join)(rootDir, "/cdk");
44
44
  const appName = (0, utils_1.pascalCase)(app);
@@ -49,6 +49,7 @@ function getConfig(props) {
49
49
  init,
50
50
  yamlTemplateLocation,
51
51
  stages,
52
+ regions,
52
53
  cdkDir,
53
54
  appName: {
54
55
  kebab: kebabAppName,
@@ -82,6 +83,7 @@ const newCdkProject = async (props) => {
82
83
  stack: config.stackName,
83
84
  imports: imports_1.Imports.newAppImports(config.appName),
84
85
  stages: config.stages,
86
+ regions: config.regions,
85
87
  });
86
88
  // lib directory
87
89
  await (0, stack_1.constructStack)({
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/bin/commands/new-project/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"fs\";\nimport { basename, dirname, join } from \"path\";\nimport { ux } from \"@oclif/core\";\nimport chalk from \"chalk\";\nimport kebabCase from \"lodash.kebabcase\";\nimport type { CliCommandResponse } from \"../../../types/cli\";\nimport { execute } from \"../../../utils/exec\";\nimport { gitRootOrCwd } from \"../../../utils/git\";\nimport { constructApp } from \"./utils/app\";\nimport { Imports } from \"./utils/imports\";\nimport { buildDirectory } from \"./utils/init\";\nimport { constructTest } from \"./utils/snapshot\";\nimport { constructStack } from \"./utils/stack\";\nimport type { Name } from \"./utils/utils\";\nimport { getCommands, pascalCase } from \"./utils/utils\";\n\nexport type PackageManager = \"npm\" | \"yarn\";\n\ninterface NewProjectProps {\n init: boolean;\n app: string;\n stack: string;\n stages: string[];\n yamlTemplateLocation?: string;\n packageManager: PackageManager;\n}\n\ninterface NewProjectConfig extends Omit<NewProjectProps, \"stack\" | \"app\"> {\n cdkDir: string;\n appPath: string;\n appName: Name;\n stackPath: string;\n stackName: Name;\n testPath: string;\n}\n\nconst checkPathExists = (path: string): void => {\n if (!existsSync(path)) {\n throw new Error(`File not found - ${path}`);\n }\n};\n\nconst checkPathDoesNotExist = (path: string): void => {\n if (existsSync(path)) {\n throw new Error(`There is already a file at - ${path}`);\n }\n};\n\nfunction validateConfig(config: NewProjectConfig): void {\n if (!config.init) {\n checkPathExists(config.cdkDir);\n }\n checkPathDoesNotExist(config.appPath); // TODO: Update the app file if it already exists\n checkPathDoesNotExist(config.stackPath);\n\n if (config.yamlTemplateLocation) {\n checkPathExists(config.yamlTemplateLocation);\n }\n}\n\nfunction getConfig(props: NewProjectProps): NewProjectConfig {\n const { init, app, stack, stages, yamlTemplateLocation, packageManager } = props;\n\n const rootDir = gitRootOrCwd();\n const cdkDir = join(rootDir, \"/cdk\");\n\n const appName = pascalCase(app);\n const kebabAppName = kebabCase(appName);\n const stackName = pascalCase(stack);\n const kebabStackName = kebabCase(stackName);\n\n const config: NewProjectConfig = {\n init,\n yamlTemplateLocation,\n stages,\n cdkDir,\n appName: {\n kebab: kebabAppName,\n pascal: appName,\n },\n appPath: `${cdkDir}/bin/${kebabAppName}.ts`,\n stackName: {\n kebab: kebabStackName,\n pascal: stackName,\n },\n stackPath: `${cdkDir}/lib/${kebabAppName}.ts`,\n testPath: `${cdkDir}/lib/${kebabAppName}.test.ts`,\n packageManager,\n };\n\n validateConfig(config);\n\n return config;\n}\n\nexport const newCdkProject = async (props: NewProjectProps): CliCommandResponse => {\n console.log(\"Starting CDK generator\");\n\n const config = getConfig(props);\n\n if (config.init) {\n buildDirectory({ outputDir: config.cdkDir });\n }\n\n console.log(`New app ${config.appName.pascal} will be written to ${config.appPath}`);\n console.log(`New stack ${config.stackName.pascal} will be written to ${config.stackPath}`);\n\n // bin directory\n await constructApp({\n appName: config.appName,\n outputFile: \"cdk.ts\",\n outputDir: dirname(config.appPath),\n stack: config.stackName,\n imports: Imports.newAppImports(config.appName),\n stages: config.stages,\n });\n\n // lib directory\n await constructStack({\n imports: Imports.newStackImports(!!config.yamlTemplateLocation),\n appName: config.appName,\n outputFile: basename(config.stackPath),\n outputDir: dirname(config.stackPath),\n yamlTemplateLocation: config.yamlTemplateLocation,\n });\n\n // lib directory\n await constructTest({\n imports: Imports.newTestImports(config.appName),\n stackName: config.stackName,\n appName: config.appName,\n outputFile: basename(config.testPath),\n outputDir: dirname(config.stackPath),\n });\n\n const commands = getCommands(config.packageManager, config.cdkDir);\n\n if (config.init) {\n ux.action.start(chalk.yellow(\"Installing dependencies. This may take a while...\"));\n await commands.installDependencies();\n ux.action.stop();\n }\n\n // Run `eslint --fix` on the generated files instead of trying to generate code that completely satisfies the linter\n await execute(\n \"./node_modules/.bin/eslint\",\n [\"lib/** bin/**\", \"--ext .ts\", \"--no-error-on-unmatched-pattern\", \"--fix\"],\n {\n cwd: config.cdkDir,\n },\n );\n\n ux.action.start(chalk.yellow(\"Running lint check...\"));\n await commands.lint();\n ux.action.stop();\n\n ux.action.start(chalk.yellow(\"Running tests...\"));\n await commands.test();\n ux.action.stop();\n\n ux.action.start(chalk.yellow(\"Running initial synthesis...\"));\n await commands.synth();\n ux.action.stop();\n\n console.log(chalk.green(\"Success! Here's a summary of the created files:\"));\n const tree = await execute(\"tree\", [\"-I 'node_modules|cdk.out'\"], {\n cwd: config.cdkDir,\n });\n console.log(tree);\n\n const docsUrl = \"https://github.com/guardian/cdk/tree/main/docs\";\n ux.url(chalk.green(`Please see the docs (${docsUrl}) for next steps.`), docsUrl);\n\n return Promise.resolve(0);\n};\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/bin/commands/new-project/index.ts"],"names":[],"mappings":"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","sourcesContent":["import { existsSync } from \"fs\";\nimport { basename, dirname, join } from \"path\";\nimport { ux } from \"@oclif/core\";\nimport chalk from \"chalk\";\nimport kebabCase from \"lodash.kebabcase\";\nimport type { CliCommandResponse } from \"../../../types/cli\";\nimport { execute } from \"../../../utils/exec\";\nimport { gitRootOrCwd } from \"../../../utils/git\";\nimport { constructApp } from \"./utils/app\";\nimport { Imports } from \"./utils/imports\";\nimport { buildDirectory } from \"./utils/init\";\nimport { constructTest } from \"./utils/snapshot\";\nimport { constructStack } from \"./utils/stack\";\nimport type { Name } from \"./utils/utils\";\nimport { getCommands, pascalCase } from \"./utils/utils\";\n\nexport type PackageManager = \"npm\" | \"yarn\";\n\ninterface NewProjectProps {\n init: boolean;\n app: string;\n stack: string;\n stages: string[];\n regions: string[];\n yamlTemplateLocation?: string;\n packageManager: PackageManager;\n}\n\ninterface NewProjectConfig extends Omit<NewProjectProps, \"stack\" | \"app\"> {\n cdkDir: string;\n appPath: string;\n appName: Name;\n stackPath: string;\n stackName: Name;\n testPath: string;\n}\n\nconst checkPathExists = (path: string): void => {\n if (!existsSync(path)) {\n throw new Error(`File not found - ${path}`);\n }\n};\n\nconst checkPathDoesNotExist = (path: string): void => {\n if (existsSync(path)) {\n throw new Error(`There is already a file at - ${path}`);\n }\n};\n\nfunction validateConfig(config: NewProjectConfig): void {\n if (!config.init) {\n checkPathExists(config.cdkDir);\n }\n checkPathDoesNotExist(config.appPath); // TODO: Update the app file if it already exists\n checkPathDoesNotExist(config.stackPath);\n\n if (config.yamlTemplateLocation) {\n checkPathExists(config.yamlTemplateLocation);\n }\n}\n\nfunction getConfig(props: NewProjectProps): NewProjectConfig {\n const { init, app, stack, stages, regions, yamlTemplateLocation, packageManager } = props;\n\n const rootDir = gitRootOrCwd();\n const cdkDir = join(rootDir, \"/cdk\");\n\n const appName = pascalCase(app);\n const kebabAppName = kebabCase(appName);\n const stackName = pascalCase(stack);\n const kebabStackName = kebabCase(stackName);\n\n const config: NewProjectConfig = {\n init,\n yamlTemplateLocation,\n stages,\n regions,\n cdkDir,\n appName: {\n kebab: kebabAppName,\n pascal: appName,\n },\n appPath: `${cdkDir}/bin/${kebabAppName}.ts`,\n stackName: {\n kebab: kebabStackName,\n pascal: stackName,\n },\n stackPath: `${cdkDir}/lib/${kebabAppName}.ts`,\n testPath: `${cdkDir}/lib/${kebabAppName}.test.ts`,\n packageManager,\n };\n\n validateConfig(config);\n\n return config;\n}\n\nexport const newCdkProject = async (props: NewProjectProps): CliCommandResponse => {\n console.log(\"Starting CDK generator\");\n\n const config = getConfig(props);\n\n if (config.init) {\n buildDirectory({ outputDir: config.cdkDir });\n }\n\n console.log(`New app ${config.appName.pascal} will be written to ${config.appPath}`);\n console.log(`New stack ${config.stackName.pascal} will be written to ${config.stackPath}`);\n\n // bin directory\n await constructApp({\n appName: config.appName,\n outputFile: \"cdk.ts\",\n outputDir: dirname(config.appPath),\n stack: config.stackName,\n imports: Imports.newAppImports(config.appName),\n stages: config.stages,\n regions: config.regions,\n });\n\n // lib directory\n await constructStack({\n imports: Imports.newStackImports(!!config.yamlTemplateLocation),\n appName: config.appName,\n outputFile: basename(config.stackPath),\n outputDir: dirname(config.stackPath),\n yamlTemplateLocation: config.yamlTemplateLocation,\n });\n\n // lib directory\n await constructTest({\n imports: Imports.newTestImports(config.appName),\n stackName: config.stackName,\n appName: config.appName,\n outputFile: basename(config.testPath),\n outputDir: dirname(config.stackPath),\n });\n\n const commands = getCommands(config.packageManager, config.cdkDir);\n\n if (config.init) {\n ux.action.start(chalk.yellow(\"Installing dependencies. This may take a while...\"));\n await commands.installDependencies();\n ux.action.stop();\n }\n\n // Run `eslint --fix` on the generated files instead of trying to generate code that completely satisfies the linter\n await execute(\n \"./node_modules/.bin/eslint\",\n [\"lib/** bin/**\", \"--ext .ts\", \"--no-error-on-unmatched-pattern\", \"--fix\"],\n {\n cwd: config.cdkDir,\n },\n );\n\n ux.action.start(chalk.yellow(\"Running lint check...\"));\n await commands.lint();\n ux.action.stop();\n\n ux.action.start(chalk.yellow(\"Running tests...\"));\n await commands.test();\n ux.action.stop();\n\n ux.action.start(chalk.yellow(\"Running initial synthesis...\"));\n await commands.synth();\n ux.action.stop();\n\n console.log(chalk.green(\"Success! Here's a summary of the created files:\"));\n const tree = await execute(\"tree\", [\"-I 'node_modules|cdk.out'\"], {\n cwd: config.cdkDir,\n });\n console.log(tree);\n\n const docsUrl = \"https://github.com/guardian/cdk/tree/main/docs\";\n ux.url(chalk.green(`Please see the docs (${docsUrl}) for next steps.`), docsUrl);\n\n return Promise.resolve(0);\n};\n"]}
@@ -6,6 +6,7 @@ interface AppBuilderProps {
6
6
  appName: Name;
7
7
  stack: Name;
8
8
  stages: string[];
9
+ regions: string[];
9
10
  outputFile: string;
10
11
  outputDir: string;
11
12
  comment?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,UAAU;IACrB,MAAM,EAAE,eAAe,CAAC;IAExB,IAAI,EAAE,SAAS,CAAC;gBAEJ,KAAK,EAAE,eAAe;IAO5B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;CAsBxC;AAED,eAAO,MAAM,YAAY,UAAiB,eAAe,KAAG,QAAQ,IAAI,CAGvE,CAAC"}
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/app.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAEpC,UAAU,eAAe;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,IAAI,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,qBAAa,UAAU;IACrB,MAAM,EAAE,eAAe,CAAC;IAExB,IAAI,EAAE,SAAS,CAAC;gBAEJ,KAAK,EAAE,eAAe;IAO5B,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;CAyBxC;AAED,eAAO,MAAM,YAAY,UAAiB,eAAe,KAAG,QAAQ,IAAI,CAGvE,CAAC"}
@@ -9,16 +9,19 @@ class AppBuilder {
9
9
  this.code.closeBlockFormatter = (s) => s ?? "}";
10
10
  }
11
11
  async constructCdkFile() {
12
- const { comment, outputFile, imports, appName, stack, outputDir, stages } = this.config;
12
+ const { comment, outputFile, imports, appName, stack, outputDir, stages, regions } = this.config;
13
13
  this.code.openFile(outputFile);
14
14
  if (comment) {
15
15
  this.code.line(comment);
16
16
  this.code.line();
17
17
  }
18
18
  imports.render(this.code);
19
- this.code.line("const app = new App();");
19
+ this.code.line("const app = new GuRoot();");
20
20
  stages.forEach((stage) => {
21
- this.code.line(`new ${appName.pascal}(app, "${appName.pascal}-${stage}", { stack: "${stack.kebab}", stage: "${stage}" });`);
21
+ regions.forEach((region) => {
22
+ const regionNoHyphen = region.replace("-", "");
23
+ this.code.line(`new ${appName.pascal}(app, "${appName.pascal}-${regionNoHyphen}-${stage}", { stack: "${stack.kebab}", stage: "${stage}", env: { region: "${region}" } });`);
24
+ });
22
25
  });
23
26
  this.code.closeFile(outputFile);
24
27
  await this.code.save(outputDir);
@@ -1 +1 @@
1
- {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/app.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAetC,MAAa,UAAU;IAKrB,YAAY,KAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QAEpB,IAAI,CAAC,IAAI,GAAG,IAAI,qBAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAExF,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAClB;QAED,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAEzC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,CAAC,IAAI,CAAC,IAAI,CACZ,OAAO,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,IAAI,KAAK,gBAAgB,KAAK,CAAC,KAAK,cAAc,KAAK,OAAO,CAC5G,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;CACF;AAlCD,gCAkCC;AAEM,MAAM,YAAY,GAAG,KAAK,EAAE,KAAsB,EAAiB,EAAE;IAC1E,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC;AACnC,CAAC,CAAC;AAHW,QAAA,YAAY,gBAGvB","sourcesContent":["import { CodeMaker } from \"codemaker\";\nimport type { Imports } from \"./imports\";\nimport type { Name } from \"./utils\";\n\ninterface AppBuilderProps {\n imports: Imports;\n appName: Name;\n stack: Name;\n stages: string[];\n outputFile: string;\n outputDir: string;\n comment?: string;\n migrated?: boolean;\n}\n\nexport class AppBuilder {\n config: AppBuilderProps;\n\n code: CodeMaker;\n\n constructor(props: AppBuilderProps) {\n this.config = props;\n\n this.code = new CodeMaker({ indentationLevel: 2 });\n this.code.closeBlockFormatter = (s?: string): string => s ?? \"}\";\n }\n\n async constructCdkFile(): Promise<void> {\n const { comment, outputFile, imports, appName, stack, outputDir, stages } = this.config;\n\n this.code.openFile(outputFile);\n if (comment) {\n this.code.line(comment);\n this.code.line();\n }\n\n imports.render(this.code);\n\n this.code.line(\"const app = new App();\");\n\n stages.forEach((stage) => {\n this.code.line(\n `new ${appName.pascal}(app, \"${appName.pascal}-${stage}\", { stack: \"${stack.kebab}\", stage: \"${stage}\" });`,\n );\n });\n\n this.code.closeFile(outputFile);\n await this.code.save(outputDir);\n }\n}\n\nexport const constructApp = async (props: AppBuilderProps): Promise<void> => {\n const builder = new AppBuilder(props);\n await builder.constructCdkFile();\n};\n"]}
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/app.ts"],"names":[],"mappings":";;;AAAA,yCAAsC;AAgBtC,MAAa,UAAU;IAKrB,YAAY,KAAsB;QAChC,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QAEpB,IAAI,CAAC,IAAI,GAAG,IAAI,qBAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAU,EAAU,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC;IACnE,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC;QAEjG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC/B,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;SAClB;QAED,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAE1B,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;QAE5C,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;YACvB,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBACzB,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC/C,IAAI,CAAC,IAAI,CAAC,IAAI,CACZ,OAAO,OAAO,CAAC,MAAM,UAAU,OAAO,CAAC,MAAM,IAAI,cAAc,IAAI,KAAK,gBAAgB,KAAK,CAAC,KAAK,cAAc,KAAK,sBAAsB,MAAM,SAAS,CAC5J,CAAC;YACJ,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAChC,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;CACF;AArCD,gCAqCC;AAEM,MAAM,YAAY,GAAG,KAAK,EAAE,KAAsB,EAAiB,EAAE;IAC1E,MAAM,OAAO,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC;IACtC,MAAM,OAAO,CAAC,gBAAgB,EAAE,CAAC;AACnC,CAAC,CAAC;AAHW,QAAA,YAAY,gBAGvB","sourcesContent":["import { CodeMaker } from \"codemaker\";\nimport type { Imports } from \"./imports\";\nimport type { Name } from \"./utils\";\n\ninterface AppBuilderProps {\n imports: Imports;\n appName: Name;\n stack: Name;\n stages: string[];\n regions: string[];\n outputFile: string;\n outputDir: string;\n comment?: string;\n migrated?: boolean;\n}\n\nexport class AppBuilder {\n config: AppBuilderProps;\n\n code: CodeMaker;\n\n constructor(props: AppBuilderProps) {\n this.config = props;\n\n this.code = new CodeMaker({ indentationLevel: 2 });\n this.code.closeBlockFormatter = (s?: string): string => s ?? \"}\";\n }\n\n async constructCdkFile(): Promise<void> {\n const { comment, outputFile, imports, appName, stack, outputDir, stages, regions } = this.config;\n\n this.code.openFile(outputFile);\n if (comment) {\n this.code.line(comment);\n this.code.line();\n }\n\n imports.render(this.code);\n\n this.code.line(\"const app = new GuRoot();\");\n\n stages.forEach((stage) => {\n regions.forEach((region) => {\n const regionNoHyphen = region.replace(\"-\", \"\");\n this.code.line(\n `new ${appName.pascal}(app, \"${appName.pascal}-${regionNoHyphen}-${stage}\", { stack: \"${stack.kebab}\", stage: \"${stage}\", env: { region: \"${region}\" } });`,\n );\n });\n });\n\n this.code.closeFile(outputFile);\n await this.code.save(outputDir);\n }\n}\n\nexport const constructApp = async (props: AppBuilderProps): Promise<void> => {\n const builder = new AppBuilder(props);\n await builder.constructCdkFile();\n};\n"]}
@@ -29,15 +29,15 @@ class Imports {
29
29
  }
30
30
  static newAppImports({ kebab, pascal }) {
31
31
  return new Imports({
32
- "aws-cdk-lib": {
33
- types: [],
34
- components: ["App"],
35
- },
36
32
  "source-map-support/register": {
37
33
  basic: true,
38
34
  types: [],
39
35
  components: [],
40
36
  },
37
+ "@guardian/cdk/lib/constructs/root": {
38
+ types: [],
39
+ components: ["GuRoot"],
40
+ },
41
41
  [`../lib/${kebab}`]: {
42
42
  types: [],
43
43
  components: [pascal],
@@ -1 +1 @@
1
- {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/imports.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CodeMaker } from \"codemaker\";\nimport type { Name } from \"./utils\";\n\ninterface Import {\n types: string[];\n components: string[];\n basic?: boolean;\n}\n\nexport class Imports {\n private readonly imports: Record<string, Import>;\n\n private constructor(imports: Record<string, Import>) {\n this.imports = imports;\n }\n\n public static newStackImports(addCfnIncludeImports: boolean): Imports {\n return new Imports({\n ...(addCfnIncludeImports && {\n path: {\n types: [],\n components: [\"join\"],\n },\n \"aws-cdk-lib/cloudformation-include\": {\n types: [],\n components: [\"CfnInclude\"],\n },\n }),\n \"aws-cdk-lib\": {\n types: [\"App\"],\n components: [],\n },\n \"@guardian/cdk/lib/constructs/core\": {\n types: [\"GuStackProps\"],\n components: [\"GuStack\"],\n },\n });\n }\n\n public static newAppImports({ kebab, pascal }: Name): Imports {\n return new Imports({\n \"aws-cdk-lib\": {\n types: [],\n components: [\"App\"],\n },\n \"source-map-support/register\": {\n basic: true,\n types: [],\n components: [],\n },\n [`../lib/${kebab}`]: {\n types: [],\n components: [pascal],\n },\n });\n }\n\n public static newTestImports({ kebab, pascal }: Name): Imports {\n return new Imports({\n \"aws-cdk-lib\": {\n types: [],\n components: [\"App\"],\n },\n \"aws-cdk-lib/assertions\": {\n types: [],\n components: [\"Template\"],\n },\n [`./${kebab}`]: {\n types: [],\n components: [pascal],\n },\n });\n }\n\n render(code: CodeMaker): void {\n Object.entries(this.imports)\n // Render \"basic\" imports before any others, still in alphabetical order\n // Render relative imports after absolute imports\n .sort(([aKey, aImports], [bKey, bImports]) => {\n if (aImports.basic && !bImports.basic) {\n return -1;\n } else if (bImports.basic && !aImports.basic) {\n return 1;\n } else if (aKey.startsWith(\".\") && !bKey.startsWith(\".\")) {\n return 1;\n } else if (bKey.startsWith(\".\") && !aKey.startsWith(\".\")) {\n return -1;\n } else {\n return aKey.localeCompare(bKey);\n }\n })\n .forEach(([lib, imports]) => {\n imports.basic && code.line(`import \"${lib}\";`);\n\n imports.types.length && code.line(`import type { ${imports.types.sort().join(\", \")} } from \"${lib}\";`);\n\n imports.components.length && code.line(`import { ${imports.components.sort().join(\", \")} } from \"${lib}\";`);\n });\n code.line();\n }\n}\n"]}
1
+ {"version":3,"file":"imports.js","sourceRoot":"","sources":["../../../../../src/bin/commands/new-project/utils/imports.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CodeMaker } from \"codemaker\";\nimport type { Name } from \"./utils\";\n\ninterface Import {\n types: string[];\n components: string[];\n basic?: boolean;\n}\n\nexport class Imports {\n private readonly imports: Record<string, Import>;\n\n private constructor(imports: Record<string, Import>) {\n this.imports = imports;\n }\n\n public static newStackImports(addCfnIncludeImports: boolean): Imports {\n return new Imports({\n ...(addCfnIncludeImports && {\n path: {\n types: [],\n components: [\"join\"],\n },\n \"aws-cdk-lib/cloudformation-include\": {\n types: [],\n components: [\"CfnInclude\"],\n },\n }),\n \"aws-cdk-lib\": {\n types: [\"App\"],\n components: [],\n },\n \"@guardian/cdk/lib/constructs/core\": {\n types: [\"GuStackProps\"],\n components: [\"GuStack\"],\n },\n });\n }\n\n public static newAppImports({ kebab, pascal }: Name): Imports {\n return new Imports({\n \"source-map-support/register\": {\n basic: true,\n types: [],\n components: [],\n },\n \"@guardian/cdk/lib/constructs/root\": {\n types: [],\n components: [\"GuRoot\"],\n },\n [`../lib/${kebab}`]: {\n types: [],\n components: [pascal],\n },\n });\n }\n\n public static newTestImports({ kebab, pascal }: Name): Imports {\n return new Imports({\n \"aws-cdk-lib\": {\n types: [],\n components: [\"App\"],\n },\n \"aws-cdk-lib/assertions\": {\n types: [],\n components: [\"Template\"],\n },\n [`./${kebab}`]: {\n types: [],\n components: [pascal],\n },\n });\n }\n\n render(code: CodeMaker): void {\n Object.entries(this.imports)\n // Render \"basic\" imports before any others, still in alphabetical order\n // Render relative imports after absolute imports\n .sort(([aKey, aImports], [bKey, bImports]) => {\n if (aImports.basic && !bImports.basic) {\n return -1;\n } else if (bImports.basic && !aImports.basic) {\n return 1;\n } else if (aKey.startsWith(\".\") && !bKey.startsWith(\".\")) {\n return 1;\n } else if (bKey.startsWith(\".\") && !aKey.startsWith(\".\")) {\n return -1;\n } else {\n return aKey.localeCompare(bKey);\n }\n })\n .forEach(([lib, imports]) => {\n imports.basic && code.line(`import \"${lib}\";`);\n\n imports.types.length && code.line(`import type { ${imports.types.sort().join(\", \")} } from \"${lib}\";`);\n\n imports.components.length && code.line(`import { ${imports.components.sort().join(\", \")} } from \"${lib}\";`);\n });\n code.line();\n }\n}\n"]}
package/lib/bin/index.js CHANGED
@@ -52,6 +52,11 @@ const parseCommandLineArguments = () => {
52
52
  description: "The stage(s) for your stack. Can be specified multiple times, e.g. --stage CODE --stage PROD",
53
53
  type: "array",
54
54
  demandOption: true,
55
+ })
56
+ .option("region", {
57
+ description: "The region(s) for your stack. Can be specified multiple times, e.g. --region eu-west-1 --region us-east-1",
58
+ type: "array",
59
+ default: ["eu-west-1"],
55
60
  })
56
61
  .option("package-manager", {
57
62
  description: "The Node package manager to use. Match this to the repository (package-lock.json = npm, yarn.lock = yarn). If the repository has neither file, and there is no strong convention in your team, we recommend npm.",
@@ -83,6 +88,7 @@ parseCommandLineArguments()
83
88
  const stack = argv.stack;
84
89
  const yamlTemplateLocation = argv["yaml-template-location"];
85
90
  const stage = argv.stage;
91
+ const regions = argv.region;
86
92
  const packageManager = argv["package-manager"];
87
93
  const stages = stage.map((_) => _.toUpperCase());
88
94
  return (0, new_project_1.newCdkProject)({
@@ -91,6 +97,7 @@ parseCommandLineArguments()
91
97
  stack,
92
98
  yamlTemplateLocation,
93
99
  stages,
100
+ regions,
94
101
  packageManager: packageManager,
95
102
  });
96
103
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { LibraryInfo } from \"../constants\";\nimport type { CliCommandResponse } from \"../types/cli\";\nimport { awsCredentialProviderChain } from \"./aws-credential-provider\";\nimport { accountReadinessCommand } from \"./commands/account-readiness\";\nimport { awsCdkVersionCommand } from \"./commands/aws-cdk-version\";\nimport type { PackageManager } from \"./commands/new-project\";\nimport { newCdkProject } from \"./commands/new-project\";\n\nconst Commands = {\n AwsCdkVersion: \"aws-cdk-version\",\n AccountReadiness: \"account-readiness\",\n New: \"new\",\n};\n\nconst parseCommandLineArguments = () => {\n /*\n The type of `yargs.argv` is `T | Promise<T>`.\n To avoid creating custom type guards, use `Promise.resolve` which takes `T | PromiseLike<T>` and returns `Promise<T>`.\n That is, use `Promise.resolve` to provide a single type.\n See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/7b2f0d45985538a40df96244481bfc6cd309c250/types/yargs/index.d.ts#L74\n */\n return Promise.resolve(\n yargs\n .usage(\"$0 COMMAND [args]\")\n .command(Commands.AwsCdkVersion, \"Print the version of AWS CDK libraries being used\")\n .command(Commands.AccountReadiness, \"Perform checks on an AWS account to see if it is GuCDK ready\", (yargs) =>\n yargs\n .option(\"profile\", { type: \"string\", description: \"AWS profile\" })\n .option(\"region\", { type: \"string\", description: \"AWS region\", default: \"eu-west-1\" }),\n )\n .command(\n Commands.New,\n \"Creates a new CDK project within a `cdk` directory at the root of the repository\",\n (yargs) =>\n yargs\n .option(\"init\", {\n type: \"boolean\",\n description: \"Create the cdk directory before building the app and stack files (defaults to true)\",\n default: true,\n })\n .option(\"app\", {\n type: \"string\",\n description: \"The name of your application e.g. Amigo\",\n demandOption: true,\n })\n .option(\"stack\", {\n type: \"string\",\n description:\n \"The Guardian stack being used (as defined in your riff-raff.yaml). This will be applied as a tag to all of your resources.\",\n demandOption: true,\n })\n .option(\"yaml-template-location\", {\n type: \"string\",\n description: \"Path to the YAML CloudFormation template\",\n })\n .option(\"stage\", {\n description:\n \"The stage(s) for your stack. Can be specified multiple times, e.g. --stage CODE --stage PROD\",\n type: \"array\",\n demandOption: true,\n })\n .option(\"package-manager\", {\n description:\n \"The Node package manager to use. Match this to the repository (package-lock.json = npm, yarn.lock = yarn). If the repository has neither file, and there is no strong convention in your team, we recommend npm.\",\n choices: [\"npm\", \"yarn\"],\n demandOption: true,\n }),\n )\n .version(\n `${LibraryInfo.VERSION} (using aws-cdk-lib ${LibraryInfo.AWS_CDK_VERSION}, constructs ${LibraryInfo.CONSTRUCTS_VERSION})`,\n )\n .demandCommand(1, \"\") // just print help\n .help()\n .alias(\"h\", \"help\").argv,\n );\n};\n\nparseCommandLineArguments()\n .then((argv): CliCommandResponse => {\n const command = argv._[0];\n switch (command) {\n case Commands.AwsCdkVersion: {\n return awsCdkVersionCommand();\n }\n case Commands.AccountReadiness: {\n // TODO remove casting as yargs should be able to infer the type of the options\n const profile = argv.profile as string;\n const region = argv.region as string;\n return accountReadinessCommand({ credentialProvider: awsCredentialProviderChain(profile), region: region });\n }\n case Commands.New: {\n // TODO remove casting as yargs should be able to infer the type of the options\n const init = argv.init as boolean;\n const app = argv.app as string;\n const stack = argv.stack as string;\n const yamlTemplateLocation = argv[\"yaml-template-location\"] as string | undefined;\n const stage = argv.stage as string[];\n const packageManager = argv[\"package-manager\"] as string;\n\n const stages = stage.map((_) => _.toUpperCase());\n return newCdkProject({\n init,\n app,\n stack,\n yamlTemplateLocation,\n stages,\n packageManager: packageManager as PackageManager,\n });\n }\n default:\n throw new Error(`Unknown command: ${command ?? \"\"}`);\n }\n })\n .then((commandResponse) => {\n if (typeof commandResponse === \"number\") {\n process.exitCode = commandResponse;\n } else if (typeof commandResponse === \"string\") {\n console.log(commandResponse);\n } else {\n const responseWithVersionInfo = { \"@guardian/cdk\": { version: LibraryInfo.VERSION }, ...commandResponse };\n console.log(JSON.stringify(responseWithVersionInfo));\n }\n })\n .catch((err) => {\n console.error(err);\n process.exitCode = 1;\n });\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/bin/index.ts"],"names":[],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nimport yargs from \"yargs\";\nimport { LibraryInfo } from \"../constants\";\nimport type { CliCommandResponse } from \"../types/cli\";\nimport { awsCredentialProviderChain } from \"./aws-credential-provider\";\nimport { accountReadinessCommand } from \"./commands/account-readiness\";\nimport { awsCdkVersionCommand } from \"./commands/aws-cdk-version\";\nimport type { PackageManager } from \"./commands/new-project\";\nimport { newCdkProject } from \"./commands/new-project\";\n\nconst Commands = {\n AwsCdkVersion: \"aws-cdk-version\",\n AccountReadiness: \"account-readiness\",\n New: \"new\",\n};\n\nconst parseCommandLineArguments = () => {\n /*\n The type of `yargs.argv` is `T | Promise<T>`.\n To avoid creating custom type guards, use `Promise.resolve` which takes `T | PromiseLike<T>` and returns `Promise<T>`.\n That is, use `Promise.resolve` to provide a single type.\n See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/7b2f0d45985538a40df96244481bfc6cd309c250/types/yargs/index.d.ts#L74\n */\n return Promise.resolve(\n yargs\n .usage(\"$0 COMMAND [args]\")\n .command(Commands.AwsCdkVersion, \"Print the version of AWS CDK libraries being used\")\n .command(Commands.AccountReadiness, \"Perform checks on an AWS account to see if it is GuCDK ready\", (yargs) =>\n yargs\n .option(\"profile\", { type: \"string\", description: \"AWS profile\" })\n .option(\"region\", { type: \"string\", description: \"AWS region\", default: \"eu-west-1\" }),\n )\n .command(\n Commands.New,\n \"Creates a new CDK project within a `cdk` directory at the root of the repository\",\n (yargs) =>\n yargs\n .option(\"init\", {\n type: \"boolean\",\n description: \"Create the cdk directory before building the app and stack files (defaults to true)\",\n default: true,\n })\n .option(\"app\", {\n type: \"string\",\n description: \"The name of your application e.g. Amigo\",\n demandOption: true,\n })\n .option(\"stack\", {\n type: \"string\",\n description:\n \"The Guardian stack being used (as defined in your riff-raff.yaml). This will be applied as a tag to all of your resources.\",\n demandOption: true,\n })\n .option(\"yaml-template-location\", {\n type: \"string\",\n description: \"Path to the YAML CloudFormation template\",\n })\n .option(\"stage\", {\n description:\n \"The stage(s) for your stack. Can be specified multiple times, e.g. --stage CODE --stage PROD\",\n type: \"array\",\n demandOption: true,\n })\n .option(\"region\", {\n description:\n \"The region(s) for your stack. Can be specified multiple times, e.g. --region eu-west-1 --region us-east-1\",\n type: \"array\",\n default: [\"eu-west-1\"],\n })\n .option(\"package-manager\", {\n description:\n \"The Node package manager to use. Match this to the repository (package-lock.json = npm, yarn.lock = yarn). If the repository has neither file, and there is no strong convention in your team, we recommend npm.\",\n choices: [\"npm\", \"yarn\"],\n demandOption: true,\n }),\n )\n .version(\n `${LibraryInfo.VERSION} (using aws-cdk-lib ${LibraryInfo.AWS_CDK_VERSION}, constructs ${LibraryInfo.CONSTRUCTS_VERSION})`,\n )\n .demandCommand(1, \"\") // just print help\n .help()\n .alias(\"h\", \"help\").argv,\n );\n};\n\nparseCommandLineArguments()\n .then((argv): CliCommandResponse => {\n const command = argv._[0];\n switch (command) {\n case Commands.AwsCdkVersion: {\n return awsCdkVersionCommand();\n }\n case Commands.AccountReadiness: {\n // TODO remove casting as yargs should be able to infer the type of the options\n const profile = argv.profile as string;\n const region = argv.region as string;\n return accountReadinessCommand({ credentialProvider: awsCredentialProviderChain(profile), region: region });\n }\n case Commands.New: {\n // TODO remove casting as yargs should be able to infer the type of the options\n const init = argv.init as boolean;\n const app = argv.app as string;\n const stack = argv.stack as string;\n const yamlTemplateLocation = argv[\"yaml-template-location\"] as string | undefined;\n const stage = argv.stage as string[];\n const regions = argv.region as string[];\n const packageManager = argv[\"package-manager\"] as string;\n\n const stages = stage.map((_) => _.toUpperCase());\n\n return newCdkProject({\n init,\n app,\n stack,\n yamlTemplateLocation,\n stages,\n regions,\n packageManager: packageManager as PackageManager,\n });\n }\n default:\n throw new Error(`Unknown command: ${command ?? \"\"}`);\n }\n })\n .then((commandResponse) => {\n if (typeof commandResponse === \"number\") {\n process.exitCode = commandResponse;\n } else if (typeof commandResponse === \"string\") {\n console.log(commandResponse);\n } else {\n const responseWithVersionInfo = { \"@guardian/cdk\": { version: LibraryInfo.VERSION }, ...commandResponse };\n console.log(JSON.stringify(responseWithVersionInfo));\n }\n })\n .catch((err) => {\n console.error(err);\n process.exitCode = 1;\n });\n"]}
@@ -5,6 +5,10 @@ export interface GuAlarmProps extends AlarmProps, AppIdentity {
5
5
  snsTopicName: string;
6
6
  okAction?: boolean;
7
7
  }
8
+ export interface Http4xxAlarmProps extends Omit<GuAlarmProps, "snsTopicName" | "evaluationPeriods" | "metric" | "period" | "threshold" | "treatMissingData" | "app"> {
9
+ tolerated4xxPercentage: number;
10
+ numberOfMinutesAboveThresholdBeforeAlarm?: number;
11
+ }
8
12
  export interface Http5xxAlarmProps extends Omit<GuAlarmProps, "snsTopicName" | "evaluationPeriods" | "metric" | "period" | "threshold" | "treatMissingData" | "app"> {
9
13
  tolerated5xxPercentage: number;
10
14
  numberOfMinutesAboveThresholdBeforeAlarm?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"alarm.d.ts","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/alarm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAI7D,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEpD,MAAM,WAAW,YAAa,SAAQ,UAAU,EAAE,WAAW;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBACf,SAAQ,IAAI,CACV,YAAY,EACZ,cAAc,GAAG,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,kBAAkB,GAAG,KAAK,CACtG;IACD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wCAAwC,CAAC,EAAE,MAAM,CAAC;CACnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,OAAQ,SAAQ,KAAK;gBACpB,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY;CAa5D"}
1
+ {"version":3,"file":"alarm.d.ts","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/alarm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AAI7D,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEpD,MAAM,WAAW,YAAa,SAAQ,UAAU,EAAE,WAAW;IAC3D,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,iBACf,SAAQ,IAAI,CACV,YAAY,EACZ,cAAc,GAAG,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,kBAAkB,GAAG,KAAK,CACtG;IACD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wCAAwC,CAAC,EAAE,MAAM,CAAC;CACnD;AAED,MAAM,WAAW,iBACf,SAAQ,IAAI,CACV,YAAY,EACZ,cAAc,GAAG,mBAAmB,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,GAAG,kBAAkB,GAAG,KAAK,CACtG;IACD,sBAAsB,EAAE,MAAM,CAAC;IAC/B,wCAAwC,CAAC,EAAE,MAAM,CAAC;CACnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,OAAQ,SAAQ,KAAK;gBACpB,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY;CAa5D"}
@@ -1 +1 @@
1
- {"version":3,"file":"alarm.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/alarm.ts"],"names":[],"mappings":";;;AAAA,+DAAmD;AAEnD,+EAA+D;AAC/D,iDAA4C;AAkB5C;;;;;;;;;;;;;;;GAeG;AACH,MAAa,OAAQ,SAAQ,sBAAK;IAChC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmB;QACzD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAClC,MAAM,EAAE,YAAY,EAAE,cAAc,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;QAEhE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAW,eAAe,MAAM,IAAI,OAAO,IAAI,YAAY,EAAE,CAAC;QAC5E,MAAM,QAAQ,GAAW,eAAK,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjF,IAAI,CAAC,cAAc,CAAC,IAAI,kCAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,WAAW,CAAC,IAAI,kCAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;SAC3C;IACH,CAAC;CACF;AAdD,0BAcC","sourcesContent":["import { Alarm } from \"aws-cdk-lib/aws-cloudwatch\";\nimport type { AlarmProps } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { SnsAction } from \"aws-cdk-lib/aws-cloudwatch-actions\";\nimport { Topic } from \"aws-cdk-lib/aws-sns\";\nimport type { ITopic } from \"aws-cdk-lib/aws-sns\";\nimport type { AppIdentity, GuStack } from \"../core\";\n\nexport interface GuAlarmProps extends AlarmProps, AppIdentity {\n snsTopicName: string;\n okAction?: boolean;\n}\n\nexport interface Http5xxAlarmProps\n extends Omit<\n GuAlarmProps,\n \"snsTopicName\" | \"evaluationPeriods\" | \"metric\" | \"period\" | \"threshold\" | \"treatMissingData\" | \"app\"\n > {\n tolerated5xxPercentage: number;\n numberOfMinutesAboveThresholdBeforeAlarm?: number;\n}\n\n/**\n * Creates a CloudWatch alarm which sends notifications to the specified SNS topic.\n *\n * Alarm actions are enabled by default.\n *\n * To enable the alarm only in PROD, use the value of `Stage`:\n * ```typescript\n * new GuAlarm(stack, \"alarm\", {\n * // other required props\n * actionsEnabled: this.stage === \"PROD\",\n * });\n * ```\n *\n * This library provides an implementation of some commonly used alarms, which require less boilerplate than this construct,\n * for example the [[`GuAlb5xxPercentageAlarm`]]. Prefer using these more specific implementations where possible.\n */\nexport class GuAlarm extends Alarm {\n constructor(scope: GuStack, id: string, props: GuAlarmProps) {\n const { region, account } = scope;\n const { snsTopicName, actionsEnabled = true, okAction } = props;\n\n super(scope, id, { ...props, actionsEnabled });\n\n const topicArn: string = `arn:aws:sns:${region}:${account}:${snsTopicName}`;\n const snsTopic: ITopic = Topic.fromTopicArn(scope, `SnsTopicFor${id}`, topicArn);\n this.addAlarmAction(new SnsAction(snsTopic));\n if (okAction) {\n this.addOkAction(new SnsAction(snsTopic));\n }\n }\n}\n"]}
1
+ {"version":3,"file":"alarm.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/alarm.ts"],"names":[],"mappings":";;;AAAA,+DAAmD;AAEnD,+EAA+D;AAC/D,iDAA4C;AA2B5C;;;;;;;;;;;;;;;GAeG;AACH,MAAa,OAAQ,SAAQ,sBAAK;IAChC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmB;QACzD,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC;QAClC,MAAM,EAAE,YAAY,EAAE,cAAc,GAAG,IAAI,EAAE,QAAQ,EAAE,GAAG,KAAK,CAAC;QAEhE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,EAAE,GAAG,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QAE/C,MAAM,QAAQ,GAAW,eAAe,MAAM,IAAI,OAAO,IAAI,YAAY,EAAE,CAAC;QAC5E,MAAM,QAAQ,GAAW,eAAK,CAAC,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QACjF,IAAI,CAAC,cAAc,CAAC,IAAI,kCAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAC7C,IAAI,QAAQ,EAAE;YACZ,IAAI,CAAC,WAAW,CAAC,IAAI,kCAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;SAC3C;IACH,CAAC;CACF;AAdD,0BAcC","sourcesContent":["import { Alarm } from \"aws-cdk-lib/aws-cloudwatch\";\nimport type { AlarmProps } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { SnsAction } from \"aws-cdk-lib/aws-cloudwatch-actions\";\nimport { Topic } from \"aws-cdk-lib/aws-sns\";\nimport type { ITopic } from \"aws-cdk-lib/aws-sns\";\nimport type { AppIdentity, GuStack } from \"../core\";\n\nexport interface GuAlarmProps extends AlarmProps, AppIdentity {\n snsTopicName: string;\n okAction?: boolean;\n}\n\nexport interface Http4xxAlarmProps\n extends Omit<\n GuAlarmProps,\n \"snsTopicName\" | \"evaluationPeriods\" | \"metric\" | \"period\" | \"threshold\" | \"treatMissingData\" | \"app\"\n > {\n tolerated4xxPercentage: number;\n numberOfMinutesAboveThresholdBeforeAlarm?: number;\n}\n\nexport interface Http5xxAlarmProps\n extends Omit<\n GuAlarmProps,\n \"snsTopicName\" | \"evaluationPeriods\" | \"metric\" | \"period\" | \"threshold\" | \"treatMissingData\" | \"app\"\n > {\n tolerated5xxPercentage: number;\n numberOfMinutesAboveThresholdBeforeAlarm?: number;\n}\n\n/**\n * Creates a CloudWatch alarm which sends notifications to the specified SNS topic.\n *\n * Alarm actions are enabled by default.\n *\n * To enable the alarm only in PROD, use the value of `Stage`:\n * ```typescript\n * new GuAlarm(stack, \"alarm\", {\n * // other required props\n * actionsEnabled: this.stage === \"PROD\",\n * });\n * ```\n *\n * This library provides an implementation of some commonly used alarms, which require less boilerplate than this construct,\n * for example the [[`GuAlb5xxPercentageAlarm`]]. Prefer using these more specific implementations where possible.\n */\nexport class GuAlarm extends Alarm {\n constructor(scope: GuStack, id: string, props: GuAlarmProps) {\n const { region, account } = scope;\n const { snsTopicName, actionsEnabled = true, okAction } = props;\n\n super(scope, id, { ...props, actionsEnabled });\n\n const topicArn: string = `arn:aws:sns:${region}:${account}:${snsTopicName}`;\n const snsTopic: ITopic = Topic.fromTopicArn(scope, `SnsTopicFor${id}`, topicArn);\n this.addAlarmAction(new SnsAction(snsTopic));\n if (okAction) {\n this.addOkAction(new SnsAction(snsTopic));\n }\n }\n}\n"]}
@@ -2,7 +2,10 @@ import type { GuStack } from "../core";
2
2
  import { AppIdentity } from "../core";
3
3
  import type { GuApplicationLoadBalancer, GuApplicationTargetGroup } from "../loadbalancing";
4
4
  import { GuAlarm } from "./alarm";
5
- import type { GuAlarmProps, Http5xxAlarmProps } from "./alarm";
5
+ import type { GuAlarmProps, Http4xxAlarmProps, Http5xxAlarmProps } from "./alarm";
6
+ interface GuAlb4xxPercentageAlarmProps extends Pick<GuAlarmProps, "snsTopicName">, Http4xxAlarmProps, AppIdentity {
7
+ loadBalancer: GuApplicationLoadBalancer;
8
+ }
6
9
  interface GuAlb5xxPercentageAlarmProps extends Pick<GuAlarmProps, "snsTopicName">, Http5xxAlarmProps, AppIdentity {
7
10
  loadBalancer: GuApplicationLoadBalancer;
8
11
  }
@@ -16,6 +19,13 @@ interface GuUnhealthyInstancesAlarmProps extends Pick<GuAlarmProps, "snsTopicNam
16
19
  export declare class GuAlb5xxPercentageAlarm extends GuAlarm {
17
20
  constructor(scope: GuStack, props: GuAlb5xxPercentageAlarmProps);
18
21
  }
22
+ /**
23
+ * Creates an alarm which is triggered whenever the percentage of requests with a 4xx response code exceeds
24
+ * the specified threshold.
25
+ */
26
+ export declare class GuAlb4xxPercentageAlarm extends GuAlarm {
27
+ constructor(scope: GuStack, props: GuAlb4xxPercentageAlarmProps);
28
+ }
19
29
  /**
20
30
  * Creates an alarm which is triggered whenever there have been several healthcheck failures within a single hour.
21
31
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ec2-alarms.d.ts","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/ec2-alarms.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAE/D,UAAU,4BAA6B,SAAQ,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,EAAE,iBAAiB,EAAE,WAAW;IAC/G,YAAY,EAAE,yBAAyB,CAAC;CACzC;AAED,UAAU,8BAA+B,SAAQ,IAAI,CAAC,YAAY,EAAE,cAAc,GAAG,gBAAgB,CAAC,EAAE,WAAW;IACjH,WAAW,EAAE,wBAAwB,CAAC;CACvC;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,OAAO;gBACtC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,4BAA4B;CAyBhE;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,OAAO;gBACxC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,8BAA8B;CAyBlE"}
1
+ {"version":3,"file":"ec2-alarms.d.ts","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/ec2-alarms.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACtC,OAAO,KAAK,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,MAAM,kBAAkB,CAAC;AAC5F,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAElF,UAAU,4BAA6B,SAAQ,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,EAAE,iBAAiB,EAAE,WAAW;IAC/G,YAAY,EAAE,yBAAyB,CAAC;CACzC;AACD,UAAU,4BAA6B,SAAQ,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,EAAE,iBAAiB,EAAE,WAAW;IAC/G,YAAY,EAAE,yBAAyB,CAAC;CACzC;AAED,UAAU,8BAA+B,SAAQ,IAAI,CAAC,YAAY,EAAE,cAAc,GAAG,gBAAgB,CAAC,EAAE,WAAW;IACjH,WAAW,EAAE,wBAAwB,CAAC;CACvC;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,OAAO;gBACtC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,4BAA4B;CAyBhE;AAED;;;GAGG;AACH,qBAAa,uBAAwB,SAAQ,OAAO;gBACtC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,4BAA4B;CAyBhE;AAED;;GAEG;AACH,qBAAa,yBAA0B,SAAQ,OAAO;gBACxC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,8BAA8B;CAyBlE"}
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GuUnhealthyInstancesAlarm = exports.GuAlb5xxPercentageAlarm = void 0;
3
+ exports.GuUnhealthyInstancesAlarm = exports.GuAlb4xxPercentageAlarm = exports.GuAlb5xxPercentageAlarm = void 0;
4
4
  const aws_cdk_lib_1 = require("aws-cdk-lib");
5
5
  const aws_cloudwatch_1 = require("aws-cdk-lib/aws-cloudwatch");
6
6
  const aws_elasticloadbalancingv2_1 = require("aws-cdk-lib/aws-elasticloadbalancingv2");
@@ -38,6 +38,38 @@ class GuAlb5xxPercentageAlarm extends alarm_1.GuAlarm {
38
38
  }
39
39
  }
40
40
  exports.GuAlb5xxPercentageAlarm = GuAlb5xxPercentageAlarm;
41
+ /**
42
+ * Creates an alarm which is triggered whenever the percentage of requests with a 4xx response code exceeds
43
+ * the specified threshold.
44
+ */
45
+ class GuAlb4xxPercentageAlarm extends alarm_1.GuAlarm {
46
+ constructor(scope, props) {
47
+ const mathExpression = new aws_cloudwatch_1.MathExpression({
48
+ expression: "100*(m1+m2)/m3",
49
+ usingMetrics: {
50
+ m1: props.loadBalancer.metrics.httpCodeElb(aws_elasticloadbalancingv2_1.HttpCodeElb.ELB_4XX_COUNT),
51
+ m2: props.loadBalancer.metrics.httpCodeTarget(aws_elasticloadbalancingv2_1.HttpCodeTarget.TARGET_4XX_COUNT),
52
+ m3: props.loadBalancer.metrics.requestCount(),
53
+ },
54
+ label: `% of 4XX responses served for ${props.app} (load balancer and instances combined)`,
55
+ period: aws_cdk_lib_1.Duration.minutes(1),
56
+ });
57
+ const defaultAlarmName = `High 4XX error percentage from ${props.app} in ${scope.stage}`;
58
+ const defaultDescription = `${props.app} exceeded ${props.tolerated4xxPercentage}% error rate`;
59
+ const alarmProps = {
60
+ ...props,
61
+ metric: mathExpression,
62
+ treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
63
+ threshold: props.tolerated4xxPercentage,
64
+ comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
65
+ alarmName: props.alarmName ?? defaultAlarmName,
66
+ alarmDescription: props.alarmDescription ?? defaultDescription,
67
+ evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,
68
+ };
69
+ super(scope, core_1.AppIdentity.suffixText(props, "High4xxPercentageAlarm"), alarmProps);
70
+ }
71
+ }
72
+ exports.GuAlb4xxPercentageAlarm = GuAlb4xxPercentageAlarm;
41
73
  /**
42
74
  * Creates an alarm which is triggered whenever there have been several healthcheck failures within a single hour.
43
75
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ec2-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/ec2-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,+DAA6G;AAC7G,uFAAqF;AAErF,kCAAsC;AAEtC,mCAAkC;AAWlC;;;GAGG;AACH,MAAa,uBAAwB,SAAQ,eAAO;IAClD,YAAY,KAAc,EAAE,KAAmC;QAC7D,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,gBAAgB;YAC5B,YAAY,EAAE;gBACZ,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,WAAW,CAAC,wCAAW,CAAC,aAAa,CAAC;gBACrE,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,cAAc,CAAC,2CAAc,CAAC,gBAAgB,CAAC;gBAC9E,EAAE,EAAE,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,YAAY,EAAE;aAC9C;YACD,KAAK,EAAE,iCAAiC,KAAK,CAAC,GAAG,yCAAyC;YAC1F,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC5B,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,kCAAkC,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;QACzF,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,GAAG,aAAa,KAAK,CAAC,sBAAsB,cAAc,CAAC;QAC/F,MAAM,UAAU,GAAG;YACjB,GAAG,KAAK;YACR,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,sBAAsB;YACvC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;YAC9D,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;SACvE,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,wBAAwB,CAAC,EAAE,UAAU,CAAC,CAAC;IACpF,CAAC;CACF;AA1BD,0DA0BC;AAED;;GAEG;AACH,MAAa,yBAA0B,SAAQ,eAAO;IACpD,YAAY,KAAc,EAAE,KAAqC;QAC/D,MAAM,SAAS,GAAG,2BAA2B,KAAK,CAAC,GAAG,OAAO,KAAK,CAAC,KAAK,EAAE,CAAC;QAE3E,MAAM,MAAM,GAAG,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnC,MAAM,iBAAiB,GAAG,EAAE,CAAC;QAC7B,MAAM,kBAAkB,GAAG,sBAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,GAAG,iBAAiB,CAAC,CAAC,aAAa,EAAE,CAAC;QAEpG,MAAM,gBAAgB,GAAG,GAAG,KAAK,CAAC,GAAG,qEAAqE,kBAAkB;;;;cAIlH,KAAK,CAAC,GAAG,yFAAyF,CAAC;QAC7G,MAAM,UAAU,GAAiB;YAC/B,GAAG,KAAK;YACR,SAAS,EAAE,SAAS;YACpB,gBAAgB,EAAE,gBAAgB;YAClC,MAAM,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,SAAS,EAAE,0BAAS,CAAC,OAAO,EAAE,CAAC;YACrG,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,CAAC;YACZ,kBAAkB,EAAE,mCAAkB,CAAC,kCAAkC;YACzE,iBAAiB,EAAE,EAAE;YACrB,iBAAiB;SAClB,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,yBAAyB,CAAC,EAAE,UAAU,CAAC,CAAC;IACrF,CAAC;CACF;AA1BD,8DA0BC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport { ComparisonOperator, MathExpression, Statistic, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { HttpCodeElb, HttpCodeTarget } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport type { GuApplicationLoadBalancer, GuApplicationTargetGroup } from \"../loadbalancing\";\nimport { GuAlarm } from \"./alarm\";\nimport type { GuAlarmProps, Http5xxAlarmProps } from \"./alarm\";\n\ninterface GuAlb5xxPercentageAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\">, Http5xxAlarmProps, AppIdentity {\n loadBalancer: GuApplicationLoadBalancer;\n}\n\ninterface GuUnhealthyInstancesAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\" | \"actionsEnabled\">, AppIdentity {\n targetGroup: GuApplicationTargetGroup;\n}\n\n/**\n * Creates an alarm which is triggered whenever the percentage of requests with a 5xx response code exceeds\n * the specified threshold.\n */\nexport class GuAlb5xxPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuAlb5xxPercentageAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*(m1+m2)/m3\",\n usingMetrics: {\n m1: props.loadBalancer.metrics.httpCodeElb(HttpCodeElb.ELB_5XX_COUNT),\n m2: props.loadBalancer.metrics.httpCodeTarget(HttpCodeTarget.TARGET_5XX_COUNT),\n m3: props.loadBalancer.metrics.requestCount(),\n },\n label: `% of 5XX responses served for ${props.app} (load balancer and instances combined)`,\n period: Duration.minutes(1),\n });\n const defaultAlarmName = `High 5XX error percentage from ${props.app} in ${scope.stage}`;\n const defaultDescription = `${props.app} exceeded ${props.tolerated5xxPercentage}% error rate`;\n const alarmProps = {\n ...props,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.tolerated5xxPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n };\n super(scope, AppIdentity.suffixText(props, \"High5xxPercentageAlarm\"), alarmProps);\n }\n}\n\n/**\n * Creates an alarm which is triggered whenever there have been several healthcheck failures within a single hour.\n */\nexport class GuUnhealthyInstancesAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuUnhealthyInstancesAlarmProps) {\n const alarmName = `Unhealthy instances for ${props.app} in ${scope.stage}`;\n\n const period = Duration.minutes(1);\n const evaluationPeriods = 60;\n const evaluationInterval = Duration.minutes(period.toMinutes() * evaluationPeriods).toHumanString();\n\n const alarmDescription = `${props.app}'s instances have failed healthchecks several times over the last ${evaluationInterval}.\n This typically results in the AutoScaling Group cycling instances and can lead to problems with deployment,\n scaling or handling traffic spikes.\n\n Check ${props.app}'s application logs or ssh onto an unhealthy instance in order to debug these problems.`;\n const alarmProps: GuAlarmProps = {\n ...props,\n alarmName: alarmName,\n alarmDescription: alarmDescription,\n metric: props.targetGroup.metrics.unhealthyHostCount().with({ period, statistic: Statistic.MAXIMUM }),\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: 1,\n comparisonOperator: ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,\n datapointsToAlarm: 30,\n evaluationPeriods,\n };\n super(scope, AppIdentity.suffixText(props, \"UnhealthyInstancesAlarm\"), alarmProps);\n }\n}\n"]}
1
+ {"version":3,"file":"ec2-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/ec2-alarms.ts"],"names":[],"mappings":"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","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport { ComparisonOperator, MathExpression, Statistic, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { HttpCodeElb, HttpCodeTarget } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport type { GuApplicationLoadBalancer, GuApplicationTargetGroup } from \"../loadbalancing\";\nimport { GuAlarm } from \"./alarm\";\nimport type { GuAlarmProps, Http4xxAlarmProps, Http5xxAlarmProps } from \"./alarm\";\n\ninterface GuAlb4xxPercentageAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\">, Http4xxAlarmProps, AppIdentity {\n loadBalancer: GuApplicationLoadBalancer;\n}\ninterface GuAlb5xxPercentageAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\">, Http5xxAlarmProps, AppIdentity {\n loadBalancer: GuApplicationLoadBalancer;\n}\n\ninterface GuUnhealthyInstancesAlarmProps extends Pick<GuAlarmProps, \"snsTopicName\" | \"actionsEnabled\">, AppIdentity {\n targetGroup: GuApplicationTargetGroup;\n}\n\n/**\n * Creates an alarm which is triggered whenever the percentage of requests with a 5xx response code exceeds\n * the specified threshold.\n */\nexport class GuAlb5xxPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuAlb5xxPercentageAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*(m1+m2)/m3\",\n usingMetrics: {\n m1: props.loadBalancer.metrics.httpCodeElb(HttpCodeElb.ELB_5XX_COUNT),\n m2: props.loadBalancer.metrics.httpCodeTarget(HttpCodeTarget.TARGET_5XX_COUNT),\n m3: props.loadBalancer.metrics.requestCount(),\n },\n label: `% of 5XX responses served for ${props.app} (load balancer and instances combined)`,\n period: Duration.minutes(1),\n });\n const defaultAlarmName = `High 5XX error percentage from ${props.app} in ${scope.stage}`;\n const defaultDescription = `${props.app} exceeded ${props.tolerated5xxPercentage}% error rate`;\n const alarmProps = {\n ...props,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.tolerated5xxPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n };\n super(scope, AppIdentity.suffixText(props, \"High5xxPercentageAlarm\"), alarmProps);\n }\n}\n\n/**\n * Creates an alarm which is triggered whenever the percentage of requests with a 4xx response code exceeds\n * the specified threshold.\n */\nexport class GuAlb4xxPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuAlb4xxPercentageAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*(m1+m2)/m3\",\n usingMetrics: {\n m1: props.loadBalancer.metrics.httpCodeElb(HttpCodeElb.ELB_4XX_COUNT),\n m2: props.loadBalancer.metrics.httpCodeTarget(HttpCodeTarget.TARGET_4XX_COUNT),\n m3: props.loadBalancer.metrics.requestCount(),\n },\n label: `% of 4XX responses served for ${props.app} (load balancer and instances combined)`,\n period: Duration.minutes(1),\n });\n const defaultAlarmName = `High 4XX error percentage from ${props.app} in ${scope.stage}`;\n const defaultDescription = `${props.app} exceeded ${props.tolerated4xxPercentage}% error rate`;\n const alarmProps = {\n ...props,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.tolerated4xxPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n };\n super(scope, AppIdentity.suffixText(props, \"High4xxPercentageAlarm\"), alarmProps);\n }\n}\n\n/**\n * Creates an alarm which is triggered whenever there have been several healthcheck failures within a single hour.\n */\nexport class GuUnhealthyInstancesAlarm extends GuAlarm {\n constructor(scope: GuStack, props: GuUnhealthyInstancesAlarmProps) {\n const alarmName = `Unhealthy instances for ${props.app} in ${scope.stage}`;\n\n const period = Duration.minutes(1);\n const evaluationPeriods = 60;\n const evaluationInterval = Duration.minutes(period.toMinutes() * evaluationPeriods).toHumanString();\n\n const alarmDescription = `${props.app}'s instances have failed healthchecks several times over the last ${evaluationInterval}.\n This typically results in the AutoScaling Group cycling instances and can lead to problems with deployment,\n scaling or handling traffic spikes.\n\n Check ${props.app}'s application logs or ssh onto an unhealthy instance in order to debug these problems.`;\n const alarmProps: GuAlarmProps = {\n ...props,\n alarmName: alarmName,\n alarmDescription: alarmDescription,\n metric: props.targetGroup.metrics.unhealthyHostCount().with({ period, statistic: Statistic.MAXIMUM }),\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: 1,\n comparisonOperator: ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,\n datapointsToAlarm: 30,\n evaluationPeriods,\n };\n super(scope, AppIdentity.suffixText(props, \"UnhealthyInstancesAlarm\"), alarmProps);\n }\n}\n"]}
@@ -3,7 +3,7 @@ import { App } from "aws-cdk-lib";
3
3
  import type { CloudAssembly } from "aws-cdk-lib/cx-api";
4
4
  /**
5
5
  * A replacement for `App`, sitting at the root of a CDK application.
6
- * `GuRootExperimental` will synthesise a `riff-raff.yaml` file for a CDK application.
6
+ * `GuRoot` will synthesise a `riff-raff.yaml` file for a CDK application.
7
7
  *
8
8
  * Usage is a case of updating `/<repo-root>/cdk/bin/cdk.ts` from:
9
9
  *
@@ -18,15 +18,15 @@ import type { CloudAssembly } from "aws-cdk-lib/cx-api";
18
18
  * To:
19
19
  *
20
20
  * ```ts
21
- * import { GuRootExperimental } from "@guardian/cdk/lib/experimental/constructs/root";
21
+ * import { GuRoot } from "@guardian/cdk/lib/constructs/root";
22
22
  *
23
- * const app = new GuRootExperimental();
23
+ * const app = new GuRoot();
24
24
  *
25
25
  * new MyStack(app, "my-stack-CODE", {});
26
26
  * new MyStack(app, "my-stack-PROD", {});
27
27
  * ```
28
28
  */
29
- export declare class GuRootExperimental extends App {
29
+ export declare class GuRoot extends App {
30
30
  synth(options?: StageSynthesisOptions): CloudAssembly;
31
31
  }
32
32
  //# sourceMappingURL=root.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../../src/constructs/root.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAGxD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,MAAO,SAAQ,GAAG;IACpB,KAAK,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,aAAa;CAI/D"}
@@ -1,11 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GuRootExperimental = void 0;
3
+ exports.GuRoot = void 0;
4
4
  const aws_cdk_lib_1 = require("aws-cdk-lib");
5
5
  const riff_raff_yaml_file_1 = require("../riff-raff-yaml-file");
6
6
  /**
7
7
  * A replacement for `App`, sitting at the root of a CDK application.
8
- * `GuRootExperimental` will synthesise a `riff-raff.yaml` file for a CDK application.
8
+ * `GuRoot` will synthesise a `riff-raff.yaml` file for a CDK application.
9
9
  *
10
10
  * Usage is a case of updating `/<repo-root>/cdk/bin/cdk.ts` from:
11
11
  *
@@ -20,19 +20,19 @@ const riff_raff_yaml_file_1 = require("../riff-raff-yaml-file");
20
20
  * To:
21
21
  *
22
22
  * ```ts
23
- * import { GuRootExperimental } from "@guardian/cdk/lib/experimental/constructs/root";
23
+ * import { GuRoot } from "@guardian/cdk/lib/constructs/root";
24
24
  *
25
- * const app = new GuRootExperimental();
25
+ * const app = new GuRoot();
26
26
  *
27
27
  * new MyStack(app, "my-stack-CODE", {});
28
28
  * new MyStack(app, "my-stack-PROD", {});
29
29
  * ```
30
30
  */
31
- class GuRootExperimental extends aws_cdk_lib_1.App {
31
+ class GuRoot extends aws_cdk_lib_1.App {
32
32
  synth(options) {
33
- new riff_raff_yaml_file_1.RiffRaffYamlFileExperimental(this).synth();
33
+ new riff_raff_yaml_file_1.RiffRaffYamlFile(this).synth();
34
34
  return super.synth(options);
35
35
  }
36
36
  }
37
- exports.GuRootExperimental = GuRootExperimental;
37
+ exports.GuRoot = GuRoot;
38
38
  //# sourceMappingURL=root.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"root.js","sourceRoot":"","sources":["../../src/constructs/root.ts"],"names":[],"mappings":";;;AACA,6CAAkC;AAElC,gEAA0D;AAE1D;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAa,MAAO,SAAQ,iBAAG;IACpB,KAAK,CAAC,OAA+B;QAC5C,IAAI,sCAAgB,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;CACF;AALD,wBAKC","sourcesContent":["import type { StageSynthesisOptions } from \"aws-cdk-lib\";\nimport { App } from \"aws-cdk-lib\";\nimport type { CloudAssembly } from \"aws-cdk-lib/cx-api\";\nimport { RiffRaffYamlFile } from \"../riff-raff-yaml-file\";\n\n/**\n * A replacement for `App`, sitting at the root of a CDK application.\n * `GuRoot` will synthesise a `riff-raff.yaml` file for a CDK application.\n *\n * Usage is a case of updating `/<repo-root>/cdk/bin/cdk.ts` from:\n *\n * ```ts\n * import { App } from \"aws-cdk-lib\";\n *\n * const app = new App();\n *\n * new MyStack(app, \"my-stack-CODE\", {});\n * new MyStack(app, \"my-stack-PROD\", {});\n * ```\n * To:\n *\n * ```ts\n * import { GuRoot } from \"@guardian/cdk/lib/constructs/root\";\n *\n * const app = new GuRoot();\n *\n * new MyStack(app, \"my-stack-CODE\", {});\n * new MyStack(app, \"my-stack-PROD\", {});\n * ```\n */\nexport class GuRoot extends App {\n override synth(options?: StageSynthesisOptions): CloudAssembly {\n new RiffRaffYamlFile(this).synth();\n return super.synth(options);\n }\n}\n"]}
@@ -5,7 +5,7 @@ import { Construct } from "constructs";
5
5
  import { GuCertificate } from "../../constructs/acm";
6
6
  import type { GuUserDataProps } from "../../constructs/autoscaling";
7
7
  import { GuAutoScalingGroup } from "../../constructs/autoscaling";
8
- import type { Http5xxAlarmProps, NoMonitoring } from "../../constructs/cloudwatch";
8
+ import type { Http4xxAlarmProps, Http5xxAlarmProps, NoMonitoring } from "../../constructs/cloudwatch";
9
9
  import type { GuStack } from "../../constructs/core";
10
10
  import { AppIdentity } from "../../constructs/core";
11
11
  import type { GuInstanceRoleProps } from "../../constructs/iam";
@@ -80,6 +80,10 @@ export interface Alarms {
80
80
  * Enable the 5xx alarm with settings.
81
81
  */
82
82
  http5xxAlarm: false | Http5xxAlarmProps;
83
+ /**
84
+ * Enable the 4xx alarm with settings.
85
+ */
86
+ http4xxAlarm?: false | Http4xxAlarmProps;
83
87
  /**
84
88
  * Enable the unhealthy instances alarm.
85
89
  */
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/patterns/ec2-app/base.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/patterns/ec2-app/base.ts"],"names":[],"mappings":"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"}
@@ -135,7 +135,15 @@ class GuEc2App extends constructs_1.Construct {
135
135
  }));
136
136
  }
137
137
  if (!monitoringConfiguration.noMonitoring) {
138
- const { http5xxAlarm, snsTopicName, unhealthyInstancesAlarm } = monitoringConfiguration;
138
+ const { http5xxAlarm, http4xxAlarm, snsTopicName, unhealthyInstancesAlarm } = monitoringConfiguration;
139
+ if (http4xxAlarm) {
140
+ new cloudwatch_1.GuAlb4xxPercentageAlarm(scope, {
141
+ app,
142
+ loadBalancer,
143
+ snsTopicName,
144
+ ...http4xxAlarm,
145
+ });
146
+ }
139
147
  if (http5xxAlarm) {
140
148
  new cloudwatch_1.GuAlb5xxPercentageAlarm(scope, {
141
149
  app,