@guardian/cdk 59.5.5 → 60.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/constructs/ec2/vpc.d.ts +1 -0
- package/lib/constructs/ec2/vpc.d.ts.map +1 -1
- package/lib/constructs/ec2/vpc.js +22 -2
- package/lib/constructs/ec2/vpc.js.map +1 -1
- package/lib/constructs/ecs/ecs-task.d.ts +6 -1
- package/lib/constructs/ecs/ecs-task.d.ts.map +1 -1
- package/lib/constructs/ecs/ecs-task.js +7 -1
- package/lib/constructs/ecs/ecs-task.js.map +1 -1
- package/package.json +10 -10
|
@@ -18,6 +18,7 @@ export declare const maybeApp: (props?: {
|
|
|
18
18
|
export declare class GuVpc {
|
|
19
19
|
static subnets(scope: GuStack, subnets: string[]): ISubnet[];
|
|
20
20
|
static subnetsFromParameter(scope: GuStack, props?: GuSubnetProps): ISubnet[];
|
|
21
|
+
static subnetsFromParameterFixedNumber(scope: GuStack, props?: GuSubnetProps, numSubnets?: number): ISubnet[];
|
|
21
22
|
static fromId(scope: GuStack, id: string, props: VpcFromIdProps): IVpc;
|
|
22
23
|
static fromIdParameter(scope: GuStack, id: string, props?: VpcFromIdParameterProps): IVpc;
|
|
23
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vpc.d.ts","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"vpc.d.ts","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGxE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC,UAAU,cAAe,SAAQ,IAAI,CAAC,aAAa,EAAE,mBAAmB,CAAC;IACvE,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,KAAK,uBAAuB,GAAG,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;AAG7D,oBAAY,UAAU;IACpB,MAAM,WAAW;IACjB,OAAO,YAAY;CACpB;AAGD,MAAM,WAAW,aAAa;IAC5B,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAMD,eAAO,MAAM,QAAQ,WAAY;IAAE,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,KAAG,MAA0B,CAAC;AAE/E,qBAAa,KAAK;IAChB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE;IAkB5D,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,aAAa,GAAG,OAAO,EAAE;IAgB7E,MAAM,CAAC,+BAA+B,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,aAAa,EAAE,UAAU,GAAE,MAAU,GAAG,OAAO,EAAE;IAoBhH,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,GAAG,IAAI;IAOtE,MAAM,CAAC,eAAe,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,uBAAuB,GAAG,IAAI;CAI1F"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.GuVpc = exports.maybeApp = exports.SubnetType = void 0;
|
|
4
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
4
5
|
const aws_ec2_1 = require("aws-cdk-lib/aws-ec2");
|
|
6
|
+
const constants_1 = require("../../constants");
|
|
5
7
|
const core_1 = require("../core");
|
|
6
8
|
// TODO convert to boolean
|
|
7
9
|
var SubnetType;
|
|
@@ -33,14 +35,32 @@ class GuVpc {
|
|
|
33
35
|
}
|
|
34
36
|
static subnetsFromParameter(scope, props) {
|
|
35
37
|
const type = props?.type ?? SubnetType.PRIVATE;
|
|
38
|
+
const parameterDefault = type === SubnetType.PRIVATE
|
|
39
|
+
? constants_1.NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets
|
|
40
|
+
: constants_1.NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets;
|
|
36
41
|
const subnets = new core_1.GuSubnetListParameter(scope, `${(0, exports.maybeApp)(props)}${type}Subnets`, {
|
|
37
42
|
description: `A list of ${type.toLowerCase()} subnets`,
|
|
38
|
-
|
|
39
|
-
default: `/account/vpc/primary/subnets/${type.toLowerCase()}`,
|
|
43
|
+
default: parameterDefault.path,
|
|
40
44
|
fromSSM: true,
|
|
41
45
|
});
|
|
42
46
|
return GuVpc.subnets(scope, subnets.valueAsList);
|
|
43
47
|
}
|
|
48
|
+
static subnetsFromParameterFixedNumber(scope, props, numSubnets = 3) {
|
|
49
|
+
const type = props?.type ?? SubnetType.PRIVATE;
|
|
50
|
+
const parameterDefault = type === SubnetType.PRIVATE
|
|
51
|
+
? constants_1.NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets
|
|
52
|
+
: constants_1.NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets;
|
|
53
|
+
const subnets = new core_1.GuSubnetListParameter(scope, `${(0, exports.maybeApp)(props)}${type}Subnets`, {
|
|
54
|
+
description: `A list of ${type.toLowerCase()} subnets`,
|
|
55
|
+
default: parameterDefault.path,
|
|
56
|
+
fromSSM: true,
|
|
57
|
+
});
|
|
58
|
+
const subnetIds = [];
|
|
59
|
+
for (let i = 0; i < numSubnets; i++) {
|
|
60
|
+
subnetIds.push(aws_cdk_lib_1.Fn.select(i, subnets.valueAsList));
|
|
61
|
+
}
|
|
62
|
+
return subnetIds.map((subnetId) => aws_ec2_1.Subnet.fromSubnetId(scope, `subnet-${subnetId}`, subnetId));
|
|
63
|
+
}
|
|
44
64
|
static fromId(scope, id, props) {
|
|
45
65
|
return aws_ec2_1.Vpc.fromVpcAttributes(scope, id, {
|
|
46
66
|
availabilityZones: scope.availabilityZones,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vpc.js","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":";;;AAAA,iDAAkD;AAElD,kCAAgE;AAShE,0BAA0B;AAC1B,IAAY,UAGX;AAHD,WAAY,UAAU;IACpB,+BAAiB,CAAA;IACjB,iCAAmB,CAAA;AACrB,CAAC,EAHW,UAAU,0BAAV,UAAU,QAGrB;AAQD;;;GAGG;AACI,MAAM,QAAQ,GAAG,CAAC,KAAwB,EAAU,EAAE,CAAC,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC;AAAlE,QAAA,QAAQ,YAA0D;AAE/E,MAAa,KAAK;IAChB,MAAM,CAAC,OAAO,CAAC,KAAc,EAAE,OAAiB;QAC9C;;;;;;;;;;;WAWG;QACH,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAC9B,gBAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,UAAU,QAAQ,EAAE,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAC1F,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,oBAAoB,CAAC,KAAc,EAAE,KAAqB;QAC/D,MAAM,IAAI,GAAG,KAAK,EAAE,IAAI,IAAI,UAAU,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"vpc.js","sourceRoot":"","sources":["../../../src/constructs/ec2/vpc.ts"],"names":[],"mappings":"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","sourcesContent":["import { Fn } from \"aws-cdk-lib\";\nimport { Subnet, Vpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { ISubnet, IVpc, VpcAttributes } from \"aws-cdk-lib/aws-ec2\";\nimport { NAMED_SSM_PARAMETER_PATHS } from \"../../constants\";\nimport { GuSubnetListParameter, GuVpcParameter } from \"../core\";\nimport type { GuStack } from \"../core\";\n\ninterface VpcFromIdProps extends Omit<VpcAttributes, \"availabilityZones\"> {\n availabilityZones?: string[];\n}\n\ntype VpcFromIdParameterProps = Omit<VpcFromIdProps, \"vpcId\">;\n\n// TODO convert to boolean\nexport enum SubnetType {\n PUBLIC = \"Public\",\n PRIVATE = \"Private\",\n}\n\n// TODO: Migrate this to use `AppIdentity`\nexport interface GuSubnetProps {\n type?: SubnetType;\n app?: string;\n}\n\n/*\n * Some stacks maybe have multiple patterns (such as `GuEc2App`), therefore creating multiple VPC and subnet resources.\n * This function ensures that, where desired, we can have unique IDs for each VPC and subnet declaration\n */\nexport const maybeApp = (props?: { app?: string }): string => props?.app ?? \"\";\n\nexport class GuVpc {\n static subnets(scope: GuStack, subnets: string[]): ISubnet[] {\n /**\n * As of ~1.77.0 of the aws/cdk, this line\n * [ previously Subnet.fromSubnetId(scope, `subnet-${subnetId}`, subnetId)) ]\n * resulted in the following error\n * \"Found an encoded list token string in a scalar string context. Use 'Fn.select(0, list)' (not 'list[0]') to extract elements from token lists.\"\n * See https://github.com/aws/aws-cdk/issues/11945 for more information\n *\n * As a hacky workaround, we have moved to using the fromSubnetAttributes method and hardcoded an empty value\n * for the routeTableId prop. This prevents the error and, when tested on existing stacks, results in no change to the CFN output\n *\n * TODO: Understand VPCs and Subnets better and develop a better solution to this problem\n */\n return subnets.map((subnetId) =>\n Subnet.fromSubnetAttributes(scope, `subnet-${subnetId}`, { subnetId, routeTableId: \" \" }),\n );\n }\n\n static subnetsFromParameter(scope: GuStack, props?: GuSubnetProps): ISubnet[] {\n const type = props?.type ?? SubnetType.PRIVATE;\n const parameterDefault =\n type === SubnetType.PRIVATE\n ? NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets\n : NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets;\n\n const subnets = new GuSubnetListParameter(scope, `${maybeApp(props)}${type}Subnets`, {\n description: `A list of ${type.toLowerCase()} subnets`,\n default: parameterDefault.path,\n fromSSM: true,\n });\n\n return GuVpc.subnets(scope, subnets.valueAsList);\n }\n\n static subnetsFromParameterFixedNumber(scope: GuStack, props?: GuSubnetProps, numSubnets: number = 3): ISubnet[] {\n const type = props?.type ?? SubnetType.PRIVATE;\n const parameterDefault =\n type === SubnetType.PRIVATE\n ? NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPrivateSubnets\n : NAMED_SSM_PARAMETER_PATHS.PrimaryVpcPublicSubnets;\n\n const subnets = new GuSubnetListParameter(scope, `${maybeApp(props)}${type}Subnets`, {\n description: `A list of ${type.toLowerCase()} subnets`,\n default: parameterDefault.path,\n fromSSM: true,\n });\n\n const subnetIds: string[] = [];\n for (let i = 0; i < numSubnets; i++) {\n subnetIds.push(Fn.select(i, subnets.valueAsList));\n }\n return subnetIds.map((subnetId) => Subnet.fromSubnetId(scope, `subnet-${subnetId}`, subnetId));\n }\n\n static fromId(scope: GuStack, id: string, props: VpcFromIdProps): IVpc {\n return Vpc.fromVpcAttributes(scope, id, {\n availabilityZones: scope.availabilityZones,\n ...props,\n });\n }\n\n static fromIdParameter(scope: GuStack, id: string, props?: VpcFromIdParameterProps): IVpc {\n const vpc = GuVpcParameter.getInstance(scope);\n return GuVpc.fromId(scope, id, { ...props, vpcId: vpc.valueAsString });\n }\n}\n"]}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ISecurityGroup, IVpc } from "aws-cdk-lib/aws-ec2";
|
|
1
|
+
import type { ISecurityGroup, ISubnet, IVpc } from "aws-cdk-lib/aws-ec2";
|
|
2
2
|
import type { IRepository } from "aws-cdk-lib/aws-ecr";
|
|
3
3
|
import type { RepositoryImageProps } from "aws-cdk-lib/aws-ecs";
|
|
4
4
|
import type { PolicyStatement } from "aws-cdk-lib/aws-iam";
|
|
@@ -48,6 +48,9 @@ export type GuEcsTaskMonitoringProps = {
|
|
|
48
48
|
/**
|
|
49
49
|
* Configuration options for the [[`GuEcsTask`]] pattern.
|
|
50
50
|
*
|
|
51
|
+
* Note it is recommended to use GuVpc.subnetsFromParameterFixedNumber for the subnets prop rather than
|
|
52
|
+
* GuVpc.subnetsFromParameter, as using the latter can result a custom resource being required
|
|
53
|
+
*
|
|
51
54
|
* See [[`ContainerConfiguration`]] for details of how to configure the container used to run the task.
|
|
52
55
|
*
|
|
53
56
|
* `taskTimeoutInMinutes` does what is says on the tin. The default timeout is 15 minutes.
|
|
@@ -87,6 +90,8 @@ export type GuEcsTaskMonitoringProps = {
|
|
|
87
90
|
*/
|
|
88
91
|
export interface GuEcsTaskProps extends AppIdentity {
|
|
89
92
|
vpc: IVpc;
|
|
93
|
+
subnets: ISubnet[];
|
|
94
|
+
assignPublicIp?: boolean;
|
|
90
95
|
containerConfiguration: ContainerConfiguration;
|
|
91
96
|
taskTimeoutInMinutes?: number;
|
|
92
97
|
cpu?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ecs-task.d.ts","sourceRoot":"","sources":["../../../src/constructs/ecs/ecs-task.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"ecs-task.d.ts","sourceRoot":"","sources":["../../../src/constructs/ecs/ecs-task.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AACzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAWhE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,OAAO,EAAgD,YAAY,EAAW,MAAM,+BAA+B,CAAC;AACpH,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qCAAqC,CAAC;AAEnF,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,WAAW,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,YAAY,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,IAAI,EAAE,UAAU,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC;AAE7E,MAAM,MAAM,wBAAwB,GAAG;IAAE,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,KAAK,CAAA;CAAE,CAAC;AAEpF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,MAAM,WAAW,cAAe,SAAQ,WAAW;IACjD,GAAG,EAAE,IAAI,CAAC;IACV,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,sBAAsB,EAAE,sBAAsB,CAAC;IAC/C,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,YAAY,GAAG,wBAAwB,CAAC;IACjE,cAAc,CAAC,EAAE,cAAc,EAAE,CAAC;IAClC,kBAAkB,CAAC,EAAE,eAAe,EAAE,CAAC;IACvC,oBAAoB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IACjD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAcD;;;;;;;;;;GAUG;AACH,qBAAa,SAAU,SAAQ,SAAS;IACtC,YAAY,EAAE,YAAY,CAAC;gBAEf,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc;CA+I9D"}
|
|
@@ -42,7 +42,7 @@ class GuEcsTask extends constructs_1.Construct {
|
|
|
42
42
|
cpu = 2048, // 2 cores and from 4-16GB memory
|
|
43
43
|
memory = 4096, // 4GB
|
|
44
44
|
storage, // default is 20 GB when not provided in props
|
|
45
|
-
containerConfiguration, taskCommand, taskTimeoutInMinutes = 15, customTaskPolicies, vpc, monitoringConfiguration, securityGroups = [], environmentOverrides, enableDistributablePolicy = true, readonlyRootFilesystem = false, containerInsights = false, } = props;
|
|
45
|
+
containerConfiguration, taskCommand, taskTimeoutInMinutes = 15, customTaskPolicies, vpc, subnets, monitoringConfiguration, securityGroups = [], environmentOverrides, enableDistributablePolicy = true, readonlyRootFilesystem = false, containerInsights = false, } = props;
|
|
46
46
|
if (storage && storage < 21) {
|
|
47
47
|
throw new Error("Storage must be at least 21. See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-ephemeralstorage.html");
|
|
48
48
|
}
|
|
@@ -59,6 +59,10 @@ class GuEcsTask extends constructs_1.Construct {
|
|
|
59
59
|
memoryMiB: memory.toString(),
|
|
60
60
|
family: `${stack}-${stage}-${app}`,
|
|
61
61
|
ephemeralStorageGiB: storage,
|
|
62
|
+
runtimePlatform: {
|
|
63
|
+
cpuArchitecture: aws_ecs_1.CpuArchitecture.ARM64,
|
|
64
|
+
operatingSystemFamily: aws_ecs_1.OperatingSystemFamily.of("LINUX"),
|
|
65
|
+
},
|
|
62
66
|
});
|
|
63
67
|
const containerDefinition = taskDefinition.addContainer(`${id}-TaskContainer`, {
|
|
64
68
|
image: getContainer(containerConfiguration),
|
|
@@ -83,6 +87,8 @@ class GuEcsTask extends constructs_1.Construct {
|
|
|
83
87
|
platformVersion: aws_ecs_1.FargatePlatformVersion.LATEST,
|
|
84
88
|
}),
|
|
85
89
|
taskDefinition,
|
|
90
|
+
subnets: { subnets },
|
|
91
|
+
assignPublicIp: false,
|
|
86
92
|
integrationPattern: aws_stepfunctions_1.IntegrationPattern.RUN_JOB,
|
|
87
93
|
resultPath: aws_stepfunctions_1.JsonPath.DISCARD,
|
|
88
94
|
taskTimeout: aws_stepfunctions_1.Timeout.duration(aws_cdk_lib_1.Duration.minutes(taskTimeoutInMinutes)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ecs-task.js","sourceRoot":"","sources":["../../../src/constructs/ecs/ecs-task.ts"],"names":[],"mappings":";;;AAAA,6CAAkD;AAClD,+DAAqE;AACrE,+EAA+D;AAI/D,iDAO6B;AAE7B,iDAA4C;AAC5C,qEAAoH;AAEpH,iFAAyF;AACzF,2CAAuC;AAGvC,kCAAsC;AACtC,gCAA2D;AAgH3D;;;GAGG;AACH,MAAM,YAAY,GAAG,CAAC,MAA8B,EAAE,EAAE;IACtD,IAAI,MAAM,CAAC,IAAI,IAAI,YAAY,EAAE;QAC/B,OAAO,wBAAc,CAAC,iBAAiB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;KAC5E;SAAM;QACL,OAAO,wBAAc,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,IAAI,cAAc,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;KACpF;AACH,CAAC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAa,SAAU,SAAQ,sBAAS;IAGtC,YAAY,KAAc,EAAE,EAAU,EAAE,KAAqB;QAC3D,KAAK,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAEjB,MAAM,EACJ,GAAG;QAEH,iJAAiJ;QACjJ,GAAG,GAAG,IAAI,EAAE,iCAAiC;QAC7C,MAAM,GAAG,IAAI,EAAE,MAAM;QACrB,OAAO,EAAE,8CAA8C;QACvD,sBAAsB,EACtB,WAAW,EACX,oBAAoB,GAAG,EAAE,EACzB,kBAAkB,EAClB,GAAG,EACH,uBAAuB,EACvB,cAAc,GAAG,EAAE,EACnB,oBAAoB,EACpB,yBAAyB,GAAG,IAAI,EAChC,sBAAsB,GAAG,KAAK,EAC9B,iBAAiB,GAAG,KAAK,GAC1B,GAAG,KAAK,CAAC;QAEV,IAAI,OAAO,IAAI,OAAO,GAAG,EAAE,EAAE;YAC3B,MAAM,IAAI,KAAK,CACb,yJAAyJ,CAC1J,CAAC;SACH;QAED,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;QAE/B,MAAM,OAAO,GAAG,IAAI,iBAAO,CAAC,KAAK,EAAE,GAAG,EAAE,UAAU,EAAE;YAClD,WAAW,EAAE,GAAG,GAAG,YAAY,KAAK,EAAE;YACtC,8BAA8B,EAAE,IAAI;YACpC,GAAG;YACH,iBAAiB;SAClB,CAAC,CAAC;QAEH,MAAM,cAAc,GAAG,IAAI,wBAAc,CAAC,KAAK,EAAE,GAAG,EAAE,iBAAiB,EAAE;YACvE,aAAa,EAAE,uBAAa,CAAC,OAAO;YACpC,GAAG,EAAE,GAAG,CAAC,QAAQ,EAAE;YACnB,SAAS,EAAE,MAAM,CAAC,QAAQ,EAAE;YAC5B,MAAM,EAAE,GAAG,KAAK,IAAI,KAAK,IAAI,GAAG,EAAE;YAClC,mBAAmB,EAAE,OAAO;SAC7B,CAAC,CAAC;QAEH,MAAM,mBAAmB,GAAG,cAAc,CAAC,YAAY,CAAC,GAAG,EAAE,gBAAgB,EAAE;YAC7E,KAAK,EAAE,YAAY,CAAC,sBAAsB,CAAC;YAC3C,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS;YACjD,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS;YACtD,GAAG;YACH,cAAc,EAAE,MAAM;YACtB,OAAO,EAAE,oBAAU,CAAC,OAAO,CAAC;gBAC1B,YAAY,EAAE,GAAG;gBACjB,YAAY,EAAE,EAAE;aACjB,CAAC;YACF,sBAAsB;SACvB,CAAC,CAAC;QAEH,IAAI,yBAAyB,EAAE;YAC7B,MAAM,UAAU,GAAG,IAAI,uCAAiC,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;YACzE,cAAc,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;SAChD;QAED,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;QAEjF,MAAM,IAAI,GAAG,IAAI,oCAAU,CAAC,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE;YAC/C,OAAO;YACP,YAAY,EAAE,IAAI,gDAAsB,CAAC;gBACvC,eAAe,EAAE,gCAAsB,CAAC,MAAM;aAC/C,CAAC;YACF,cAAc;YACd,kBAAkB,EAAE,sCAAkB,CAAC,OAAO;YAC9C,UAAU,EAAE,4BAAQ,CAAC,OAAO;YAC5B,WAAW,EAAE,2BAAO,CAAC,QAAQ,CAAC,sBAAQ,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;YACrE,cAAc;YACd,kBAAkB,EAAE;gBAClB;oBACE,mBAAmB,EAAE,mBAAmB;oBACxC,WAAW,EAAE,oBAAoB;iBAClC;aACF;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,YAAY,GAAG,IAAI,gCAAY,CAAC,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE;YAChE,cAAc,EAAE,kCAAc,CAAC,aAAa,CAAC,IAAI,CAAC;YAClD,gBAAgB,EAAE,GAAG,GAAG,IAAI,KAAK,EAAE;SACpC,CAAC,CAAC;QAEH,IAAI,CAAC,uBAAuB,CAAC,YAAY,EAAE;YACzC,MAAM,UAAU,GAAG,eAAK,CAAC,YAAY,CACnC,KAAK,EACL,kBAAW,CAAC,UAAU,CAAC,KAAK,EAAE,YAAY,CAAC,EAC3C,uBAAuB,CAAC,WAAW,CACpC,CAAC;YACF,MAAM,MAAM,GAAG;gBACb;oBACE,IAAI,EAAE,GAAG,GAAG,mBAAmB;oBAC/B,WAAW,EAAE,GAAG,GAAG,IAAI,KAAK,cAAc;oBAC1C,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC;wBACrC,MAAM,EAAE,sBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;wBACzB,SAAS,EAAE,KAAK;qBACjB,CAAC;iBACH;gBACD;oBACE,IAAI,EAAE,GAAG,GAAG,UAAU;oBACtB,WAAW,EAAE,GAAG,GAAG,IAAI,KAAK,iBAAiB;oBAC7C,MAAM,EAAE,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC;wBACvC,MAAM,EAAE,sBAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;wBACzB,SAAS,EAAE,KAAK;qBACjB,CAAC;iBACH;aACF,CAAC;YAEF,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,EAAE;gBAC/C,MAAM,KAAK,GAAG,IAAI,sBAAK,CAAC,KAAK,EAAE,IAAI,EAAE;oBACnC,gBAAgB,EAAE,WAAW;oBAC7B,cAAc,EAAE,IAAI;oBACpB,MAAM,EAAE,MAAM;oBACd,kEAAkE;oBAClE,SAAS,EAAE,CAAC;oBACZ,iBAAiB,EAAE,CAAC;oBACpB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;iBACjD,CAAC,CAAC;gBACH,KAAK,CAAC,cAAc,CAAC,IAAI,kCAAS,CAAC,UAAU,CAAC,CAAC,CAAC;gBAChD,kBAAW,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC;SACJ;QAED,0CAA0C;QAC1C,CAAC,OAAO,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,kBAAW,CAAC,eAAe,CAAC,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QAE3G,IAAI,uBAAS,CAAC,KAAK,EAAE,GAAG,EAAE,wBAAwB,EAAE;YAClD,KAAK,EAAE,IAAI,CAAC,YAAY,CAAC,eAAe;SACzC,CAAC,CAAC;IACL,CAAC;CACF;AA3ID,8BA2IC","sourcesContent":["import { CfnOutput, Duration } from \"aws-cdk-lib\";\nimport { Alarm, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { SnsAction } from \"aws-cdk-lib/aws-cloudwatch-actions\";\nimport type { ISecurityGroup, IVpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { IRepository } from \"aws-cdk-lib/aws-ecr\";\nimport type { RepositoryImageProps } from \"aws-cdk-lib/aws-ecs\";\nimport {\n Cluster,\n Compatibility,\n ContainerImage,\n FargatePlatformVersion,\n LogDrivers,\n TaskDefinition,\n} from \"aws-cdk-lib/aws-ecs\";\nimport type { PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { Topic } from \"aws-cdk-lib/aws-sns\";\nimport { DefinitionBody, IntegrationPattern, JsonPath, StateMachine, Timeout } from \"aws-cdk-lib/aws-stepfunctions\";\nimport type { TaskEnvironmentVariable } from \"aws-cdk-lib/aws-stepfunctions-tasks\";\nimport { EcsFargateLaunchTarget, EcsRunTask } from \"aws-cdk-lib/aws-stepfunctions-tasks\";\nimport { Construct } from \"constructs\";\nimport type { NoMonitoring } from \"../cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport { GuGetDistributablePolicyStatement } from \"../iam\";\n\n/**\n * Configuration to determine what container to use for the task\n * For example, to run the task in the latest node container:\n *\n * ```typescript\n * const containerConfiguration = {\n * id: 'node:latest'\n * }\n * ```\n *\n * Alternatively you can specify a repository and version, for example for an ECR repository:\n * ```typescript\n * import { Repository } from \"aws-cdk-lib/aws-ecr\";\n * const repository = new Repository(scope, `${app}-repository`, {\n repositoryName: app,\n });\n * const containerConfiguration = {\n * repository: Repository.fromRepositoryArn(\"<repository arn>\"),\n * version: '1'\n * }\n * ```\n */\n\nexport type RepositoryContainer = {\n repository: IRepository;\n version: string;\n type: \"repository\";\n};\n\nexport type RegistryContainer = {\n id?: string;\n imageProps?: RepositoryImageProps;\n type: \"registry\";\n};\n\nexport type ContainerConfiguration = RepositoryContainer | RegistryContainer;\n\nexport type GuEcsTaskMonitoringProps = { snsTopicArn: string; noMonitoring: false };\n\n/**\n * Configuration options for the [[`GuEcsTask`]] pattern.\n *\n * See [[`ContainerConfiguration`]] for details of how to configure the container used to run the task.\n *\n * `taskTimeoutInMinutes` does what is says on the tin. The default timeout is 15 minutes.\n *\n * The `taskCommand` prop allows you to specify a command to run when the task starts (this can also be done via a CMD statement in\n * your Dockerfile). For example:\n *\n * const props = {\n * //other props\n * taskCommand: `aws s3 cp s3://${distbucket}/${stack}/${stage}/${app}/task.sh . && ./task.sh\n }\n *\n * It is advisable to configure alarms for when the job fails/times out. To do this specify the alarmSnsTopicArn prop.\n *\n * `customTaskPolicies` allows your task to interact with other AWS services. By default a task\n * will have read access to the distribution bucket for your account.\n *\n * You can specify security groups to apply to task using the `securityGroups` prop.\n *\n * You can also set the memory and cpu units for your task. See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size\n * for further details.\n *\n * If you want to pass input from the step function into your EcsTask you can do so via the `environmentOverrides` prop, which allows you to wire up\n * step function input JSON to environment variables set on the container. For example,\n * const props = {\n * ...otherProps\n * environmentOverrides: [\n {\n name: \"VERSION\",\n value: JsonPath.stringAt(\"$.version\"),\n },\n }\n * With the above override, your task will attempt to find a `version` property in the JSON input passed to the step function, and apply it to the\n * VERSION environment variable. Alternatively, you could hard code a value for the variable in CDK.\n * See https://docs.aws.amazon.com/step-functions/latest/dg/connect-ecs.html for further detail and other override options - this construct currently\n * only supports environment variables.\n */\nexport interface GuEcsTaskProps extends AppIdentity {\n vpc: IVpc;\n containerConfiguration: ContainerConfiguration;\n taskTimeoutInMinutes?: number;\n cpu?: number;\n memory?: number;\n taskCommand?: string;\n monitoringConfiguration: NoMonitoring | GuEcsTaskMonitoringProps;\n securityGroups?: ISecurityGroup[];\n customTaskPolicies?: PolicyStatement[];\n environmentOverrides?: TaskEnvironmentVariable[];\n storage?: number;\n /**\n * Whether to give the task IAM role access to the account's dist bucket.\n * This is enabled by default to avoid breaking changes, but consumers of this pattern\n * that pull a container image that doesn't need extra dependencies from S3\n * shoud set this value to `false`.\n */\n enableDistributablePolicy?: boolean;\n /**\n * When this parameter is true, the container is given read-only access to its root file system.\n * @default false\n */\n readonlyRootFilesystem?: boolean;\n /**\n * If `true`, CloudWatch Container Insights will be enabled for the cluster\n * @default false\n */\n containerInsights?: boolean;\n}\n\n/**\n * Containers can be specified either via a repository and version or by container id (in which case it will\n * be fetched from docker hub).\n */\nconst getContainer = (config: ContainerConfiguration) => {\n if (config.type == \"repository\") {\n return ContainerImage.fromEcrRepository(config.repository, config.version);\n } else {\n return ContainerImage.fromRegistry(config.id ?? \"ubuntu:jammy\", config.imageProps);\n }\n};\n\n/**\n * Pattern which creates all of the resources needed for a fargate task\n *\n * The task will be wrapped in a step function to allow for easier triggering and alarming on failure.\n *\n * For all configuration options, see [[`GuEcsTaskProps`]].\n *\n * Note that if your task reliably completes in less than 15 minutes then you should probably use a [[`GuLambda`]] instead. This\n * pattern was mainly created to work around the 15 minute lambda timeout.\n *\n */\nexport class GuEcsTask extends Construct {\n stateMachine: StateMachine;\n\n constructor(scope: GuStack, id: string, props: GuEcsTaskProps) {\n super(scope, id);\n\n const {\n app,\n\n // see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-cpu for details\n cpu = 2048, // 2 cores and from 4-16GB memory\n memory = 4096, // 4GB\n storage, // default is 20 GB when not provided in props\n containerConfiguration,\n taskCommand,\n taskTimeoutInMinutes = 15,\n customTaskPolicies,\n vpc,\n monitoringConfiguration,\n securityGroups = [],\n environmentOverrides,\n enableDistributablePolicy = true,\n readonlyRootFilesystem = false,\n containerInsights = false,\n } = props;\n\n if (storage && storage < 21) {\n throw new Error(\n \"Storage must be at least 21. See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-ephemeralstorage.html\",\n );\n }\n\n const { stack, stage } = scope;\n\n const cluster = new Cluster(scope, `${id}-Cluster`, {\n clusterName: `${app}-cluster-${stage}`,\n enableFargateCapacityProviders: true,\n vpc,\n containerInsights,\n });\n\n const taskDefinition = new TaskDefinition(scope, `${id}-TaskDefinition`, {\n compatibility: Compatibility.FARGATE,\n cpu: cpu.toString(),\n memoryMiB: memory.toString(),\n family: `${stack}-${stage}-${app}`,\n ephemeralStorageGiB: storage,\n });\n\n const containerDefinition = taskDefinition.addContainer(`${id}-TaskContainer`, {\n image: getContainer(containerConfiguration),\n entryPoint: taskCommand ? [\"/bin/sh\"] : undefined,\n command: taskCommand ? [\"-c\", taskCommand] : undefined, // if unset, falls back to CMD in docker file, or no command will be run\n cpu,\n memoryLimitMiB: memory,\n logging: LogDrivers.awsLogs({\n streamPrefix: app,\n logRetention: 14,\n }),\n readonlyRootFilesystem,\n });\n\n if (enableDistributablePolicy) {\n const distPolicy = new GuGetDistributablePolicyStatement(scope, { app });\n taskDefinition.addToTaskRolePolicy(distPolicy);\n }\n\n (customTaskPolicies ?? []).forEach((p) => taskDefinition.addToTaskRolePolicy(p));\n\n const task = new EcsRunTask(scope, `${id}-task`, {\n cluster,\n launchTarget: new EcsFargateLaunchTarget({\n platformVersion: FargatePlatformVersion.LATEST,\n }),\n taskDefinition,\n integrationPattern: IntegrationPattern.RUN_JOB,\n resultPath: JsonPath.DISCARD,\n taskTimeout: Timeout.duration(Duration.minutes(taskTimeoutInMinutes)),\n securityGroups,\n containerOverrides: [\n {\n containerDefinition: containerDefinition,\n environment: environmentOverrides,\n },\n ],\n });\n\n this.stateMachine = new StateMachine(scope, `${id}-StateMachine`, {\n definitionBody: DefinitionBody.fromChainable(task),\n stateMachineName: `${app}-${stage}`,\n });\n\n if (!monitoringConfiguration.noMonitoring) {\n const alarmTopic = Topic.fromTopicArn(\n scope,\n AppIdentity.suffixText(props, \"AlarmTopic\"),\n monitoringConfiguration.snsTopicArn,\n );\n const alarms = [\n {\n name: `${app}-execution-failed`,\n description: `${app}-${stage} job failed `,\n metric: this.stateMachine.metricFailed({\n period: Duration.hours(1),\n statistic: \"sum\",\n }),\n },\n {\n name: `${app}-timeout`,\n description: `${app}-${stage} job timed out `,\n metric: this.stateMachine.metricTimedOut({\n period: Duration.hours(1),\n statistic: \"sum\",\n }),\n },\n ];\n\n alarms.forEach(({ name, description, metric }) => {\n const alarm = new Alarm(scope, name, {\n alarmDescription: description,\n actionsEnabled: true,\n metric: metric,\n // default for comparisonOperator is GreaterThanOrEqualToThreshold\n threshold: 1,\n evaluationPeriods: 1,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n });\n alarm.addAlarmAction(new SnsAction(alarmTopic));\n AppIdentity.taggedConstruct({ app }, alarm);\n });\n }\n\n // Tag all constructs with correct app tag\n [cluster, task, taskDefinition, this.stateMachine].forEach((c) => AppIdentity.taggedConstruct({ app }, c));\n\n new CfnOutput(scope, `${id}-StateMachineArnOutput`, {\n value: this.stateMachine.stateMachineArn,\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"ecs-task.js","sourceRoot":"","sources":["../../../src/constructs/ecs/ecs-task.ts"],"names":[],"mappings":"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","sourcesContent":["import { CfnOutput, Duration } from \"aws-cdk-lib\";\nimport { Alarm, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport { SnsAction } from \"aws-cdk-lib/aws-cloudwatch-actions\";\nimport type { ISecurityGroup, ISubnet, IVpc } from \"aws-cdk-lib/aws-ec2\";\nimport type { IRepository } from \"aws-cdk-lib/aws-ecr\";\nimport type { RepositoryImageProps } from \"aws-cdk-lib/aws-ecs\";\nimport {\n Cluster,\n Compatibility,\n ContainerImage,\n CpuArchitecture,\n FargatePlatformVersion,\n LogDrivers,\n OperatingSystemFamily,\n TaskDefinition,\n} from \"aws-cdk-lib/aws-ecs\";\nimport type { PolicyStatement } from \"aws-cdk-lib/aws-iam\";\nimport { Topic } from \"aws-cdk-lib/aws-sns\";\nimport { DefinitionBody, IntegrationPattern, JsonPath, StateMachine, Timeout } from \"aws-cdk-lib/aws-stepfunctions\";\nimport type { TaskEnvironmentVariable } from \"aws-cdk-lib/aws-stepfunctions-tasks\";\nimport { EcsFargateLaunchTarget, EcsRunTask } from \"aws-cdk-lib/aws-stepfunctions-tasks\";\nimport { Construct } from \"constructs\";\nimport type { NoMonitoring } from \"../cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport { AppIdentity } from \"../core\";\nimport { GuGetDistributablePolicyStatement } from \"../iam\";\n\n/**\n * Configuration to determine what container to use for the task\n * For example, to run the task in the latest node container:\n *\n * ```typescript\n * const containerConfiguration = {\n * id: 'node:latest'\n * }\n * ```\n *\n * Alternatively you can specify a repository and version, for example for an ECR repository:\n * ```typescript\n * import { Repository } from \"aws-cdk-lib/aws-ecr\";\n * const repository = new Repository(scope, `${app}-repository`, {\n repositoryName: app,\n });\n * const containerConfiguration = {\n * repository: Repository.fromRepositoryArn(\"<repository arn>\"),\n * version: '1'\n * }\n * ```\n */\n\nexport type RepositoryContainer = {\n repository: IRepository;\n version: string;\n type: \"repository\";\n};\n\nexport type RegistryContainer = {\n id?: string;\n imageProps?: RepositoryImageProps;\n type: \"registry\";\n};\n\nexport type ContainerConfiguration = RepositoryContainer | RegistryContainer;\n\nexport type GuEcsTaskMonitoringProps = { snsTopicArn: string; noMonitoring: false };\n\n/**\n * Configuration options for the [[`GuEcsTask`]] pattern.\n *\n * Note it is recommended to use GuVpc.subnetsFromParameterFixedNumber for the subnets prop rather than\n * GuVpc.subnetsFromParameter, as using the latter can result a custom resource being required\n *\n * See [[`ContainerConfiguration`]] for details of how to configure the container used to run the task.\n *\n * `taskTimeoutInMinutes` does what is says on the tin. The default timeout is 15 minutes.\n *\n * The `taskCommand` prop allows you to specify a command to run when the task starts (this can also be done via a CMD statement in\n * your Dockerfile). For example:\n *\n * const props = {\n * //other props\n * taskCommand: `aws s3 cp s3://${distbucket}/${stack}/${stage}/${app}/task.sh . && ./task.sh\n }\n *\n * It is advisable to configure alarms for when the job fails/times out. To do this specify the alarmSnsTopicArn prop.\n *\n * `customTaskPolicies` allows your task to interact with other AWS services. By default a task\n * will have read access to the distribution bucket for your account.\n *\n * You can specify security groups to apply to task using the `securityGroups` prop.\n *\n * You can also set the memory and cpu units for your task. See https://docs.aws.amazon.com/AmazonECS/latest/developerguide/task_definition_parameters.html#task_size\n * for further details.\n *\n * If you want to pass input from the step function into your EcsTask you can do so via the `environmentOverrides` prop, which allows you to wire up\n * step function input JSON to environment variables set on the container. For example,\n * const props = {\n * ...otherProps\n * environmentOverrides: [\n {\n name: \"VERSION\",\n value: JsonPath.stringAt(\"$.version\"),\n },\n }\n * With the above override, your task will attempt to find a `version` property in the JSON input passed to the step function, and apply it to the\n * VERSION environment variable. Alternatively, you could hard code a value for the variable in CDK.\n * See https://docs.aws.amazon.com/step-functions/latest/dg/connect-ecs.html for further detail and other override options - this construct currently\n * only supports environment variables.\n */\nexport interface GuEcsTaskProps extends AppIdentity {\n vpc: IVpc;\n subnets: ISubnet[];\n assignPublicIp?: boolean;\n containerConfiguration: ContainerConfiguration;\n taskTimeoutInMinutes?: number;\n cpu?: number;\n memory?: number;\n taskCommand?: string;\n monitoringConfiguration: NoMonitoring | GuEcsTaskMonitoringProps;\n securityGroups?: ISecurityGroup[];\n customTaskPolicies?: PolicyStatement[];\n environmentOverrides?: TaskEnvironmentVariable[];\n storage?: number;\n /**\n * Whether to give the task IAM role access to the account's dist bucket.\n * This is enabled by default to avoid breaking changes, but consumers of this pattern\n * that pull a container image that doesn't need extra dependencies from S3\n * shoud set this value to `false`.\n */\n enableDistributablePolicy?: boolean;\n /**\n * When this parameter is true, the container is given read-only access to its root file system.\n * @default false\n */\n readonlyRootFilesystem?: boolean;\n /**\n * If `true`, CloudWatch Container Insights will be enabled for the cluster\n * @default false\n */\n containerInsights?: boolean;\n}\n\n/**\n * Containers can be specified either via a repository and version or by container id (in which case it will\n * be fetched from docker hub).\n */\nconst getContainer = (config: ContainerConfiguration) => {\n if (config.type == \"repository\") {\n return ContainerImage.fromEcrRepository(config.repository, config.version);\n } else {\n return ContainerImage.fromRegistry(config.id ?? \"ubuntu:jammy\", config.imageProps);\n }\n};\n\n/**\n * Pattern which creates all of the resources needed for a fargate task\n *\n * The task will be wrapped in a step function to allow for easier triggering and alarming on failure.\n *\n * For all configuration options, see [[`GuEcsTaskProps`]].\n *\n * Note that if your task reliably completes in less than 15 minutes then you should probably use a [[`GuLambda`]] instead. This\n * pattern was mainly created to work around the 15 minute lambda timeout.\n *\n */\nexport class GuEcsTask extends Construct {\n stateMachine: StateMachine;\n\n constructor(scope: GuStack, id: string, props: GuEcsTaskProps) {\n super(scope, id);\n\n const {\n app,\n\n // see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ecs-taskdefinition.html#cfn-ecs-taskdefinition-cpu for details\n cpu = 2048, // 2 cores and from 4-16GB memory\n memory = 4096, // 4GB\n storage, // default is 20 GB when not provided in props\n containerConfiguration,\n taskCommand,\n taskTimeoutInMinutes = 15,\n customTaskPolicies,\n vpc,\n subnets,\n monitoringConfiguration,\n securityGroups = [],\n environmentOverrides,\n enableDistributablePolicy = true,\n readonlyRootFilesystem = false,\n containerInsights = false,\n } = props;\n\n if (storage && storage < 21) {\n throw new Error(\n \"Storage must be at least 21. See https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ecs-taskdefinition-ephemeralstorage.html\",\n );\n }\n\n const { stack, stage } = scope;\n\n const cluster = new Cluster(scope, `${id}-Cluster`, {\n clusterName: `${app}-cluster-${stage}`,\n enableFargateCapacityProviders: true,\n vpc,\n containerInsights,\n });\n\n const taskDefinition = new TaskDefinition(scope, `${id}-TaskDefinition`, {\n compatibility: Compatibility.FARGATE,\n cpu: cpu.toString(),\n memoryMiB: memory.toString(),\n family: `${stack}-${stage}-${app}`,\n ephemeralStorageGiB: storage,\n runtimePlatform: {\n cpuArchitecture: CpuArchitecture.ARM64,\n operatingSystemFamily: OperatingSystemFamily.of(\"LINUX\"),\n },\n });\n\n const containerDefinition = taskDefinition.addContainer(`${id}-TaskContainer`, {\n image: getContainer(containerConfiguration),\n entryPoint: taskCommand ? [\"/bin/sh\"] : undefined,\n command: taskCommand ? [\"-c\", taskCommand] : undefined, // if unset, falls back to CMD in docker file, or no command will be run\n cpu,\n memoryLimitMiB: memory,\n logging: LogDrivers.awsLogs({\n streamPrefix: app,\n logRetention: 14,\n }),\n readonlyRootFilesystem,\n });\n\n if (enableDistributablePolicy) {\n const distPolicy = new GuGetDistributablePolicyStatement(scope, { app });\n taskDefinition.addToTaskRolePolicy(distPolicy);\n }\n\n (customTaskPolicies ?? []).forEach((p) => taskDefinition.addToTaskRolePolicy(p));\n\n const task = new EcsRunTask(scope, `${id}-task`, {\n cluster,\n launchTarget: new EcsFargateLaunchTarget({\n platformVersion: FargatePlatformVersion.LATEST,\n }),\n taskDefinition,\n subnets: { subnets },\n assignPublicIp: false,\n integrationPattern: IntegrationPattern.RUN_JOB,\n resultPath: JsonPath.DISCARD,\n taskTimeout: Timeout.duration(Duration.minutes(taskTimeoutInMinutes)),\n securityGroups,\n containerOverrides: [\n {\n containerDefinition: containerDefinition,\n environment: environmentOverrides,\n },\n ],\n });\n\n this.stateMachine = new StateMachine(scope, `${id}-StateMachine`, {\n definitionBody: DefinitionBody.fromChainable(task),\n stateMachineName: `${app}-${stage}`,\n });\n\n if (!monitoringConfiguration.noMonitoring) {\n const alarmTopic = Topic.fromTopicArn(\n scope,\n AppIdentity.suffixText(props, \"AlarmTopic\"),\n monitoringConfiguration.snsTopicArn,\n );\n const alarms = [\n {\n name: `${app}-execution-failed`,\n description: `${app}-${stage} job failed `,\n metric: this.stateMachine.metricFailed({\n period: Duration.hours(1),\n statistic: \"sum\",\n }),\n },\n {\n name: `${app}-timeout`,\n description: `${app}-${stage} job timed out `,\n metric: this.stateMachine.metricTimedOut({\n period: Duration.hours(1),\n statistic: \"sum\",\n }),\n },\n ];\n\n alarms.forEach(({ name, description, metric }) => {\n const alarm = new Alarm(scope, name, {\n alarmDescription: description,\n actionsEnabled: true,\n metric: metric,\n // default for comparisonOperator is GreaterThanOrEqualToThreshold\n threshold: 1,\n evaluationPeriods: 1,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n });\n alarm.addAlarmAction(new SnsAction(alarmTopic));\n AppIdentity.taggedConstruct({ app }, alarm);\n });\n }\n\n // Tag all constructs with correct app tag\n [cluster, task, taskDefinition, this.stateMachine].forEach((c) => AppIdentity.taggedConstruct({ app }, c));\n\n new CfnOutput(scope, `${id}-StateMachineArnOutput`, {\n value: this.stateMachine.stateMachineArn,\n });\n }\n}\n"]}
|
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": "
|
|
4
|
+
"version": "60.0.0",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
7
7
|
"files": [
|
|
@@ -33,16 +33,16 @@
|
|
|
33
33
|
"@guardian/eslint-plugin-tsdoc-required": "^0.1.3",
|
|
34
34
|
"@guardian/tsconfig": "^1.0.0",
|
|
35
35
|
"@types/git-url-parse": "^9.0.3",
|
|
36
|
-
"@types/jest": "^29.5.
|
|
36
|
+
"@types/jest": "^29.5.14",
|
|
37
37
|
"@types/js-yaml": "^4.0.9",
|
|
38
38
|
"@types/lodash.camelcase": "^4.3.9",
|
|
39
39
|
"@types/lodash.kebabcase": "^4.1.9",
|
|
40
40
|
"@types/lodash.upperfirst": "^4.3.9",
|
|
41
|
-
"@types/node": "22.
|
|
41
|
+
"@types/node": "22.9.0",
|
|
42
42
|
"@types/yargs": "^17.0.33",
|
|
43
|
-
"aws-cdk": "2.
|
|
44
|
-
"aws-cdk-lib": "2.
|
|
45
|
-
"constructs": "10.
|
|
43
|
+
"aws-cdk": "2.166.0",
|
|
44
|
+
"aws-cdk-lib": "2.166.0",
|
|
45
|
+
"constructs": "10.4.2",
|
|
46
46
|
"eslint": "^8.57.1",
|
|
47
47
|
"eslint-plugin-custom-rules": "file:tools/eslint",
|
|
48
48
|
"gh-pages": "^6.2.0",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"serve": "^14.2.4",
|
|
52
52
|
"ts-jest": "^29.2.5",
|
|
53
53
|
"ts-node": "^10.9.2",
|
|
54
|
-
"typedoc": "^0.26.
|
|
54
|
+
"typedoc": "^0.26.11",
|
|
55
55
|
"typescript": "5.1.6"
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
@@ -68,8 +68,8 @@
|
|
|
68
68
|
"yargs": "^17.7.2"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"aws-cdk": "2.
|
|
72
|
-
"aws-cdk-lib": "2.
|
|
73
|
-
"constructs": "10.
|
|
71
|
+
"aws-cdk": "2.166.0",
|
|
72
|
+
"aws-cdk-lib": "2.166.0",
|
|
73
|
+
"constructs": "10.4.2"
|
|
74
74
|
}
|
|
75
75
|
}
|