@guardian/cdk 49.0.0-beta.1 → 49.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.
Files changed (82) hide show
  1. package/lib/aspects/cfn-parameter-reporter.d.ts +9 -0
  2. package/lib/aspects/cfn-parameter-reporter.d.ts.map +1 -0
  3. package/lib/aspects/cfn-parameter-reporter.js +21 -0
  4. package/lib/aspects/cfn-parameter-reporter.js.map +1 -0
  5. package/lib/bin/commands/new-project/index.d.ts +1 -1
  6. package/lib/bin/commands/new-project/index.d.ts.map +1 -1
  7. package/lib/constants/metadata-keys.d.ts +0 -1
  8. package/lib/constants/metadata-keys.d.ts.map +1 -1
  9. package/lib/constants/metadata-keys.js +0 -1
  10. package/lib/constants/metadata-keys.js.map +1 -1
  11. package/lib/constructs/acm/certificate.d.ts +1 -1
  12. package/lib/constructs/acm/certificate.d.ts.map +1 -1
  13. package/lib/constructs/autoscaling/user-data.d.ts +1 -1
  14. package/lib/constructs/autoscaling/user-data.d.ts.map +1 -1
  15. package/lib/constructs/autoscaling/user-data.js +8 -8
  16. package/lib/constructs/autoscaling/user-data.js.map +1 -1
  17. package/lib/constructs/core/parameters/base.d.ts +2 -2
  18. package/lib/constructs/core/parameters/base.d.ts.map +1 -1
  19. package/lib/constructs/core/stack.d.ts +7 -1
  20. package/lib/constructs/core/stack.d.ts.map +1 -1
  21. package/lib/constructs/core/stack.js +31 -23
  22. package/lib/constructs/core/stack.js.map +1 -1
  23. package/lib/constructs/dns/dns-records.js +1 -1
  24. package/lib/constructs/dns/dns-records.js.map +1 -1
  25. package/lib/constructs/ec2/vpc.d.ts +1 -1
  26. package/lib/constructs/ec2/vpc.d.ts.map +1 -1
  27. package/lib/constructs/ecs/ecs-task.d.ts +4 -4
  28. package/lib/constructs/ecs/ecs-task.d.ts.map +1 -1
  29. package/lib/constructs/iam/policies/base-policy.d.ts +3 -3
  30. package/lib/constructs/iam/policies/base-policy.d.ts.map +1 -1
  31. package/lib/constructs/iam/roles/instance-role.d.ts +1 -1
  32. package/lib/constructs/iam/roles/instance-role.d.ts.map +1 -1
  33. package/lib/constructs/iam/roles/roles.d.ts +1 -1
  34. package/lib/constructs/iam/roles/roles.d.ts.map +1 -1
  35. package/lib/constructs/kinesis/kinesis-stream.d.ts +1 -1
  36. package/lib/constructs/kinesis/kinesis-stream.d.ts.map +1 -1
  37. package/lib/constructs/vpc/vpc.d.ts +1 -1
  38. package/lib/constructs/vpc/vpc.d.ts.map +1 -1
  39. package/lib/constructs/vpc/vpc.js +1 -1
  40. package/lib/constructs/vpc/vpc.js.map +1 -1
  41. package/lib/experimental/constructs/error-budget-alarm.d.ts +47 -2
  42. package/lib/experimental/constructs/error-budget-alarm.d.ts.map +1 -1
  43. package/lib/experimental/constructs/error-budget-alarm.js +84 -42
  44. package/lib/experimental/constructs/error-budget-alarm.js.map +1 -1
  45. package/lib/experimental/constructs/index.d.ts +3 -0
  46. package/lib/experimental/constructs/index.d.ts.map +1 -0
  47. package/lib/{constructs/sns → experimental/constructs}/index.js +2 -1
  48. package/lib/experimental/constructs/index.js.map +1 -0
  49. package/lib/experimental/patterns/sns-lambda.d.ts.map +1 -1
  50. package/lib/experimental/patterns/sns-lambda.js +1 -2
  51. package/lib/experimental/patterns/sns-lambda.js.map +1 -1
  52. package/lib/experimental/riff-raff-yaml-file/index.js +48 -48
  53. package/lib/experimental/riff-raff-yaml-file/index.js.map +1 -1
  54. package/lib/experimental/riff-raff-yaml-file/types.d.ts +7 -7
  55. package/lib/experimental/riff-raff-yaml-file/types.d.ts.map +1 -1
  56. package/lib/patterns/api-multiple-lambdas.d.ts +5 -1
  57. package/lib/patterns/api-multiple-lambdas.d.ts.map +1 -1
  58. package/lib/patterns/api-multiple-lambdas.js +3 -1
  59. package/lib/patterns/api-multiple-lambdas.js.map +1 -1
  60. package/lib/patterns/ec2-app/base.d.ts.map +1 -1
  61. package/lib/patterns/ec2-app/base.js +0 -5
  62. package/lib/patterns/ec2-app/base.js.map +1 -1
  63. package/lib/patterns/ec2-app/framework.d.ts +1 -1
  64. package/lib/patterns/ec2-app/framework.d.ts.map +1 -1
  65. package/lib/types/access.d.ts +1 -1
  66. package/lib/types/access.d.ts.map +1 -1
  67. package/lib/types/cli.d.ts +1 -1
  68. package/lib/types/cli.d.ts.map +1 -1
  69. package/lib/utils/lambda/event-source.d.ts +4 -4
  70. package/lib/utils/lambda/event-source.d.ts.map +1 -1
  71. package/lib/utils/lambda/event-source.js +4 -4
  72. package/lib/utils/lambda/event-source.js.map +1 -1
  73. package/lib/utils/mixin/types.d.ts +1 -1
  74. package/lib/utils/mixin/types.d.ts.map +1 -1
  75. package/package.json +21 -21
  76. package/lib/constructs/sns/index.d.ts +0 -2
  77. package/lib/constructs/sns/index.d.ts.map +0 -1
  78. package/lib/constructs/sns/index.js.map +0 -1
  79. package/lib/constructs/sns/sns-topic.d.ts +0 -15
  80. package/lib/constructs/sns/sns-topic.d.ts.map +0 -1
  81. package/lib/constructs/sns/sns-topic.js +0 -17
  82. package/lib/constructs/sns/sns-topic.js.map +0 -1
@@ -4,7 +4,7 @@ import { Construct } from "constructs";
4
4
  import type { Http5xxAlarmProps, NoMonitoring } from "../constructs/cloudwatch";
5
5
  import type { AppIdentity, GuStack } from "../constructs/core";
6
6
  import type { GuLambdaFunction } from "../constructs/lambda";
7
- export declare type HttpMethod = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE" | "PATCH";
7
+ export type HttpMethod = "GET" | "HEAD" | "POST" | "PUT" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE" | "PATCH";
8
8
  export interface ApiTarget {
9
9
  /**
10
10
  * The path for the request (e.g. /test).
@@ -18,6 +18,10 @@ export interface ApiTarget {
18
18
  * The Lambda function responsible for handling the request.
19
19
  */
20
20
  lambda: GuLambdaFunction;
21
+ /**
22
+ * Whether an apiKey is required for this method.
23
+ */
24
+ apiKeyRequired?: true;
21
25
  }
22
26
  /**
23
27
  * Configuration for an alarm based on the percentage of 5XX responses served by the API Gateway instance.
@@ -1 +1 @@
1
- {"version":3,"file":"api-multiple-lambdas.d.ts","sourceRoot":"","sources":["../../src/patterns/api-multiple-lambdas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAqB,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,oBAAY,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEhH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB;;OAEG;IACH,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,iBAAiB,CAAC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,iCAAkC,SAAQ,YAAY,EAAE,WAAW;IAClF;;OAEG;IACH,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB;;;;;;;OAOG;IACH,uBAAuB,EAAE,YAAY,GAAG,gBAAgB,CAAC;CAC1D;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,qBAAa,4BAA6B,SAAQ,SAAS;IACzD,SAAgB,GAAG,EAAE,OAAO,CAAC;gBAEjB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,iCAAiC;CAsBrE"}
1
+ {"version":3,"file":"api-multiple-lambdas.d.ts","sourceRoot":"","sources":["../../src/patterns/api-multiple-lambdas.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,EAAqB,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAEhF,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAEhH,MAAM,WAAW,SAAS;IACxB;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IACb;;OAEG;IACH,UAAU,EAAE,UAAU,CAAC;IACvB;;OAEG;IACH,MAAM,EAAE,gBAAgB,CAAC;IACzB;;OAEG;IACH,cAAc,CAAC,EAAE,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,iBAAiB,CAAC;IAChC,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,MAAM,WAAW,iCAAkC,SAAQ,YAAY,EAAE,WAAW;IAClF;;OAEG;IACH,OAAO,EAAE,SAAS,EAAE,CAAC;IACrB;;;;;;;OAOG;IACH,uBAAuB,EAAE,YAAY,GAAG,gBAAgB,CAAC;CAC1D;AAQD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,qBAAa,4BAA6B,SAAQ,SAAS;IACzD,SAAgB,GAAG,EAAE,OAAO,CAAC;gBAEjB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,iCAAiC;CAwBrE"}
@@ -72,7 +72,9 @@ class GuApiGatewayWithLambdaByPath extends constructs_1.Construct {
72
72
  this.api = apiGateway;
73
73
  props.targets.map((target) => {
74
74
  const resource = apiGateway.root.resourceForPath(target.path);
75
- resource.addMethod(target.httpMethod, new aws_apigateway_1.LambdaIntegration(target.lambda));
75
+ resource.addMethod(target.httpMethod, new aws_apigateway_1.LambdaIntegration(target.lambda), {
76
+ apiKeyRequired: target.apiKeyRequired,
77
+ });
76
78
  });
77
79
  if (!isNoMonitoring(props.monitoringConfiguration)) {
78
80
  new api_gateway_alarms_1.GuApiGateway5xxPercentageAlarm(scope, {
@@ -1 +1 @@
1
- {"version":3,"file":"api-multiple-lambdas.js","sourceRoot":"","sources":["../../src/patterns/api-multiple-lambdas.ts"],"names":[],"mappings":";;;AACA,+DAAwE;AACxE,2CAAuC;AAEvC,oFAA6F;AA0D7F,SAAS,cAAc,CACrB,uBAAwD;IAExD,OAAsB,uBAAwB,CAAC,YAAY,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAa,4BAA6B,SAAQ,sBAAS;IAGzD,YAAY,KAAc,EAAE,KAAwC;QAClE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,oCAAoC;QAC7D,MAAM,UAAU,GAAG,IAAI,wBAAO,CAAC,KAAK,EAAE,SAAS,EAAE;YAC/C,4FAA4F;YAC5F,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE;YACzD,GAAG,KAAK;SACT,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC;QACtB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9D,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,kCAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9E,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE;YAClD,IAAI,mDAA8B,CAAC,KAAK,EAAE;gBACxC,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,kBAAkB,EAAE,UAAU;gBAC9B,YAAY,EAAE,KAAK,CAAC,uBAAuB,CAAC,YAAY;gBACxD,GAAG,KAAK,CAAC,uBAAuB,CAAC,YAAY;aAC9C,CAAC,CAAC;SACJ;IACH,CAAC;CACF;AAzBD,oEAyBC","sourcesContent":["import type { RestApiProps } from \"aws-cdk-lib/aws-apigateway\";\nimport { LambdaIntegration, RestApi } from \"aws-cdk-lib/aws-apigateway\";\nimport { Construct } from \"constructs\";\nimport type { Http5xxAlarmProps, NoMonitoring } from \"../constructs/cloudwatch\";\nimport { GuApiGateway5xxPercentageAlarm } from \"../constructs/cloudwatch/api-gateway-alarms\";\nimport type { AppIdentity, GuStack } from \"../constructs/core\";\nimport type { GuLambdaFunction } from \"../constructs/lambda\";\n\n// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods\nexport type HttpMethod = \"GET\" | \"HEAD\" | \"POST\" | \"PUT\" | \"DELETE\" | \"CONNECT\" | \"OPTIONS\" | \"TRACE\" | \"PATCH\";\n\nexport interface ApiTarget {\n /**\n * The path for the request (e.g. /test).\n */\n path: string;\n /**\n * The [[`HttpMethod`]] for the target (e.g. GET, POST, PUT).\n */\n httpMethod: HttpMethod;\n /**\n * The Lambda function responsible for handling the request.\n */\n lambda: GuLambdaFunction;\n}\n\n/**\n * Configuration for an alarm based on the percentage of 5XX responses served by the API Gateway instance.\n *\n * For example:\n *\n * ```typescript\n * monitoringConfiguration: {\n * snsTopicName: \"my-topic-for-cloudwatch-alerts\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: <sensible_error_percentage_threshold>,\n * }\n * }\n * ```\n */\nexport interface ApiGatewayAlarms {\n snsTopicName: string;\n http5xxAlarm: Http5xxAlarmProps;\n noMonitoring?: false;\n}\n\nexport interface GuApiGatewayWithLambdaByPathProps extends RestApiProps, AppIdentity {\n /**\n * A list of [[`ApiTarget`]]s to configure for the API Gateway instance.\n */\n targets: ApiTarget[];\n /**\n * Alarm configuration for your API. For more details, see [[`ApiGatewayAlarms`]].\n *\n * If your team do not use CloudWatch, it's possible to opt-out with the following configuration:\n * ```typescript\n * monitoringConfiguration: { noMonitoring: true }\n * ```\n */\n monitoringConfiguration: NoMonitoring | ApiGatewayAlarms;\n}\n\nfunction isNoMonitoring(\n monitoringConfiguration: NoMonitoring | ApiGatewayAlarms\n): monitoringConfiguration is NoMonitoring {\n return (<NoMonitoring>monitoringConfiguration).noMonitoring;\n}\n\n/**\n * A pattern to create an API Gateway instance which uses path-based routing to route requests\n * to two or more Lambda functions.\n *\n * This pattern should be used if you need to configure path-based routing to serve different\n * requests with different Lambdas. If you intend to serve all traffic via a single Lambda, use\n * the [[`GuApiLambda`]] pattern instead.\n *\n * Example usage:\n *\n * ```typescript\n * // Configure lambdas\n * const lambdaOne = new GuLambdaFunction(this, \"lambda-one\", {\n * app: \"example-lambda-one\",\n * runtime: Runtime.NODEJS_14_X,\n * handler: \"lambda-one.handler\",\n * fileName: \"lambda-one.zip\",\n * });\n * const lambdaTwo = new GuLambdaFunction(this, \"lambda-two\", {\n * app: \"example-lambda-two\",\n * runtime: Runtime.NODEJS_14_X,\n * handler: \"lambda-two.handler\",\n * fileName: \"lambda-two.zip\",\n * });\n *\n * // Wire up the API\n * new GuApiGatewayWithLambdaByPath(this, {\n * app: \"example-api-gateway-instance\",\n * targets: [\n * {\n * path: \"lambda-one\",\n * httpMethod: \"GET\",\n * lambda: lambdaOne,\n * },\n * {\n * path: \"lambda-two\",\n * httpMethod: \"GET\",\n * lambda: lambdaTwo,\n * },\n * ],\n * // Create an alarm\n * monitoringConfiguration: {\n * snsTopicName: \"my-topic-for-cloudwatch-alerts\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * }\n * }\n * });\n * ```\n *\n * For all API configuration options, see [[`GuApiGatewayWithLambdaByPathProps`]].\n *\n * For details on configuring the individual Lambda functions, see [[`GuLambdaFunction`]].\n */\nexport class GuApiGatewayWithLambdaByPath extends Construct {\n public readonly api: RestApi;\n\n constructor(scope: GuStack, props: GuApiGatewayWithLambdaByPathProps) {\n super(scope, props.app); // The assumption is `app` is unique\n const apiGateway = new RestApi(scope, \"RestApi\", {\n // Override to avoid clashes as default is just api ID, which is often shared across stages.\n restApiName: `${scope.stack}-${scope.stage}-${props.app}`,\n ...props,\n });\n\n this.api = apiGateway;\n props.targets.map((target) => {\n const resource = apiGateway.root.resourceForPath(target.path);\n resource.addMethod(target.httpMethod, new LambdaIntegration(target.lambda));\n });\n if (!isNoMonitoring(props.monitoringConfiguration)) {\n new GuApiGateway5xxPercentageAlarm(scope, {\n app: props.app,\n apiGatewayInstance: apiGateway,\n snsTopicName: props.monitoringConfiguration.snsTopicName,\n ...props.monitoringConfiguration.http5xxAlarm,\n });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"api-multiple-lambdas.js","sourceRoot":"","sources":["../../src/patterns/api-multiple-lambdas.ts"],"names":[],"mappings":";;;AACA,+DAAwE;AACxE,2CAAuC;AAEvC,oFAA6F;AA8D7F,SAAS,cAAc,CACrB,uBAAwD;IAExD,OAAsB,uBAAwB,CAAC,YAAY,CAAC;AAC9D,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqDG;AACH,MAAa,4BAA6B,SAAQ,sBAAS;IAGzD,YAAY,KAAc,EAAE,KAAwC;QAClE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,oCAAoC;QAC7D,MAAM,UAAU,GAAG,IAAI,wBAAO,CAAC,KAAK,EAAE,SAAS,EAAE;YAC/C,4FAA4F;YAC5F,WAAW,EAAE,GAAG,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,GAAG,EAAE;YACzD,GAAG,KAAK;SACT,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,GAAG,UAAU,CAAC;QACtB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;YAC3B,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;YAC9D,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,EAAE,IAAI,kCAAiB,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE;gBAC1E,cAAc,EAAE,MAAM,CAAC,cAAc;aACtC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,uBAAuB,CAAC,EAAE;YAClD,IAAI,mDAA8B,CAAC,KAAK,EAAE;gBACxC,GAAG,EAAE,KAAK,CAAC,GAAG;gBACd,kBAAkB,EAAE,UAAU;gBAC9B,YAAY,EAAE,KAAK,CAAC,uBAAuB,CAAC,YAAY;gBACxD,GAAG,KAAK,CAAC,uBAAuB,CAAC,YAAY;aAC9C,CAAC,CAAC;SACJ;IACH,CAAC;CACF;AA3BD,oEA2BC","sourcesContent":["import type { RestApiProps } from \"aws-cdk-lib/aws-apigateway\";\nimport { LambdaIntegration, RestApi } from \"aws-cdk-lib/aws-apigateway\";\nimport { Construct } from \"constructs\";\nimport type { Http5xxAlarmProps, NoMonitoring } from \"../constructs/cloudwatch\";\nimport { GuApiGateway5xxPercentageAlarm } from \"../constructs/cloudwatch/api-gateway-alarms\";\nimport type { AppIdentity, GuStack } from \"../constructs/core\";\nimport type { GuLambdaFunction } from \"../constructs/lambda\";\n\n// https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods\nexport type HttpMethod = \"GET\" | \"HEAD\" | \"POST\" | \"PUT\" | \"DELETE\" | \"CONNECT\" | \"OPTIONS\" | \"TRACE\" | \"PATCH\";\n\nexport interface ApiTarget {\n /**\n * The path for the request (e.g. /test).\n */\n path: string;\n /**\n * The [[`HttpMethod`]] for the target (e.g. GET, POST, PUT).\n */\n httpMethod: HttpMethod;\n /**\n * The Lambda function responsible for handling the request.\n */\n lambda: GuLambdaFunction;\n /**\n * Whether an apiKey is required for this method.\n */\n apiKeyRequired?: true;\n}\n\n/**\n * Configuration for an alarm based on the percentage of 5XX responses served by the API Gateway instance.\n *\n * For example:\n *\n * ```typescript\n * monitoringConfiguration: {\n * snsTopicName: \"my-topic-for-cloudwatch-alerts\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: <sensible_error_percentage_threshold>,\n * }\n * }\n * ```\n */\nexport interface ApiGatewayAlarms {\n snsTopicName: string;\n http5xxAlarm: Http5xxAlarmProps;\n noMonitoring?: false;\n}\n\nexport interface GuApiGatewayWithLambdaByPathProps extends RestApiProps, AppIdentity {\n /**\n * A list of [[`ApiTarget`]]s to configure for the API Gateway instance.\n */\n targets: ApiTarget[];\n /**\n * Alarm configuration for your API. For more details, see [[`ApiGatewayAlarms`]].\n *\n * If your team do not use CloudWatch, it's possible to opt-out with the following configuration:\n * ```typescript\n * monitoringConfiguration: { noMonitoring: true }\n * ```\n */\n monitoringConfiguration: NoMonitoring | ApiGatewayAlarms;\n}\n\nfunction isNoMonitoring(\n monitoringConfiguration: NoMonitoring | ApiGatewayAlarms\n): monitoringConfiguration is NoMonitoring {\n return (<NoMonitoring>monitoringConfiguration).noMonitoring;\n}\n\n/**\n * A pattern to create an API Gateway instance which uses path-based routing to route requests\n * to two or more Lambda functions.\n *\n * This pattern should be used if you need to configure path-based routing to serve different\n * requests with different Lambdas. If you intend to serve all traffic via a single Lambda, use\n * the [[`GuApiLambda`]] pattern instead.\n *\n * Example usage:\n *\n * ```typescript\n * // Configure lambdas\n * const lambdaOne = new GuLambdaFunction(this, \"lambda-one\", {\n * app: \"example-lambda-one\",\n * runtime: Runtime.NODEJS_14_X,\n * handler: \"lambda-one.handler\",\n * fileName: \"lambda-one.zip\",\n * });\n * const lambdaTwo = new GuLambdaFunction(this, \"lambda-two\", {\n * app: \"example-lambda-two\",\n * runtime: Runtime.NODEJS_14_X,\n * handler: \"lambda-two.handler\",\n * fileName: \"lambda-two.zip\",\n * });\n *\n * // Wire up the API\n * new GuApiGatewayWithLambdaByPath(this, {\n * app: \"example-api-gateway-instance\",\n * targets: [\n * {\n * path: \"lambda-one\",\n * httpMethod: \"GET\",\n * lambda: lambdaOne,\n * },\n * {\n * path: \"lambda-two\",\n * httpMethod: \"GET\",\n * lambda: lambdaTwo,\n * },\n * ],\n * // Create an alarm\n * monitoringConfiguration: {\n * snsTopicName: \"my-topic-for-cloudwatch-alerts\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * }\n * }\n * });\n * ```\n *\n * For all API configuration options, see [[`GuApiGatewayWithLambdaByPathProps`]].\n *\n * For details on configuring the individual Lambda functions, see [[`GuLambdaFunction`]].\n */\nexport class GuApiGatewayWithLambdaByPath extends Construct {\n public readonly api: RestApi;\n\n constructor(scope: GuStack, props: GuApiGatewayWithLambdaByPathProps) {\n super(scope, props.app); // The assumption is `app` is unique\n const apiGateway = new RestApi(scope, \"RestApi\", {\n // Override to avoid clashes as default is just api ID, which is often shared across stages.\n restApiName: `${scope.stack}-${scope.stage}-${props.app}`,\n ...props,\n });\n\n this.api = apiGateway;\n props.targets.map((target) => {\n const resource = apiGateway.root.resourceForPath(target.path);\n resource.addMethod(target.httpMethod, new LambdaIntegration(target.lambda), {\n apiKeyRequired: target.apiKeyRequired,\n });\n });\n if (!isNoMonitoring(props.monitoringConfiguration)) {\n new GuApiGateway5xxPercentageAlarm(scope, {\n app: props.app,\n apiGatewayInstance: apiGateway,\n snsTopicName: props.monitoringConfiguration.snsTopicName,\n ...props.monitoringConfiguration.http5xxAlarm,\n });\n }\n }\n}\n"]}
@@ -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":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE/D,OAAO,KAAK,EAAE,YAAY,EAAS,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAI9E,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,kBAAkB,EAAc,MAAM,8BAA8B,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEnF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAmD,MAAM,uBAAuB,CAAC;AAErG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAEhE,OAAO,EACL,yBAAyB,EACzB,wBAAwB,EACxB,0BAA0B,EAC3B,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE/D,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,OAAO,CAAC;IACjB;;;;;;;OAOG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,MAAM;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,KAAK,GAAG,iBAAiB,CAAC;IACxC,uBAAuB,EAAE,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEG;AACH,MAAM,WAAW,aAAc,SAAQ,WAAW;IAChD,QAAQ,EAAE,eAAe,GAAG,MAAM,CAAC;IACnC,MAAM,EAAE,SAAS,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,CAAC,EAAE,mBAAmB,CAAC;IACxC,uBAAuB,EAAE,MAAM,GAAG,YAAY,CAAC;IAC/C,YAAY,EAAE,YAAY,CAAC;IAC3B,kBAAkB,CAAC,EAAE,uBAAuB,CAAC;IAC7C,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,YAAY,CAAC,EAAE,WAAW,EAAE,CAAC;IAC7B,OAAO,EAAE,aAAa,CAAC;IACvB,gBAAgB,EAAE,YAAY,CAAC;IAC/B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,IAAI,CAAC;IACX,cAAc,CAAC,EAAE,OAAO,EAAE,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,EAAE,CAAC;CAC3B;AAUD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2KG;AACH,qBAAa,QAAS,SAAQ,SAAS;IASrC,SAAgB,GAAG,EAAE,IAAI,CAAC;IAC1B,SAAgB,WAAW,EAAE,aAAa,CAAC;IAC3C,SAAgB,YAAY,EAAE,yBAAyB,CAAC;IACxD,SAAgB,gBAAgB,EAAE,kBAAkB,CAAC;IACrD,SAAgB,QAAQ,EAAE,0BAA0B,CAAC;IACrD,SAAgB,WAAW,EAAE,wBAAwB,CAAC;gBAE1C,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,aAAa;CAsKjD"}
@@ -234,11 +234,6 @@ class GuEc2App extends constructs_1.Construct {
234
234
  ...(blockDevices && { blockDevices }),
235
235
  imageRecipe,
236
236
  });
237
- // We are selectively tagging the ASG so that we can expose the number of stacks using this pattern
238
- // based on which autoscaling groups possess this tag. It may become useful or necessary to tag all resources in the future,
239
- // but we have decided that this is sufficient for now.
240
- // TODO: Do we need to tag all resources with this value? What would the use-cases be?
241
- aws_cdk_lib_1.Tags.of(autoScalingGroup).add(constants_1.MetadataKeys.PATTERN_NAME, this.constructor.name, { applyToLaunchedInstances: true });
242
237
  // This allows automatic shipping of instance Cloud Init logs when using the
243
238
  // `cdk-base` Amigo role on your AMI.
244
239
  aws_cdk_lib_1.Tags.of(autoScalingGroup).add(constants_1.MetadataKeys.LOG_KINESIS_STREAM_NAME, core_1.GuLoggingStreamNameParameter.getInstance(scope).valueAsString);
@@ -1 +1 @@
1
- {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/patterns/ec2-app/base.ts"],"names":[],"mappings":"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","sourcesContent":["import { Duration, Tags } from \"aws-cdk-lib\";\nimport type { BlockDevice } from \"aws-cdk-lib/aws-autoscaling\";\nimport { HealthCheck } from \"aws-cdk-lib/aws-autoscaling\";\nimport type { InstanceType, IPeer, ISubnet, IVpc } from \"aws-cdk-lib/aws-ec2\";\nimport { Port } from \"aws-cdk-lib/aws-ec2\";\nimport { ApplicationProtocol } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport { Bucket } from \"aws-cdk-lib/aws-s3\";\nimport { Construct } from \"constructs\";\nimport { AccessScope, MetadataKeys, NAMED_SSM_PARAMETER_PATHS } from \"../../constants\";\nimport { GuCertificate } from \"../../constructs/acm\";\nimport type { GuUserDataProps } from \"../../constructs/autoscaling\";\nimport { GuAutoScalingGroup, GuUserData } from \"../../constructs/autoscaling\";\nimport type { Http5xxAlarmProps, NoMonitoring } from \"../../constructs/cloudwatch\";\nimport { GuAlb5xxPercentageAlarm, GuUnhealthyInstancesAlarm } from \"../../constructs/cloudwatch\";\nimport type { GuStack } from \"../../constructs/core\";\nimport { AppIdentity, GuLoggingStreamNameParameter, GuStringParameter } from \"../../constructs/core\";\nimport { GuSecurityGroup, GuVpc, SubnetType } from \"../../constructs/ec2\";\nimport type { GuInstanceRoleProps } from \"../../constructs/iam\";\nimport { GuGetPrivateConfigPolicy, GuInstanceRole } from \"../../constructs/iam\";\nimport {\n GuApplicationLoadBalancer,\n GuApplicationTargetGroup,\n GuHttpsApplicationListener,\n} from \"../../constructs/loadbalancing\";\nimport { AppAccess } from \"../../types\";\nimport type { GuAsgCapacity, GuDomainName } from \"../../types\";\n\nexport interface AccessLoggingProps {\n enabled: boolean;\n prefix?: string;\n}\n\n/**\n * To ship your application logs to ELK automatically, you must:\n *\n * 1. Set the `enabled` flag to true\n * 2. Include the `cdk-base` Amigo role in your AMI\n * 3. Log to `journald`. We recommend doing this by logging to `stdout` and\n * using `systemd` to start your app\n * 4. Confirm that your [[`systemdUnitName`]] is configured properly.\n *\n * Unless you have explicitly opted-out, appropriate IAM permissions for logging\n * to Kinesis will be configured automatically via the [[`GuEc2App`]] pattern.\n */\nexport interface ApplicationLoggingProps {\n enabled: boolean;\n /**\n * Defaults to app name. That is, if your app runs as `<app>.service`\n * (e.g. `janus.service`), this will 'just work'.\n *\n * If it runs with a non-standard name, you will need to override the default\n * behavour. I.e. if your app is running as `some-different-name.service`, then\n * this prop should be set to `some-different-name`.\n */\n systemdUnitName?: string;\n}\n\nexport interface Alarms {\n snsTopicName: string;\n http5xxAlarm: false | Http5xxAlarmProps;\n unhealthyInstancesAlarm: boolean;\n noMonitoring?: false;\n}\n\n/**\n * Configuration options for the [[`GuEc2App`]] pattern.\n *\n * To grant EC2 instances additional IAM permissions, use the `roleConfiguration` prop. For example,\n * to allow your app to write to DynamoDB:\n *\n * ```typescript\n * // other props\n * roleConfiguration: {\n * additionalPolicies: [new GuDynamoDBWritePolicy(stack, \"DynamoTable\", { tableName: \"my-dynamo-table\" })],\n * }\n * ```\n *\n * To create alarms (recommended), use:\n * ```typescript\n * // other props\n * monitoringConfiguration: {\n * snsTopicName: \"alerts-topic-for-my-team\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * },\n * unhealthyInstancesAlarm: true,\n * }\n * ```\n *\n * To opt out of creating alarms, use:\n *```typescript\n * // other props\n * monitoringConfiguration: { noMonitoring: true }\n * ```\n *\n * To automatically ship application logs from `stdout` to ELK, use:\n *\n * ```typescript\n * {\n * // other props\n * applicationLogging: { enabled: true }\n * }\n * ```\n *\n * For more details on the requirements for application log shipping, see [[`ApplicationLoggingProps`]].\n *\n * To enable access logging for your load balancer, you can specify the prefix to write the logs to.\n * The S3 bucket used to hold these access logs must be specified in SSM at `/account/services/access-logging/bucket`\n * You must specify a region in your stack declaration if you are to use this prop, as specified here:\n * https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-elasticloadbalancingv2.ApplicationLoadBalancer.html#logwbraccesswbrlogsbucket-prefix\n * For example:\n * ```typescript\n * {\n * // other props\n * accessLogging: {\n * enabled: true,\n * prefix: \"my-application-logs\"\n * }\n * }\n *\n * If you would like to enable access logging at the root of the S3 bucket (ie without a prefix), you can omit the prefix\n * For example:\n * ```typescript\n * {\n * // other props\n * accessLogging: {\n * enabled: true,\n * }\n * }\n * ```\n */\nexport interface GuEc2AppProps extends AppIdentity {\n userData: GuUserDataProps | string;\n access: AppAccess;\n applicationPort: number;\n roleConfiguration?: GuInstanceRoleProps;\n monitoringConfiguration: Alarms | NoMonitoring;\n instanceType: InstanceType;\n applicationLogging?: ApplicationLoggingProps;\n accessLogging?: AccessLoggingProps;\n blockDevices?: BlockDevice[];\n scaling: GuAsgCapacity;\n certificateProps: GuDomainName;\n withoutImdsv2?: boolean;\n imageRecipe?: string;\n vpc?: IVpc;\n privateSubnets?: ISubnet[];\n publicSubnets?: ISubnet[];\n}\n\nfunction restrictedCidrRanges(ranges: IPeer[]) {\n return ranges.map((range) => ({\n range,\n port: Port.tcp(443),\n description: `Allow access on port 443 from ${range.uniqueId}`,\n }));\n}\n\n/**\n * Pattern which creates the resources needed to run an application on EC2 instances.\n * For convenience, you may wish to use [[`GuPlayApp`]] or [[`GuNodeApp`]], which extend this class.\n *\n * This pattern will grant your EC2 instances a number of commonly needed IAM permissions. For more information on\n * this, see [[`GuInstanceRole`]]. To add additional permissions to your EC2 instances, see [[`GuEc2AppProps`]].\n *\n * This pattern will automatically create security groups/rules which allow for:\n * 1. Incoming traffic over HTTPS (from the whole internet or from the specified CIDR ranges, depending on the\n * [[`AppAccess`]] specified).\n * 2. Communication between the load balancer and the EC2 instances over HTTP, via the specified application port.\n * 3. Outbound traffic from your EC2 instances over HTTPS (to enable communication with third-party APIs).\n *\n * Example usage for a public facing app (open to the internet):\n * ```typescript\n * new GuEc2App(stack, {\n * applicationPort: 1234,\n * app: \"app-name\",\n * access: { scope: AccessScope.PUBLIC },\n * instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MEDIUM),\n * certificateProps:{\n * domainName: \"prod-guardian.com\",\n * },\n * monitoringConfiguration: {\n * snsTopicName: \"alerts-topic-for-my-team\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * },\n * unhealthyInstancesAlarm: true,\n * },\n * userData: {\n * distributable: {\n * fileName: \"app-name.deb\",\n * executionStatement: `dpkg -i /app-name/app-name.deb`,\n * }\n * },\n * });\n * ```\n *\n * Example usage for an app which is restricted to specific CIDR ranges:\n * ```typescript\n * new GuEc2App(stack, {\n * applicationPort: 1234,\n * app: \"app-name\",\n * access: {\n * scope: AccessScope.RESTRICTED,\n * cidrRanges: [Peer.ipv4(\"192.168.1.1/32\"), Peer.ipv4(\"8.8.8.8/32\")],\n * },\n * instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MEDIUM),\n * certificateProps:{\n * domainName: \"prod-guardian.com\",\n * },\n * monitoringConfiguration: {\n * snsTopicName: \"alerts-topic-for-my-team\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * },\n * unhealthyInstancesAlarm: true,\n * }\n * userData: {\n * distributable: {\n * fileName: \"app-name.deb\",\n * executionStatement: `dpkg -i /app-name/app-name.deb`,\n * }\n * },\n * });\n * ```\n *\n * ### Varying values by stage\n *\n * There are times when you want a resource's configuration to be stage aware,\n * for example the number of instances in an ASG.\n *\n * To do this, we can use a simple ternary:\n * ```typescript\n * new GuEc2App(this, {\n * // other required properties\n * scaling: this.stage === \"PROD\" ? { minimumInstances: 6 } : { minimumInstances: 1 }\n * });\n * ```\n *\n * If multiple properties need to be stage aware, consider encoding this into the `props` of the calling class:\n *\n * ```typescript\n * export interface MyAppProps extends GuStackProps {\n * domainName: string;\n * scaling: GuAsgCapacity;\n * monitoringConfiguration: Alarms | NoMonitoring;\n * }\n *\n * export class MyApp extends GuStack {\n * private static app = \"cdk-playground\";\n *\n * constructor(scope: App, id: string, props: MyAppProps) {\n * const { stage, domainName, scaling, monitoringConfiguration } = props;\n *\n * super(scope, id, props);\n *\n * new GuPlayApp(this, {\n * app: \"my-app\",\n * instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MICRO),\n * access: { scope: AccessScope.PUBLIC },\n * userData: {\n * distributable: {\n * fileName: `my-app.deb`,\n * executionStatement: `dpkg -i /my-app/my-app.deb`,\n * },\n * },\n * certificateProps: {\n * domainName,\n * },\n * monitoringConfiguration,\n * scaling,\n * });\n * }\n * }\n *\n * new MyApp(app, \"MyApp-CODE\", {\n * stage: \"CODE\",\n * domainName: \"my-app.code.dev-gutools.co.uk\",\n * scaling: { minimumInstances: 1 },\n * monitoringConfiguration: { noMonitoring: true },\n * });\n *\n * new MyApp(app, \"MyApp-PROD\", {\n * stage: \"PROD\",\n * domainName: \"my-app.prod.gutools.co.uk\",\n * scaling: { minimumInstances: 6 },\n * monitoringConfiguration: {\n * // config to enable alarms in PROD\n * },\n * });\n * ```\n *\n * If you _must_ support a non-standard VPC setup, it's possible to override the VPC and subnet selection into which\n * instances will be started. You need to set the three props below in order for this to work:\n * vpc: this must be an IVpc instance indicating the VPC to deploy into (usually obtained from `Vpc.fromVpcAttributes`)\n * privateSubnets: a list of ISubnet indicating the subnets for the autoscaling group to deploy instances into (usually\n * obtained from `GuVpc.subnets`)\n * publicSubnets: a list of ISubnet indicating the subnets for the loadbalancer to use, if the loadbalancer\n * is intended for public access (usually obtained from `GuVpc.subnets`)\n * On the other hand, if the access is private, then an \"internal\" loadbalancer is used in the `privateSubnets` list.\n * Please note that no checking is applied to the subnet lists to ensure that they correspond to the vpc given; as\n * an advanced feature it is assumed that the caller ensures this. If the subnets are mismatched then the resulting\n * Cloudformation will fail to deploy.\n *\n * ### Customising the infrastructure generated by this pattern\n *\n * Although we allow users to customise many aspects of their infrastructure via [[`GuEc2AppProps`]], it's possible\n * that there are less common use-cases which are currently unsupported via the API. In these circumstances escape\n * hatches can be used to override specific resources in the stack.\n *\n * In order to do this:\n *\n * 1. Create desired resource using Guardian or AWS constructs, for example:\n * ```typescript\n * const sg = new GuSecurityGroup(\n * // custom parameters\n * );\n * ```\n * 2. Access the CloudFormation version of the resource that you wish to customise, for example:\n * ```typescript\n * const pattern = new GuEc2App(\n * // all parameters\n * )\n * const cfnLb = pattern.loadBalancer.node.defaultChild as CfnLoadBalancer;\n * ```\n * 3. Replace the resource generated by the pattern with your bespoke resource, for example:\n * ```typescript\n * cfnLb.securityGroups = [sg.securityGroupId];\n * ```\n */\nexport class GuEc2App extends Construct {\n /*\n * These are public for now, as this allows users to\n * modify these constructs as desired to fit their\n * specific needs.\n * In the future, we might build functionality to better enable users\n * to access in-pattern constructs, but this would allow teams to be unblocked\n * in the short term.\n * */\n public readonly vpc: IVpc;\n public readonly certificate: GuCertificate;\n public readonly loadBalancer: GuApplicationLoadBalancer;\n public readonly autoScalingGroup: GuAutoScalingGroup;\n public readonly listener: GuHttpsApplicationListener;\n public readonly targetGroup: GuApplicationTargetGroup;\n\n constructor(scope: GuStack, props: GuEc2AppProps) {\n const {\n access,\n accessLogging = { enabled: false },\n app,\n // We should update this default once a significant number of apps have migrated to devx-logs\n applicationLogging = { enabled: false },\n applicationPort,\n blockDevices,\n certificateProps: { domainName, hostedZoneId },\n instanceType,\n monitoringConfiguration,\n roleConfiguration = { withoutLogShipping: false, additionalPolicies: [] },\n scaling: { minimumInstances, maximumInstances = minimumInstances * 2 },\n userData,\n withoutImdsv2,\n imageRecipe,\n vpc = GuVpc.fromIdParameter(scope, AppIdentity.suffixText({ app }, \"VPC\")),\n privateSubnets = GuVpc.subnetsFromParameter(scope, { type: SubnetType.PRIVATE, app }),\n publicSubnets = GuVpc.subnetsFromParameter(scope, { type: SubnetType.PUBLIC, app }),\n } = props;\n\n super(scope, app); // The assumption is `app` is unique\n\n // We should really prevent users from doing this via the type system,\n // but that requires a breaking change to the API\n if (applicationLogging.enabled && roleConfiguration.withoutLogShipping) {\n throw new Error(\n \"Application logging has been enabled (via the `applicationLogging` prop) but your `roleConfiguration` sets \" +\n \"`withoutLogShipping` to true. Please turn off application logging or remove `withoutLogShipping`\"\n );\n }\n\n AppAccess.validate(access);\n\n const certificate = new GuCertificate(scope, {\n app,\n domainName,\n hostedZoneId,\n });\n\n const maybePrivateConfigPolicy =\n typeof userData !== \"string\" && userData.configuration\n ? [new GuGetPrivateConfigPolicy(scope, \"GetPrivateConfigFromS3Policy\", userData.configuration)]\n : [];\n\n const mergedRoleConfiguration: GuInstanceRoleProps = {\n withoutLogShipping: roleConfiguration.withoutLogShipping,\n additionalPolicies: maybePrivateConfigPolicy.concat(roleConfiguration.additionalPolicies ?? []),\n };\n\n const autoScalingGroup = new GuAutoScalingGroup(scope, \"AutoScalingGroup\", {\n app,\n vpc,\n instanceType,\n minimumInstances,\n maximumInstances,\n withoutImdsv2,\n role: new GuInstanceRole(scope, { app, ...mergedRoleConfiguration }),\n healthCheck: HealthCheck.elb({ grace: Duration.minutes(2) }), // should this be defaulted at pattern or construct level?\n userData: typeof userData !== \"string\" ? new GuUserData(scope, { app, ...userData }).userData : userData,\n vpcSubnets: { subnets: privateSubnets },\n ...(blockDevices && { blockDevices }),\n imageRecipe,\n });\n\n // We are selectively tagging the ASG so that we can expose the number of stacks using this pattern\n // based on which autoscaling groups possess this tag. It may become useful or necessary to tag all resources in the future,\n // but we have decided that this is sufficient for now.\n // TODO: Do we need to tag all resources with this value? What would the use-cases be?\n Tags.of(autoScalingGroup).add(MetadataKeys.PATTERN_NAME, this.constructor.name, { applyToLaunchedInstances: true });\n\n // This allows automatic shipping of instance Cloud Init logs when using the\n // `cdk-base` Amigo role on your AMI.\n Tags.of(autoScalingGroup).add(\n MetadataKeys.LOG_KINESIS_STREAM_NAME,\n GuLoggingStreamNameParameter.getInstance(scope).valueAsString\n );\n\n if (applicationLogging.enabled) {\n // This allows automatic shipping of application logs when using the\n // `cdk-base` Amigo role on your AMI.\n Tags.of(autoScalingGroup).add(\n MetadataKeys.SYSTEMD_UNIT,\n applicationLogging.systemdUnitName ? `${applicationLogging.systemdUnitName}.service` : `${app}.service`\n );\n }\n\n const loadBalancer = new GuApplicationLoadBalancer(scope, \"LoadBalancer\", {\n app,\n vpc,\n // Setting internetFacing to true does not necessarily allow public access to the load balancer itself. That is handled by the listener's `open` prop.\n internetFacing: access.scope !== AccessScope.INTERNAL,\n vpcSubnets: {\n subnets: access.scope === AccessScope.INTERNAL ? privateSubnets : publicSubnets,\n },\n });\n\n if (accessLogging.enabled) {\n const accessLoggingBucket = new GuStringParameter(scope, \"AccessLoggingBucket\", {\n description: NAMED_SSM_PARAMETER_PATHS.AccessLoggingBucket.description,\n default: NAMED_SSM_PARAMETER_PATHS.AccessLoggingBucket.path,\n fromSSM: true,\n });\n\n loadBalancer.logAccessLogs(\n Bucket.fromBucketName(\n scope,\n AppIdentity.suffixText(props, \"AccessLoggingBucket\"),\n accessLoggingBucket.valueAsString\n ),\n accessLogging.prefix\n );\n }\n\n const targetGroup = new GuApplicationTargetGroup(scope, \"TargetGroup\", {\n app,\n vpc,\n protocol: ApplicationProtocol.HTTP,\n targets: [autoScalingGroup],\n port: applicationPort,\n });\n\n const listener = new GuHttpsApplicationListener(scope, \"Listener\", {\n app,\n loadBalancer,\n certificate,\n targetGroup,\n // When open=true, AWS will create a security group which allows all inbound traffic over HTTPS\n open: access.scope === AccessScope.PUBLIC,\n });\n\n // Since AWS won't create a security group automatically when open=false, we need to add our own\n if (access.scope !== AccessScope.PUBLIC) {\n loadBalancer.addSecurityGroup(\n new GuSecurityGroup(scope, `${access.scope}IngressSecurityGroup`, {\n app,\n vpc,\n description: \"Allow restricted ingress from CIDR ranges\",\n allowAllOutbound: false,\n ingresses: restrictedCidrRanges(access.cidrRanges),\n })\n );\n }\n\n if (!monitoringConfiguration.noMonitoring) {\n const { http5xxAlarm, snsTopicName, unhealthyInstancesAlarm } = monitoringConfiguration;\n\n if (http5xxAlarm) {\n new GuAlb5xxPercentageAlarm(scope, {\n app,\n loadBalancer,\n snsTopicName,\n ...http5xxAlarm,\n });\n }\n if (unhealthyInstancesAlarm) {\n new GuUnhealthyInstancesAlarm(scope, {\n app,\n targetGroup,\n snsTopicName,\n });\n }\n }\n\n this.vpc = vpc;\n this.certificate = certificate;\n this.loadBalancer = loadBalancer;\n this.autoScalingGroup = autoScalingGroup;\n this.listener = listener;\n this.targetGroup = targetGroup;\n }\n}\n"]}
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../../../src/patterns/ec2-app/base.ts"],"names":[],"mappings":"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","sourcesContent":["import { Duration, Tags } from \"aws-cdk-lib\";\nimport type { BlockDevice } from \"aws-cdk-lib/aws-autoscaling\";\nimport { HealthCheck } from \"aws-cdk-lib/aws-autoscaling\";\nimport type { InstanceType, IPeer, ISubnet, IVpc } from \"aws-cdk-lib/aws-ec2\";\nimport { Port } from \"aws-cdk-lib/aws-ec2\";\nimport { ApplicationProtocol } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport { Bucket } from \"aws-cdk-lib/aws-s3\";\nimport { Construct } from \"constructs\";\nimport { AccessScope, MetadataKeys, NAMED_SSM_PARAMETER_PATHS } from \"../../constants\";\nimport { GuCertificate } from \"../../constructs/acm\";\nimport type { GuUserDataProps } from \"../../constructs/autoscaling\";\nimport { GuAutoScalingGroup, GuUserData } from \"../../constructs/autoscaling\";\nimport type { Http5xxAlarmProps, NoMonitoring } from \"../../constructs/cloudwatch\";\nimport { GuAlb5xxPercentageAlarm, GuUnhealthyInstancesAlarm } from \"../../constructs/cloudwatch\";\nimport type { GuStack } from \"../../constructs/core\";\nimport { AppIdentity, GuLoggingStreamNameParameter, GuStringParameter } from \"../../constructs/core\";\nimport { GuSecurityGroup, GuVpc, SubnetType } from \"../../constructs/ec2\";\nimport type { GuInstanceRoleProps } from \"../../constructs/iam\";\nimport { GuGetPrivateConfigPolicy, GuInstanceRole } from \"../../constructs/iam\";\nimport {\n GuApplicationLoadBalancer,\n GuApplicationTargetGroup,\n GuHttpsApplicationListener,\n} from \"../../constructs/loadbalancing\";\nimport { AppAccess } from \"../../types\";\nimport type { GuAsgCapacity, GuDomainName } from \"../../types\";\n\nexport interface AccessLoggingProps {\n enabled: boolean;\n prefix?: string;\n}\n\n/**\n * To ship your application logs to ELK automatically, you must:\n *\n * 1. Set the `enabled` flag to true\n * 2. Include the `cdk-base` Amigo role in your AMI\n * 3. Log to `journald`. We recommend doing this by logging to `stdout` and\n * using `systemd` to start your app\n * 4. Confirm that your [[`systemdUnitName`]] is configured properly.\n *\n * Unless you have explicitly opted-out, appropriate IAM permissions for logging\n * to Kinesis will be configured automatically via the [[`GuEc2App`]] pattern.\n */\nexport interface ApplicationLoggingProps {\n enabled: boolean;\n /**\n * Defaults to app name. That is, if your app runs as `<app>.service`\n * (e.g. `janus.service`), this will 'just work'.\n *\n * If it runs with a non-standard name, you will need to override the default\n * behavour. I.e. if your app is running as `some-different-name.service`, then\n * this prop should be set to `some-different-name`.\n */\n systemdUnitName?: string;\n}\n\nexport interface Alarms {\n snsTopicName: string;\n http5xxAlarm: false | Http5xxAlarmProps;\n unhealthyInstancesAlarm: boolean;\n noMonitoring?: false;\n}\n\n/**\n * Configuration options for the [[`GuEc2App`]] pattern.\n *\n * To grant EC2 instances additional IAM permissions, use the `roleConfiguration` prop. For example,\n * to allow your app to write to DynamoDB:\n *\n * ```typescript\n * // other props\n * roleConfiguration: {\n * additionalPolicies: [new GuDynamoDBWritePolicy(stack, \"DynamoTable\", { tableName: \"my-dynamo-table\" })],\n * }\n * ```\n *\n * To create alarms (recommended), use:\n * ```typescript\n * // other props\n * monitoringConfiguration: {\n * snsTopicName: \"alerts-topic-for-my-team\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * },\n * unhealthyInstancesAlarm: true,\n * }\n * ```\n *\n * To opt out of creating alarms, use:\n *```typescript\n * // other props\n * monitoringConfiguration: { noMonitoring: true }\n * ```\n *\n * To automatically ship application logs from `stdout` to ELK, use:\n *\n * ```typescript\n * {\n * // other props\n * applicationLogging: { enabled: true }\n * }\n * ```\n *\n * For more details on the requirements for application log shipping, see [[`ApplicationLoggingProps`]].\n *\n * To enable access logging for your load balancer, you can specify the prefix to write the logs to.\n * The S3 bucket used to hold these access logs must be specified in SSM at `/account/services/access-logging/bucket`\n * You must specify a region in your stack declaration if you are to use this prop, as specified here:\n * https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-elasticloadbalancingv2.ApplicationLoadBalancer.html#logwbraccesswbrlogsbucket-prefix\n * For example:\n * ```typescript\n * {\n * // other props\n * accessLogging: {\n * enabled: true,\n * prefix: \"my-application-logs\"\n * }\n * }\n *\n * If you would like to enable access logging at the root of the S3 bucket (ie without a prefix), you can omit the prefix\n * For example:\n * ```typescript\n * {\n * // other props\n * accessLogging: {\n * enabled: true,\n * }\n * }\n * ```\n */\nexport interface GuEc2AppProps extends AppIdentity {\n userData: GuUserDataProps | string;\n access: AppAccess;\n applicationPort: number;\n roleConfiguration?: GuInstanceRoleProps;\n monitoringConfiguration: Alarms | NoMonitoring;\n instanceType: InstanceType;\n applicationLogging?: ApplicationLoggingProps;\n accessLogging?: AccessLoggingProps;\n blockDevices?: BlockDevice[];\n scaling: GuAsgCapacity;\n certificateProps: GuDomainName;\n withoutImdsv2?: boolean;\n imageRecipe?: string;\n vpc?: IVpc;\n privateSubnets?: ISubnet[];\n publicSubnets?: ISubnet[];\n}\n\nfunction restrictedCidrRanges(ranges: IPeer[]) {\n return ranges.map((range) => ({\n range,\n port: Port.tcp(443),\n description: `Allow access on port 443 from ${range.uniqueId}`,\n }));\n}\n\n/**\n * Pattern which creates the resources needed to run an application on EC2 instances.\n * For convenience, you may wish to use [[`GuPlayApp`]] or [[`GuNodeApp`]], which extend this class.\n *\n * This pattern will grant your EC2 instances a number of commonly needed IAM permissions. For more information on\n * this, see [[`GuInstanceRole`]]. To add additional permissions to your EC2 instances, see [[`GuEc2AppProps`]].\n *\n * This pattern will automatically create security groups/rules which allow for:\n * 1. Incoming traffic over HTTPS (from the whole internet or from the specified CIDR ranges, depending on the\n * [[`AppAccess`]] specified).\n * 2. Communication between the load balancer and the EC2 instances over HTTP, via the specified application port.\n * 3. Outbound traffic from your EC2 instances over HTTPS (to enable communication with third-party APIs).\n *\n * Example usage for a public facing app (open to the internet):\n * ```typescript\n * new GuEc2App(stack, {\n * applicationPort: 1234,\n * app: \"app-name\",\n * access: { scope: AccessScope.PUBLIC },\n * instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MEDIUM),\n * certificateProps:{\n * domainName: \"prod-guardian.com\",\n * },\n * monitoringConfiguration: {\n * snsTopicName: \"alerts-topic-for-my-team\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * },\n * unhealthyInstancesAlarm: true,\n * },\n * userData: {\n * distributable: {\n * fileName: \"app-name.deb\",\n * executionStatement: `dpkg -i /app-name/app-name.deb`,\n * }\n * },\n * });\n * ```\n *\n * Example usage for an app which is restricted to specific CIDR ranges:\n * ```typescript\n * new GuEc2App(stack, {\n * applicationPort: 1234,\n * app: \"app-name\",\n * access: {\n * scope: AccessScope.RESTRICTED,\n * cidrRanges: [Peer.ipv4(\"192.168.1.1/32\"), Peer.ipv4(\"8.8.8.8/32\")],\n * },\n * instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MEDIUM),\n * certificateProps:{\n * domainName: \"prod-guardian.com\",\n * },\n * monitoringConfiguration: {\n * snsTopicName: \"alerts-topic-for-my-team\",\n * http5xxAlarm: {\n * tolerated5xxPercentage: 1,\n * },\n * unhealthyInstancesAlarm: true,\n * }\n * userData: {\n * distributable: {\n * fileName: \"app-name.deb\",\n * executionStatement: `dpkg -i /app-name/app-name.deb`,\n * }\n * },\n * });\n * ```\n *\n * ### Varying values by stage\n *\n * There are times when you want a resource's configuration to be stage aware,\n * for example the number of instances in an ASG.\n *\n * To do this, we can use a simple ternary:\n * ```typescript\n * new GuEc2App(this, {\n * // other required properties\n * scaling: this.stage === \"PROD\" ? { minimumInstances: 6 } : { minimumInstances: 1 }\n * });\n * ```\n *\n * If multiple properties need to be stage aware, consider encoding this into the `props` of the calling class:\n *\n * ```typescript\n * export interface MyAppProps extends GuStackProps {\n * domainName: string;\n * scaling: GuAsgCapacity;\n * monitoringConfiguration: Alarms | NoMonitoring;\n * }\n *\n * export class MyApp extends GuStack {\n * private static app = \"cdk-playground\";\n *\n * constructor(scope: App, id: string, props: MyAppProps) {\n * const { stage, domainName, scaling, monitoringConfiguration } = props;\n *\n * super(scope, id, props);\n *\n * new GuPlayApp(this, {\n * app: \"my-app\",\n * instanceType: InstanceType.of(InstanceClass.T4G, InstanceSize.MICRO),\n * access: { scope: AccessScope.PUBLIC },\n * userData: {\n * distributable: {\n * fileName: `my-app.deb`,\n * executionStatement: `dpkg -i /my-app/my-app.deb`,\n * },\n * },\n * certificateProps: {\n * domainName,\n * },\n * monitoringConfiguration,\n * scaling,\n * });\n * }\n * }\n *\n * new MyApp(app, \"MyApp-CODE\", {\n * stage: \"CODE\",\n * domainName: \"my-app.code.dev-gutools.co.uk\",\n * scaling: { minimumInstances: 1 },\n * monitoringConfiguration: { noMonitoring: true },\n * });\n *\n * new MyApp(app, \"MyApp-PROD\", {\n * stage: \"PROD\",\n * domainName: \"my-app.prod.gutools.co.uk\",\n * scaling: { minimumInstances: 6 },\n * monitoringConfiguration: {\n * // config to enable alarms in PROD\n * },\n * });\n * ```\n *\n * If you _must_ support a non-standard VPC setup, it's possible to override the VPC and subnet selection into which\n * instances will be started. You need to set the three props below in order for this to work:\n * vpc: this must be an IVpc instance indicating the VPC to deploy into (usually obtained from `Vpc.fromVpcAttributes`)\n * privateSubnets: a list of ISubnet indicating the subnets for the autoscaling group to deploy instances into (usually\n * obtained from `GuVpc.subnets`)\n * publicSubnets: a list of ISubnet indicating the subnets for the loadbalancer to use, if the loadbalancer\n * is intended for public access (usually obtained from `GuVpc.subnets`)\n * On the other hand, if the access is private, then an \"internal\" loadbalancer is used in the `privateSubnets` list.\n * Please note that no checking is applied to the subnet lists to ensure that they correspond to the vpc given; as\n * an advanced feature it is assumed that the caller ensures this. If the subnets are mismatched then the resulting\n * Cloudformation will fail to deploy.\n *\n * ### Customising the infrastructure generated by this pattern\n *\n * Although we allow users to customise many aspects of their infrastructure via [[`GuEc2AppProps`]], it's possible\n * that there are less common use-cases which are currently unsupported via the API. In these circumstances escape\n * hatches can be used to override specific resources in the stack.\n *\n * In order to do this:\n *\n * 1. Create desired resource using Guardian or AWS constructs, for example:\n * ```typescript\n * const sg = new GuSecurityGroup(\n * // custom parameters\n * );\n * ```\n * 2. Access the CloudFormation version of the resource that you wish to customise, for example:\n * ```typescript\n * const pattern = new GuEc2App(\n * // all parameters\n * )\n * const cfnLb = pattern.loadBalancer.node.defaultChild as CfnLoadBalancer;\n * ```\n * 3. Replace the resource generated by the pattern with your bespoke resource, for example:\n * ```typescript\n * cfnLb.securityGroups = [sg.securityGroupId];\n * ```\n */\nexport class GuEc2App extends Construct {\n /*\n * These are public for now, as this allows users to\n * modify these constructs as desired to fit their\n * specific needs.\n * In the future, we might build functionality to better enable users\n * to access in-pattern constructs, but this would allow teams to be unblocked\n * in the short term.\n * */\n public readonly vpc: IVpc;\n public readonly certificate: GuCertificate;\n public readonly loadBalancer: GuApplicationLoadBalancer;\n public readonly autoScalingGroup: GuAutoScalingGroup;\n public readonly listener: GuHttpsApplicationListener;\n public readonly targetGroup: GuApplicationTargetGroup;\n\n constructor(scope: GuStack, props: GuEc2AppProps) {\n const {\n access,\n accessLogging = { enabled: false },\n app,\n // We should update this default once a significant number of apps have migrated to devx-logs\n applicationLogging = { enabled: false },\n applicationPort,\n blockDevices,\n certificateProps: { domainName, hostedZoneId },\n instanceType,\n monitoringConfiguration,\n roleConfiguration = { withoutLogShipping: false, additionalPolicies: [] },\n scaling: { minimumInstances, maximumInstances = minimumInstances * 2 },\n userData,\n withoutImdsv2,\n imageRecipe,\n vpc = GuVpc.fromIdParameter(scope, AppIdentity.suffixText({ app }, \"VPC\")),\n privateSubnets = GuVpc.subnetsFromParameter(scope, { type: SubnetType.PRIVATE, app }),\n publicSubnets = GuVpc.subnetsFromParameter(scope, { type: SubnetType.PUBLIC, app }),\n } = props;\n\n super(scope, app); // The assumption is `app` is unique\n\n // We should really prevent users from doing this via the type system,\n // but that requires a breaking change to the API\n if (applicationLogging.enabled && roleConfiguration.withoutLogShipping) {\n throw new Error(\n \"Application logging has been enabled (via the `applicationLogging` prop) but your `roleConfiguration` sets \" +\n \"`withoutLogShipping` to true. Please turn off application logging or remove `withoutLogShipping`\"\n );\n }\n\n AppAccess.validate(access);\n\n const certificate = new GuCertificate(scope, {\n app,\n domainName,\n hostedZoneId,\n });\n\n const maybePrivateConfigPolicy =\n typeof userData !== \"string\" && userData.configuration\n ? [new GuGetPrivateConfigPolicy(scope, \"GetPrivateConfigFromS3Policy\", userData.configuration)]\n : [];\n\n const mergedRoleConfiguration: GuInstanceRoleProps = {\n withoutLogShipping: roleConfiguration.withoutLogShipping,\n additionalPolicies: maybePrivateConfigPolicy.concat(roleConfiguration.additionalPolicies ?? []),\n };\n\n const autoScalingGroup = new GuAutoScalingGroup(scope, \"AutoScalingGroup\", {\n app,\n vpc,\n instanceType,\n minimumInstances,\n maximumInstances,\n withoutImdsv2,\n role: new GuInstanceRole(scope, { app, ...mergedRoleConfiguration }),\n healthCheck: HealthCheck.elb({ grace: Duration.minutes(2) }), // should this be defaulted at pattern or construct level?\n userData: typeof userData !== \"string\" ? new GuUserData(scope, { app, ...userData }).userData : userData,\n vpcSubnets: { subnets: privateSubnets },\n ...(blockDevices && { blockDevices }),\n imageRecipe,\n });\n\n // This allows automatic shipping of instance Cloud Init logs when using the\n // `cdk-base` Amigo role on your AMI.\n Tags.of(autoScalingGroup).add(\n MetadataKeys.LOG_KINESIS_STREAM_NAME,\n GuLoggingStreamNameParameter.getInstance(scope).valueAsString\n );\n\n if (applicationLogging.enabled) {\n // This allows automatic shipping of application logs when using the\n // `cdk-base` Amigo role on your AMI.\n Tags.of(autoScalingGroup).add(\n MetadataKeys.SYSTEMD_UNIT,\n applicationLogging.systemdUnitName ? `${applicationLogging.systemdUnitName}.service` : `${app}.service`\n );\n }\n\n const loadBalancer = new GuApplicationLoadBalancer(scope, \"LoadBalancer\", {\n app,\n vpc,\n // Setting internetFacing to true does not necessarily allow public access to the load balancer itself. That is handled by the listener's `open` prop.\n internetFacing: access.scope !== AccessScope.INTERNAL,\n vpcSubnets: {\n subnets: access.scope === AccessScope.INTERNAL ? privateSubnets : publicSubnets,\n },\n });\n\n if (accessLogging.enabled) {\n const accessLoggingBucket = new GuStringParameter(scope, \"AccessLoggingBucket\", {\n description: NAMED_SSM_PARAMETER_PATHS.AccessLoggingBucket.description,\n default: NAMED_SSM_PARAMETER_PATHS.AccessLoggingBucket.path,\n fromSSM: true,\n });\n\n loadBalancer.logAccessLogs(\n Bucket.fromBucketName(\n scope,\n AppIdentity.suffixText(props, \"AccessLoggingBucket\"),\n accessLoggingBucket.valueAsString\n ),\n accessLogging.prefix\n );\n }\n\n const targetGroup = new GuApplicationTargetGroup(scope, \"TargetGroup\", {\n app,\n vpc,\n protocol: ApplicationProtocol.HTTP,\n targets: [autoScalingGroup],\n port: applicationPort,\n });\n\n const listener = new GuHttpsApplicationListener(scope, \"Listener\", {\n app,\n loadBalancer,\n certificate,\n targetGroup,\n // When open=true, AWS will create a security group which allows all inbound traffic over HTTPS\n open: access.scope === AccessScope.PUBLIC,\n });\n\n // Since AWS won't create a security group automatically when open=false, we need to add our own\n if (access.scope !== AccessScope.PUBLIC) {\n loadBalancer.addSecurityGroup(\n new GuSecurityGroup(scope, `${access.scope}IngressSecurityGroup`, {\n app,\n vpc,\n description: \"Allow restricted ingress from CIDR ranges\",\n allowAllOutbound: false,\n ingresses: restrictedCidrRanges(access.cidrRanges),\n })\n );\n }\n\n if (!monitoringConfiguration.noMonitoring) {\n const { http5xxAlarm, snsTopicName, unhealthyInstancesAlarm } = monitoringConfiguration;\n\n if (http5xxAlarm) {\n new GuAlb5xxPercentageAlarm(scope, {\n app,\n loadBalancer,\n snsTopicName,\n ...http5xxAlarm,\n });\n }\n if (unhealthyInstancesAlarm) {\n new GuUnhealthyInstancesAlarm(scope, {\n app,\n targetGroup,\n snsTopicName,\n });\n }\n }\n\n this.vpc = vpc;\n this.certificate = certificate;\n this.loadBalancer = loadBalancer;\n this.autoScalingGroup = autoScalingGroup;\n this.listener = listener;\n this.targetGroup = targetGroup;\n }\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { GuStack } from "../../constructs/core";
2
2
  import type { GuEc2AppProps } from "./base";
3
3
  import { GuEc2App } from "./base";
4
- declare type GuEc2FrameworkAppProps = Omit<GuEc2AppProps, "applicationPort">;
4
+ type GuEc2FrameworkAppProps = Omit<GuEc2AppProps, "applicationPort">;
5
5
  /**
6
6
  * Creates an instance of [[`GuEc2App`]], with an application port of 9000.
7
7
  */
@@ -1 +1 @@
1
- {"version":3,"file":"framework.d.ts","sourceRoot":"","sources":["../../../src/patterns/ec2-app/framework.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,aAAK,sBAAsB,GAAG,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;AAErE;;GAEG;AACH,qBAAa,SAAU,SAAQ,QAAQ;IACrC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAQ;gBAExB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB;CAG1D;AAED;;GAEG;AACH,qBAAa,SAAU,SAAQ,QAAQ;IACrC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAQ;gBAExB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB;CAG1D"}
1
+ {"version":3,"file":"framework.d.ts","sourceRoot":"","sources":["../../../src/patterns/ec2-app/framework.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAElC,KAAK,sBAAsB,GAAG,IAAI,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;AAErE;;GAEG;AACH,qBAAa,SAAU,SAAQ,QAAQ;IACrC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAQ;gBAExB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB;CAG1D;AAED;;GAEG;AACH,qBAAa,SAAU,SAAQ,QAAQ;IACrC,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAQ;gBAExB,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB;CAG1D"}
@@ -50,7 +50,7 @@ export interface InternalAccess extends Access {
50
50
  scope: AccessScope.INTERNAL;
51
51
  cidrRanges: IPeer[];
52
52
  }
53
- export declare type AppAccess = PublicAccess | RestrictedAccess | InternalAccess;
53
+ export type AppAccess = PublicAccess | RestrictedAccess | InternalAccess;
54
54
  export declare const AppAccess: {
55
55
  /**
56
56
  * Validate the CIDR rules for AppAccess.
@@ -1 +1 @@
1
- {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/types/access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAiB,SAAQ,MAAM;IAC9C,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC;IAC9B,UAAU,EAAE,KAAK,EAAE,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAe,SAAQ,MAAM;IAC5C,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC;IAC5B,UAAU,EAAE,KAAK,EAAE,CAAC;CACrB;AAED,oBAAY,SAAS,GAAG,YAAY,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAEzE,eAAO,MAAM,SAAS;IACpB;;;;;;;;OAQG;uBACgB,SAAS;CA6B7B,CAAC"}
1
+ {"version":3,"file":"access.d.ts","sourceRoot":"","sources":["../../src/types/access.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAEjD,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,MAAM;IACrB,KAAK,EAAE,WAAW,CAAC;CACpB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,YAAa,SAAQ,MAAM;IAC1C,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC;CAC3B;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,gBAAiB,SAAQ,MAAM;IAC9C,KAAK,EAAE,WAAW,CAAC,UAAU,CAAC;IAC9B,UAAU,EAAE,KAAK,EAAE,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,cAAe,SAAQ,MAAM;IAC5C,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC;IAC5B,UAAU,EAAE,KAAK,EAAE,CAAC;CACrB;AAED,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,gBAAgB,GAAG,cAAc,CAAC;AAEzE,eAAO,MAAM,SAAS;IACpB;;;;;;;;OAQG;uBACgB,SAAS;CA6B7B,CAAC"}
@@ -4,7 +4,7 @@ export interface AwsConfig {
4
4
  credentialProvider: CredentialProviderChain;
5
5
  region: string;
6
6
  }
7
- export declare type CliCommandResponse = Promise<string | Record<string, unknown> | number>;
7
+ export type CliCommandResponse = Promise<string | Record<string, unknown> | number>;
8
8
  export interface VpcInDetail extends Vpc {
9
9
  subnets: SubnetList;
10
10
  isUsed: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/types/cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,SAAS;IACxB,kBAAkB,EAAE,uBAAuB,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB;AAGD,oBAAY,kBAAkB,GAAG,OAAO,CAEpC,MAAM,GAEN,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAEvB,MAAM,CACT,CAAC;AAEF,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CACjB"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/types/cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AACvD,OAAO,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,SAAS;IACxB,kBAAkB,EAAE,uBAAuB,CAAC;IAC5C,MAAM,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAEpC,MAAM,GAEN,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAEvB,MAAM,CACT,CAAC;AAEF,MAAM,WAAW,WAAY,SAAQ,GAAG;IACtC,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;CACjB"}
@@ -1,7 +1,7 @@
1
1
  import { Duration } from "aws-cdk-lib";
2
2
  import type { IEventSourceDlq } from "aws-cdk-lib/aws-lambda";
3
3
  import type { KinesisEventSourceProps } from "aws-cdk-lib/aws-lambda-event-sources";
4
- export declare type StreamProcessingProps = Omit<KinesisEventSourceProps, "bisectBatchOnError" | "maxRecordAge" | "onFailure" | "retryAttempts">;
4
+ export type StreamProcessingProps = Omit<KinesisEventSourceProps, "bisectBatchOnError" | "maxRecordAge" | "onFailure" | "retryAttempts">;
5
5
  /**
6
6
  * In order to prevent your lambda from continuously retrying if it encounters errors
7
7
  * whilst processing a batch, use `retryBehaviour` to give up on a record once it reaches a certain age,
@@ -26,10 +26,10 @@ export interface StreamErrorHandlingProps {
26
26
  deadLetterQueueForSkippedRecords?: IEventSourceDlq;
27
27
  blockProcessingAndRetryIndefinitely?: false;
28
28
  }
29
- declare type AwsErrorHandlingProps = Pick<KinesisEventSourceProps, "bisectBatchOnError" | "maxRecordAge" | "onFailure" | "retryAttempts">;
29
+ type AwsErrorHandlingProps = Pick<KinesisEventSourceProps, "bisectBatchOnError" | "maxRecordAge" | "onFailure" | "retryAttempts">;
30
30
  export declare function toAwsErrorHandlingProps(errorHandlingProps: StreamErrorHandlingProps): AwsErrorHandlingProps;
31
- declare type AwsRetryProp = Pick<AwsErrorHandlingProps, "maxRecordAge" | "retryAttempts">;
32
- declare type RetryType = "attempts" | "recordAge";
31
+ type AwsRetryProp = Pick<AwsErrorHandlingProps, "maxRecordAge" | "retryAttempts">;
32
+ type RetryType = "attempts" | "recordAge";
33
33
  /**
34
34
  * To retry based on number of attempts, use:
35
35
  * ```typescript
@@ -1 +1 @@
1
- {"version":3,"file":"event-source.d.ts","sourceRoot":"","sources":["../../../src/utils/lambda/event-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAEpF,oBAAY,qBAAqB,GAAG,IAAI,CACtC,uBAAuB,EACvB,oBAAoB,GAAG,cAAc,GAAG,WAAW,GAAG,eAAe,CACtE,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,WAAW,CAAC;IAC5B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,gCAAgC,CAAC,EAAE,eAAe,CAAC;IACnD,mCAAmC,CAAC,EAAE,KAAK,CAAC;CAC7C;AAED,aAAK,qBAAqB,GAAG,IAAI,CAC/B,uBAAuB,EACvB,oBAAoB,GAAG,cAAc,GAAG,WAAW,GAAG,eAAe,CACtE,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,kBAAkB,EAAE,wBAAwB,GAAG,qBAAqB,CAM3G;AAED,aAAK,YAAY,GAAG,IAAI,CAAC,qBAAqB,EAAE,cAAc,GAAG,eAAe,CAAC,CAAC;AAClF,aAAK,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAE1C;;;;;;;;;GASG;AACH,qBAAa,WAAW;WACR,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;WAGxC,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW;IAG9C,SAAS,IAAI,YAAY;IAKhC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B,OAAO;CAIR"}
1
+ {"version":3,"file":"event-source.d.ts","sourceRoot":"","sources":["../../../src/utils/lambda/event-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAEpF,MAAM,MAAM,qBAAqB,GAAG,IAAI,CACtC,uBAAuB,EACvB,oBAAoB,GAAG,cAAc,GAAG,WAAW,GAAG,eAAe,CACtE,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,wBAAwB;IACvC,cAAc,EAAE,WAAW,CAAC;IAC5B,kBAAkB,EAAE,OAAO,CAAC;IAC5B,gCAAgC,CAAC,EAAE,eAAe,CAAC;IACnD,mCAAmC,CAAC,EAAE,KAAK,CAAC;CAC7C;AAED,KAAK,qBAAqB,GAAG,IAAI,CAC/B,uBAAuB,EACvB,oBAAoB,GAAG,cAAc,GAAG,WAAW,GAAG,eAAe,CACtE,CAAC;AAEF,wBAAgB,uBAAuB,CAAC,kBAAkB,EAAE,wBAAwB,GAAG,qBAAqB,CAM3G;AAED,KAAK,YAAY,GAAG,IAAI,CAAC,qBAAqB,EAAE,cAAc,GAAG,eAAe,CAAC,CAAC;AAClF,KAAK,SAAS,GAAG,UAAU,GAAG,WAAW,CAAC;AAE1C;;;;;;;;;GASG;AACH,qBAAa,WAAW;WACR,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW;WAGxC,MAAM,CAAC,QAAQ,EAAE,QAAQ,GAAG,WAAW;IAG9C,SAAS,IAAI,YAAY;IAKhC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAC;IAE9B,OAAO;CAIR"}
@@ -21,10 +21,6 @@ exports.toAwsErrorHandlingProps = toAwsErrorHandlingProps;
21
21
  * ```
22
22
  */
23
23
  class StreamRetry {
24
- constructor(amount, type) {
25
- this.amount = amount;
26
- this.retryType = type;
27
- }
28
24
  static maxAttempts(amount) {
29
25
  return new StreamRetry(amount, "attempts");
30
26
  }
@@ -36,6 +32,10 @@ class StreamRetry {
36
32
  ? { retryAttempts: this.amount }
37
33
  : { maxRecordAge: aws_cdk_lib_1.Duration.seconds(this.amount) };
38
34
  }
35
+ constructor(amount, type) {
36
+ this.amount = amount;
37
+ this.retryType = type;
38
+ }
39
39
  }
40
40
  exports.StreamRetry = StreamRetry;
41
41
  //# sourceMappingURL=event-source.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"event-source.js","sourceRoot":"","sources":["../../../src/utils/lambda/event-source.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAuCvC,SAAgB,uBAAuB,CAAC,kBAA4C;IAClF,OAAO;QACL,kBAAkB,EAAE,kBAAkB,CAAC,kBAAkB;QACzD,SAAS,EAAE,kBAAkB,CAAC,gCAAgC;QAC9D,GAAG,kBAAkB,CAAC,cAAc,CAAC,SAAS,EAAE;KACjD,CAAC;AACJ,CAAC;AAND,0DAMC;AAKD;;;;;;;;;GASG;AACH,MAAa,WAAW;IAetB,YAAoB,MAAc,EAAE,IAAe;QACjD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;IAjBM,MAAM,CAAC,WAAW,CAAC,MAAc;QACtC,OAAO,IAAI,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC;IACM,MAAM,CAAC,MAAM,CAAC,QAAkB;QACrC,OAAO,IAAI,WAAW,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;IACM,SAAS;QACd,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU;YAClC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,MAAM,EAAE;YAChC,CAAC,CAAC,EAAE,YAAY,EAAE,sBAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACtD,CAAC;CAQF;AAnBD,kCAmBC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport type { IEventSourceDlq } from \"aws-cdk-lib/aws-lambda\";\nimport type { KinesisEventSourceProps } from \"aws-cdk-lib/aws-lambda-event-sources\";\n\nexport type StreamProcessingProps = Omit<\n KinesisEventSourceProps,\n \"bisectBatchOnError\" | \"maxRecordAge\" | \"onFailure\" | \"retryAttempts\"\n>;\n\n/**\n * In order to prevent your lambda from continuously retrying if it encounters errors\n * whilst processing a batch, use `retryBehaviour` to give up on a record once it reaches a certain age,\n * or after a specified number of attempts. See [[`StreamRetry`]] for more details.\n *\n * In order to isolate bad records as part of the retry process, you may also want to bisect problematic batches\n * using `bisectBatchOnError`. For example:\n *\n * ```typescript\n * const errorHandlingProps: ErrorHandlingProps = {\n * bisectBatchOnError: true,\n * retryBehaviour: StreamRetry.maxAttempts(5),\n * }\n * ```\n *\n * Records which could not be processed successfully can (optionally) be sent to a dead letter queue\n * via `deadLetterQueueForSkippedRecords`.\n */\nexport interface StreamErrorHandlingProps {\n retryBehaviour: StreamRetry;\n bisectBatchOnError: boolean;\n deadLetterQueueForSkippedRecords?: IEventSourceDlq;\n blockProcessingAndRetryIndefinitely?: false;\n}\n\ntype AwsErrorHandlingProps = Pick<\n KinesisEventSourceProps,\n \"bisectBatchOnError\" | \"maxRecordAge\" | \"onFailure\" | \"retryAttempts\"\n>;\n\nexport function toAwsErrorHandlingProps(errorHandlingProps: StreamErrorHandlingProps): AwsErrorHandlingProps {\n return {\n bisectBatchOnError: errorHandlingProps.bisectBatchOnError,\n onFailure: errorHandlingProps.deadLetterQueueForSkippedRecords,\n ...errorHandlingProps.retryBehaviour.toAwsProp(),\n };\n}\n\ntype AwsRetryProp = Pick<AwsErrorHandlingProps, \"maxRecordAge\" | \"retryAttempts\">;\ntype RetryType = \"attempts\" | \"recordAge\";\n\n/**\n * To retry based on number of attempts, use:\n * ```typescript\n * StreamRetry.maxAttempts(5)\n * ```\n * To retry based on the age of a record, use:\n * ```typescript\n * StreamRetry.maxAge(Duration.minutes(5))\n * ```\n */\nexport class StreamRetry {\n public static maxAttempts(amount: number): StreamRetry {\n return new StreamRetry(amount, \"attempts\");\n }\n public static maxAge(duration: Duration): StreamRetry {\n return new StreamRetry(duration.toSeconds(), \"recordAge\");\n }\n public toAwsProp(): AwsRetryProp {\n return this.retryType === \"attempts\"\n ? { retryAttempts: this.amount }\n : { maxRecordAge: Duration.seconds(this.amount) };\n }\n private readonly amount: number;\n readonly retryType: RetryType;\n\n private constructor(amount: number, type: RetryType) {\n this.amount = amount;\n this.retryType = type;\n }\n}\n"]}
1
+ {"version":3,"file":"event-source.js","sourceRoot":"","sources":["../../../src/utils/lambda/event-source.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AAuCvC,SAAgB,uBAAuB,CAAC,kBAA4C;IAClF,OAAO;QACL,kBAAkB,EAAE,kBAAkB,CAAC,kBAAkB;QACzD,SAAS,EAAE,kBAAkB,CAAC,gCAAgC;QAC9D,GAAG,kBAAkB,CAAC,cAAc,CAAC,SAAS,EAAE;KACjD,CAAC;AACJ,CAAC;AAND,0DAMC;AAKD;;;;;;;;;GASG;AACH,MAAa,WAAW;IACf,MAAM,CAAC,WAAW,CAAC,MAAc;QACtC,OAAO,IAAI,WAAW,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC7C,CAAC;IACM,MAAM,CAAC,MAAM,CAAC,QAAkB;QACrC,OAAO,IAAI,WAAW,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,WAAW,CAAC,CAAC;IAC5D,CAAC;IACM,SAAS;QACd,OAAO,IAAI,CAAC,SAAS,KAAK,UAAU;YAClC,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,CAAC,MAAM,EAAE;YAChC,CAAC,CAAC,EAAE,YAAY,EAAE,sBAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;IACtD,CAAC;IAID,YAAoB,MAAc,EAAE,IAAe;QACjD,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;CACF;AAnBD,kCAmBC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport type { IEventSourceDlq } from \"aws-cdk-lib/aws-lambda\";\nimport type { KinesisEventSourceProps } from \"aws-cdk-lib/aws-lambda-event-sources\";\n\nexport type StreamProcessingProps = Omit<\n KinesisEventSourceProps,\n \"bisectBatchOnError\" | \"maxRecordAge\" | \"onFailure\" | \"retryAttempts\"\n>;\n\n/**\n * In order to prevent your lambda from continuously retrying if it encounters errors\n * whilst processing a batch, use `retryBehaviour` to give up on a record once it reaches a certain age,\n * or after a specified number of attempts. See [[`StreamRetry`]] for more details.\n *\n * In order to isolate bad records as part of the retry process, you may also want to bisect problematic batches\n * using `bisectBatchOnError`. For example:\n *\n * ```typescript\n * const errorHandlingProps: ErrorHandlingProps = {\n * bisectBatchOnError: true,\n * retryBehaviour: StreamRetry.maxAttempts(5),\n * }\n * ```\n *\n * Records which could not be processed successfully can (optionally) be sent to a dead letter queue\n * via `deadLetterQueueForSkippedRecords`.\n */\nexport interface StreamErrorHandlingProps {\n retryBehaviour: StreamRetry;\n bisectBatchOnError: boolean;\n deadLetterQueueForSkippedRecords?: IEventSourceDlq;\n blockProcessingAndRetryIndefinitely?: false;\n}\n\ntype AwsErrorHandlingProps = Pick<\n KinesisEventSourceProps,\n \"bisectBatchOnError\" | \"maxRecordAge\" | \"onFailure\" | \"retryAttempts\"\n>;\n\nexport function toAwsErrorHandlingProps(errorHandlingProps: StreamErrorHandlingProps): AwsErrorHandlingProps {\n return {\n bisectBatchOnError: errorHandlingProps.bisectBatchOnError,\n onFailure: errorHandlingProps.deadLetterQueueForSkippedRecords,\n ...errorHandlingProps.retryBehaviour.toAwsProp(),\n };\n}\n\ntype AwsRetryProp = Pick<AwsErrorHandlingProps, \"maxRecordAge\" | \"retryAttempts\">;\ntype RetryType = \"attempts\" | \"recordAge\";\n\n/**\n * To retry based on number of attempts, use:\n * ```typescript\n * StreamRetry.maxAttempts(5)\n * ```\n * To retry based on the age of a record, use:\n * ```typescript\n * StreamRetry.maxAge(Duration.minutes(5))\n * ```\n */\nexport class StreamRetry {\n public static maxAttempts(amount: number): StreamRetry {\n return new StreamRetry(amount, \"attempts\");\n }\n public static maxAge(duration: Duration): StreamRetry {\n return new StreamRetry(duration.toSeconds(), \"recordAge\");\n }\n public toAwsProp(): AwsRetryProp {\n return this.retryType === \"attempts\"\n ? { retryAttempts: this.amount }\n : { maxRecordAge: Duration.seconds(this.amount) };\n }\n private readonly amount: number;\n readonly retryType: RetryType;\n\n private constructor(amount: number, type: RetryType) {\n this.amount = amount;\n this.retryType = type;\n }\n}\n"]}
@@ -1,2 +1,2 @@
1
- export declare type AnyConstructor = new (...args: any[]) => {};
1
+ export type AnyConstructor = new (...args: any[]) => {};
2
2
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/mixin/types.ts"],"names":[],"mappings":"AACA,oBAAY,cAAc,GAAG,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/mixin/types.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@guardian/cdk",
3
3
  "description": "Generic Guardian flavoured AWS CDK components",
4
- "version": "49.0.0-beta.1",
4
+ "version": "49.0.1",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
@@ -28,48 +28,48 @@
28
28
  "cli:dev": "ts-node src/bin/index.ts"
29
29
  },
30
30
  "devDependencies": {
31
- "@guardian/eslint-config-typescript": "1.0.11",
31
+ "@guardian/eslint-config-typescript": "3.0.0",
32
32
  "@types/git-url-parse": "^9.0.1",
33
- "@types/jest": "^29.2.0",
33
+ "@types/jest": "^29.2.5",
34
34
  "@types/js-yaml": "^4.0.5",
35
35
  "@types/lodash.camelcase": "^4.3.7",
36
36
  "@types/lodash.kebabcase": "^4.1.7",
37
37
  "@types/lodash.upperfirst": "^4.3.7",
38
- "@types/node": "18.11.2",
39
- "@types/yargs": "^17.0.13",
40
- "aws-cdk": "2.45.0",
38
+ "@types/node": "18.11.18",
39
+ "@types/yargs": "^17.0.19",
40
+ "aws-cdk": "2.59.0",
41
41
  "cz-conventional-changelog": "^3.3.0",
42
- "eslint": "^8.25.0",
42
+ "eslint": "^8.31.0",
43
43
  "eslint-plugin-custom-rules": "file:tools/eslint",
44
44
  "gh-pages": "^4.0.0",
45
- "jest": "^29.2.1",
46
- "prettier": "^2.7.1",
45
+ "jest": "^29.3.1",
46
+ "prettier": "^2.8.1",
47
47
  "semantic-release": "^19.0.5",
48
- "serve": "^14.0.1",
48
+ "serve": "^14.1.2",
49
49
  "ts-jest": "^29.0.3",
50
50
  "ts-node": "^10.9.1",
51
- "typedoc": "^0.23.17",
52
- "typescript": "~4.8.4"
51
+ "typedoc": "^0.23.23",
52
+ "typescript": "~4.9.4"
53
53
  },
54
54
  "dependencies": {
55
- "@oclif/core": "1.16.5",
56
- "aws-cdk-lib": "2.45.0",
57
- "aws-sdk": "^2.1235.0",
55
+ "@oclif/core": "1.23.1",
56
+ "aws-cdk-lib": "2.59.0",
57
+ "aws-sdk": "^2.1288.0",
58
58
  "chalk": "^4.1.2",
59
- "codemaker": "^1.69.0",
60
- "constructs": "10.1.127",
59
+ "codemaker": "^1.72.0",
60
+ "constructs": "10.1.215",
61
61
  "git-url-parse": "^13.1.0",
62
62
  "js-yaml": "^4.1.0",
63
63
  "lodash.camelcase": "^4.3.0",
64
64
  "lodash.kebabcase": "^4.1.1",
65
65
  "lodash.upperfirst": "^4.3.1",
66
66
  "read-pkg-up": "7.0.1",
67
- "yargs": "^17.6.0"
67
+ "yargs": "^17.6.2"
68
68
  },
69
69
  "peerDependencies": {
70
- "aws-cdk": "2.45.0",
71
- "aws-cdk-lib": "2.45.0",
72
- "constructs": "10.1.127"
70
+ "aws-cdk": "2.59.0",
71
+ "aws-cdk-lib": "2.59.0",
72
+ "constructs": "10.1.215"
73
73
  },
74
74
  "config": {
75
75
  "commitizen": {
@@ -1,2 +0,0 @@
1
- export * from "./sns-topic";
2
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/constructs/sns/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/constructs/sns/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,8CAA4B","sourcesContent":["export * from \"./sns-topic\";\n"]}
@@ -1,15 +0,0 @@
1
- import { Topic } from "aws-cdk-lib/aws-sns";
2
- import type { TopicProps } from "aws-cdk-lib/aws-sns";
3
- import type { GuStack } from "../core";
4
- declare type GuSnsTopicProps = TopicProps;
5
- /**
6
- * Construct which creates an SNS Topic.
7
- *
8
- * This resource is stateful.
9
- * @see https://github.com/guardian/cdk/blob/main/docs/stateful-resources.md
10
- */
11
- export declare class GuSnsTopic extends Topic {
12
- constructor(scope: GuStack, id: string, props?: GuSnsTopicProps);
13
- }
14
- export {};
15
- //# sourceMappingURL=sns-topic.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sns-topic.d.ts","sourceRoot":"","sources":["../../../src/constructs/sns/sns-topic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,aAAK,eAAe,GAAG,UAAU,CAAC;AAElC;;;;;GAKG;AACH,qBAAa,UAAW,SAAQ,KAAK;gBACvB,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,eAAe;CAGhE"}
@@ -1,17 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GuSnsTopic = void 0;
4
- const aws_sns_1 = require("aws-cdk-lib/aws-sns");
5
- /**
6
- * Construct which creates an SNS Topic.
7
- *
8
- * This resource is stateful.
9
- * @see https://github.com/guardian/cdk/blob/main/docs/stateful-resources.md
10
- */
11
- class GuSnsTopic extends aws_sns_1.Topic {
12
- constructor(scope, id, props) {
13
- super(scope, id, props);
14
- }
15
- }
16
- exports.GuSnsTopic = GuSnsTopic;
17
- //# sourceMappingURL=sns-topic.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sns-topic.js","sourceRoot":"","sources":["../../../src/constructs/sns/sns-topic.ts"],"names":[],"mappings":";;;AAAA,iDAA4C;AAM5C;;;;;GAKG;AACH,MAAa,UAAW,SAAQ,eAAK;IACnC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAuB;QAC7D,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF;AAJD,gCAIC","sourcesContent":["import { Topic } from \"aws-cdk-lib/aws-sns\";\nimport type { TopicProps } from \"aws-cdk-lib/aws-sns\";\nimport type { GuStack } from \"../core\";\n\ntype GuSnsTopicProps = TopicProps;\n\n/**\n * Construct which creates an SNS Topic.\n *\n * This resource is stateful.\n * @see https://github.com/guardian/cdk/blob/main/docs/stateful-resources.md\n */\nexport class GuSnsTopic extends Topic {\n constructor(scope: GuStack, id: string, props?: GuSnsTopicProps) {\n super(scope, id, props);\n }\n}\n"]}