Skip to content

Commit 9dbec8a

Browse files
surukondabiffgaut
andauthored
fix(aws-apigateway-kinesisstreams): Update construct to match DESIGN_GUIDELINES.md (#395)
* enhance aws-apigateway-kinesisstreams construct with best practice cloudwatch.Alarms * add missing package.json file * fix tests Co-authored-by: santhosh <> Co-authored-by: biffgaut <[email protected]>
1 parent 3aca3c0 commit 9dbec8a

File tree

7 files changed

+109
-4
lines changed

7 files changed

+109
-4
lines changed

source/patterns/@aws-solutions-constructs/aws-apigateway-kinesisstreams/README.md

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ _Parameters_
5959
|existingStreamObj?|[`kinesis.Stream`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-kinesis.Stream.html)|Existing instance of Kinesis Stream, providing both this and `kinesisStreamProps` will cause an error.|
6060
|kinesisStreamProps?|[`kinesis.StreamProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-kinesis.StreamProps.html)|Optional user-provided props to override the default props for the Kinesis stream.|
6161
|logGroupProps?|[`logs.LogGroupProps`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.LogGroupProps.html)|User provided props to override the default props for for the CloudWatchLogs LogGroup.|
62+
|createCloudWatchAlarms|`boolean`|Whether to create recommended CloudWatch alarms for Kinesis Data Stream. Default value is set to `true`|
6263

6364
## Pattern Properties
6465

@@ -69,6 +70,7 @@ _Parameters_
6970
|apiGatewayCloudWatchRole|[`iam.Role`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-iam.Role.html)|Returns an instance of the iam.Role created by the construct for API Gateway for CloudWatch access.|
7071
|apiGatewayLogGroup|[`logs.LogGroup`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-logs.LogGroup.html)|Returns an instance of the LogGroup created by the construct for API Gateway access logging to CloudWatch.|
7172
|kinesisStream|[`kinesis.Stream`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-kinesis.Stream.html)|Returns an instance of the Kinesis stream created or used by the pattern.|
73+
|cloudwatchAlarms?|[`cloudwatch.Alarm[]`](https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_aws-cloudwatch.Alarm.html)|Returns an array of recommended CloudWatch Alarms created by the construct for Kinesis Data stream|
7274

7375
## Sample API Usage
7476

source/patterns/@aws-solutions-constructs/aws-apigateway-kinesisstreams/lib/index.ts

+13
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import * as defaults from '@aws-solutions-constructs/core';
1919
// Note: To ensure CDKv2 compatibility, keep the import statement for Construct separate
2020
import { Construct } from '@aws-cdk/core';
2121
import * as logs from '@aws-cdk/aws-logs';
22+
import * as cloudwatch from '@aws-cdk/aws-cloudwatch';
2223

2324
/**
2425
* @summary The properties for the ApiGatewayToKinesisStreamsProps class.
@@ -81,6 +82,12 @@ export interface ApiGatewayToKinesisStreamsProps {
8182
* @default - Default props are used
8283
*/
8384
readonly logGroupProps?: logs.LogGroupProps
85+
/**
86+
* Whether to create recommended CloudWatch alarms
87+
*
88+
* @default - Alarms are created
89+
*/
90+
readonly createCloudWatchAlarms?: boolean;
8491
}
8592

8693
/**
@@ -92,6 +99,7 @@ export class ApiGatewayToKinesisStreams extends Construct {
9299
public readonly apiGatewayCloudWatchRole: iam.Role;
93100
public readonly apiGatewayLogGroup: logs.LogGroup;
94101
public readonly kinesisStream: kinesis.Stream;
102+
public readonly cloudwatchAlarms?: cloudwatch.Alarm[];
95103

96104
/**
97105
* @summary Constructs a new instance of the ApiGatewayToKinesisStreams class.
@@ -154,6 +162,11 @@ export class ApiGatewayToKinesisStreams extends Construct {
154162
requestValidator,
155163
requestModel: { 'application/json': this.getPutRecordsModel(props.putRecordsRequestModel) }
156164
});
165+
166+
if (props.createCloudWatchAlarms === undefined || props.createCloudWatchAlarms) {
167+
// Deploy best practices CW Alarms for Kinesis Stream
168+
this.cloudwatchAlarms = defaults.buildKinesisStreamCWAlarms(this);
169+
}
157170
}
158171

159172
private getPutRecordTemplate(putRecordTemplate?: string): string {

source/patterns/@aws-solutions-constructs/aws-apigateway-kinesisstreams/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
"@aws-cdk/aws-iam": "0.0.0",
5959
"@aws-cdk/aws-kinesis": "0.0.0",
6060
"@aws-cdk/aws-logs": "0.0.0",
61+
"@aws-cdk/aws-cloudwatch": "0.0.0",
6162
"@aws-solutions-constructs/core": "0.0.0",
6263
"constructs": "^3.2.0"
6364
},
@@ -87,7 +88,8 @@
8788
"@aws-cdk/aws-kinesis": "0.0.0",
8889
"@aws-solutions-constructs/core": "0.0.0",
8990
"constructs": "^3.2.0",
90-
"@aws-cdk/aws-logs": "0.0.0"
91+
"@aws-cdk/aws-logs": "0.0.0",
92+
"@aws-cdk/aws-cloudwatch": "0.0.0"
9193
},
9294
"keywords": [
9395
"aws",

source/patterns/@aws-solutions-constructs/aws-apigateway-kinesisstreams/test/apigateway-kinesis.test.ts

+13-3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ test('Test construct properties', () => {
2929
expect(pattern.apiGatewayCloudWatchRole !== null);
3030
expect(pattern.apiGatewayLogGroup !== null);
3131
expect(pattern.kinesisStream !== null);
32+
expect(pattern.cloudwatchAlarms !== null);
3233
});
3334

3435
// --------------------------------------------------------------
@@ -80,24 +81,33 @@ test('Test deployment w/ overwritten properties', () => {
8081
ShardCount: 1,
8182
Name: 'my-stream'
8283
});
84+
85+
// Test for Cloudwatch Alarms
86+
expect(stack).toCountResources('AWS::CloudWatch::Alarm', 2);
8387
});
8488

8589
// --------------------------------------------------------------
86-
// Test deployment w/ existing stream
90+
// Test deployment w/ existing stream without default cloudwatch alarms
8791
// --------------------------------------------------------------
8892
test('Test deployment w/ existing stream', () => {
8993
const stack = new Stack();
9094

91-
new ApiGatewayToKinesisStreams(stack, 'api-gateway-kinesis', {
95+
const construct = new ApiGatewayToKinesisStreams(stack, 'api-gateway-kinesis', {
9296
apiGatewayProps: {},
9397
existingStreamObj: new kinesis.Stream(stack, 'ExistingStream', {
9498
shardCount: 5,
9599
retentionPeriod: Duration.days(4)
96-
})
100+
}),
101+
createCloudWatchAlarms: false
97102
});
98103

99104
expect(stack).toHaveResource('AWS::Kinesis::Stream', {
100105
ShardCount: 5,
101106
RetentionPeriodHours: 96
102107
});
108+
109+
expect(construct.cloudwatchAlarms == null);
110+
111+
// Since createCloudWatchAlars is set to false, no Alarm should exist
112+
expect(stack).not.toHaveResource('AWS::CloudWatch::Alarm');
103113
});

source/patterns/@aws-solutions-constructs/aws-apigateway-kinesisstreams/test/integ.apigateway-kinesis-overwrite.expected.json

+26
Original file line numberDiff line numberDiff line change
@@ -477,6 +477,32 @@
477477
]
478478
}
479479
},
480+
"testapigatewaykinesisoverwriteKinesisStreamGetRecordsIteratorAgeAlarmAF0BEF52": {
481+
"Type": "AWS::CloudWatch::Alarm",
482+
"Properties": {
483+
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
484+
"EvaluationPeriods": 1,
485+
"AlarmDescription": "Consumer Record Processing Falling Behind, there is risk for data loss due to record expiration.",
486+
"MetricName": "GetRecords.IteratorAgeMilliseconds",
487+
"Namespace": "AWS/Kinesis",
488+
"Period": 300,
489+
"Statistic": "Maximum",
490+
"Threshold": 2592000
491+
}
492+
},
493+
"testapigatewaykinesisoverwriteKinesisStreamReadProvisionedThroughputExceededAlarm5C0040FB": {
494+
"Type": "AWS::CloudWatch::Alarm",
495+
"Properties": {
496+
"ComparisonOperator": "GreaterThanThreshold",
497+
"EvaluationPeriods": 1,
498+
"AlarmDescription": "Consumer Application is Reading at a Slower Rate Than Expected.",
499+
"MetricName": "ReadProvisionedThroughputExceeded",
500+
"Namespace": "AWS/Kinesis",
501+
"Period": 300,
502+
"Statistic": "Average",
503+
"Threshold": 0
504+
}
505+
},
480506
"KinesisStream46752A3E": {
481507
"Type": "AWS::Kinesis::Stream",
482508
"Properties": {

source/patterns/@aws-solutions-constructs/aws-apigateway-kinesisstreams/test/integ.no-arguments.expected.json

+26
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,32 @@
514514
]
515515
}
516516
},
517+
"testapigatewaykinesisdefaultKinesisStreamGetRecordsIteratorAgeAlarm0638BB32": {
518+
"Type": "AWS::CloudWatch::Alarm",
519+
"Properties": {
520+
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
521+
"EvaluationPeriods": 1,
522+
"AlarmDescription": "Consumer Record Processing Falling Behind, there is risk for data loss due to record expiration.",
523+
"MetricName": "GetRecords.IteratorAgeMilliseconds",
524+
"Namespace": "AWS/Kinesis",
525+
"Period": 300,
526+
"Statistic": "Maximum",
527+
"Threshold": 2592000
528+
}
529+
},
530+
"testapigatewaykinesisdefaultKinesisStreamReadProvisionedThroughputExceededAlarmE7251F6A": {
531+
"Type": "AWS::CloudWatch::Alarm",
532+
"Properties": {
533+
"ComparisonOperator": "GreaterThanThreshold",
534+
"EvaluationPeriods": 1,
535+
"AlarmDescription": "Consumer Application is Reading at a Slower Rate Than Expected.",
536+
"MetricName": "ReadProvisionedThroughputExceeded",
537+
"Namespace": "AWS/Kinesis",
538+
"Period": 300,
539+
"Statistic": "Average",
540+
"Threshold": 0
541+
}
542+
},
517543
"KinesisStream46752A3E": {
518544
"Type": "AWS::Kinesis::Stream",
519545
"Properties": {

source/patterns/@aws-solutions-constructs/aws-wafwebacl-apigateway/test/integ.wafwebacl-apigateway-kinesisstreams.expected.json

+26
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,32 @@
513513
]
514514
}
515515
},
516+
"ApiGatwayToKinesisStreamsKinesisStreamGetRecordsIteratorAgeAlarm1705B52A": {
517+
"Type": "AWS::CloudWatch::Alarm",
518+
"Properties": {
519+
"ComparisonOperator": "GreaterThanOrEqualToThreshold",
520+
"EvaluationPeriods": 1,
521+
"AlarmDescription": "Consumer Record Processing Falling Behind, there is risk for data loss due to record expiration.",
522+
"MetricName": "GetRecords.IteratorAgeMilliseconds",
523+
"Namespace": "AWS/Kinesis",
524+
"Period": 300,
525+
"Statistic": "Maximum",
526+
"Threshold": 2592000
527+
}
528+
},
529+
"ApiGatwayToKinesisStreamsKinesisStreamReadProvisionedThroughputExceededAlarm69C57002": {
530+
"Type": "AWS::CloudWatch::Alarm",
531+
"Properties": {
532+
"ComparisonOperator": "GreaterThanThreshold",
533+
"EvaluationPeriods": 1,
534+
"AlarmDescription": "Consumer Application is Reading at a Slower Rate Than Expected.",
535+
"MetricName": "ReadProvisionedThroughputExceeded",
536+
"Namespace": "AWS/Kinesis",
537+
"Period": 300,
538+
"Statistic": "Average",
539+
"Threshold": 0
540+
}
541+
},
516542
"KinesisStream46752A3E": {
517543
"Type": "AWS::Kinesis::Stream",
518544
"Properties": {

0 commit comments

Comments
 (0)