@guardian/cdk 50.8.0 → 50.8.2

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.
@@ -1,7 +1,6 @@
1
1
  export declare const RegexPattern: {
2
2
  ARN: string;
3
3
  S3ARN: string;
4
- GUARDIAN_EMAIL: string;
5
4
  ACM_ARN: string;
6
5
  };
7
6
  //# sourceMappingURL=regex-pattern.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"regex-pattern.d.ts","sourceRoot":"","sources":["../../src/constants/regex-pattern.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,YAAY;;;;;CAKxB,CAAC"}
1
+ {"version":3,"file":"regex-pattern.d.ts","sourceRoot":"","sources":["../../src/constants/regex-pattern.ts"],"names":[],"mappings":"AAQA,eAAO,MAAM,YAAY;;;;CAIxB,CAAC"}
@@ -4,13 +4,11 @@ exports.RegexPattern = void 0;
4
4
  const arnRegex = "arn:aws:[a-z0-9]*:[a-z0-9\\-]*:[0-9]{12}:.*";
5
5
  const s3BucketRegex = "(?!^(\\d{1,3}\\.){3}\\d{1,3}$)(^[a-z0-9]([a-z0-9-]*(\\.[a-z0-9])?)*$(?<!\\-))";
6
6
  const s3ArnRegex = `arn:aws:s3:::${s3BucketRegex}*`;
7
- const emailRegex = "^[a-zA-Z]+(\\.[a-zA-Z]+)*@theguardian.com$";
8
7
  // TODO be more strict on region?
9
8
  const acmRegex = "arn:aws:acm:[0-9a-z\\-]+:[0-9]{12}:certificate/[0-9a-z\\-]+";
10
9
  exports.RegexPattern = {
11
10
  ARN: arnRegex,
12
11
  S3ARN: s3ArnRegex,
13
- GUARDIAN_EMAIL: emailRegex,
14
12
  ACM_ARN: acmRegex,
15
13
  };
16
14
  //# sourceMappingURL=regex-pattern.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"regex-pattern.js","sourceRoot":"","sources":["../../src/constants/regex-pattern.ts"],"names":[],"mappings":";;;AAAA,MAAM,QAAQ,GAAG,6CAA6C,CAAC;AAE/D,MAAM,aAAa,GAAG,+EAA+E,CAAC;AACtG,MAAM,UAAU,GAAG,gBAAgB,aAAa,GAAG,CAAC;AAEpD,MAAM,UAAU,GAAG,4CAA4C,CAAC;AAEhE,iCAAiC;AACjC,MAAM,QAAQ,GAAG,6DAA6D,CAAC;AAElE,QAAA,YAAY,GAAG;IAC1B,GAAG,EAAE,QAAQ;IACb,KAAK,EAAE,UAAU;IACjB,cAAc,EAAE,UAAU;IAC1B,OAAO,EAAE,QAAQ;CAClB,CAAC","sourcesContent":["const arnRegex = \"arn:aws:[a-z0-9]*:[a-z0-9\\\\-]*:[0-9]{12}:.*\";\n\nconst s3BucketRegex = \"(?!^(\\\\d{1,3}\\\\.){3}\\\\d{1,3}$)(^[a-z0-9]([a-z0-9-]*(\\\\.[a-z0-9])?)*$(?<!\\\\-))\";\nconst s3ArnRegex = `arn:aws:s3:::${s3BucketRegex}*`;\n\nconst emailRegex = \"^[a-zA-Z]+(\\\\.[a-zA-Z]+)*@theguardian.com$\";\n\n// TODO be more strict on region?\nconst acmRegex = \"arn:aws:acm:[0-9a-z\\\\-]+:[0-9]{12}:certificate/[0-9a-z\\\\-]+\";\n\nexport const RegexPattern = {\n ARN: arnRegex,\n S3ARN: s3ArnRegex,\n GUARDIAN_EMAIL: emailRegex,\n ACM_ARN: acmRegex,\n};\n"]}
1
+ {"version":3,"file":"regex-pattern.js","sourceRoot":"","sources":["../../src/constants/regex-pattern.ts"],"names":[],"mappings":";;;AAAA,MAAM,QAAQ,GAAG,6CAA6C,CAAC;AAE/D,MAAM,aAAa,GAAG,+EAA+E,CAAC;AACtG,MAAM,UAAU,GAAG,gBAAgB,aAAa,GAAG,CAAC;AAEpD,iCAAiC;AACjC,MAAM,QAAQ,GAAG,6DAA6D,CAAC;AAElE,QAAA,YAAY,GAAG;IAC1B,GAAG,EAAE,QAAQ;IACb,KAAK,EAAE,UAAU;IACjB,OAAO,EAAE,QAAQ;CAClB,CAAC","sourcesContent":["const arnRegex = \"arn:aws:[a-z0-9]*:[a-z0-9\\\\-]*:[0-9]{12}:.*\";\n\nconst s3BucketRegex = \"(?!^(\\\\d{1,3}\\\\.){3}\\\\d{1,3}$)(^[a-z0-9]([a-z0-9-]*(\\\\.[a-z0-9])?)*$(?<!\\\\-))\";\nconst s3ArnRegex = `arn:aws:s3:::${s3BucketRegex}*`;\n\n// TODO be more strict on region?\nconst acmRegex = \"arn:aws:acm:[0-9a-z\\\\-]+:[0-9]{12}:certificate/[0-9a-z\\\\-]+\";\n\nexport const RegexPattern = {\n ARN: arnRegex,\n S3ARN: s3ArnRegex,\n ACM_ARN: acmRegex,\n};\n"]}
@@ -1,10 +1,12 @@
1
+ import { Duration } from "aws-cdk-lib";
1
2
  import type { GuStack } from "../core";
2
3
  import type { GuLambdaFunction } from "../lambda";
3
4
  import { GuAlarm } from "./alarm";
4
5
  import type { GuAlarmProps } from "./alarm";
5
6
  export interface GuLambdaErrorPercentageMonitoringProps extends Omit<GuAlarmProps, "metric" | "threshold" | "comparisonOperator" | "evaluationPeriods" | "treatMissingData" | "app"> {
6
7
  toleratedErrorPercentage: number;
7
- numberOfMinutesAboveThresholdBeforeAlarm?: number;
8
+ lengthOfEvaluationPeriod?: Duration;
9
+ numberOfEvaluationPeriodsAboveThresholdBeforeAlarm?: number;
8
10
  noMonitoring?: false;
9
11
  }
10
12
  interface GuLambdaAlarmProps extends GuLambdaErrorPercentageMonitoringProps {
@@ -1 +1 @@
1
- {"version":3,"file":"lambda-alarms.d.ts","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/lambda-alarms.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,WAAW,sCACf,SAAQ,IAAI,CACV,YAAY,EACZ,QAAQ,GAAG,WAAW,GAAG,oBAAoB,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,KAAK,CACjG;IACD,wBAAwB,EAAE,MAAM,CAAC;IACjC,wCAAwC,CAAC,EAAE,MAAM,CAAC;IAClD,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,UAAU,kBAAmB,SAAQ,sCAAsC;IACzE,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,4BAA6B,SAAQ,OAAO;gBAC3C,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB;CAsBlE;AAED,MAAM,WAAW,iCACf,SAAQ,IAAI,CACV,YAAY,EACZ,QAAQ,GAAG,WAAW,GAAG,oBAAoB,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,KAAK,CACjG;IACD;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAElC;;;;OAIG;IACH,wCAAwC,CAAC,EAAE,MAAM,CAAC;IAElD,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,UAAU,4BAA6B,SAAQ,iCAAiC;IAC9E,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,qBAAa,uBAAwB,SAAQ,OAAO;gBACtC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,4BAA4B;CAkB5E"}
1
+ {"version":3,"file":"lambda-alarms.d.ts","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/lambda-alarms.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAE5C,MAAM,WAAW,sCACf,SAAQ,IAAI,CACV,YAAY,EACZ,QAAQ,GAAG,WAAW,GAAG,oBAAoB,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,KAAK,CACjG;IACD,wBAAwB,EAAE,MAAM,CAAC;IACjC,wBAAwB,CAAC,EAAE,QAAQ,CAAC;IACpC,kDAAkD,CAAC,EAAE,MAAM,CAAC;IAC5D,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,UAAU,kBAAmB,SAAQ,sCAAsC;IACzE,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED;;GAEG;AACH,qBAAa,4BAA6B,SAAQ,OAAO;gBAC3C,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,kBAAkB;CAsBlE;AAED,MAAM,WAAW,iCACf,SAAQ,IAAI,CACV,YAAY,EACZ,QAAQ,GAAG,WAAW,GAAG,oBAAoB,GAAG,mBAAmB,GAAG,kBAAkB,GAAG,KAAK,CACjG;IACD;;;;OAIG;IACH,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAElC;;;;OAIG;IACH,wCAAwC,CAAC,EAAE,MAAM,CAAC;IAElD,YAAY,CAAC,EAAE,KAAK,CAAC;CACtB;AAED,UAAU,4BAA6B,SAAQ,iCAAiC;IAC9E,MAAM,EAAE,gBAAgB,CAAC;CAC1B;AAED,qBAAa,uBAAwB,SAAQ,OAAO;gBACtC,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,4BAA4B;CAkB5E"}
@@ -13,7 +13,7 @@ class GuLambdaErrorPercentageAlarm extends alarm_1.GuAlarm {
13
13
  expression: "100*m1/m2",
14
14
  usingMetrics: { m1: props.lambda.metricErrors(), m2: props.lambda.metricInvocations() },
15
15
  label: `Error % of ${props.lambda.functionName}`,
16
- period: aws_cdk_lib_1.Duration.minutes(1),
16
+ period: props.lengthOfEvaluationPeriod ?? aws_cdk_lib_1.Duration.minutes(1),
17
17
  });
18
18
  const defaultAlarmName = `High error % from ${props.lambda.functionName} lambda in ${scope.stage}`;
19
19
  const defaultDescription = `${props.lambda.functionName} exceeded ${props.toleratedErrorPercentage}% error rate`;
@@ -24,7 +24,7 @@ class GuLambdaErrorPercentageAlarm extends alarm_1.GuAlarm {
24
24
  treatMissingData: aws_cloudwatch_1.TreatMissingData.NOT_BREACHING,
25
25
  threshold: props.toleratedErrorPercentage,
26
26
  comparisonOperator: aws_cloudwatch_1.ComparisonOperator.GREATER_THAN_THRESHOLD,
27
- evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,
27
+ evaluationPeriods: props.numberOfEvaluationPeriodsAboveThresholdBeforeAlarm ?? 1,
28
28
  alarmName: props.alarmName ?? defaultAlarmName,
29
29
  alarmDescription: props.alarmDescription ?? defaultDescription,
30
30
  };
@@ -1 +1 @@
1
- {"version":3,"file":"lambda-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/lambda-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,+DAAkG;AAGlG,mCAAkC;AAiBlC;;GAEG;AACH,MAAa,4BAA6B,SAAQ,eAAO;IACvD,YAAY,KAAc,EAAE,EAAU,EAAE,KAAyB;QAC/D,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE;YACvF,KAAK,EAAE,cAAc,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE;YAChD,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC5B,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,qBAAqB,KAAK,CAAC,MAAM,CAAC,YAAY,cAAc,KAAK,CAAC,KAAK,EAAE,CAAC;QACnG,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,aAAa,KAAK,CAAC,wBAAwB,cAAc,CAAC;QACjH,MAAM,UAAU,GAAiB;YAC/B,GAAG,KAAK;YACR,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;YACrB,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,wBAAwB;YACzC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;YACtE,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;SAC/D,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;IAC/B,CAAC;CACF;AAvBD,oEAuBC;AA4BD,MAAa,uBAAwB,SAAQ,eAAO;IAClD,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmC;QACzE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,GAAG,KAAK;YACR,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;YACrB,SAAS,EACP,KAAK,CAAC,SAAS,IAAI,+BAA+B,KAAK,CAAC,MAAM,CAAC,YAAY,cAAc,KAAK,CAAC,KAAK,GAAG;YACzG,gBAAgB,EACd,KAAK,CAAC,gBAAgB,IAAI,4EAA4E;YACxG,SAAS,EAAE,KAAK,CAAC,wBAAwB,IAAI,CAAC;YAC9C,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;YACtE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC;gBACnC,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,SAAS,EAAE,KAAK;aACjB,CAAC;YACF,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;SAC9D,CAAC,CAAC;IACL,CAAC;CACF;AAnBD,0DAmBC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport { ComparisonOperator, MathExpression, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport type { GuLambdaFunction } from \"../lambda\";\nimport { GuAlarm } from \"./alarm\";\nimport type { GuAlarmProps } from \"./alarm\";\n\nexport interface GuLambdaErrorPercentageMonitoringProps\n extends Omit<\n GuAlarmProps,\n \"metric\" | \"threshold\" | \"comparisonOperator\" | \"evaluationPeriods\" | \"treatMissingData\" | \"app\"\n > {\n toleratedErrorPercentage: number;\n numberOfMinutesAboveThresholdBeforeAlarm?: number;\n noMonitoring?: false;\n}\n\ninterface GuLambdaAlarmProps extends GuLambdaErrorPercentageMonitoringProps {\n lambda: GuLambdaFunction;\n}\n\n/**\n * Creates an alarm which is triggered whenever the error percentage specified is exceeded.\n */\nexport class GuLambdaErrorPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, id: string, props: GuLambdaAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*m1/m2\",\n usingMetrics: { m1: props.lambda.metricErrors(), m2: props.lambda.metricInvocations() },\n label: `Error % of ${props.lambda.functionName}`,\n period: Duration.minutes(1),\n });\n const defaultAlarmName = `High error % from ${props.lambda.functionName} lambda in ${scope.stage}`;\n const defaultDescription = `${props.lambda.functionName} exceeded ${props.toleratedErrorPercentage}% error rate`;\n const alarmProps: GuAlarmProps = {\n ...props,\n app: props.lambda.app,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.toleratedErrorPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n };\n super(scope, id, alarmProps);\n }\n}\n\nexport interface GuLambdaThrottlingMonitoringProps\n extends Omit<\n GuAlarmProps,\n \"metric\" | \"threshold\" | \"comparisonOperator\" | \"evaluationPeriods\" | \"treatMissingData\" | \"app\"\n > {\n /**\n * Sum of thottled invocations above which to alarm.\n *\n * @defaultValue 0\n */\n toleratedThrottlingCount?: number;\n\n /**\n * Evaluation period in minutes for alarm.\n *\n * @defaultValue 1\n */\n numberOfMinutesAboveThresholdBeforeAlarm?: number;\n\n noMonitoring?: false;\n}\n\ninterface GuLambdaThrottlingAlarmProps extends GuLambdaThrottlingMonitoringProps {\n lambda: GuLambdaFunction;\n}\n\nexport class GuLambdaThrottlingAlarm extends GuAlarm {\n constructor(scope: GuStack, id: string, props: GuLambdaThrottlingAlarmProps) {\n super(scope, id, {\n ...props,\n app: props.lambda.app,\n alarmName:\n props.alarmName ?? `Lambda throttling alarm for ${props.lambda.functionName} lambda in ${scope.stage}.`,\n alarmDescription:\n props.alarmDescription ?? \"Alarm when lambda is throttled (which causes requests to fail with a 429).\",\n threshold: props.toleratedThrottlingCount ?? 0,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n metric: props.lambda.metricThrottles({\n period: Duration.seconds(60),\n statistic: \"sum\",\n }),\n treatMissingData: TreatMissingData.NOT_BREACHING,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n });\n }\n}\n"]}
1
+ {"version":3,"file":"lambda-alarms.js","sourceRoot":"","sources":["../../../src/constructs/cloudwatch/lambda-alarms.ts"],"names":[],"mappings":";;;AAAA,6CAAuC;AACvC,+DAAkG;AAGlG,mCAAkC;AAkBlC;;GAEG;AACH,MAAa,4BAA6B,SAAQ,eAAO;IACvD,YAAY,KAAc,EAAE,EAAU,EAAE,KAAyB;QAC/D,MAAM,cAAc,GAAG,IAAI,+BAAc,CAAC;YACxC,UAAU,EAAE,WAAW;YACvB,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,EAAE,EAAE,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE;YACvF,KAAK,EAAE,cAAc,KAAK,CAAC,MAAM,CAAC,YAAY,EAAE;YAChD,MAAM,EAAE,KAAK,CAAC,wBAAwB,IAAI,sBAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;SAC9D,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,qBAAqB,KAAK,CAAC,MAAM,CAAC,YAAY,cAAc,KAAK,CAAC,KAAK,EAAE,CAAC;QACnG,MAAM,kBAAkB,GAAG,GAAG,KAAK,CAAC,MAAM,CAAC,YAAY,aAAa,KAAK,CAAC,wBAAwB,cAAc,CAAC;QACjH,MAAM,UAAU,GAAiB;YAC/B,GAAG,KAAK;YACR,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;YACrB,MAAM,EAAE,cAAc;YACtB,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,SAAS,EAAE,KAAK,CAAC,wBAAwB;YACzC,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;YAC7D,iBAAiB,EAAE,KAAK,CAAC,kDAAkD,IAAI,CAAC;YAChF,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,gBAAgB;YAC9C,gBAAgB,EAAE,KAAK,CAAC,gBAAgB,IAAI,kBAAkB;SAC/D,CAAC;QACF,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE,UAAU,CAAC,CAAC;IAC/B,CAAC;CACF;AAvBD,oEAuBC;AA4BD,MAAa,uBAAwB,SAAQ,eAAO;IAClD,YAAY,KAAc,EAAE,EAAU,EAAE,KAAmC;QACzE,KAAK,CAAC,KAAK,EAAE,EAAE,EAAE;YACf,GAAG,KAAK;YACR,GAAG,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG;YACrB,SAAS,EACP,KAAK,CAAC,SAAS,IAAI,+BAA+B,KAAK,CAAC,MAAM,CAAC,YAAY,cAAc,KAAK,CAAC,KAAK,GAAG;YACzG,gBAAgB,EACd,KAAK,CAAC,gBAAgB,IAAI,4EAA4E;YACxG,SAAS,EAAE,KAAK,CAAC,wBAAwB,IAAI,CAAC;YAC9C,iBAAiB,EAAE,KAAK,CAAC,wCAAwC,IAAI,CAAC;YACtE,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,eAAe,CAAC;gBACnC,MAAM,EAAE,sBAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC5B,SAAS,EAAE,KAAK;aACjB,CAAC;YACF,gBAAgB,EAAE,iCAAgB,CAAC,aAAa;YAChD,kBAAkB,EAAE,mCAAkB,CAAC,sBAAsB;SAC9D,CAAC,CAAC;IACL,CAAC;CACF;AAnBD,0DAmBC","sourcesContent":["import { Duration } from \"aws-cdk-lib\";\nimport { ComparisonOperator, MathExpression, TreatMissingData } from \"aws-cdk-lib/aws-cloudwatch\";\nimport type { GuStack } from \"../core\";\nimport type { GuLambdaFunction } from \"../lambda\";\nimport { GuAlarm } from \"./alarm\";\nimport type { GuAlarmProps } from \"./alarm\";\n\nexport interface GuLambdaErrorPercentageMonitoringProps\n extends Omit<\n GuAlarmProps,\n \"metric\" | \"threshold\" | \"comparisonOperator\" | \"evaluationPeriods\" | \"treatMissingData\" | \"app\"\n > {\n toleratedErrorPercentage: number;\n lengthOfEvaluationPeriod?: Duration;\n numberOfEvaluationPeriodsAboveThresholdBeforeAlarm?: number;\n noMonitoring?: false;\n}\n\ninterface GuLambdaAlarmProps extends GuLambdaErrorPercentageMonitoringProps {\n lambda: GuLambdaFunction;\n}\n\n/**\n * Creates an alarm which is triggered whenever the error percentage specified is exceeded.\n */\nexport class GuLambdaErrorPercentageAlarm extends GuAlarm {\n constructor(scope: GuStack, id: string, props: GuLambdaAlarmProps) {\n const mathExpression = new MathExpression({\n expression: \"100*m1/m2\",\n usingMetrics: { m1: props.lambda.metricErrors(), m2: props.lambda.metricInvocations() },\n label: `Error % of ${props.lambda.functionName}`,\n period: props.lengthOfEvaluationPeriod ?? Duration.minutes(1),\n });\n const defaultAlarmName = `High error % from ${props.lambda.functionName} lambda in ${scope.stage}`;\n const defaultDescription = `${props.lambda.functionName} exceeded ${props.toleratedErrorPercentage}% error rate`;\n const alarmProps: GuAlarmProps = {\n ...props,\n app: props.lambda.app,\n metric: mathExpression,\n treatMissingData: TreatMissingData.NOT_BREACHING,\n threshold: props.toleratedErrorPercentage,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n evaluationPeriods: props.numberOfEvaluationPeriodsAboveThresholdBeforeAlarm ?? 1,\n alarmName: props.alarmName ?? defaultAlarmName,\n alarmDescription: props.alarmDescription ?? defaultDescription,\n };\n super(scope, id, alarmProps);\n }\n}\n\nexport interface GuLambdaThrottlingMonitoringProps\n extends Omit<\n GuAlarmProps,\n \"metric\" | \"threshold\" | \"comparisonOperator\" | \"evaluationPeriods\" | \"treatMissingData\" | \"app\"\n > {\n /**\n * Sum of thottled invocations above which to alarm.\n *\n * @defaultValue 0\n */\n toleratedThrottlingCount?: number;\n\n /**\n * Evaluation period in minutes for alarm.\n *\n * @defaultValue 1\n */\n numberOfMinutesAboveThresholdBeforeAlarm?: number;\n\n noMonitoring?: false;\n}\n\ninterface GuLambdaThrottlingAlarmProps extends GuLambdaThrottlingMonitoringProps {\n lambda: GuLambdaFunction;\n}\n\nexport class GuLambdaThrottlingAlarm extends GuAlarm {\n constructor(scope: GuStack, id: string, props: GuLambdaThrottlingAlarmProps) {\n super(scope, id, {\n ...props,\n app: props.lambda.app,\n alarmName:\n props.alarmName ?? `Lambda throttling alarm for ${props.lambda.functionName} lambda in ${scope.stage}.`,\n alarmDescription:\n props.alarmDescription ?? \"Alarm when lambda is throttled (which causes requests to fail with a 429).\",\n threshold: props.toleratedThrottlingCount ?? 0,\n evaluationPeriods: props.numberOfMinutesAboveThresholdBeforeAlarm ?? 1,\n metric: props.lambda.metricThrottles({\n period: Duration.seconds(60),\n statistic: \"sum\",\n }),\n treatMissingData: TreatMissingData.NOT_BREACHING,\n comparisonOperator: ComparisonOperator.GREATER_THAN_THRESHOLD,\n });\n }\n}\n"]}
@@ -5,6 +5,5 @@ export * from "./ec2";
5
5
  export * from "./fastly";
6
6
  export * from "./log-shipping";
7
7
  export * from "./s3";
8
- export * from "./ses";
9
8
  export * from "./vpc";
10
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,MAAM,CAAC;AACrB,cAAc,OAAO,CAAC;AACtB,cAAc,OAAO,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,QAAQ,CAAC;AACvB,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,MAAM,CAAC;AACrB,cAAc,OAAO,CAAC"}
@@ -21,6 +21,5 @@ __exportStar(require("./ec2"), exports);
21
21
  __exportStar(require("./fastly"), exports);
22
22
  __exportStar(require("./log-shipping"), exports);
23
23
  __exportStar(require("./s3"), exports);
24
- __exportStar(require("./ses"), exports);
25
24
  __exportStar(require("./vpc"), exports);
26
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wCAAsB;AACtB,gDAA8B;AAC9B,yCAAuB;AACvB,wCAAsB;AACtB,2CAAyB;AACzB,iDAA+B;AAC/B,uCAAqB;AACrB,wCAAsB;AACtB,wCAAsB","sourcesContent":["export * from \"./acm\";\nexport * from \"./anghammarad\";\nexport * from \"./base\";\nexport * from \"./ec2\";\nexport * from \"./fastly\";\nexport * from \"./log-shipping\";\nexport * from \"./s3\";\nexport * from \"./ses\";\nexport * from \"./vpc\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,wCAAsB;AACtB,gDAA8B;AAC9B,yCAAuB;AACvB,wCAAsB;AACtB,2CAAyB;AACzB,iDAA+B;AAC/B,uCAAqB;AACrB,wCAAsB","sourcesContent":["export * from \"./acm\";\nexport * from \"./anghammarad\";\nexport * from \"./base\";\nexport * from \"./ec2\";\nexport * from \"./fastly\";\nexport * from \"./log-shipping\";\nexport * from \"./s3\";\nexport * from \"./vpc\";\n"]}
@@ -1,6 +1,15 @@
1
1
  import type { GuStack } from "../../core";
2
2
  import { GuAllowPolicy } from "./base-policy";
3
+ interface GuSESSenderPolicyProps {
4
+ /**
5
+ * The email address to allow sending from.
6
+ *
7
+ * This address should be registered with SES.
8
+ */
9
+ sendingAddress: string;
10
+ }
3
11
  export declare class GuSESSenderPolicy extends GuAllowPolicy {
4
- constructor(scope: GuStack);
12
+ constructor(scope: GuStack, props: GuSESSenderPolicyProps);
5
13
  }
14
+ export {};
6
15
  //# sourceMappingURL=ses.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ses.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ses.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,KAAK,EAAE,OAAO;CAQ3B"}
1
+ {"version":3,"file":"ses.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ses.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAE9C,UAAU,sBAAsB;IAC9B;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,iBAAkB,SAAQ,aAAa;gBACtC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,sBAAsB;CAM1D"}
@@ -1,14 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GuSESSenderPolicy = void 0;
4
- const core_1 = require("../../core");
5
4
  const base_policy_1 = require("./base-policy");
6
5
  class GuSESSenderPolicy extends base_policy_1.GuAllowPolicy {
7
- constructor(scope) {
8
- const emailSenderParam = new core_1.GuGuardianEmailSenderParameter(scope);
6
+ constructor(scope, props) {
9
7
  super(scope, "GuSESSenderPolicy", {
10
8
  actions: ["ses:SendEmail"],
11
- resources: [`arn:aws:ses:${scope.region}:${scope.account}:identity/${emailSenderParam.valueAsString}`],
9
+ resources: [`arn:aws:ses:${scope.region}:${scope.account}:identity/${props.sendingAddress}`],
12
10
  });
13
11
  }
14
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ses.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ses.ts"],"names":[],"mappings":";;;AAAA,qCAA4D;AAE5D,+CAA8C;AAE9C,MAAa,iBAAkB,SAAQ,2BAAa;IAClD,YAAY,KAAc;QACxB,MAAM,gBAAgB,GAAG,IAAI,qCAA8B,CAAC,KAAK,CAAC,CAAC;QAEnE,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,OAAO,EAAE,CAAC,eAAe,CAAC;YAC1B,SAAS,EAAE,CAAC,eAAe,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,aAAa,gBAAgB,CAAC,aAAa,EAAE,CAAC;SACvG,CAAC,CAAC;IACL,CAAC;CACF;AATD,8CASC","sourcesContent":["import { GuGuardianEmailSenderParameter } from \"../../core\";\nimport type { GuStack } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\nexport class GuSESSenderPolicy extends GuAllowPolicy {\n constructor(scope: GuStack) {\n const emailSenderParam = new GuGuardianEmailSenderParameter(scope);\n\n super(scope, \"GuSESSenderPolicy\", {\n actions: [\"ses:SendEmail\"],\n resources: [`arn:aws:ses:${scope.region}:${scope.account}:identity/${emailSenderParam.valueAsString}`],\n });\n }\n}\n"]}
1
+ {"version":3,"file":"ses.js","sourceRoot":"","sources":["../../../../src/constructs/iam/policies/ses.ts"],"names":[],"mappings":";;;AACA,+CAA8C;AAW9C,MAAa,iBAAkB,SAAQ,2BAAa;IAClD,YAAY,KAAc,EAAE,KAA6B;QACvD,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,OAAO,EAAE,CAAC,eAAe,CAAC;YAC1B,SAAS,EAAE,CAAC,eAAe,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,OAAO,aAAa,KAAK,CAAC,cAAc,EAAE,CAAC;SAC7F,CAAC,CAAC;IACL,CAAC;CACF;AAPD,8CAOC","sourcesContent":["import type { GuStack } from \"../../core\";\nimport { GuAllowPolicy } from \"./base-policy\";\n\ninterface GuSESSenderPolicyProps {\n /**\n * The email address to allow sending from.\n *\n * This address should be registered with SES.\n */\n sendingAddress: string;\n}\n\nexport class GuSESSenderPolicy extends GuAllowPolicy {\n constructor(scope: GuStack, props: GuSESSenderPolicyProps) {\n super(scope, \"GuSESSenderPolicy\", {\n actions: [\"ses:SendEmail\"],\n resources: [`arn:aws:ses:${scope.region}:${scope.account}:identity/${props.sendingAddress}`],\n });\n }\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"github-actions.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/github-actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAUjC,MAAM,WAAW,kCAAkC;IACjD;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAYD,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,kCAAkC,CAAC;CAChD;AAyBD;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,SAAQ,MAAM;gBACjC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,wBAAwB;CAmB5D"}
1
+ {"version":3,"file":"github-actions.d.ts","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/github-actions.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAC1C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAgBjC,MAAM,WAAW,kCAAkC;IACjD;;OAEG;IACH,kBAAkB,EAAE,MAAM,CAAC;IAE3B;;OAEG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAYD,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,QAAQ,EAAE,QAAQ,EAAE,CAAC;IAErB;;;OAGG;IACH,SAAS,CAAC,EAAE,kCAAkC,CAAC;CAChD;AAyBD;;;;;;;;GAQG;AACH,qBAAa,mBAAoB,SAAQ,MAAM;gBACjC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,wBAAwB;CAmB5D"}
@@ -7,9 +7,15 @@ const roles_1 = require("./roles");
7
7
  const GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN = "token.actions.githubusercontent.com";
8
8
  /*
9
9
  Thumbprint of `GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN`.
10
- See: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
10
+
11
+ See:
12
+ - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html
13
+ - https://github.blog/changelog/2023-06-27-github-actions-update-on-oidc-integration-with-aws/
11
14
  */
12
- const GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN_THUMBPRINT = "6938fd4d98bab03faadb97b34396831e3780aea1";
15
+ const GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN_THUMBPRINTS = [
16
+ "6938fd4d98bab03faadb97b34396831e3780aea1",
17
+ "1c58a3a8518e8759bf075b76b750d4f2df264fcd",
18
+ ];
13
19
  const GuGithubActionsRepositoryCondition = {
14
20
  toString: ({ githubOrganisation, repositories }) => `repo:${githubOrganisation}/${repositories ?? "*"}`,
15
21
  };
@@ -34,7 +40,7 @@ class GitHubOidcProvider extends aws_cdk_lib_1.CfnResource {
34
40
  properties: {
35
41
  Url: `https://${GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN}`,
36
42
  ClientIdList: ["sts.amazonaws.com"],
37
- ThumbprintList: [GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN_THUMBPRINT],
43
+ ThumbprintList: GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN_THUMBPRINTS,
38
44
  },
39
45
  });
40
46
  }
@@ -1 +1 @@
1
- {"version":3,"file":"github-actions.js","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/github-actions.ts"],"names":[],"mappings":";;;AAAA,6CAAqD;AACrD,iDAAyD;AAGzD,mCAAiC;AAEjC,MAAM,sCAAsC,GAAG,qCAAqC,CAAC;AAErF;;;EAGE;AACF,MAAM,iDAAiD,GAAG,0CAA0C,CAAC;AAcrG,MAAM,kCAAkC,GAAG;IACzC,QAAQ,EAAE,CAAC,EAAE,kBAAkB,EAAE,YAAY,EAAsC,EAAU,EAAE,CAC7F,QAAQ,kBAAkB,IAAI,YAAY,IAAI,GAAG,EAAE;CACtD,CAAC;AAEF,MAAM,yBAAyB,GAAuC;IACpE,kBAAkB,EAAE,UAAU;IAC9B,YAAY,EAAE,GAAG;CAClB,CAAC;AAeF;;;;;;;;;GASG;AACH,MAAM,kBAAmB,SAAQ,yBAAW;IAC1C,YAAY,KAAc;QACxB,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,IAAI,EAAE,wBAAwB;YAC9B,UAAU,EAAE;gBACV,GAAG,EAAE,WAAW,sCAAsC,EAAE;gBACxD,YAAY,EAAE,CAAC,mBAAmB,CAAC;gBACnC,cAAc,EAAE,CAAC,iDAAiD,CAAC;aACpE;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAa,mBAAoB,SAAQ,cAAM;IAC7C,YAAY,KAAc,EAAE,KAA+B;QACzD,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,SAAS,EAAE,IAAI,4BAAkB,CAC/B,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC,GAAG,EACjC;gBACE,UAAU,EAAE;oBACV,CAAC,GAAG,sCAAsC,MAAM,CAAC,EAAE,kCAAkC,CAAC,QAAQ,CAC5F,KAAK,CAAC,SAAS,IAAI,yBAAyB,CAC7C;iBACF;aACF,EACD,+BAA+B,CAChC;SACF,CAAC,CAAC;QAEH,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAEpD,IAAI,uBAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;CACF;AApBD,kDAoBC","sourcesContent":["import { CfnOutput, CfnResource } from \"aws-cdk-lib\";\nimport { FederatedPrincipal } from \"aws-cdk-lib/aws-iam\";\nimport type { GuStack } from \"../../core\";\nimport type { GuPolicy } from \"../policies\";\nimport { GuRole } from \"./roles\";\n\nconst GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN = \"token.actions.githubusercontent.com\";\n\n/*\nThumbprint of `GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN`.\nSee: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html\n*/\nconst GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN_THUMBPRINT = \"6938fd4d98bab03faadb97b34396831e3780aea1\";\n\nexport interface GuGithubActionsRepositoryCondition {\n /**\n * The GitHub organisation/user to constrain the IAM Role to.\n */\n githubOrganisation: string;\n\n /**\n * Repositories to constrain the IAM Role to.\n */\n repositories?: string;\n}\n\nconst GuGithubActionsRepositoryCondition = {\n toString: ({ githubOrganisation, repositories }: GuGithubActionsRepositoryCondition): string =>\n `repo:${githubOrganisation}/${repositories ?? \"*\"}`,\n};\n\nconst ALL_GUARDIAN_REPOSITORIES: GuGithubActionsRepositoryCondition = {\n githubOrganisation: \"guardian\",\n repositories: \"*\",\n};\n\nexport interface GuGithubActionsRoleProps {\n /**\n * A list of IAM Policies for the GitHub Action.\n */\n policies: GuPolicy[];\n\n /**\n * Repositories where GitHub Actions can assumes this role.\n * Defaults to [[`ALL_GUARDIAN_REPOSITORIES`]].\n */\n condition?: GuGithubActionsRepositoryCondition;\n}\n\n/*\nAWS CDK implements an OIDCProvider as a custom resource.\nThis requires a lambda to be deployed into the account.\nAs far as I can tell, the lambda is automating the setting of `ThumbprintList`, which is quite generic.\nIt's simpler for us to be specific here.\n\nSee:\n - https://github.com/aws/aws-cdk/blob/851c8ca9989856fa61496ff113f9cb8c66d02f3b/packages/%40aws-cdk/aws-iam/lib/oidc-provider.ts\n - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html\n */\nclass GitHubOidcProvider extends CfnResource {\n constructor(scope: GuStack) {\n super(scope, \"GithubActionsOidc\", {\n type: \"AWS::IAM::OIDCProvider\",\n properties: {\n Url: `https://${GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN}`,\n ClientIdList: [\"sts.amazonaws.com\"],\n ThumbprintList: [GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN_THUMBPRINT],\n },\n });\n }\n}\n\n/**\n * A construct to create an IAM role for GitHub Actions to assume via `AssumeRoleWithWebIdentity`.\n *\n * An Output will be added to the stack with the Role's ARN for use with https://github.com/aws-actions/configure-aws-credentials.\n *\n * See:\n * - https://github.com/aws-actions/configure-aws-credentials\n * - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html\n */\nexport class GuGithubActionsRole extends GuRole {\n constructor(scope: GuStack, props: GuGithubActionsRoleProps) {\n super(scope, \"GithubActionsRole\", {\n assumedBy: new FederatedPrincipal(\n new GitHubOidcProvider(scope).ref,\n {\n StringLike: {\n [`${GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN}:sub`]: GuGithubActionsRepositoryCondition.toString(\n props.condition ?? ALL_GUARDIAN_REPOSITORIES\n ),\n },\n },\n \"sts:AssumeRoleWithWebIdentity\"\n ),\n });\n\n props.policies.forEach((p) => p.attachToRole(this));\n\n new CfnOutput(this, `${this.node.id}-Arn`, { value: this.roleArn });\n }\n}\n"]}
1
+ {"version":3,"file":"github-actions.js","sourceRoot":"","sources":["../../../../src/constructs/iam/roles/github-actions.ts"],"names":[],"mappings":";;;AAAA,6CAAqD;AACrD,iDAAyD;AAGzD,mCAAiC;AAEjC,MAAM,sCAAsC,GAAG,qCAAqC,CAAC;AAErF;;;;;;EAME;AACF,MAAM,kDAAkD,GAAG;IACzD,0CAA0C;IAC1C,0CAA0C;CAC3C,CAAC;AAcF,MAAM,kCAAkC,GAAG;IACzC,QAAQ,EAAE,CAAC,EAAE,kBAAkB,EAAE,YAAY,EAAsC,EAAU,EAAE,CAC7F,QAAQ,kBAAkB,IAAI,YAAY,IAAI,GAAG,EAAE;CACtD,CAAC;AAEF,MAAM,yBAAyB,GAAuC;IACpE,kBAAkB,EAAE,UAAU;IAC9B,YAAY,EAAE,GAAG;CAClB,CAAC;AAeF;;;;;;;;;GASG;AACH,MAAM,kBAAmB,SAAQ,yBAAW;IAC1C,YAAY,KAAc;QACxB,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,IAAI,EAAE,wBAAwB;YAC9B,UAAU,EAAE;gBACV,GAAG,EAAE,WAAW,sCAAsC,EAAE;gBACxD,YAAY,EAAE,CAAC,mBAAmB,CAAC;gBACnC,cAAc,EAAE,kDAAkD;aACnE;SACF,CAAC,CAAC;IACL,CAAC;CACF;AAED;;;;;;;;GAQG;AACH,MAAa,mBAAoB,SAAQ,cAAM;IAC7C,YAAY,KAAc,EAAE,KAA+B;QACzD,KAAK,CAAC,KAAK,EAAE,mBAAmB,EAAE;YAChC,SAAS,EAAE,IAAI,4BAAkB,CAC/B,IAAI,kBAAkB,CAAC,KAAK,CAAC,CAAC,GAAG,EACjC;gBACE,UAAU,EAAE;oBACV,CAAC,GAAG,sCAAsC,MAAM,CAAC,EAAE,kCAAkC,CAAC,QAAQ,CAC5F,KAAK,CAAC,SAAS,IAAI,yBAAyB,CAC7C;iBACF;aACF,EACD,+BAA+B,CAChC;SACF,CAAC,CAAC;QAEH,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC;QAEpD,IAAI,uBAAS,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;IACtE,CAAC;CACF;AApBD,kDAoBC","sourcesContent":["import { CfnOutput, CfnResource } from \"aws-cdk-lib\";\nimport { FederatedPrincipal } from \"aws-cdk-lib/aws-iam\";\nimport type { GuStack } from \"../../core\";\nimport type { GuPolicy } from \"../policies\";\nimport { GuRole } from \"./roles\";\n\nconst GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN = \"token.actions.githubusercontent.com\";\n\n/*\nThumbprint of `GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN`.\n\nSee:\n - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc_verify-thumbprint.html\n - https://github.blog/changelog/2023-06-27-github-actions-update-on-oidc-integration-with-aws/\n*/\nconst GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN_THUMBPRINTS = [\n \"6938fd4d98bab03faadb97b34396831e3780aea1\",\n \"1c58a3a8518e8759bf075b76b750d4f2df264fcd\",\n];\n\nexport interface GuGithubActionsRepositoryCondition {\n /**\n * The GitHub organisation/user to constrain the IAM Role to.\n */\n githubOrganisation: string;\n\n /**\n * Repositories to constrain the IAM Role to.\n */\n repositories?: string;\n}\n\nconst GuGithubActionsRepositoryCondition = {\n toString: ({ githubOrganisation, repositories }: GuGithubActionsRepositoryCondition): string =>\n `repo:${githubOrganisation}/${repositories ?? \"*\"}`,\n};\n\nconst ALL_GUARDIAN_REPOSITORIES: GuGithubActionsRepositoryCondition = {\n githubOrganisation: \"guardian\",\n repositories: \"*\",\n};\n\nexport interface GuGithubActionsRoleProps {\n /**\n * A list of IAM Policies for the GitHub Action.\n */\n policies: GuPolicy[];\n\n /**\n * Repositories where GitHub Actions can assumes this role.\n * Defaults to [[`ALL_GUARDIAN_REPOSITORIES`]].\n */\n condition?: GuGithubActionsRepositoryCondition;\n}\n\n/*\nAWS CDK implements an OIDCProvider as a custom resource.\nThis requires a lambda to be deployed into the account.\nAs far as I can tell, the lambda is automating the setting of `ThumbprintList`, which is quite generic.\nIt's simpler for us to be specific here.\n\nSee:\n - https://github.com/aws/aws-cdk/blob/851c8ca9989856fa61496ff113f9cb8c66d02f3b/packages/%40aws-cdk/aws-iam/lib/oidc-provider.ts\n - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html\n */\nclass GitHubOidcProvider extends CfnResource {\n constructor(scope: GuStack) {\n super(scope, \"GithubActionsOidc\", {\n type: \"AWS::IAM::OIDCProvider\",\n properties: {\n Url: `https://${GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN}`,\n ClientIdList: [\"sts.amazonaws.com\"],\n ThumbprintList: GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN_THUMBPRINTS,\n },\n });\n }\n}\n\n/**\n * A construct to create an IAM role for GitHub Actions to assume via `AssumeRoleWithWebIdentity`.\n *\n * An Output will be added to the stack with the Role's ARN for use with https://github.com/aws-actions/configure-aws-credentials.\n *\n * See:\n * - https://github.com/aws-actions/configure-aws-credentials\n * - https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_create_oidc.html\n */\nexport class GuGithubActionsRole extends GuRole {\n constructor(scope: GuStack, props: GuGithubActionsRoleProps) {\n super(scope, \"GithubActionsRole\", {\n assumedBy: new FederatedPrincipal(\n new GitHubOidcProvider(scope).ref,\n {\n StringLike: {\n [`${GITHUB_ACTIONS_ID_TOKEN_REQUEST_DOMAIN}:sub`]: GuGithubActionsRepositoryCondition.toString(\n props.condition ?? ALL_GUARDIAN_REPOSITORIES\n ),\n },\n },\n \"sts:AssumeRoleWithWebIdentity\"\n ),\n });\n\n props.policies.forEach((p) => p.attachToRole(this));\n\n new CfnOutput(this, `${this.node.id}-Arn`, { value: this.roleArn });\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": "50.8.0",
4
+ "version": "50.8.2",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
7
7
  "files": [
@@ -1,6 +0,0 @@
1
- import type { GuStack } from "../stack";
2
- import { GuStringParameter } from "./base";
3
- export declare class GuGuardianEmailSenderParameter extends GuStringParameter {
4
- constructor(scope: GuStack);
5
- }
6
- //# sourceMappingURL=ses.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ses.d.ts","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/ses.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAE3C,qBAAa,8BAA+B,SAAQ,iBAAiB;gBACvD,KAAK,EAAE,OAAO;CAO3B"}
@@ -1,16 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.GuGuardianEmailSenderParameter = void 0;
4
- const constants_1 = require("../../../constants");
5
- const base_1 = require("./base");
6
- class GuGuardianEmailSenderParameter extends base_1.GuStringParameter {
7
- constructor(scope) {
8
- super(scope, "EmailSenderAddress", {
9
- allowedPattern: constants_1.RegexPattern.GUARDIAN_EMAIL,
10
- constraintDescription: "Must be an @theguardian.com email address",
11
- description: "The sender of emails sent using SES.",
12
- });
13
- }
14
- }
15
- exports.GuGuardianEmailSenderParameter = GuGuardianEmailSenderParameter;
16
- //# sourceMappingURL=ses.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ses.js","sourceRoot":"","sources":["../../../../src/constructs/core/parameters/ses.ts"],"names":[],"mappings":";;;AAAA,kDAAkD;AAElD,iCAA2C;AAE3C,MAAa,8BAA+B,SAAQ,wBAAiB;IACnE,YAAY,KAAc;QACxB,KAAK,CAAC,KAAK,EAAE,oBAAoB,EAAE;YACjC,cAAc,EAAE,wBAAY,CAAC,cAAc;YAC3C,qBAAqB,EAAE,2CAA2C;YAClE,WAAW,EAAE,sCAAsC;SACpD,CAAC,CAAC;IACL,CAAC;CACF;AARD,wEAQC","sourcesContent":["import { RegexPattern } from \"../../../constants\";\nimport type { GuStack } from \"../stack\";\nimport { GuStringParameter } from \"./base\";\n\nexport class GuGuardianEmailSenderParameter extends GuStringParameter {\n constructor(scope: GuStack) {\n super(scope, \"EmailSenderAddress\", {\n allowedPattern: RegexPattern.GUARDIAN_EMAIL,\n constraintDescription: \"Must be an @theguardian.com email address\",\n description: \"The sender of emails sent using SES.\",\n });\n }\n}\n"]}