-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add new pattern for API Gateway with routing to multiple Lambdas (
#1250) * refactor!: renaming and reorganisation to make space for new API Lambda pattern BREAKING CHANGE: A small number of types/classes have been renamed or relocated. 1. The Http5xxAlarmProps type should now be imported from "@guardian/cdk/lib/constructs/cloudwatch" 2. The Gu5xxPercentageAlarm construct is renamed: GuAlb5xxPercentageAlarm 3. The Gu5xxPercentageAlarmProps type is renamed: GuAlb5xxPercentageAlarmProps * feat: add new pattern for API Gateway with routing to multiple Lambdas * docs: add better documentation for new pattern and explain use-cases
- Loading branch information
1 parent
5840385
commit a43211e
Showing
13 changed files
with
1,848 additions
and
25 deletions.
There are no files selected for viewing
276 changes: 276 additions & 0 deletions
276
src/constructs/cloudwatch/__snapshots__/api-gateway-alarms.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,276 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`The GuApiGateway5xxPercentageAlarm construct should create the correct alarm resource with minimal config 1`] = ` | ||
Object { | ||
"Outputs": Object { | ||
"RestApiEndpoint0551178A": Object { | ||
"Value": Object { | ||
"Fn::Join": Array [ | ||
"", | ||
Array [ | ||
"https://", | ||
Object { | ||
"Ref": "RestApi0C43BF4B", | ||
}, | ||
".execute-api.", | ||
Object { | ||
"Ref": "AWS::Region", | ||
}, | ||
".", | ||
Object { | ||
"Ref": "AWS::URLSuffix", | ||
}, | ||
"/", | ||
Object { | ||
"Ref": "RestApiDeploymentStageprod3855DE66", | ||
}, | ||
"/", | ||
], | ||
], | ||
}, | ||
}, | ||
}, | ||
"Resources": Object { | ||
"ApiGatewayHigh5xxPercentageAlarmTesting67154503": Object { | ||
"Properties": Object { | ||
"ActionsEnabled": true, | ||
"AlarmActions": Array [ | ||
Object { | ||
"Fn::Join": Array [ | ||
"", | ||
Array [ | ||
"arn:aws:sns:", | ||
Object { | ||
"Ref": "AWS::Region", | ||
}, | ||
":", | ||
Object { | ||
"Ref": "AWS::AccountId", | ||
}, | ||
":test-topic", | ||
], | ||
], | ||
}, | ||
], | ||
"AlarmDescription": "testing exceeded 1% error rate", | ||
"AlarmName": "High 5XX error % from testing (ApiGateway) in TEST", | ||
"ComparisonOperator": "GreaterThanThreshold", | ||
"EvaluationPeriods": 1, | ||
"Metrics": Array [ | ||
Object { | ||
"Expression": "100*m1/m2", | ||
"Id": "expr_1", | ||
"Label": "% of 5XX responses served for testing", | ||
}, | ||
Object { | ||
"Id": "m1", | ||
"MetricStat": Object { | ||
"Metric": Object { | ||
"Dimensions": Array [ | ||
Object { | ||
"Name": "ApiName", | ||
"Value": "RestApi", | ||
}, | ||
], | ||
"MetricName": "5XXError", | ||
"Namespace": "AWS/ApiGateway", | ||
}, | ||
"Period": 60, | ||
"Stat": "Sum", | ||
}, | ||
"ReturnData": false, | ||
}, | ||
Object { | ||
"Id": "m2", | ||
"MetricStat": Object { | ||
"Metric": Object { | ||
"Dimensions": Array [ | ||
Object { | ||
"Name": "ApiName", | ||
"Value": "RestApi", | ||
}, | ||
], | ||
"MetricName": "Count", | ||
"Namespace": "AWS/ApiGateway", | ||
}, | ||
"Period": 60, | ||
"Stat": "SampleCount", | ||
}, | ||
"ReturnData": false, | ||
}, | ||
], | ||
"Threshold": 1, | ||
"TreatMissingData": "notBreaching", | ||
}, | ||
"Type": "AWS::CloudWatch::Alarm", | ||
}, | ||
"RestApi0C43BF4B": Object { | ||
"Properties": Object { | ||
"Name": "RestApi", | ||
"Tags": Array [ | ||
Object { | ||
"Key": "gu:cdk:version", | ||
"Value": "TEST", | ||
}, | ||
Object { | ||
"Key": "gu:repo", | ||
"Value": "guardian/cdk", | ||
}, | ||
Object { | ||
"Key": "Stack", | ||
"Value": "test-stack", | ||
}, | ||
Object { | ||
"Key": "Stage", | ||
"Value": "TEST", | ||
}, | ||
], | ||
}, | ||
"Type": "AWS::ApiGateway::RestApi", | ||
}, | ||
"RestApiAccount7C83CF5A": Object { | ||
"DependsOn": Array [ | ||
"RestApi0C43BF4B", | ||
], | ||
"Properties": Object { | ||
"CloudWatchRoleArn": Object { | ||
"Fn::GetAtt": Array [ | ||
"RestApiCloudWatchRoleE3ED6605", | ||
"Arn", | ||
], | ||
}, | ||
}, | ||
"Type": "AWS::ApiGateway::Account", | ||
}, | ||
"RestApiCloudWatchRoleE3ED6605": Object { | ||
"Properties": Object { | ||
"AssumeRolePolicyDocument": Object { | ||
"Statement": Array [ | ||
Object { | ||
"Action": "sts:AssumeRole", | ||
"Effect": "Allow", | ||
"Principal": Object { | ||
"Service": "apigateway.amazonaws.com", | ||
}, | ||
}, | ||
], | ||
"Version": "2012-10-17", | ||
}, | ||
"ManagedPolicyArns": Array [ | ||
Object { | ||
"Fn::Join": Array [ | ||
"", | ||
Array [ | ||
"arn:", | ||
Object { | ||
"Ref": "AWS::Partition", | ||
}, | ||
":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs", | ||
], | ||
], | ||
}, | ||
], | ||
"Tags": Array [ | ||
Object { | ||
"Key": "gu:cdk:version", | ||
"Value": "TEST", | ||
}, | ||
Object { | ||
"Key": "gu:repo", | ||
"Value": "guardian/cdk", | ||
}, | ||
Object { | ||
"Key": "Stack", | ||
"Value": "test-stack", | ||
}, | ||
Object { | ||
"Key": "Stage", | ||
"Value": "TEST", | ||
}, | ||
], | ||
}, | ||
"Type": "AWS::IAM::Role", | ||
}, | ||
"RestApiDeployment180EC50354bd4ad342d73c9ba2d68e58585d62d5": Object { | ||
"DependsOn": Array [ | ||
"RestApiGET0F59260B", | ||
"RestApitest9059D171", | ||
], | ||
"Properties": Object { | ||
"Description": "Automatically created by the RestApi construct", | ||
"RestApiId": Object { | ||
"Ref": "RestApi0C43BF4B", | ||
}, | ||
}, | ||
"Type": "AWS::ApiGateway::Deployment", | ||
}, | ||
"RestApiDeploymentStageprod3855DE66": Object { | ||
"DependsOn": Array [ | ||
"RestApiAccount7C83CF5A", | ||
], | ||
"Properties": Object { | ||
"DeploymentId": Object { | ||
"Ref": "RestApiDeployment180EC50354bd4ad342d73c9ba2d68e58585d62d5", | ||
}, | ||
"RestApiId": Object { | ||
"Ref": "RestApi0C43BF4B", | ||
}, | ||
"StageName": "prod", | ||
"Tags": Array [ | ||
Object { | ||
"Key": "gu:cdk:version", | ||
"Value": "TEST", | ||
}, | ||
Object { | ||
"Key": "gu:repo", | ||
"Value": "guardian/cdk", | ||
}, | ||
Object { | ||
"Key": "Stack", | ||
"Value": "test-stack", | ||
}, | ||
Object { | ||
"Key": "Stage", | ||
"Value": "TEST", | ||
}, | ||
], | ||
}, | ||
"Type": "AWS::ApiGateway::Stage", | ||
}, | ||
"RestApiGET0F59260B": Object { | ||
"Properties": Object { | ||
"AuthorizationType": "NONE", | ||
"HttpMethod": "GET", | ||
"Integration": Object { | ||
"Type": "MOCK", | ||
}, | ||
"ResourceId": Object { | ||
"Fn::GetAtt": Array [ | ||
"RestApi0C43BF4B", | ||
"RootResourceId", | ||
], | ||
}, | ||
"RestApiId": Object { | ||
"Ref": "RestApi0C43BF4B", | ||
}, | ||
}, | ||
"Type": "AWS::ApiGateway::Method", | ||
}, | ||
"RestApitest9059D171": Object { | ||
"Properties": Object { | ||
"ParentId": Object { | ||
"Fn::GetAtt": Array [ | ||
"RestApi0C43BF4B", | ||
"RootResourceId", | ||
], | ||
}, | ||
"PathPart": "test", | ||
"RestApiId": Object { | ||
"Ref": "RestApi0C43BF4B", | ||
}, | ||
}, | ||
"Type": "AWS::ApiGateway::Resource", | ||
}, | ||
}, | ||
} | ||
`; |
2 changes: 1 addition & 1 deletion
2
src/constructs/cloudwatch/__snapshots__/ec2-alarms.test.ts.snap
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import { Template } from "aws-cdk-lib/assertions"; | ||
import { MockIntegration, RestApi } from "aws-cdk-lib/aws-apigateway"; | ||
import { simpleGuStackForTesting } from "../../utils/test"; | ||
import type { AppIdentity, GuStack } from "../core"; | ||
import { GuApiGateway5xxPercentageAlarm } from "./api-gateway-alarms"; | ||
|
||
const app: AppIdentity = { | ||
app: "testing", | ||
}; | ||
|
||
function setupBasicRestApi(stack: GuStack): RestApi { | ||
const restApi = new RestApi(stack, "RestApi", {}); | ||
restApi.root.addResource("test"); | ||
restApi.root.addMethod("GET", new MockIntegration()); | ||
return restApi; | ||
} | ||
|
||
describe("The GuApiGateway5xxPercentageAlarm construct", () => { | ||
it("should create the correct alarm resource with minimal config", () => { | ||
const stack = simpleGuStackForTesting(); | ||
const props = { | ||
tolerated5xxPercentage: 1, | ||
snsTopicName: "test-topic", | ||
}; | ||
new GuApiGateway5xxPercentageAlarm(stack, { ...app, apiGatewayInstance: setupBasicRestApi(stack), ...props }); | ||
expect(Template.fromStack(stack).toJSON()).toMatchSnapshot(); | ||
}); | ||
|
||
it("should use a custom description if one is provided", () => { | ||
const stack = simpleGuStackForTesting(); | ||
const props = { | ||
alarmDescription: "test-custom-alarm-description", | ||
tolerated5xxPercentage: 1, | ||
snsTopicName: "test-topic", | ||
}; | ||
new GuApiGateway5xxPercentageAlarm(stack, { ...app, apiGatewayInstance: setupBasicRestApi(stack), ...props }); | ||
Template.fromStack(stack).hasResourceProperties("AWS::CloudWatch::Alarm", { | ||
AlarmDescription: "test-custom-alarm-description", | ||
}); | ||
}); | ||
|
||
it("should use a custom alarm name if one is provided", () => { | ||
const stack = simpleGuStackForTesting(); | ||
const props = { | ||
alarmName: "test-custom-alarm-name", | ||
tolerated5xxPercentage: 1, | ||
snsTopicName: "test-topic", | ||
}; | ||
new GuApiGateway5xxPercentageAlarm(stack, { ...app, apiGatewayInstance: setupBasicRestApi(stack), ...props }); | ||
Template.fromStack(stack).hasResourceProperties("AWS::CloudWatch::Alarm", { | ||
AlarmName: "test-custom-alarm-name", | ||
}); | ||
}); | ||
|
||
it("should adjust the number of evaluation periods if a custom value is provided", () => { | ||
const stack = simpleGuStackForTesting(); | ||
const props = { | ||
tolerated5xxPercentage: 1, | ||
numberOfMinutesAboveThresholdBeforeAlarm: 3, | ||
snsTopicName: "test-topic", | ||
}; | ||
new GuApiGateway5xxPercentageAlarm(stack, { ...app, apiGatewayInstance: setupBasicRestApi(stack), ...props }); | ||
Template.fromStack(stack).hasResourceProperties("AWS::CloudWatch::Alarm", { | ||
EvaluationPeriods: 3, | ||
}); | ||
}); | ||
}); |
Oops, something went wrong.