@guardian/cdk 50.0.0-beta.1 → 50.1.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.
- package/lib/bin/commands/new-project/index.js +9 -9
- package/lib/bin/commands/new-project/index.js.map +1 -1
- package/lib/constants/ssm-parameter-paths.d.ts +1 -0
- package/lib/constants/ssm-parameter-paths.d.ts.map +1 -1
- package/lib/constants/ssm-parameter-paths.js +4 -0
- package/lib/constants/ssm-parameter-paths.js.map +1 -1
- package/lib/constructs/autoscaling/asg.d.ts +2 -1
- package/lib/constructs/autoscaling/asg.d.ts.map +1 -1
- package/lib/constructs/autoscaling/asg.js +26 -10
- package/lib/constructs/autoscaling/asg.js.map +1 -1
- package/lib/constructs/cloudwatch/alarm.d.ts +1 -0
- package/lib/constructs/cloudwatch/alarm.d.ts.map +1 -1
- package/lib/constructs/cloudwatch/alarm.js +4 -1
- package/lib/constructs/cloudwatch/alarm.js.map +1 -1
- package/lib/constructs/lambda/lambda.d.ts +33 -22
- package/lib/constructs/lambda/lambda.d.ts.map +1 -1
- package/lib/constructs/lambda/lambda.js +29 -19
- package/lib/constructs/lambda/lambda.js.map +1 -1
- package/lib/constructs/loadbalancing/alb/application-listener.d.ts +1 -1
- package/lib/constructs/loadbalancing/alb/application-listener.d.ts.map +1 -1
- package/lib/constructs/loadbalancing/alb/application-listener.js +9 -7
- package/lib/constructs/loadbalancing/alb/application-listener.js.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/deployments/cloudformation.d.ts.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/deployments/cloudformation.js +3 -0
- package/lib/experimental/riff-raff-yaml-file/deployments/cloudformation.js.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/index.d.ts.map +1 -1
- package/lib/experimental/riff-raff-yaml-file/index.js +1 -4
- package/lib/experimental/riff-raff-yaml-file/index.js.map +1 -1
- package/lib/patterns/ec2-app/base.d.ts +112 -243
- package/lib/patterns/ec2-app/base.d.ts.map +1 -1
- package/lib/patterns/ec2-app/base.js +14 -176
- package/lib/patterns/ec2-app/base.js.map +1 -1
- package/lib/patterns/ec2-app/framework.d.ts +13 -1
- package/lib/patterns/ec2-app/framework.d.ts.map +1 -1
- package/lib/patterns/ec2-app/framework.js +17 -1
- package/lib/patterns/ec2-app/framework.js.map +1 -1
- package/lib/patterns/scheduled-lambda.d.ts.map +1 -1
- package/lib/patterns/scheduled-lambda.js +1 -3
- package/lib/patterns/scheduled-lambda.js.map +1 -1
- package/lib/types/amigo.d.ts +12 -0
- package/lib/types/amigo.d.ts.map +1 -1
- package/lib/types/amigo.js.map +1 -1
- package/package.json +18 -17
|
@@ -101,30 +101,30 @@ const newCdkProject = async (props) => {
|
|
|
101
101
|
});
|
|
102
102
|
const commands = (0, utils_1.getCommands)(config.packageManager, config.cdkDir);
|
|
103
103
|
if (config.init) {
|
|
104
|
-
core_1.
|
|
104
|
+
core_1.ux.action.start(chalk_1.default.yellow("Installing dependencies. This may take a while..."));
|
|
105
105
|
await commands.installDependencies();
|
|
106
|
-
core_1.
|
|
106
|
+
core_1.ux.action.stop();
|
|
107
107
|
}
|
|
108
108
|
// Run `eslint --fix` on the generated files instead of trying to generate code that completely satisfies the linter
|
|
109
109
|
await (0, exec_1.execute)("./node_modules/.bin/eslint", ["lib/** bin/**", "--ext .ts", "--no-error-on-unmatched-pattern", "--fix"], {
|
|
110
110
|
cwd: config.cdkDir,
|
|
111
111
|
});
|
|
112
|
-
core_1.
|
|
112
|
+
core_1.ux.action.start(chalk_1.default.yellow("Running lint check..."));
|
|
113
113
|
await commands.lint();
|
|
114
|
-
core_1.
|
|
115
|
-
core_1.
|
|
114
|
+
core_1.ux.action.stop();
|
|
115
|
+
core_1.ux.action.start(chalk_1.default.yellow("Running tests..."));
|
|
116
116
|
await commands.test();
|
|
117
|
-
core_1.
|
|
118
|
-
core_1.
|
|
117
|
+
core_1.ux.action.stop();
|
|
118
|
+
core_1.ux.action.start(chalk_1.default.yellow("Running initial synthesis..."));
|
|
119
119
|
await commands.synth();
|
|
120
|
-
core_1.
|
|
120
|
+
core_1.ux.action.stop();
|
|
121
121
|
console.log(chalk_1.default.green("Success! Here's a summary of the created files:"));
|
|
122
122
|
const tree = await (0, exec_1.execute)("tree", ["-I 'node_modules|cdk.out'"], {
|
|
123
123
|
cwd: config.cdkDir,
|
|
124
124
|
});
|
|
125
125
|
console.log(tree);
|
|
126
126
|
const docsUrl = "https://github.com/guardian/cdk/tree/main/docs";
|
|
127
|
-
core_1.
|
|
127
|
+
core_1.ux.url(chalk_1.default.green(`Please see the docs (${docsUrl}) for next steps.`), docsUrl);
|
|
128
128
|
return Promise.resolve(0);
|
|
129
129
|
};
|
|
130
130
|
exports.newCdkProject = newCdkProject;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/bin/commands/new-project/index.ts"],"names":[],"mappings":";;;;;;AAAA,2BAAgC;AAChC,+BAA+C;AAC/C,
|
|
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(),\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"]}
|
|
@@ -14,6 +14,7 @@ interface NamedSsmParameterPaths {
|
|
|
14
14
|
PrimaryVpcPrivateSubnets: SsmParameterPath;
|
|
15
15
|
PrimaryVpcPublicSubnets: SsmParameterPath;
|
|
16
16
|
FastlyCustomerId: SsmParameterPath;
|
|
17
|
+
OrganisationDistributionBucket: SsmParameterPath;
|
|
17
18
|
}
|
|
18
19
|
export declare const VPC_SSM_PARAMETER_PREFIX = "/account/vpc";
|
|
19
20
|
export declare const NAMED_SSM_PARAMETER_PATHS: NamedSsmParameterPaths;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssm-parameter-paths.d.ts","sourceRoot":"","sources":["../../src/constants/ssm-parameter-paths.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAInB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,sBAAsB;IAC9B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,mBAAmB,EAAE,gBAAgB,CAAC;IACtC,mBAAmB,EAAE,gBAAgB,CAAC;IACtC,YAAY,EAAE,gBAAgB,CAAC;IAC/B,wBAAwB,EAAE,gBAAgB,CAAC;IAC3C,uBAAuB,EAAE,gBAAgB,CAAC;IAC1C,gBAAgB,EAAE,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"ssm-parameter-paths.d.ts","sourceRoot":"","sources":["../../src/constants/ssm-parameter-paths.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IAInB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,sBAAsB;IAC9B,WAAW,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,kBAAkB,EAAE,gBAAgB,CAAC;IACrC,mBAAmB,EAAE,gBAAgB,CAAC;IACtC,mBAAmB,EAAE,gBAAgB,CAAC;IACtC,YAAY,EAAE,gBAAgB,CAAC;IAC/B,wBAAwB,EAAE,gBAAgB,CAAC;IAC3C,uBAAuB,EAAE,gBAAgB,CAAC;IAC1C,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,8BAA8B,EAAE,gBAAgB,CAAC;CAClD;AAED,eAAO,MAAM,wBAAwB,iBAAiB,CAAC;AAEvD,eAAO,MAAM,yBAAyB,EAAE,sBA8CvC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,gBAAgB,EAE/B,CAAC"}
|
|
@@ -38,6 +38,10 @@ exports.NAMED_SSM_PARAMETER_PATHS = {
|
|
|
38
38
|
path: `${exports.VPC_SSM_PARAMETER_PREFIX}/primary/subnets/public`,
|
|
39
39
|
description: "A comma-separated list of public subnets",
|
|
40
40
|
},
|
|
41
|
+
OrganisationDistributionBucket: {
|
|
42
|
+
path: "/organisation/services/artifact.bucket",
|
|
43
|
+
description: "SSM parameter containing the S3 bucket name holding organisation-level DevX artifacts",
|
|
44
|
+
},
|
|
41
45
|
FastlyCustomerId: {
|
|
42
46
|
path: "/account/external/fastly/customer.id",
|
|
43
47
|
description: "SSM parameter containing the Fastly Customer ID. Can be obtained from https://manage.fastly.com/account/company by an admin",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ssm-parameter-paths.js","sourceRoot":"","sources":["../../src/constants/ssm-parameter-paths.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"ssm-parameter-paths.js","sourceRoot":"","sources":["../../src/constants/ssm-parameter-paths.ts"],"names":[],"mappings":";;;AAuBa,QAAA,wBAAwB,GAAG,cAAc,CAAC;AAE1C,QAAA,yBAAyB,GAA2B;IAC/D,WAAW,EAAE;QACX,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,+DAA+D;QAC5E,QAAQ,EAAE,IAAI;KACf;IACD,iBAAiB,EAAE;QACjB,IAAI,EAAE,uCAAuC;QAC7C,WAAW,EAAE,mEAAmE;KACjF;IACD,kBAAkB,EAAE;QAClB,IAAI,EAAE,mCAAmC;QACzC,WAAW,EAAE,4EAA4E;QACzF,aAAa,EAAE,2BAA2B;KAC3C;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,qCAAqC;KACnD;IACD,mBAAmB,EAAE;QACnB,IAAI,EAAE,yCAAyC;QAC/C,WAAW,EAAE,qFAAqF;QAClG,aAAa,EAAE,yBAAyB;KACzC;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,GAAG,gCAAwB,aAAa;QAC9C,WAAW,EAAE,2FAA2F;KACzG;IACD,wBAAwB,EAAE;QACxB,IAAI,EAAE,GAAG,gCAAwB,0BAA0B;QAC3D,WAAW,EAAE,2CAA2C;KACzD;IACD,uBAAuB,EAAE;QACvB,IAAI,EAAE,GAAG,gCAAwB,yBAAyB;QAC1D,WAAW,EAAE,0CAA0C;KACxD;IACD,8BAA8B,EAAE;QAC9B,IAAI,EAAE,wCAAwC;QAC9C,WAAW,EAAE,uFAAuF;KACrG;IACD,gBAAgB,EAAE;QAChB,IAAI,EAAE,sCAAsC;QAC5C,WAAW,EACT,6HAA6H;QAC/H,QAAQ,EAAE,IAAI;KACf;CACF,CAAC;AAEW,QAAA,uBAAuB,GAAuB,MAAM,CAAC,MAAM,CACtE,iCAAyB,CACJ,CAAC","sourcesContent":["export interface SsmParameterPath {\n path: string;\n description: string;\n optional?: boolean;\n\n // Recommended naming convention for target resource, such as an S3 bucket.\n // $account is substituted as the account name.\n namingPattern?: string;\n}\n\ninterface NamedSsmParameterPaths {\n Anghammarad: SsmParameterPath;\n LoggingStreamName: SsmParameterPath;\n DistributionBucket: SsmParameterPath;\n AccessLoggingBucket: SsmParameterPath;\n ConfigurationBucket: SsmParameterPath;\n PrimaryVpcId: SsmParameterPath;\n PrimaryVpcPrivateSubnets: SsmParameterPath;\n PrimaryVpcPublicSubnets: SsmParameterPath;\n FastlyCustomerId: SsmParameterPath;\n OrganisationDistributionBucket: SsmParameterPath;\n}\n\nexport const VPC_SSM_PARAMETER_PREFIX = \"/account/vpc\";\n\nexport const NAMED_SSM_PARAMETER_PATHS: NamedSsmParameterPaths = {\n Anghammarad: {\n path: \"/account/services/anghammarad.topic.arn\",\n description: \"SSM parameter containing the ARN of the Anghammarad SNS topic\",\n optional: true,\n },\n LoggingStreamName: {\n path: \"/account/services/logging.stream.name\",\n description: \"SSM parameter containing the Name (not ARN) on the kinesis stream\",\n },\n DistributionBucket: {\n path: \"/account/services/artifact.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding distribution artifacts\",\n namingPattern: \"com-gu-$account-artifacts\",\n },\n AccessLoggingBucket: {\n path: \"/account/services/access-logging/bucket\",\n description: \"S3 bucket to store your access logs\",\n },\n ConfigurationBucket: {\n path: \"/account/services/private.config.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding the app's private configuration\",\n namingPattern: \"com-gu-$account-configs\",\n },\n PrimaryVpcId: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/id`,\n description: \"Virtual Private Cloud to run EC2 instances within. Should NOT be the account default VPC.\",\n },\n PrimaryVpcPrivateSubnets: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/subnets/private`,\n description: \"A comma-separated list of private subnets\",\n },\n PrimaryVpcPublicSubnets: {\n path: `${VPC_SSM_PARAMETER_PREFIX}/primary/subnets/public`,\n description: \"A comma-separated list of public subnets\",\n },\n OrganisationDistributionBucket: {\n path: \"/organisation/services/artifact.bucket\",\n description: \"SSM parameter containing the S3 bucket name holding organisation-level DevX artifacts\",\n },\n FastlyCustomerId: {\n path: \"/account/external/fastly/customer.id\",\n description:\n \"SSM parameter containing the Fastly Customer ID. Can be obtained from https://manage.fastly.com/account/company by an admin\",\n optional: true,\n },\n};\n\nexport const ALL_SSM_PARAMETER_PATHS: SsmParameterPath[] = Object.values(\n NAMED_SSM_PARAMETER_PATHS\n) as SsmParameterPath[];\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AutoScalingGroup } from "aws-cdk-lib/aws-autoscaling";
|
|
2
2
|
import type { AutoScalingGroupProps } from "aws-cdk-lib/aws-autoscaling";
|
|
3
3
|
import { UserData } from "aws-cdk-lib/aws-ec2";
|
|
4
|
-
import type { ISecurityGroup } from "aws-cdk-lib/aws-ec2";
|
|
4
|
+
import type { InstanceType, ISecurityGroup } from "aws-cdk-lib/aws-ec2";
|
|
5
5
|
import type { ApplicationTargetGroup } from "aws-cdk-lib/aws-elasticloadbalancingv2";
|
|
6
6
|
import type { GuAsgCapacity } from "../../types";
|
|
7
7
|
import type { AmigoProps } from "../../types/amigo";
|
|
@@ -10,6 +10,7 @@ import type { AppIdentity, GuStack } from "../core";
|
|
|
10
10
|
export interface GuAutoScalingGroupProps extends Omit<AutoScalingGroupProps, "imageId" | "osType" | "machineImage" | "userData" | "minCapacity" | "maxCapacity" | "desiredCapacity" | "requireImdsv2" | "securityGroup">, AppIdentity, GuAsgCapacity {
|
|
11
11
|
imageId?: GuAmiParameter;
|
|
12
12
|
imageRecipe?: string | AmigoProps;
|
|
13
|
+
instanceType: InstanceType;
|
|
13
14
|
userData: UserData | string;
|
|
14
15
|
additionalSecurityGroups?: ISecurityGroup[];
|
|
15
16
|
targetGroup?: ApplicationTargetGroup;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asg.d.ts","sourceRoot":"","sources":["../../../src/constructs/autoscaling/asg.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAuB,MAAM,6BAA6B,CAAC;AAC9F,OAAO,
|
|
1
|
+
{"version":3,"file":"asg.d.ts","sourceRoot":"","sources":["../../../src/constructs/autoscaling/asg.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,qBAAqB,EAAuB,MAAM,6BAA6B,CAAC;AAC9F,OAAO,EAAuC,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAsB,MAAM,qBAAqB,CAAC;AAC5F,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,wCAAwC,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAQpD,MAAM,WAAW,uBACf,SAAQ,IAAI,CACR,qBAAqB,EACnB,SAAS,GACT,QAAQ,GACR,cAAc,GACd,UAAU,GACV,aAAa,GACb,aAAa,GACb,iBAAiB,GACjB,eAAe,GACf,eAAe,CAClB,EACD,WAAW,EACX,aAAa;IACf,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;IAClC,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAC;IAC5B,wBAAwB,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5C,WAAW,CAAC,EAAE,sBAAsB,CAAC;IACrC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;;;;;;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,qBAAa,kBAAmB,SAAQ,uBAAqC;IAC3E,SAAgB,GAAG,EAAE,MAAM,CAAC;IAC5B,SAAgB,YAAY,EAAE,cAAc,CAAC;IAC7C,SAAgB,WAAW,CAAC,EAAE,MAAM,GAAG,UAAU,CAAC;gBAEtC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,uBAAuB;CAoFvE"}
|
|
@@ -30,18 +30,17 @@ const iam_1 = require("../iam");
|
|
|
30
30
|
*/
|
|
31
31
|
class GuAutoScalingGroup extends (0, app_aware_construct_1.GuAppAwareConstruct)(aws_autoscaling_1.AutoScalingGroup) {
|
|
32
32
|
constructor(scope, id, props) {
|
|
33
|
-
const { app, additionalSecurityGroups = [], imageId = new core_1.GuAmiParameter(scope, { app }), imageRecipe, minimumInstances, maximumInstances, role = new iam_1.GuInstanceRole(scope, { app }), targetGroup, userData: userDataLike, vpc, withoutImdsv2 = false, } = props;
|
|
33
|
+
const { app, additionalSecurityGroups = [], blockDevices, imageId = new core_1.GuAmiParameter(scope, { app }), imageRecipe, instanceType, minimumInstances, maximumInstances, role = new iam_1.GuInstanceRole(scope, { app }), targetGroup, userData: userDataLike, vpc, withoutImdsv2 = false, } = props;
|
|
34
34
|
// Ensure min and max are defined in the same way. Throwing an `Error` when necessary. For example when min is defined via a Mapping, but max is not.
|
|
35
35
|
if (aws_cdk_lib_1.Token.isUnresolved(minimumInstances) && !aws_cdk_lib_1.Token.isUnresolved(maximumInstances)) {
|
|
36
36
|
throw new Error("minimumInstances is defined via a Mapping, but maximumInstances is not. Create maximumInstances via a Mapping too.");
|
|
37
37
|
}
|
|
38
38
|
const userData = userDataLike instanceof aws_ec2_1.UserData ? userDataLike : aws_ec2_1.UserData.custom(userDataLike);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
requireImdsv2: !withoutImdsv2,
|
|
39
|
+
// Generate an ID unique to this app
|
|
40
|
+
const launchTemplateId = `${scope.stack}-${scope.stage}-${app}`;
|
|
41
|
+
const launchTemplate = new aws_ec2_1.LaunchTemplate(scope, launchTemplateId, {
|
|
42
|
+
blockDevices,
|
|
43
|
+
instanceType,
|
|
45
44
|
machineImage: {
|
|
46
45
|
getImage: () => {
|
|
47
46
|
return {
|
|
@@ -51,17 +50,34 @@ class GuAutoScalingGroup extends (0, app_aware_construct_1.GuAppAwareConstruct)(
|
|
|
51
50
|
};
|
|
52
51
|
},
|
|
53
52
|
},
|
|
54
|
-
userData,
|
|
55
53
|
// Do not use the default AWS security group which allows egress on any port.
|
|
56
54
|
// Favour HTTPS only egress rules by default.
|
|
57
55
|
securityGroup: ec2_1.GuHttpsEgressSecurityGroup.forVpc(scope, { app, vpc }),
|
|
56
|
+
requireImdsv2: !withoutImdsv2,
|
|
57
|
+
userData,
|
|
58
|
+
role,
|
|
59
|
+
});
|
|
60
|
+
// Add Wazuh & additional consumer specified Security Groups
|
|
61
|
+
// Note: Launch templates via CDK allow specifying only one SG, so use connections
|
|
62
|
+
// https://github.com/aws/aws-cdk/issues/18712
|
|
63
|
+
[ec2_1.GuWazuhAccess.getInstance(scope, vpc), ...additionalSecurityGroups].forEach((sg) => launchTemplate.connections.addSecurityGroup(sg));
|
|
64
|
+
const asgProps = {
|
|
65
|
+
...props,
|
|
66
|
+
launchTemplate,
|
|
67
|
+
maxCapacity: maximumInstances ?? minimumInstances * 2,
|
|
68
|
+
minCapacity: minimumInstances,
|
|
69
|
+
// Omit userData, instanceType, blockDevices & role from asgProps
|
|
70
|
+
// As this are specified by the LaunchTemplate and must not be duplicated
|
|
71
|
+
blockDevices: undefined,
|
|
72
|
+
instanceType: undefined,
|
|
73
|
+
role: undefined,
|
|
74
|
+
userData: undefined,
|
|
58
75
|
};
|
|
59
|
-
super(scope, id,
|
|
76
|
+
super(scope, id, asgProps);
|
|
60
77
|
this.app = app;
|
|
61
78
|
this.amiParameter = imageId;
|
|
62
79
|
this.imageRecipe = imageRecipe;
|
|
63
80
|
targetGroup && this.attachToApplicationTargetGroup(targetGroup);
|
|
64
|
-
[ec2_1.GuWazuhAccess.getInstance(scope, vpc), ...additionalSecurityGroups].forEach((sg) => this.addSecurityGroup(sg));
|
|
65
81
|
const cfnAsg = this.node.defaultChild;
|
|
66
82
|
// A CDK AutoScalingGroup comes with this update policy, whereas the CFN autscaling group
|
|
67
83
|
// leaves it to the default value, which is actually false.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asg.js","sourceRoot":"","sources":["../../../src/constructs/autoscaling/asg.ts"],"names":[],"mappings":";;;AAAA,6CAAoC;AACpC,iEAA+D;AAE/D,
|
|
1
|
+
{"version":3,"file":"asg.js","sourceRoot":"","sources":["../../../src/constructs/autoscaling/asg.ts"],"names":[],"mappings":"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","sourcesContent":["import { Token } from \"aws-cdk-lib\";\nimport { AutoScalingGroup } from \"aws-cdk-lib/aws-autoscaling\";\nimport type { AutoScalingGroupProps, CfnAutoScalingGroup } from \"aws-cdk-lib/aws-autoscaling\";\nimport { LaunchTemplate, OperatingSystemType, UserData } from \"aws-cdk-lib/aws-ec2\";\nimport type { InstanceType, ISecurityGroup, MachineImageConfig } from \"aws-cdk-lib/aws-ec2\";\nimport type { ApplicationTargetGroup } from \"aws-cdk-lib/aws-elasticloadbalancingv2\";\nimport type { GuAsgCapacity } from \"../../types\";\nimport type { AmigoProps } from \"../../types/amigo\";\nimport { GuAppAwareConstruct } from \"../../utils/mixin/app-aware-construct\";\nimport { GuAmiParameter } from \"../core\";\nimport type { AppIdentity, GuStack } from \"../core\";\nimport { GuHttpsEgressSecurityGroup, GuWazuhAccess } from \"../ec2\";\nimport { GuInstanceRole } from \"../iam\";\n\n// Since we want to override the types of what gets passed in for the below props,\n// we need to use Omit<T, U> to remove them from the interface this extends\n// https://www.typescriptlang.org/docs/handbook/utility-types.html#omittype-keys\n// TODO avoid prop nesting to improve discoverability. See https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md#flat.\nexport interface GuAutoScalingGroupProps\n extends Omit<\n AutoScalingGroupProps,\n | \"imageId\"\n | \"osType\"\n | \"machineImage\"\n | \"userData\"\n | \"minCapacity\"\n | \"maxCapacity\"\n | \"desiredCapacity\"\n | \"requireImdsv2\"\n | \"securityGroup\"\n >,\n AppIdentity,\n GuAsgCapacity {\n imageId?: GuAmiParameter;\n imageRecipe?: string | AmigoProps;\n instanceType: InstanceType;\n userData: UserData | string;\n additionalSecurityGroups?: ISecurityGroup[];\n targetGroup?: ApplicationTargetGroup;\n withoutImdsv2?: boolean;\n}\n\n/**\n * Construct which creates an Auto Scaling group.\n *\n * By default, all EC2 instances in this group will use [[`GuInstanceRole`]],\n * which provides common permissions (e.g. the ability to download an artifact and write logs to the account's logging Kinesis stream).\n *\n * If additional IAM permissions are required, a custom role can be provided via the `role` prop.\n * You may wish to instantiate [[`GuInstanceRole`]] yourself as a basis for this custom role, as it allows custom permissions\n * to be passed in.\n *\n * All EC2 instances in this group will be automatically associated with two security groups:\n * 1. [[`GuHttpsEgressSecurityGroup`]], which allows outbound traffic over HTTPS.\n * 2. [[`GuWazuhAccess`]], which allows instances to communicate with Wazuh (for security monitoring).\n *\n * If additional ingress or egress rules are required, define custom security groups and pass them in via the\n * `additionalSecurityGroups` prop.\n *\n * All EC2 instances provisioned via this construct will use\n * [IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html).\n */\nexport class GuAutoScalingGroup extends GuAppAwareConstruct(AutoScalingGroup) {\n public readonly app: string;\n public readonly amiParameter: GuAmiParameter;\n public readonly imageRecipe?: string | AmigoProps;\n\n constructor(scope: GuStack, id: string, props: GuAutoScalingGroupProps) {\n const {\n app,\n additionalSecurityGroups = [],\n blockDevices,\n imageId = new GuAmiParameter(scope, { app }),\n imageRecipe,\n instanceType,\n minimumInstances,\n maximumInstances,\n role = new GuInstanceRole(scope, { app }),\n targetGroup,\n userData: userDataLike,\n vpc,\n withoutImdsv2 = false,\n } = props;\n\n // Ensure min and max are defined in the same way. Throwing an `Error` when necessary. For example when min is defined via a Mapping, but max is not.\n if (Token.isUnresolved(minimumInstances) && !Token.isUnresolved(maximumInstances)) {\n throw new Error(\n \"minimumInstances is defined via a Mapping, but maximumInstances is not. Create maximumInstances via a Mapping too.\"\n );\n }\n\n const userData = userDataLike instanceof UserData ? userDataLike : UserData.custom(userDataLike);\n\n // Generate an ID unique to this app\n const launchTemplateId = `${scope.stack}-${scope.stage}-${app}`;\n const launchTemplate = new LaunchTemplate(scope, launchTemplateId, {\n blockDevices,\n instanceType,\n machineImage: {\n getImage: (): MachineImageConfig => {\n return {\n osType: OperatingSystemType.LINUX,\n userData,\n imageId: imageId.valueAsString,\n };\n },\n },\n // Do not use the default AWS security group which allows egress on any port.\n // Favour HTTPS only egress rules by default.\n securityGroup: GuHttpsEgressSecurityGroup.forVpc(scope, { app, vpc }),\n requireImdsv2: !withoutImdsv2,\n userData,\n role,\n });\n\n // Add Wazuh & additional consumer specified Security Groups\n // Note: Launch templates via CDK allow specifying only one SG, so use connections\n // https://github.com/aws/aws-cdk/issues/18712\n [GuWazuhAccess.getInstance(scope, vpc), ...additionalSecurityGroups].forEach((sg) =>\n launchTemplate.connections.addSecurityGroup(sg)\n );\n\n const asgProps = {\n ...props,\n launchTemplate,\n maxCapacity: maximumInstances ?? minimumInstances * 2,\n minCapacity: minimumInstances,\n\n // Omit userData, instanceType, blockDevices & role from asgProps\n // As this are specified by the LaunchTemplate and must not be duplicated\n blockDevices: undefined,\n instanceType: undefined,\n role: undefined,\n userData: undefined,\n };\n\n super(scope, id, asgProps);\n\n this.app = app;\n this.amiParameter = imageId;\n this.imageRecipe = imageRecipe;\n\n targetGroup && this.attachToApplicationTargetGroup(targetGroup);\n\n const cfnAsg = this.node.defaultChild as CfnAutoScalingGroup;\n\n // A CDK AutoScalingGroup comes with this update policy, whereas the CFN autscaling group\n // leaves it to the default value, which is actually false.\n // { UpdatePolicy: { autoScalingScheduledAction: { IgnoreUnmodifiedGroupSizeProperties: true }}\n cfnAsg.addDeletionOverride(\"UpdatePolicy\");\n }\n}\n"]}
|
|
@@ -3,6 +3,7 @@ import type { AlarmProps } from "aws-cdk-lib/aws-cloudwatch";
|
|
|
3
3
|
import type { AppIdentity, GuStack } from "../core";
|
|
4
4
|
export interface GuAlarmProps extends AlarmProps, AppIdentity {
|
|
5
5
|
snsTopicName: string;
|
|
6
|
+
okAction?: boolean;
|
|
6
7
|
}
|
|
7
8
|
export interface Http5xxAlarmProps extends Omit<GuAlarmProps, "snsTopicName" | "evaluationPeriods" | "metric" | "period" | "threshold" | "treatMissingData" | "app"> {
|
|
8
9
|
tolerated5xxPercentage: 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;
|
|
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"}
|
|
@@ -23,11 +23,14 @@ const aws_sns_1 = require("aws-cdk-lib/aws-sns");
|
|
|
23
23
|
class GuAlarm extends aws_cloudwatch_1.Alarm {
|
|
24
24
|
constructor(scope, id, props) {
|
|
25
25
|
const { region, account } = scope;
|
|
26
|
-
const { snsTopicName, actionsEnabled = true } = props;
|
|
26
|
+
const { snsTopicName, actionsEnabled = true, okAction } = props;
|
|
27
27
|
super(scope, id, { ...props, actionsEnabled });
|
|
28
28
|
const topicArn = `arn:aws:sns:${region}:${account}:${snsTopicName}`;
|
|
29
29
|
const snsTopic = aws_sns_1.Topic.fromTopicArn(scope, `SnsTopicFor${id}`, topicArn);
|
|
30
30
|
this.addAlarmAction(new aws_cloudwatch_actions_1.SnsAction(snsTopic));
|
|
31
|
+
if (okAction) {
|
|
32
|
+
this.addOkAction(new aws_cloudwatch_actions_1.SnsAction(snsTopic));
|
|
33
|
+
}
|
|
31
34
|
}
|
|
32
35
|
}
|
|
33
36
|
exports.GuAlarm = GuAlarm;
|
|
@@ -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;
|
|
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,18 +1,10 @@
|
|
|
1
|
+
import { Function } from "aws-cdk-lib/aws-lambda";
|
|
1
2
|
import type { FunctionProps } from "aws-cdk-lib/aws-lambda";
|
|
2
|
-
import { Alias, Function } from "aws-cdk-lib/aws-lambda";
|
|
3
3
|
import { GuDistributable } from "../../types";
|
|
4
4
|
import type { GuLambdaErrorPercentageMonitoringProps, GuLambdaThrottlingMonitoringProps } from "../cloudwatch";
|
|
5
5
|
import type { GuStack } from "../core";
|
|
6
6
|
import { AppIdentity } from "../core";
|
|
7
7
|
export interface GuFunctionProps extends GuDistributable, Omit<FunctionProps, "code">, AppIdentity {
|
|
8
|
-
/**
|
|
9
|
-
* Create a new Lambda version and alias. This is only necessary if you want to use features which rely
|
|
10
|
-
* on versioning (e.g. SnapStart or Provisioned Concurrency).
|
|
11
|
-
*
|
|
12
|
-
* If you enable versioning you must ensure that your Lambda function whenever a new build is deployed via
|
|
13
|
-
* CloudFormation. The simplest way to do this is to include the build number in the `fileName` prop.
|
|
14
|
-
*/
|
|
15
|
-
enableVersioning?: boolean;
|
|
16
8
|
/**
|
|
17
9
|
* Alarm if error percentage exceeds a threshold.
|
|
18
10
|
*/
|
|
@@ -25,32 +17,51 @@ export interface GuFunctionProps extends GuDistributable, Omit<FunctionProps, "c
|
|
|
25
17
|
* @see https://docs.aws.amazon.com/lambda/latest/dg/concurrent-executions.html
|
|
26
18
|
*/
|
|
27
19
|
throttlingMonitoring?: GuLambdaThrottlingMonitoringProps;
|
|
20
|
+
/**
|
|
21
|
+
* SSM parameter for the S3 bucket that contains your lambda file.
|
|
22
|
+
*
|
|
23
|
+
* Typically you should not override this but you may need to if, for example,
|
|
24
|
+
* you are referencing a file that is shared across many apps and/or AWS
|
|
25
|
+
* accounts.
|
|
26
|
+
*
|
|
27
|
+
* @defaultValue [[`GuDistributionBucketParameter`]]
|
|
28
|
+
*/
|
|
29
|
+
bucketNamePath?: string;
|
|
28
30
|
}
|
|
29
31
|
/**
|
|
30
32
|
* Construct which creates a Lambda function.
|
|
31
33
|
*
|
|
32
|
-
* This Lambda relies on the code artifact residing in a standard location in
|
|
33
|
-
*
|
|
34
|
+
* This Lambda relies on the code artifact residing in a standard location in
|
|
35
|
+
* S3. For more details on the bucket used, see
|
|
36
|
+
* [[`GuDistributionBucketParameter`]]. By default, the path used will be
|
|
37
|
+
* `<stack>/<stage>/<app</<fileName>`. If required, e.g. if you are sharing
|
|
38
|
+
* lambda code across apps or accounts, override the source bucket using the
|
|
39
|
+
* `bucketNamePath` prop.
|
|
34
40
|
*
|
|
35
|
-
* The default memory size of this Lambda will vary depending on the runtime
|
|
36
|
-
* For Java runtimes (i.e. resource hungry Scala Lambdas!), 1024MB will
|
|
37
|
-
* the memory size defaults to 512MB. This can
|
|
41
|
+
* The default memory size of this Lambda will vary depending on the runtime
|
|
42
|
+
* chosen. For Java runtimes (i.e. resource hungry Scala Lambdas!), 1024MB will
|
|
43
|
+
* be used. For all other runtimes, the memory size defaults to 512MB. This can
|
|
44
|
+
* be overridden via the `memorySize` prop.
|
|
38
45
|
*
|
|
39
|
-
* By default, the timeout for this Lambda is 30 seconds. This can be overridden
|
|
46
|
+
* By default, the timeout for this Lambda is 30 seconds. This can be overridden
|
|
47
|
+
* via the `timeout` prop.
|
|
40
48
|
*
|
|
41
|
-
* By default the Lambda is granted permission to read from the SSM parameter
|
|
42
|
-
* (i.e. it can read all keys under
|
|
43
|
-
*
|
|
49
|
+
* By default the Lambda is granted permission to read from the SSM parameter
|
|
50
|
+
* store subtree specific to this Lambda (i.e. it can read all keys under
|
|
51
|
+
* `/<stage>/<stack>/<app>/`). If you need to add additional permissions, you
|
|
52
|
+
* can use
|
|
53
|
+
* [`addToRolePolicy`](`https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-lambda.FunctionBase.html#addwbrtowbrrolewbrpolicystatement`).
|
|
44
54
|
*
|
|
45
|
-
* The Lambda has `STACK`, `STAGE` and `APP` environment variables which can be
|
|
55
|
+
* The Lambda has `STACK`, `STAGE` and `APP` environment variables which can be
|
|
56
|
+
* used to determine its identity.
|
|
46
57
|
*
|
|
47
|
-
* Note that this construct creates a Lambda without an event source. Depending
|
|
48
|
-
*
|
|
58
|
+
* Note that this construct creates a Lambda without an event source. Depending
|
|
59
|
+
* on your use-case, you may wish to consider using a pattern which instantiates
|
|
60
|
+
* a Lambda with an event source e.g. [[`GuScheduledLambda`]].
|
|
49
61
|
*/
|
|
50
62
|
export declare class GuLambdaFunction extends Function {
|
|
51
63
|
readonly app: string;
|
|
52
64
|
readonly fileName: string;
|
|
53
|
-
readonly alias?: Alias;
|
|
54
65
|
constructor(scope: GuStack, id: string, props: GuFunctionProps);
|
|
55
66
|
}
|
|
56
67
|
//# sourceMappingURL=lambda.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lambda.d.ts","sourceRoot":"","sources":["../../../src/constructs/lambda/lambda.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"lambda.d.ts","sourceRoot":"","sources":["../../../src/constructs/lambda/lambda.ts"],"names":[],"mappings":"AAGA,OAAO,EAAQ,QAAQ,EAAiB,MAAM,wBAAwB,CAAC;AACvE,OAAO,KAAK,EAAE,aAAa,EAAW,MAAM,wBAAwB,CAAC;AAGrE,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,sCAAsC,EAAE,iCAAiC,EAAE,MAAM,eAAe,CAAC;AAC/G,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAiC,MAAM,SAAS,CAAC;AAGrE,MAAM,WAAW,eAAgB,SAAQ,eAAe,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,EAAE,WAAW;IAChG;;OAEG;IACH,yBAAyB,CAAC,EAAE,sCAAsC,CAAC;IACnE;;;;;;OAMG;IACH,oBAAoB,CAAC,EAAE,iCAAiC,CAAC;IACzD;;;;;;;;OAQG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAeD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,SAAgB,GAAG,EAAE,MAAM,CAAC;IAC5B,SAAgB,QAAQ,EAAE,MAAM,CAAC;gBAErB,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe;CAuD/D"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GuLambdaFunction = void 0;
|
|
4
|
+
/* eslint "@guardian/tsdoc-required/tsdoc-required": 2 -- to begin rolling this out for public APIs. */
|
|
4
5
|
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
5
6
|
const aws_lambda_1 = require("aws-cdk-lib/aws-lambda");
|
|
6
7
|
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
8
|
+
const aws_ssm_1 = require("aws-cdk-lib/aws-ssm");
|
|
7
9
|
const types_1 = require("../../types");
|
|
8
10
|
const cloudwatch_1 = require("../cloudwatch");
|
|
9
11
|
const core_1 = require("../core");
|
|
@@ -24,33 +26,46 @@ function defaultMemorySize(runtime, memorySize) {
|
|
|
24
26
|
/**
|
|
25
27
|
* Construct which creates a Lambda function.
|
|
26
28
|
*
|
|
27
|
-
* This Lambda relies on the code artifact residing in a standard location in
|
|
28
|
-
*
|
|
29
|
+
* This Lambda relies on the code artifact residing in a standard location in
|
|
30
|
+
* S3. For more details on the bucket used, see
|
|
31
|
+
* [[`GuDistributionBucketParameter`]]. By default, the path used will be
|
|
32
|
+
* `<stack>/<stage>/<app</<fileName>`. If required, e.g. if you are sharing
|
|
33
|
+
* lambda code across apps or accounts, override the source bucket using the
|
|
34
|
+
* `bucketNamePath` prop.
|
|
29
35
|
*
|
|
30
|
-
* The default memory size of this Lambda will vary depending on the runtime
|
|
31
|
-
* For Java runtimes (i.e. resource hungry Scala Lambdas!), 1024MB will
|
|
32
|
-
* the memory size defaults to 512MB. This can
|
|
36
|
+
* The default memory size of this Lambda will vary depending on the runtime
|
|
37
|
+
* chosen. For Java runtimes (i.e. resource hungry Scala Lambdas!), 1024MB will
|
|
38
|
+
* be used. For all other runtimes, the memory size defaults to 512MB. This can
|
|
39
|
+
* be overridden via the `memorySize` prop.
|
|
33
40
|
*
|
|
34
|
-
* By default, the timeout for this Lambda is 30 seconds. This can be overridden
|
|
41
|
+
* By default, the timeout for this Lambda is 30 seconds. This can be overridden
|
|
42
|
+
* via the `timeout` prop.
|
|
35
43
|
*
|
|
36
|
-
* By default the Lambda is granted permission to read from the SSM parameter
|
|
37
|
-
* (i.e. it can read all keys under
|
|
38
|
-
*
|
|
44
|
+
* By default the Lambda is granted permission to read from the SSM parameter
|
|
45
|
+
* store subtree specific to this Lambda (i.e. it can read all keys under
|
|
46
|
+
* `/<stage>/<stack>/<app>/`). If you need to add additional permissions, you
|
|
47
|
+
* can use
|
|
48
|
+
* [`addToRolePolicy`](`https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-lambda.FunctionBase.html#addwbrtowbrrolewbrpolicystatement`).
|
|
39
49
|
*
|
|
40
|
-
* The Lambda has `STACK`, `STAGE` and `APP` environment variables which can be
|
|
50
|
+
* The Lambda has `STACK`, `STAGE` and `APP` environment variables which can be
|
|
51
|
+
* used to determine its identity.
|
|
41
52
|
*
|
|
42
|
-
* Note that this construct creates a Lambda without an event source. Depending
|
|
43
|
-
*
|
|
53
|
+
* Note that this construct creates a Lambda without an event source. Depending
|
|
54
|
+
* on your use-case, you may wish to consider using a pattern which instantiates
|
|
55
|
+
* a Lambda with an event source e.g. [[`GuScheduledLambda`]].
|
|
44
56
|
*/
|
|
45
57
|
class GuLambdaFunction extends aws_lambda_1.Function {
|
|
46
58
|
constructor(scope, id, props) {
|
|
47
|
-
const { app, fileName, runtime, memorySize, timeout } = props;
|
|
59
|
+
const { app, fileName, runtime, memorySize, timeout, bucketNamePath } = props;
|
|
60
|
+
const bucketName = bucketNamePath
|
|
61
|
+
? aws_ssm_1.StringParameter.fromStringParameterName(scope, "bucketoverride", bucketNamePath).stringValue
|
|
62
|
+
: core_1.GuDistributionBucketParameter.getInstance(scope).valueAsString;
|
|
48
63
|
const defaultEnvironmentVariables = {
|
|
49
64
|
STACK: scope.stack,
|
|
50
65
|
STAGE: scope.stage,
|
|
51
66
|
APP: app,
|
|
52
67
|
};
|
|
53
|
-
const bucket = aws_s3_1.Bucket.fromBucketName(scope, `${id}-bucket`,
|
|
68
|
+
const bucket = aws_s3_1.Bucket.fromBucketName(scope, `${id}-bucket`, bucketName);
|
|
54
69
|
const objectKey = types_1.GuDistributable.getObjectKey(scope, { app }, { fileName });
|
|
55
70
|
const code = aws_lambda_1.Code.fromBucket(bucket, objectKey);
|
|
56
71
|
super(scope, id, {
|
|
@@ -65,11 +80,6 @@ class GuLambdaFunction extends aws_lambda_1.Function {
|
|
|
65
80
|
});
|
|
66
81
|
this.app = app;
|
|
67
82
|
this.fileName = fileName;
|
|
68
|
-
if (props.enableVersioning) {
|
|
69
|
-
this.alias = new aws_lambda_1.Alias(scope, `${id}-AliasForLambda`, {
|
|
70
|
-
aliasName: scope.stage, version: this.currentVersion
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
83
|
if (props.errorPercentageMonitoring) {
|
|
74
84
|
new cloudwatch_1.GuLambdaErrorPercentageAlarm(scope, `${id}-ErrorPercentageAlarmForLambda`, {
|
|
75
85
|
...props.errorPercentageMonitoring,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lambda.js","sourceRoot":"","sources":["../../../src/constructs/lambda/lambda.ts"],"names":[],"mappings":";;;AAAA,
|
|
1
|
+
{"version":3,"file":"lambda.js","sourceRoot":"","sources":["../../../src/constructs/lambda/lambda.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint \"@guardian/tsdoc-required/tsdoc-required\": 2 -- to begin rolling this out for public APIs. */\nimport { Duration } from \"aws-cdk-lib\";\nimport type { PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { Code, Function, RuntimeFamily } from \"aws-cdk-lib/aws-lambda\";\nimport type { FunctionProps, Runtime } from \"aws-cdk-lib/aws-lambda\";\nimport { Bucket } from \"aws-cdk-lib/aws-s3\";\nimport { StringParameter } from \"aws-cdk-lib/aws-ssm\";\nimport { GuDistributable } from \"../../types\";\nimport { GuLambdaErrorPercentageAlarm, GuLambdaThrottlingAlarm } from \"../cloudwatch\";\nimport type { GuLambdaErrorPercentageMonitoringProps, GuLambdaThrottlingMonitoringProps } from \"../cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity, GuDistributionBucketParameter } from \"../core\";\nimport { ReadParametersByName, ReadParametersByPath } from \"../iam\";\n\nexport interface GuFunctionProps extends GuDistributable, Omit<FunctionProps, \"code\">, AppIdentity {\n /**\n * Alarm if error percentage exceeds a threshold.\n */\n errorPercentageMonitoring?: GuLambdaErrorPercentageMonitoringProps;\n /**\n * Alarm if throttling occurs. Note, it is also worth considering a\n * concurrency limit (the `reservedConcurrentExecutions` prop) if you are\n * concerned about throttling.\n *\n * @see https://docs.aws.amazon.com/lambda/latest/dg/concurrent-executions.html\n */\n throttlingMonitoring?: GuLambdaThrottlingMonitoringProps;\n /**\n * SSM parameter for the S3 bucket that contains your lambda file.\n *\n * Typically you should not override this but you may need to if, for example,\n * you are referencing a file that is shared across many apps and/or AWS\n * accounts.\n *\n * @defaultValue [[`GuDistributionBucketParameter`]]\n */\n bucketNamePath?: string;\n}\n\nfunction defaultMemorySize(runtime: Runtime, memorySize?: number): number {\n if (memorySize) {\n return memorySize;\n } else {\n switch (runtime.family) {\n case RuntimeFamily.JAVA:\n return 1024;\n default:\n return 512;\n }\n }\n}\n\n/**\n * Construct which creates a Lambda function.\n *\n * This Lambda relies on the code artifact residing in a standard location in\n * S3. For more details on the bucket used, see\n * [[`GuDistributionBucketParameter`]]. By default, the path used will be\n * `<stack>/<stage>/<app</<fileName>`. If required, e.g. if you are sharing\n * lambda code across apps or accounts, override the source bucket using the\n * `bucketNamePath` prop.\n *\n * The default memory size of this Lambda will vary depending on the runtime\n * chosen. For Java runtimes (i.e. resource hungry Scala Lambdas!), 1024MB will\n * be used. For all other runtimes, the memory size defaults to 512MB. This can\n * be overridden via the `memorySize` prop.\n *\n * By default, the timeout for this Lambda is 30 seconds. This can be overridden\n * via the `timeout` prop.\n *\n * By default the Lambda is granted permission to read from the SSM parameter\n * store subtree specific to this Lambda (i.e. it can read all keys under\n * `/<stage>/<stack>/<app>/`). If you need to add additional permissions, you\n * can use\n * [`addToRolePolicy`](`https://docs.aws.amazon.com/cdk/api/v1/docs/@aws-cdk_aws-lambda.FunctionBase.html#addwbrtowbrrolewbrpolicystatement`).\n *\n * The Lambda has `STACK`, `STAGE` and `APP` environment variables which can be\n * used to determine its identity.\n *\n * Note that this construct creates a Lambda without an event source. Depending\n * on your use-case, you may wish to consider using a pattern which instantiates\n * a Lambda with an event source e.g. [[`GuScheduledLambda`]].\n */\nexport class GuLambdaFunction extends Function {\n public readonly app: string;\n public readonly fileName: string;\n\n constructor(scope: GuStack, id: string, props: GuFunctionProps) {\n const { app, fileName, runtime, memorySize, timeout, bucketNamePath } = props;\n\n const bucketName = bucketNamePath\n ? StringParameter.fromStringParameterName(scope, \"bucketoverride\", bucketNamePath).stringValue\n : GuDistributionBucketParameter.getInstance(scope).valueAsString;\n\n const defaultEnvironmentVariables = {\n STACK: scope.stack,\n STAGE: scope.stage,\n APP: app,\n };\n\n const bucket = Bucket.fromBucketName(scope, `${id}-bucket`, bucketName);\n const objectKey = GuDistributable.getObjectKey(scope, { app }, { fileName });\n const code = Code.fromBucket(bucket, objectKey);\n super(scope, id, {\n ...props,\n environment: {\n ...props.environment,\n ...defaultEnvironmentVariables,\n },\n memorySize: defaultMemorySize(runtime, memorySize),\n timeout: timeout ?? Duration.seconds(30),\n code,\n });\n\n this.app = app;\n this.fileName = fileName;\n\n if (props.errorPercentageMonitoring) {\n new GuLambdaErrorPercentageAlarm(scope, `${id}-ErrorPercentageAlarmForLambda`, {\n ...props.errorPercentageMonitoring,\n lambda: this,\n });\n }\n\n if (props.throttlingMonitoring) {\n new GuLambdaThrottlingAlarm(scope, `${id}-ThrottlingAlarmForLambda`, {\n ...props.throttlingMonitoring,\n lambda: this,\n });\n }\n\n bucket.grantRead(this, objectKey);\n\n const ssmParamReadPolicies: PolicyStatement[] = [\n new ReadParametersByPath(scope, props),\n new ReadParametersByName(scope, props),\n ];\n\n ssmParamReadPolicies.map((policy) => this.addToRolePolicy(policy));\n\n AppIdentity.taggedConstruct(props, this);\n }\n}\n"]}
|
|
@@ -28,7 +28,7 @@ export declare class GuApplicationListener extends GuApplicationListener_base {
|
|
|
28
28
|
}
|
|
29
29
|
export interface GuHttpsApplicationListenerProps extends Omit<GuApplicationListenerProps, "defaultAction" | "certificates">, AppIdentity {
|
|
30
30
|
targetGroup: GuApplicationTargetGroup;
|
|
31
|
-
certificate
|
|
31
|
+
certificate?: GuCertificate;
|
|
32
32
|
}
|
|
33
33
|
declare const GuHttpsApplicationListener_base: {
|
|
34
34
|
new (...args: any[]): {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"application-listener.d.ts","sourceRoot":"","sources":["../../../../src/constructs/loadbalancing/alb/application-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAuC,MAAM,wCAAwC,CAAC;AAClH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAEvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAE3E,MAAM,WAAW,0BAA2B,SAAQ,wBAAwB,EAAE,WAAW;CAAG;;;;;;AAE5F;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAsB,SAAQ,0BAAwC;gBACrE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,0BAA0B;CAG1E;AAED,MAAM,WAAW,+BACf,SAAQ,IAAI,CAAC,0BAA0B,EAAE,eAAe,GAAG,cAAc,CAAC,EACxE,WAAW;IACb,WAAW,EAAE,wBAAwB,CAAC;IACtC,WAAW,EAAE,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"application-listener.d.ts","sourceRoot":"","sources":["../../../../src/constructs/loadbalancing/alb/application-listener.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAuC,MAAM,wCAAwC,CAAC;AAClH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,wCAAwC,CAAC;AAEvF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAE3E,MAAM,WAAW,0BAA2B,SAAQ,wBAAwB,EAAE,WAAW;CAAG;;;;;;AAE5F;;;;;;;;;;;;GAYG;AACH,qBAAa,qBAAsB,SAAQ,0BAAwC;gBACrE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,0BAA0B;CAG1E;AAED,MAAM,WAAW,+BACf,SAAQ,IAAI,CAAC,0BAA0B,EAAE,eAAe,GAAG,cAAc,CAAC,EACxE,WAAW;IACb,WAAW,EAAE,wBAAwB,CAAC;IACtC,WAAW,CAAC,EAAE,aAAa,CAAC;CAC7B;;;;;;AAED;;;;;;GAMG;AACH,qBAAa,0BAA2B,SAAQ,+BAAwC;gBAC1E,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,+BAA+B;CAmB/E"}
|
|
@@ -33,14 +33,16 @@ class GuHttpsApplicationListener extends (0, app_aware_construct_1.GuAppAwareCon
|
|
|
33
33
|
constructor(scope, id, props) {
|
|
34
34
|
const { certificate, targetGroup } = props;
|
|
35
35
|
const mergedProps = {
|
|
36
|
-
port: 443,
|
|
37
|
-
protocol: aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTPS,
|
|
36
|
+
port: certificate ? 443 : 8080,
|
|
37
|
+
protocol: certificate ? aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTPS : aws_elasticloadbalancingv2_1.ApplicationProtocol.HTTP,
|
|
38
38
|
...props,
|
|
39
|
-
certificates:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
39
|
+
certificates: certificate
|
|
40
|
+
? [
|
|
41
|
+
{
|
|
42
|
+
certificateArn: certificate.certificateArn,
|
|
43
|
+
},
|
|
44
|
+
]
|
|
45
|
+
: [],
|
|
44
46
|
defaultAction: aws_elasticloadbalancingv2_1.ListenerAction.forward([targetGroup]),
|
|
45
47
|
};
|
|
46
48
|
super(scope, id, mergedProps);
|