@liflig/cdk 2.18.5 → 2.18.6
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/assets/cloudtrail-slack-integration-lambda/main.py +267 -0
- package/assets/pipeline-slack-notification-lambda/index.py +300 -0
- package/assets/prepare-cdk-source-lambda/index.py +159 -0
- package/assets/slack-alarm-lambda/index.py +103 -0
- package/lib/alarms/database-alarms.d.ts +125 -0
- package/lib/alarms/database-alarms.js +171 -0
- package/lib/alarms/index.d.ts +3 -0
- package/lib/alarms/index.js +10 -0
- package/lib/alarms/service-alarms.d.ts +145 -0
- package/lib/alarms/service-alarms.js +148 -0
- package/lib/alarms/ses-alarms.d.ts +67 -0
- package/lib/alarms/ses-alarms.js +49 -0
- package/lib/alarms/slack-alarm.d.ts +25 -0
- package/lib/alarms/slack-alarm.js +47 -0
- package/lib/bastion-host.d.ts +41 -0
- package/lib/bastion-host.js +86 -0
- package/lib/bin/cdk-create-snapshots.d.ts +2 -0
- package/lib/bin/fetch-pipeline-variables.d.ts +2 -0
- package/lib/build-artifacts/index.d.ts +68 -0
- package/lib/build-artifacts/index.js +118 -0
- package/lib/cdk-deploy/cdk-deploy.d.ts +63 -0
- package/lib/cdk-deploy/cdk-deploy.js +175 -0
- package/lib/cdk-deploy/index.d.ts +1 -0
- package/lib/cdk-deploy/index.js +6 -0
- package/lib/cdk-deploy/start-deploy-handler.d.ts +8 -0
- package/lib/cdk-deploy/start-deploy-handler.js +72 -0
- package/lib/cdk-deploy/status-handler.d.ts +6 -0
- package/lib/cdk-deploy/status-handler.js +83 -0
- package/lib/cdk-pipelines/cloud-assembly-lookup-handler.d.ts +6 -0
- package/lib/cdk-pipelines/cloud-assembly-lookup-handler.js +63 -0
- package/lib/cdk-pipelines/index.d.ts +3 -0
- package/lib/cdk-pipelines/index.js +10 -0
- package/lib/cdk-pipelines/liflig-cdk-pipeline.d.ts +110 -0
- package/lib/cdk-pipelines/liflig-cdk-pipeline.js +232 -0
- package/lib/cdk-pipelines/slack-notification.d.ts +51 -0
- package/lib/cdk-pipelines/slack-notification.js +54 -0
- package/lib/cdk-pipelines/variables.d.ts +15 -0
- package/lib/cdk-pipelines/variables.js +80 -0
- package/lib/cloudtrail-slack-integration/cloudtrail-slack-integration.d.ts +47 -0
- package/lib/cloudtrail-slack-integration/cloudtrail-slack-integration.js +211 -0
- package/lib/cloudtrail-slack-integration/index.d.ts +1 -0
- package/lib/cloudtrail-slack-integration/index.js +6 -0
- package/lib/configure-parameters/configure-parameters.d.ts +61 -0
- package/lib/configure-parameters/configure-parameters.js +94 -0
- package/lib/configure-parameters/index.d.ts +1 -0
- package/lib/configure-parameters/index.js +6 -0
- package/lib/cross-region-ssm-parameter.d.ts +13 -0
- package/lib/cross-region-ssm-parameter.js +46 -0
- package/lib/ecs/cluster.d.ts +25 -0
- package/lib/ecs/cluster.js +70 -0
- package/lib/ecs/fargate-service.d.ts +63 -0
- package/lib/ecs/fargate-service.js +98 -0
- package/lib/ecs/index.d.ts +3 -0
- package/lib/ecs/index.js +10 -0
- package/lib/ecs/listener-rule.d.ts +25 -0
- package/lib/ecs/listener-rule.js +27 -0
- package/lib/ecs-update-image/artifact-status.d.ts +39 -0
- package/lib/ecs-update-image/artifact-status.js +41 -0
- package/lib/ecs-update-image/ecs-update-image.d.ts +41 -0
- package/lib/ecs-update-image/ecs-update-image.js +98 -0
- package/lib/ecs-update-image/index.d.ts +3 -0
- package/lib/ecs-update-image/index.js +10 -0
- package/lib/ecs-update-image/start-deploy-handler.d.ts +6 -0
- package/lib/ecs-update-image/start-deploy-handler.js +104 -0
- package/lib/ecs-update-image/status-handler.d.ts +11 -0
- package/lib/ecs-update-image/status-handler.js +74 -0
- package/lib/ecs-update-image/tag.d.ts +47 -0
- package/lib/ecs-update-image/tag.js +67 -0
- package/lib/feature-flags.d.ts +18 -0
- package/lib/feature-flags.js +48 -0
- package/lib/griid/artefact-bucket.d.ts +7 -0
- package/lib/griid/artefact-bucket.js +30 -0
- package/lib/griid/index.d.ts +4 -0
- package/lib/griid/index.js +18 -0
- package/lib/hosted-zone-with-param.d.ts +29 -0
- package/lib/hosted-zone-with-param.js +65 -0
- package/lib/index.d.ts +32 -0
- package/lib/kinesis/index.d.ts +1 -0
- package/lib/kinesis/index.js +6 -0
- package/lib/kinesis/kinesis-to-datadog-stream.d.ts +28 -0
- package/lib/kinesis/kinesis-to-datadog-stream.js +126 -0
- package/lib/load-balancer/index.d.ts +1 -0
- package/lib/load-balancer/index.js +6 -0
- package/lib/load-balancer/load-balancer.d.ts +16 -0
- package/lib/load-balancer/load-balancer.js +60 -0
- package/lib/pipelines/conventions.d.ts +14 -0
- package/lib/pipelines/conventions.js +24 -0
- package/lib/pipelines/deploy-env.d.ts +18 -0
- package/lib/pipelines/deploy-env.js +96 -0
- package/lib/pipelines/index.d.ts +2 -0
- package/lib/pipelines/index.js +8 -0
- package/lib/pipelines/liflig-cdk-deployer-deps.d.ts +13 -0
- package/lib/pipelines/liflig-cdk-deployer-deps.js +35 -0
- package/lib/pipelines/pipeline.d.ts +78 -0
- package/lib/pipelines/pipeline.js +224 -0
- package/lib/platform/index.d.ts +1 -0
- package/lib/platform/index.js +7 -0
- package/lib/platform/platform.d.ts +37 -0
- package/lib/platform/platform.js +57 -0
- package/lib/rds/database.d.ts +49 -0
- package/lib/rds/database.js +60 -0
- package/lib/rds/index.d.ts +1 -0
- package/lib/rds/index.js +6 -0
- package/lib/ses/configurationsetdeliveryoptions/index.d.ts +26 -0
- package/lib/ses/configurationsetdeliveryoptions/index.js +48 -0
- package/lib/ses/configurationsetsnsdestination/handler.d.ts +17 -0
- package/lib/ses/configurationsetsnsdestination/handler.js +75 -0
- package/lib/ses/configurationsetsnsdestination/index.d.ts +29 -0
- package/lib/ses/configurationsetsnsdestination/index.js +75 -0
- package/lib/ses/index.d.ts +4 -0
- package/lib/ses/index.js +12 -0
- package/lib/ses/sesdomain/handler.d.ts +10 -0
- package/lib/ses/sesdomain/handler.js +82 -0
- package/lib/ses/sesdomain/index.d.ts +57 -0
- package/lib/ses/sesdomain/index.js +94 -0
- package/lib/ses/sesverifyemail/handler.d.ts +9 -0
- package/lib/ses/sesverifyemail/handler.js +25 -0
- package/lib/ses/sesverifyemail/index.d.ts +13 -0
- package/lib/ses/sesverifyemail/index.js +51 -0
- package/lib/snapshots.d.ts +4 -0
- package/lib/snapshots.js +214 -0
- package/lib/ssm-parameter-backed-resource.d.ts +45 -0
- package/lib/ssm-parameter-backed-resource.js +67 -0
- package/lib/ssm-parameter-reader.d.ts +21 -0
- package/lib/ssm-parameter-reader.js +48 -0
- package/lib/tags.d.ts +8 -0
- package/lib/tags.js +36 -0
- package/lib/utils.d.ts +2 -0
- package/lib/utils.js +17 -0
- package/lib/webapp/index.d.ts +3 -0
- package/lib/webapp/index.js +10 -0
- package/lib/webapp/monitor.d.ts +187 -0
- package/lib/webapp/monitor.js +156 -0
- package/lib/webapp/security-headers.d.ts +38 -0
- package/lib/webapp/security-headers.js +129 -0
- package/lib/webapp/webapp.d.ts +116 -0
- package/lib/webapp/webapp.js +118 -0
- package/lib/webapp-deploy-via-role.d.ts +25 -0
- package/lib/webapp-deploy-via-role.js +32 -0
- package/package.json +3 -2
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import * as cdk from "aws-cdk-lib";
|
|
2
|
+
import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch";
|
|
3
|
+
import * as logs from "aws-cdk-lib/aws-logs";
|
|
4
|
+
import * as constructs from "constructs";
|
|
5
|
+
export interface ServiceAlarmsProps extends cdk.StackProps {
|
|
6
|
+
/**
|
|
7
|
+
* The default action to use for CloudWatch alarm state changes
|
|
8
|
+
*/
|
|
9
|
+
action: cloudwatch.IAlarmAction;
|
|
10
|
+
/**
|
|
11
|
+
* The name of the ECS service.
|
|
12
|
+
*/
|
|
13
|
+
serviceName: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Various alarms and monitoring.
|
|
17
|
+
*
|
|
18
|
+
* By itself no alarms is created. Use the methods available
|
|
19
|
+
* to add alarms.
|
|
20
|
+
*
|
|
21
|
+
* See SlackAlarm construct for SNS Action.
|
|
22
|
+
*/
|
|
23
|
+
export declare class ServiceAlarms extends constructs.Construct {
|
|
24
|
+
private readonly action;
|
|
25
|
+
private readonly serviceName;
|
|
26
|
+
constructor(scope: constructs.Construct, id: string, props: ServiceAlarmsProps);
|
|
27
|
+
/**
|
|
28
|
+
* For logs stored as JSON, monitor log entries logged
|
|
29
|
+
* with level ERROR or higher, as well as any requests
|
|
30
|
+
* that causes 500 for logging with liflig-logging.
|
|
31
|
+
*/
|
|
32
|
+
addJsonErrorAlarm(props: {
|
|
33
|
+
logGroup: logs.ILogGroup;
|
|
34
|
+
alarmDescription?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Set to `false` to stop the alarm from sending OK events.
|
|
37
|
+
* @default true
|
|
38
|
+
* */
|
|
39
|
+
enableOkAction?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* An action to use for CloudWatch alarm state changes instead of the default action
|
|
42
|
+
*/
|
|
43
|
+
action?: cloudwatch.IAlarmAction;
|
|
44
|
+
}): void;
|
|
45
|
+
/**
|
|
46
|
+
* Sets up three CloudWatch Alarms for monitoring an ECS service behind a target group:
|
|
47
|
+
* 1) one that triggers if the target is responding with too many 5xx errors.
|
|
48
|
+
* 2) one that triggers if the 95% percentile of response times from the target is too high.
|
|
49
|
+
* 3) one that triggers if there are no healthy targets or if the load balancer fails to connect to targets.
|
|
50
|
+
*/
|
|
51
|
+
addTargetGroupAlarms(props: {
|
|
52
|
+
/**
|
|
53
|
+
* The full name of the target group.
|
|
54
|
+
*/
|
|
55
|
+
targetGroupFullName: string;
|
|
56
|
+
/**
|
|
57
|
+
* The full name of the application load balancer.
|
|
58
|
+
*/
|
|
59
|
+
loadBalancerFullName: string;
|
|
60
|
+
/**
|
|
61
|
+
* Configuration for a composite alarm.
|
|
62
|
+
*
|
|
63
|
+
* @default Configured with sane defaults.
|
|
64
|
+
*/
|
|
65
|
+
targetHealthAlarm?: {
|
|
66
|
+
/**
|
|
67
|
+
* @default true
|
|
68
|
+
*/
|
|
69
|
+
enabled?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* An action to use for CloudWatch alarm state changes instead of the default action
|
|
72
|
+
*/
|
|
73
|
+
action?: cloudwatch.IAlarmAction;
|
|
74
|
+
/**
|
|
75
|
+
* @default 60 seconds
|
|
76
|
+
*/
|
|
77
|
+
period?: cdk.Duration;
|
|
78
|
+
/**
|
|
79
|
+
* @default 1
|
|
80
|
+
*/
|
|
81
|
+
evaluationPeriods?: number;
|
|
82
|
+
/**
|
|
83
|
+
* @default 1
|
|
84
|
+
*/
|
|
85
|
+
threshold?: number;
|
|
86
|
+
description?: string;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* Configuration for an alarm.
|
|
90
|
+
*
|
|
91
|
+
* @default Configured with sane defaults.
|
|
92
|
+
*/
|
|
93
|
+
tooMany5xxResponsesFromTargetsAlarm?: {
|
|
94
|
+
/**
|
|
95
|
+
* @default true
|
|
96
|
+
*/
|
|
97
|
+
enabled?: boolean;
|
|
98
|
+
/**
|
|
99
|
+
* An action to use for CloudWatch alarm state changes instead of the default action
|
|
100
|
+
*/
|
|
101
|
+
action?: cloudwatch.IAlarmAction;
|
|
102
|
+
/**
|
|
103
|
+
* @default 60 seconds
|
|
104
|
+
*/
|
|
105
|
+
period?: cdk.Duration;
|
|
106
|
+
/**
|
|
107
|
+
* @default 3
|
|
108
|
+
*/
|
|
109
|
+
evaluationPeriods?: number;
|
|
110
|
+
/**
|
|
111
|
+
* @default 10
|
|
112
|
+
*/
|
|
113
|
+
threshold?: number;
|
|
114
|
+
description?: string;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Configuration for an alarm.
|
|
118
|
+
*
|
|
119
|
+
* @default Configured with sane defaults.
|
|
120
|
+
*/
|
|
121
|
+
targetResponseTimeAlarm?: {
|
|
122
|
+
/**
|
|
123
|
+
* @default true
|
|
124
|
+
*/
|
|
125
|
+
enabled?: boolean;
|
|
126
|
+
/**
|
|
127
|
+
* An action to use for CloudWatch alarm state changes instead of the default action
|
|
128
|
+
*/
|
|
129
|
+
action?: cloudwatch.IAlarmAction;
|
|
130
|
+
/**
|
|
131
|
+
* @default 5 minutes
|
|
132
|
+
*/
|
|
133
|
+
period?: cdk.Duration;
|
|
134
|
+
/**
|
|
135
|
+
* @default 1
|
|
136
|
+
*/
|
|
137
|
+
evaluationPeriods?: number;
|
|
138
|
+
/**
|
|
139
|
+
* @default 500 milliseconds
|
|
140
|
+
*/
|
|
141
|
+
threshold?: cdk.Duration;
|
|
142
|
+
description?: string;
|
|
143
|
+
};
|
|
144
|
+
}): void;
|
|
145
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ServiceAlarms = void 0;
|
|
4
|
+
const cdk = require("aws-cdk-lib");
|
|
5
|
+
const cloudwatch = require("aws-cdk-lib/aws-cloudwatch");
|
|
6
|
+
const logs = require("aws-cdk-lib/aws-logs");
|
|
7
|
+
const constructs = require("constructs");
|
|
8
|
+
/**
|
|
9
|
+
* Various alarms and monitoring.
|
|
10
|
+
*
|
|
11
|
+
* By itself no alarms is created. Use the methods available
|
|
12
|
+
* to add alarms.
|
|
13
|
+
*
|
|
14
|
+
* See SlackAlarm construct for SNS Action.
|
|
15
|
+
*/
|
|
16
|
+
class ServiceAlarms extends constructs.Construct {
|
|
17
|
+
constructor(scope, id, props) {
|
|
18
|
+
super(scope, id);
|
|
19
|
+
this.action = props.action;
|
|
20
|
+
this.serviceName = props.serviceName;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* For logs stored as JSON, monitor log entries logged
|
|
24
|
+
* with level ERROR or higher, as well as any requests
|
|
25
|
+
* that causes 500 for logging with liflig-logging.
|
|
26
|
+
*/
|
|
27
|
+
addJsonErrorAlarm(props) {
|
|
28
|
+
var _a, _b, _c, _d;
|
|
29
|
+
const errorMetricFilter = props.logGroup.addMetricFilter("ErrorMetricFilter", {
|
|
30
|
+
filterPattern: logs.FilterPattern.any(logs.FilterPattern.stringValue("$.level", "=", "ERROR"),
|
|
31
|
+
// FATAL covers some applications we run that uses log4j or
|
|
32
|
+
// other libraries. It is not existent in slf4j.
|
|
33
|
+
logs.FilterPattern.stringValue("$.level", "=", "FATAL"), logs.FilterPattern.stringValue(
|
|
34
|
+
// For liflig-logging.
|
|
35
|
+
"$.requestInfo.status.code", "=", "INTERNAL_SERVER_ERROR")),
|
|
36
|
+
metricName: "Errors",
|
|
37
|
+
metricNamespace: `stack/${cdk.Stack.of(this).stackName}/${this.serviceName}/Errors`,
|
|
38
|
+
});
|
|
39
|
+
const errorAlarm = errorMetricFilter
|
|
40
|
+
.metric()
|
|
41
|
+
.with({
|
|
42
|
+
statistic: "Sum",
|
|
43
|
+
period: cdk.Duration.seconds(60),
|
|
44
|
+
})
|
|
45
|
+
.createAlarm(this, "ErrorLogAlarm", {
|
|
46
|
+
alarmDescription: (_a = props.alarmDescription) !== null && _a !== void 0 ? _a : `${this.serviceName} logged an error`,
|
|
47
|
+
evaluationPeriods: 1,
|
|
48
|
+
threshold: 1,
|
|
49
|
+
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
|
|
50
|
+
});
|
|
51
|
+
errorAlarm.addAlarmAction((_b = props.action) !== null && _b !== void 0 ? _b : this.action);
|
|
52
|
+
if ((_c = props.enableOkAction) !== null && _c !== void 0 ? _c : true) {
|
|
53
|
+
errorAlarm.addOkAction((_d = props.action) !== null && _d !== void 0 ? _d : this.action);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Sets up three CloudWatch Alarms for monitoring an ECS service behind a target group:
|
|
58
|
+
* 1) one that triggers if the target is responding with too many 5xx errors.
|
|
59
|
+
* 2) one that triggers if the 95% percentile of response times from the target is too high.
|
|
60
|
+
* 3) one that triggers if there are no healthy targets or if the load balancer fails to connect to targets.
|
|
61
|
+
*/
|
|
62
|
+
addTargetGroupAlarms(props) {
|
|
63
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21;
|
|
64
|
+
const targetConnectionErrorAlarm = new cloudwatch.Metric({
|
|
65
|
+
metricName: "TargetConnectionErrorCount",
|
|
66
|
+
namespace: "AWS/ApplicationELB",
|
|
67
|
+
statistic: "Sum",
|
|
68
|
+
period: (_b = (_a = props.targetHealthAlarm) === null || _a === void 0 ? void 0 : _a.period) !== null && _b !== void 0 ? _b : cdk.Duration.seconds(60),
|
|
69
|
+
dimensionsMap: {
|
|
70
|
+
TargetGroup: props.targetGroupFullName,
|
|
71
|
+
LoadBalancer: props.loadBalancerFullName,
|
|
72
|
+
},
|
|
73
|
+
}).createAlarm(this, "ConnectionAlarm", {
|
|
74
|
+
actionsEnabled: true,
|
|
75
|
+
alarmDescription: `Load balancer is failing to connect to target(s) in ECS service '${this.serviceName}'.`,
|
|
76
|
+
evaluationPeriods: (_d = (_c = props.targetHealthAlarm) === null || _c === void 0 ? void 0 : _c.evaluationPeriods) !== null && _d !== void 0 ? _d : 1,
|
|
77
|
+
threshold: 1,
|
|
78
|
+
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
|
|
79
|
+
});
|
|
80
|
+
const healthAlarm = new cloudwatch.Metric({
|
|
81
|
+
metricName: "HealthyHostCount",
|
|
82
|
+
namespace: "AWS/ApplicationELB",
|
|
83
|
+
statistic: "Minimum",
|
|
84
|
+
period: (_f = (_e = props.targetHealthAlarm) === null || _e === void 0 ? void 0 : _e.period) !== null && _f !== void 0 ? _f : cdk.Duration.seconds(60),
|
|
85
|
+
dimensionsMap: {
|
|
86
|
+
TargetGroup: props.targetGroupFullName,
|
|
87
|
+
LoadBalancer: props.loadBalancerFullName,
|
|
88
|
+
},
|
|
89
|
+
}).createAlarm(this, "HealthAlarm", {
|
|
90
|
+
alarmDescription: `There are no healthy target(s) in ECS service '${this.serviceName}'.`,
|
|
91
|
+
comparisonOperator: cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD,
|
|
92
|
+
evaluationPeriods: (_h = (_g = props.targetHealthAlarm) === null || _g === void 0 ? void 0 : _g.evaluationPeriods) !== null && _h !== void 0 ? _h : 1,
|
|
93
|
+
threshold: 1,
|
|
94
|
+
treatMissingData: cloudwatch.TreatMissingData.BREACHING,
|
|
95
|
+
});
|
|
96
|
+
const targetHealthAlarm = new cloudwatch.CompositeAlarm(this, "TargetHealthAlarm", {
|
|
97
|
+
alarmRule: cdk.aws_cloudwatch.AlarmRule.anyOf(cdk.aws_cloudwatch.AlarmRule.fromAlarm(targetConnectionErrorAlarm, cloudwatch.AlarmState.ALARM), cdk.aws_cloudwatch.AlarmRule.fromAlarm(healthAlarm, cloudwatch.AlarmState.ALARM)),
|
|
98
|
+
alarmDescription: (_k = (_j = props.targetHealthAlarm) === null || _j === void 0 ? void 0 : _j.description) !== null && _k !== void 0 ? _k : `The load balancer is either receiving bad health checks from or is unable to connect to target(s) in ECS service '${this.serviceName}'`,
|
|
99
|
+
actionsEnabled: false,
|
|
100
|
+
});
|
|
101
|
+
if ((_m = (_l = props.targetHealthAlarm) === null || _l === void 0 ? void 0 : _l.enabled) !== null && _m !== void 0 ? _m : true) {
|
|
102
|
+
targetHealthAlarm.addAlarmAction((_p = (_o = props.targetHealthAlarm) === null || _o === void 0 ? void 0 : _o.action) !== null && _p !== void 0 ? _p : this.action);
|
|
103
|
+
targetHealthAlarm.addOkAction((_r = (_q = props.targetHealthAlarm) === null || _q === void 0 ? void 0 : _q.action) !== null && _r !== void 0 ? _r : this.action);
|
|
104
|
+
}
|
|
105
|
+
const tooMany5xxResponsesFromTargetsAlarm = new cloudwatch.Metric({
|
|
106
|
+
metricName: "HTTPCode_Target_5XX_Count",
|
|
107
|
+
namespace: "AWS/ApplicationELB",
|
|
108
|
+
statistic: "Sum",
|
|
109
|
+
period: (_t = (_s = props.tooMany5xxResponsesFromTargetsAlarm) === null || _s === void 0 ? void 0 : _s.period) !== null && _t !== void 0 ? _t : cdk.Duration.seconds(60),
|
|
110
|
+
dimensionsMap: {
|
|
111
|
+
TargetGroup: props.targetGroupFullName,
|
|
112
|
+
LoadBalancer: props.loadBalancerFullName,
|
|
113
|
+
},
|
|
114
|
+
}).createAlarm(this, "AlbTargets5xxAlarm", {
|
|
115
|
+
actionsEnabled: true,
|
|
116
|
+
alarmDescription: (_v = (_u = props.tooMany5xxResponsesFromTargetsAlarm) === null || _u === void 0 ? void 0 : _u.description) !== null && _v !== void 0 ? _v : `Load balancer received too many 5XX responses from target(s) in ECS service '${this.serviceName}'.`,
|
|
117
|
+
evaluationPeriods: (_x = (_w = props.tooMany5xxResponsesFromTargetsAlarm) === null || _w === void 0 ? void 0 : _w.evaluationPeriods) !== null && _x !== void 0 ? _x : 3,
|
|
118
|
+
threshold: (_z = (_y = props.tooMany5xxResponsesFromTargetsAlarm) === null || _y === void 0 ? void 0 : _y.threshold) !== null && _z !== void 0 ? _z : 10,
|
|
119
|
+
treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
|
|
120
|
+
});
|
|
121
|
+
if ((_1 = (_0 = props.tooMany5xxResponsesFromTargetsAlarm) === null || _0 === void 0 ? void 0 : _0.enabled) !== null && _1 !== void 0 ? _1 : true) {
|
|
122
|
+
tooMany5xxResponsesFromTargetsAlarm.addAlarmAction((_3 = (_2 = props.tooMany5xxResponsesFromTargetsAlarm) === null || _2 === void 0 ? void 0 : _2.action) !== null && _3 !== void 0 ? _3 : this.action);
|
|
123
|
+
tooMany5xxResponsesFromTargetsAlarm.addOkAction((_5 = (_4 = props.tooMany5xxResponsesFromTargetsAlarm) === null || _4 === void 0 ? void 0 : _4.action) !== null && _5 !== void 0 ? _5 : this.action);
|
|
124
|
+
}
|
|
125
|
+
const targetResponseTimeAlarm = new cloudwatch.Metric({
|
|
126
|
+
metricName: "TargetResponseTime",
|
|
127
|
+
namespace: "AWS/ApplicationELB",
|
|
128
|
+
statistic: "p95",
|
|
129
|
+
period: (_7 = (_6 = props.targetResponseTimeAlarm) === null || _6 === void 0 ? void 0 : _6.period) !== null && _7 !== void 0 ? _7 : cdk.Duration.minutes(5),
|
|
130
|
+
dimensionsMap: {
|
|
131
|
+
LoadBalancer: props.loadBalancerFullName,
|
|
132
|
+
TargetGroup: props.targetGroupFullName,
|
|
133
|
+
},
|
|
134
|
+
}).createAlarm(this, "TargetResponseTimeAlarm", {
|
|
135
|
+
alarmDescription: (_9 = (_8 = props.targetResponseTimeAlarm) === null || _8 === void 0 ? void 0 : _8.description) !== null && _9 !== void 0 ? _9 : `5% of responses from ECS service '${this.serviceName}' are taking longer than the expected duration of ${((_11 = (_10 = props.targetResponseTimeAlarm) === null || _10 === void 0 ? void 0 : _10.threshold) !== null && _11 !== void 0 ? _11 : cdk.Duration.millis(500)).toMilliseconds()} ms.`,
|
|
136
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
137
|
+
evaluationPeriods: (_13 = (_12 = props.targetResponseTimeAlarm) === null || _12 === void 0 ? void 0 : _12.evaluationPeriods) !== null && _13 !== void 0 ? _13 : 1,
|
|
138
|
+
threshold: ((_15 = (_14 = props.targetResponseTimeAlarm) === null || _14 === void 0 ? void 0 : _14.threshold) !== null && _15 !== void 0 ? _15 : cdk.Duration.millis(500)).toSeconds({ integral: false }),
|
|
139
|
+
treatMissingData: cloudwatch.TreatMissingData.IGNORE,
|
|
140
|
+
});
|
|
141
|
+
if ((_17 = (_16 = props.targetResponseTimeAlarm) === null || _16 === void 0 ? void 0 : _16.enabled) !== null && _17 !== void 0 ? _17 : true) {
|
|
142
|
+
targetResponseTimeAlarm.addAlarmAction((_19 = (_18 = props.targetResponseTimeAlarm) === null || _18 === void 0 ? void 0 : _18.action) !== null && _19 !== void 0 ? _19 : this.action);
|
|
143
|
+
targetResponseTimeAlarm.addOkAction((_21 = (_20 = props.targetResponseTimeAlarm) === null || _20 === void 0 ? void 0 : _20.action) !== null && _21 !== void 0 ? _21 : this.action);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
exports.ServiceAlarms = ServiceAlarms;
|
|
148
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VydmljZS1hbGFybXMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWxhcm1zL3NlcnZpY2UtYWxhcm1zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLG1DQUFrQztBQUNsQyx5REFBd0Q7QUFDeEQsNkNBQTRDO0FBQzVDLHlDQUF3QztBQWF4Qzs7Ozs7OztHQU9HO0FBQ0gsTUFBYSxhQUFjLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFJckQsWUFDRSxLQUEyQixFQUMzQixFQUFVLEVBQ1YsS0FBeUI7UUFFekIsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUVoQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUE7UUFDMUIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxDQUFBO0lBQ3RDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsaUJBQWlCLENBQUMsS0FZakI7O1FBQ0MsTUFBTSxpQkFBaUIsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FDdEQsbUJBQW1CLEVBQ25CO1lBQ0UsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxDQUNuQyxJQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsR0FBRyxFQUFFLE9BQU8sQ0FBQztZQUN2RCwyREFBMkQ7WUFDM0QsZ0RBQWdEO1lBQ2hELElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLFNBQVMsRUFBRSxHQUFHLEVBQUUsT0FBTyxDQUFDLEVBQ3ZELElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVztZQUM1QixzQkFBc0I7WUFDdEIsMkJBQTJCLEVBQzNCLEdBQUcsRUFDSCx1QkFBdUIsQ0FDeEIsQ0FDRjtZQUNELFVBQVUsRUFBRSxRQUFRO1lBQ3BCLGVBQWUsRUFBRSxTQUFTLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMs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QU0sQ0FDckQsQ0FBQTtZQUNELHVCQUF1QixDQUFDLFdBQVcsQ0FDakMsT0FBQSxPQUFBLEtBQUssQ0FBQyx1QkFBdUIsNENBQUUsTUFBTSxxQ0FBSSxJQUFJLENBQUMsTUFBTSxDQUNyRCxDQUFBO1FBQ0gsQ0FBQztJQUNILENBQUM7Q0FDRjtBQTdTRCxzQ0E2U0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjZGsgZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCJcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSBcImF3cy1jZGstbGliL2F3cy1sb2dzXCJcbmltcG9ydCAqIGFzIGNvbnN0cnVjdHMgZnJvbSBcImNvbnN0cnVjdHNcIlxuXG5leHBvcnQgaW50ZXJmYWNlIFNlcnZpY2VBbGFybXNQcm9wcyBleHRlbmRzIGNkay5TdGFja1Byb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBkZWZhdWx0IGFjdGlvbiB0byB1c2UgZm9yIENsb3VkV2F0Y2ggYWxhcm0gc3RhdGUgY2hhbmdlc1xuICAgKi9cbiAgYWN0aW9uOiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIEVDUyBzZXJ2aWNlLlxuICAgKi9cbiAgc2VydmljZU5hbWU6IHN0cmluZ1xufVxuXG4vKipcbiAqIFZhcmlvdXMgYWxhcm1zIGFuZCBtb25pdG9yaW5nLlxuICpcbiAqIEJ5IGl0c2VsZiBubyBhbGFybXMgaXMgY3JlYXRlZC4gVXNlIHRoZSBtZXRob2RzIGF2YWlsYWJsZVxuICogdG8gYWRkIGFsYXJtcy5cbiAqXG4gKiBTZWUgU2xhY2tBbGFybSBjb25zdHJ1Y3QgZm9yIFNOUyBBY3Rpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBTZXJ2aWNlQWxhcm1zIGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3Qge1xuICBwcml2YXRlIHJlYWRvbmx5IGFjdGlvbjogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb25cbiAgcHJpdmF0ZSByZWFkb25seSBzZXJ2aWNlTmFtZTogc3RyaW5nXG5cbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IFNlcnZpY2VBbGFybXNQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKVxuXG4gICAgdGhpcy5hY3Rpb24gPSBwcm9wcy5hY3Rpb25cbiAgICB0aGlzLnNlcnZpY2VOYW1lID0gcHJvcHMuc2VydmljZU5hbWVcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3IgbG9ncyBzdG9yZWQgYXMgSlNPTiwgbW9uaXRvciBsb2cgZW50cmllcyBsb2dnZWRcbiAgICogd2l0aCBsZXZlbCBFUlJPUiBvciBoaWdoZXIsIGFzIHdlbGwgYXMgYW55IHJlcXVlc3RzXG4gICAqIHRoYXQgY2F1c2VzIDUwMCBmb3IgbG9nZ2luZyB3aXRoIGxpZmxpZy1sb2dnaW5nLlxuICAgKi9cbiAgYWRkSnNvbkVycm9yQWxhcm0ocHJvcHM6IHtcbiAgICBsb2dHcm91cDogbG9ncy5JTG9nR3JvdXBcbiAgICBhbGFybURlc2NyaXB0aW9uPzogc3RyaW5nXG4gICAgLyoqXG4gICAgICogU2V0IHRvIGBmYWxzZWAgdG8gc3RvcCB0aGUgYWxhcm0gZnJvbSBzZW5kaW5nIE9LIGV2ZW50cy5cbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICogKi9cbiAgICBlbmFibGVPa0FjdGlvbj86IGJvb2xlYW5cbiAgICAvKipcbiAgICAgKiBBbiBhY3Rpb24gdG8gdXNlIGZvciBDbG91ZFdhdGNoIGFsYXJtIHN0YXRlIGNoYW5nZXMgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBhY3Rpb25cbiAgICAgKi9cbiAgICBhY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxuICB9KTogdm9pZCB7XG4gICAgY29uc3QgZXJyb3JNZXRyaWNGaWx0ZXIgPSBwcm9wcy5sb2dHcm91cC5hZGRNZXRyaWNGaWx0ZXIoXG4gICAgICBcIkVycm9yTWV0cmljRmlsdGVyXCIsXG4gICAgICB7XG4gICAgICAgIGZpbHRlclBhdHRlcm46IGxvZ3MuRmlsdGVyUGF0dGVybi5hbnkoXG4gICAgICAgICAgbG9ncy5GaWx0ZXJQYXR0ZXJuLnN0cmluZ1ZhbHVlKFwiJC5sZXZlbFwiLCBcIj1cIiwgXCJFUlJPUlwiKSxcbiAgICAgICAgICAvLyBGQVRBTCBjb3ZlcnMgc29tZSBhcHBsaWNhdGlvbnMgd2UgcnVuIHRoYXQgdXNlcyBsb2c0aiBvclxuICAgICAgICAgIC8vIG90aGVyIGxpYnJhcmllcy4gSXQgaXMgbm90IGV4aXN0ZW50IGluIHNsZjRqLlxuICAgICAgICAgIGxvZ3MuRmlsdGVyUGF0dGVybi5zdHJpbmdWYWx1ZShcIiQubGV2ZWxcIiwgXCI9XCIsIFwiRkFUQUxcIiksXG4gICAgICAgICAgbG9ncy5GaWx0ZXJQYXR0ZXJuLnN0cmluZ1ZhbHVlKFxuICAgICAgICAgICAgLy8gRm9yIGxpZmxpZy1sb2dnaW5nLlxuICAgICAgICAgICAgXCIkLnJlcXVlc3RJbmZvLnN0YXR1cy5jb2RlXCIsXG4gICAgICAgICAgICBcIj1cIixcbiAgICAgICAgICAgIFwiSU5URVJOQUxfU0VSVkVSX0VSUk9SXCIsXG4gICAgICAgICAgKSxcbiAgICAgICAgKSxcbiAgICAgICAgbWV0cmljTmFtZTogXCJFcnJvcnNcIixcbiAgICAgICAgbWV0cmljTmFtZXNwYWNlOiBgc3RhY2svJHtjZGsuU3RhY2sub2YodGhpcykuc3RhY2tOYW1lfS8ke1xuICAgICAgICAgIHRoaXMuc2VydmljZU5hbWVcbiAgICAgICAgfS9FcnJvcnNgLFxuICAgICAgfSxcbiAgICApXG5cbiAgICBjb25zdCBlcnJvckFsYXJtID0gZXJyb3JNZXRyaWNGaWx0ZXJcbiAgICAgIC5tZXRyaWMoKVxuICAgICAgLndpdGgoe1xuICAgICAgICBzdGF0aXN0aWM6IFwiU3VtXCIsXG4gICAgICAgIHBlcmlvZDogY2RrLkR1cmF0aW9uLnNlY29uZHMoNjApLFxuICAgICAgfSlcbiAgICAgIC5jcmVhdGVBbGFybSh0aGlzLCBcIkVycm9yTG9nQWxhcm1cIiwge1xuICAgICAgICBhbGFybURlc2NyaXB0aW9uOlxuICAgICAgICAgIHByb3BzLmFsYXJtRGVzY3JpcHRpb24gPz8gYCR7dGhpcy5zZXJ2aWNlTmFtZX0gbG9nZ2VkIGFuIGVycm9yYCxcbiAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLk5PVF9CUkVBQ0hJTkcsXG4gICAgICB9KVxuXG4gICAgZXJyb3JBbGFybS5hZGRBbGFybUFjdGlvbihwcm9wcy5hY3Rpb24gPz8gdGhpcy5hY3Rpb24pXG4gICAgaWYgKHByb3BzLmVuYWJsZU9rQWN0aW9uID8/IHRydWUpIHtcbiAgICAgIGVycm9yQWxhcm0uYWRkT2tBY3Rpb24ocHJvcHMuYWN0aW9uID8/IHRoaXMuYWN0aW9uKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHVwIHRocmVlIENsb3VkV2F0Y2ggQWxhcm1zIGZvciBtb25pdG9yaW5nIGFuIEVDUyBzZXJ2aWNlIGJlaGluZCBhIHRhcmdldCBncm91cDpcbiAgICogMSkgb25lIHRoYXQgdHJpZ2dlcnMgaWYgdGhlIHRhcmdldCBpcyByZXNwb25kaW5nIHdpdGggdG9vIG1hbnkgNXh4IGVycm9ycy5cbiAgICogMikgb25lIHRoYXQgdHJpZ2dlcnMgaWYgdGhlIDk1JSBwZXJjZW50aWxlIG9mIHJlc3BvbnNlIHRpbWVzIGZyb20gdGhlIHRhcmdldCBpcyB0b28gaGlnaC5cbiAgICogMykgb25lIHRoYXQgdHJpZ2dlcnMgaWYgdGhlcmUgYXJlIG5vIGhlYWx0aHkgdGFyZ2V0cyBvciBpZiB0aGUgbG9hZCBiYWxhbmNlciBmYWlscyB0byBjb25uZWN0IHRvIHRhcmdldHMuXG4gICAqL1xuICBhZGRUYXJnZXRHcm91cEFsYXJtcyhwcm9wczoge1xuICAgIC8qKlxuICAgICAqIFRoZSBmdWxsIG5hbWUgb2YgdGhlIHRhcmdldCBncm91cC5cbiAgICAgKi9cbiAgICB0YXJnZXRHcm91cEZ1bGxOYW1lOiBzdHJpbmdcbiAgICAvKipcbiAgICAgKiBUaGUgZnVsbCBuYW1lIG9mIHRoZSBhcHBsaWNhdGlvbiBsb2FkIGJhbGFuY2VyLlxuICAgICAqL1xuICAgIGxvYWRCYWxhbmNlckZ1bGxOYW1lOiBzdHJpbmdcbiAgICAvKipcbiAgICAgKiBDb25maWd1cmF0aW9uIGZvciBhIGNvbXBvc2l0ZSBhbGFybS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IENvbmZpZ3VyZWQgd2l0aCBzYW5lIGRlZmF1bHRzLlxuICAgICAqL1xuICAgIHRhcmdldEhlYWx0aEFsYXJtPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICAgKi9cbiAgICAgIGVuYWJsZWQ/OiBib29sZWFuXG4gICAgICAvKipcbiAgICAgICAqIEFuIGFjdGlvbiB0byB1c2UgZm9yIENsb3VkV2F0Y2ggYWxhcm0gc3RhdGUgY2hhbmdlcyBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IGFjdGlvblxuICAgICAgICovXG4gICAgICBhY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxuICAgICAgLyoqXG4gICAgICAgKiBAZGVmYXVsdCA2MCBzZWNvbmRzXG4gICAgICAgKi9cbiAgICAgIHBlcmlvZD86IGNkay5EdXJhdGlvblxuICAgICAgLyoqXG4gICAgICAgKiBAZGVmYXVsdCAxXG4gICAgICAgKi9cbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyXG4gICAgICAvKipcbiAgICAgICAqIEBkZWZhdWx0IDFcbiAgICAgICAqL1xuICAgICAgdGhyZXNob2xkPzogbnVtYmVyXG4gICAgICBkZXNjcmlwdGlvbj86IHN0cmluZ1xuICAgIH1cbiAgICAvKipcbiAgICAgKiBDb25maWd1cmF0aW9uIGZvciBhbiBhbGFybS5cbiAgICAgKlxuICAgICAqIEBkZWZhdWx0IENvbmZpZ3VyZWQgd2l0aCBzYW5lIGRlZmF1bHRzLlxuICAgICAqL1xuICAgIHRvb01hbnk1eHhSZXNwb25zZXNGcm9tVGFyZ2V0c0FsYXJtPzoge1xuICAgICAgLyoqXG4gICAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICAgKi9cbiAgICAgIGVuYWJsZWQ/OiBib29sZWFuXG4gICAgICAvKipcbiAgICAgICAqIEFuIGFjdGlvbiB0byB1c2UgZm9yIENsb3VkV2F0Y2ggYWxhcm0gc3RhdGUgY2hhbmdlcyBpbnN0ZWFkIG9mIHRoZSBkZWZhdWx0IGFjdGlvblxuICAgICAgICovXG4gICAgICBhY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxuICAgICAgLyoqXG4gICAgICAgKiBAZGVmYXVsdCA2MCBzZWNvbmRzXG4gICAgICAgKi9cbiAgICAgIHBlcmlvZD86IGNkay5EdXJhdGlvblxuICAgICAgLyoqXG4gICAgICAgKiBAZGVmYXVsdCAzXG4gICAgICAgKi9cbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyXG4gICAgICAvKipcbiAgICAgICAqIEBkZWZhdWx0IDEwXG4gICAgICAgKi9cbiAgICAgIHRocmVzaG9sZD86IG51bWJlclxuICAgICAgZGVzY3JpcHRpb24/OiBzdHJpbmdcbiAgICB9XG4gICAgLyoqXG4gICAgICogQ29uZmlndXJhdGlvbiBmb3IgYW4gYWxhcm0uXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCBDb25maWd1cmVkIHdpdGggc2FuZSBkZWZhdWx0cy5cbiAgICAgKi9cbiAgICB0YXJnZXRSZXNwb25zZVRpbWVBbGFybT86IHtcbiAgICAgIC8qKlxuICAgICAgICogQGRlZmF1bHQgdHJ1ZVxuICAgICAgICovXG4gICAgICBlbmFibGVkPzogYm9vbGVhblxuICAgICAgLyoqXG4gICAgICAgKiBBbiBhY3Rpb24gdG8gdXNlIGZvciBDbG91ZFdhdGNoIGFsYXJtIHN0YXRlIGNoYW5nZXMgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBhY3Rpb25cbiAgICAgICAqL1xuICAgICAgYWN0aW9uPzogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb25cbiAgICAgIC8qKlxuICAgICAgICogQGRlZmF1bHQgNSBtaW51dGVzXG4gICAgICAgKi9cbiAgICAgIHBlcmlvZD86IGNkay5EdXJhdGlvblxuICAgICAgLyoqXG4gICAgICAgKiBAZGVmYXVsdCAxXG4gICAgICAgKi9cbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzPzogbnVtYmVyXG4gICAgICAvKipcbiAgICAgICAqIEBkZWZhdWx0IDUwMCBtaWxsaXNlY29uZHNcbiAgICAgICAqL1xuICAgICAgdGhyZXNob2xkPzogY2RrLkR1cmF0aW9uXG4gICAgICBkZXNjcmlwdGlvbj86IHN0cmluZ1xuICAgIH1cbiAgfSk6IHZvaWQge1xuICAgIGNvbnN0IHRhcmdldENvbm5lY3Rpb25FcnJvckFsYXJtID0gbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgIG1ldHJpY05hbWU6IFwiVGFyZ2V0Q29ubmVjdGlvbkVycm9yQ291bnRcIixcbiAgICAgIG5hbWVzcGFjZTogXCJBV1MvQXBwbGljYXRpb25FTEJcIixcbiAgICAgIHN0YXRpc3RpYzogXCJTdW1cIixcbiAgICAgIHBlcmlvZDogcHJvcHMudGFyZ2V0SGVhbHRoQWxhcm0/LnBlcmlvZCA/PyBjZGsuRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIFRhcmdldEdyb3VwOiBwcm9wcy50YXJnZXRHcm91cEZ1bGxOYW1lLFxuICAgICAgICBMb2FkQmFsYW5jZXI6IHByb3BzLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgfSxcbiAgICB9KS5jcmVhdGVBbGFybSh0aGlzLCBcIkNvbm5lY3Rpb25BbGFybVwiLCB7XG4gICAgICBhY3Rpb25zRW5hYmxlZDogdHJ1ZSxcbiAgICAgIGFsYXJtRGVzY3JpcHRpb246IGBMb2FkIGJhbGFuY2VyIGlzIGZhaWxpbmcgdG8gY29ubmVjdCB0byB0YXJnZXQocykgaW4gRUNTIHNlcnZpY2UgJyR7dGhpcy5zZXJ2aWNlTmFtZX0nLmAsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kczogcHJvcHMudGFyZ2V0SGVhbHRoQWxhcm0/LmV2YWx1YXRpb25QZXJpb2RzID8/IDEsXG4gICAgICB0aHJlc2hvbGQ6IDEsXG4gICAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuTk9UX0JSRUFDSElORyxcbiAgICB9KVxuXG4gICAgY29uc3QgaGVhbHRoQWxhcm0gPSBuZXcgY2xvdWR3YXRjaC5NZXRyaWMoe1xuICAgICAgbWV0cmljTmFtZTogXCJIZWFsdGh5SG9zdENvdW50XCIsXG4gICAgICBuYW1lc3BhY2U6IFwiQVdTL0FwcGxpY2F0aW9uRUxCXCIsXG4gICAgICBzdGF0aXN0aWM6IFwiTWluaW11bVwiLFxuICAgICAgcGVyaW9kOiBwcm9wcy50YXJnZXRIZWFsdGhBbGFybT8ucGVyaW9kID8/IGNkay5EdXJhdGlvbi5zZWNvbmRzKDYwKSxcbiAgICAgIGRpbWVuc2lvbnNNYXA6IHtcbiAgICAgICAgVGFyZ2V0R3JvdXA6IHByb3BzLnRhcmdldEdyb3VwRnVsbE5hbWUsXG4gICAgICAgIExvYWRCYWxhbmNlcjogcHJvcHMubG9hZEJhbGFuY2VyRnVsbE5hbWUsXG4gICAgICB9LFxuICAgIH0pLmNyZWF0ZUFsYXJtKHRoaXMsIFwiSGVhbHRoQWxhcm1cIiwge1xuICAgICAgYWxhcm1EZXNjcmlwdGlvbjogYFRoZXJlIGFyZSBubyBoZWFsdGh5IHRhcmdldChzKSBpbiBFQ1Mgc2VydmljZSAnJHt0aGlzLnNlcnZpY2VOYW1lfScuYCxcbiAgICAgIGNvbXBhcmlzb25PcGVyYXRvcjogY2xvdWR3YXRjaC5Db21wYXJpc29uT3BlcmF0b3IuTEVTU19USEFOX1RIUkVTSE9MRCxcbiAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiBwcm9wcy50YXJnZXRIZWFsdGhBbGFybT8uZXZhbHVhdGlvblBlcmlvZHMgPz8gMSxcbiAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5CUkVBQ0hJTkcsXG4gICAgfSlcblxuICAgIGNvbnN0IHRhcmdldEhlYWx0aEFsYXJtID0gbmV3IGNsb3Vkd2F0Y2guQ29tcG9zaXRlQWxhcm0oXG4gICAgICB0aGlzLFxuICAgICAgXCJUYXJnZXRIZWFsdGhBbGFybVwiLFxuICAgICAge1xuICAgICAgICBhbGFybVJ1bGU6IGNkay5hd3NfY2xvdWR3YXRjaC5BbGFybVJ1bGUuYW55T2YoXG4gICAgICAgICAgY2RrLmF3c19jbG91ZHdhdGNoLkFsYXJtUnVsZS5mcm9tQWxhcm0oXG4gICAgICAgICAgICB0YXJnZXRDb25uZWN0aW9uRXJyb3JBbGFybSxcbiAgICAgICAgICAgIGNsb3Vkd2F0Y2guQWxhcm1TdGF0ZS5BTEFSTSxcbiAgICAgICAgICApLFxuICAgICAgICAgIGNkay5hd3NfY2xvdWR3YXRjaC5BbGFybVJ1bGUuZnJvbUFsYXJtKFxuICAgICAgICAgICAgaGVhbHRoQWxhcm0sXG4gICAgICAgICAgICBjbG91ZHdhdGNoLkFsYXJtU3RhdGUuQUxBUk0sXG4gICAgICAgICAgKSxcbiAgICAgICAgKSxcbiAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjpcbiAgICAgICAgICBwcm9wcy50YXJnZXRIZWFsdGhBbGFybT8uZGVzY3JpcHRpb24gPz9cbiAgICAgICAgICBgVGhlIGxvYWQgYmFsYW5jZXIgaXMgZWl0aGVyIHJlY2VpdmluZyBiYWQgaGVhbHRoIGNoZWNrcyBmcm9tIG9yIGlzIHVuYWJsZSB0byBjb25uZWN0IHRvIHRhcmdldChzKSBpbiBFQ1Mgc2VydmljZSAnJHt0aGlzLnNlcnZpY2VOYW1lfSdgLFxuICAgICAgICBhY3Rpb25zRW5hYmxlZDogZmFsc2UsXG4gICAgICB9LFxuICAgIClcbiAgICBpZiAocHJvcHMudGFyZ2V0SGVhbHRoQWxhcm0/LmVuYWJsZWQgPz8gdHJ1ZSkge1xuICAgICAgdGFyZ2V0SGVhbHRoQWxhcm0uYWRkQWxhcm1BY3Rpb24oXG4gICAgICAgIHByb3BzLnRhcmdldEhlYWx0aEFsYXJtPy5hY3Rpb24gPz8gdGhpcy5hY3Rpb24sXG4gICAgICApXG4gICAgICB0YXJnZXRIZWFsdGhBbGFybS5hZGRPa0FjdGlvbihcbiAgICAgICAgcHJvcHMudGFyZ2V0SGVhbHRoQWxhcm0/LmFjdGlvbiA/PyB0aGlzLmFjdGlvbixcbiAgICAgIClcbiAgICB9XG5cbiAgICBjb25zdCB0b29NYW55NXh4UmVzcG9uc2VzRnJvbVRhcmdldHNBbGFybSA9IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICBtZXRyaWNOYW1lOiBcIkhUVFBDb2RlX1RhcmdldF81WFhfQ291bnRcIixcbiAgICAgIG5hbWVzcGFjZTogXCJBV1MvQXBwbGljYXRpb25FTEJcIixcbiAgICAgIHN0YXRpc3RpYzogXCJTdW1cIixcbiAgICAgIHBlcmlvZDpcbiAgICAgICAgcHJvcHMudG9vTWFueTV4eFJlc3BvbnNlc0Zyb21UYXJnZXRzQWxhcm0/LnBlcmlvZCA/P1xuICAgICAgICBjZGsuRHVyYXRpb24uc2Vjb25kcyg2MCksXG4gICAgICBkaW1lbnNpb25zTWFwOiB7XG4gICAgICAgIFRhcmdldEdyb3VwOiBwcm9wcy50YXJnZXRHcm91cEZ1bGxOYW1lLFxuICAgICAgICBMb2FkQmFsYW5jZXI6IHByb3BzLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgfSxcbiAgICB9KS5jcmVhdGVBbGFybSh0aGlzLCBcIkFsYlRhcmdldHM1eHhBbGFybVwiLCB7XG4gICAgICBhY3Rpb25zRW5hYmxlZDogdHJ1ZSxcbiAgICAgIGFsYXJtRGVzY3JpcHRpb246XG4gICAgICAgIHByb3BzLnRvb01hbnk1eHhSZXNwb25zZXNGcm9tVGFyZ2V0c0FsYXJtPy5kZXNjcmlwdGlvbiA/P1xuICAgICAgICBgTG9hZCBiYWxhbmNlciByZWNlaXZlZCB0b28gbWFueSA1WFggcmVzcG9uc2VzIGZyb20gdGFyZ2V0KHMpIGluIEVDUyBzZXJ2aWNlICcke3RoaXMuc2VydmljZU5hbWV9Jy5gLFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6XG4gICAgICAgIHByb3BzLnRvb01hbnk1eHhSZXNwb25zZXNGcm9tVGFyZ2V0c0FsYXJtPy5ldmFsdWF0aW9uUGVyaW9kcyA/PyAzLFxuICAgICAgdGhyZXNob2xkOiBwcm9wcy50b29NYW55NXh4UmVzcG9uc2VzRnJvbVRhcmdldHNBbGFybT8udGhyZXNob2xkID8/IDEwLFxuICAgICAgdHJlYXRNaXNzaW5nRGF0YTogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLk5PVF9CUkVBQ0hJTkcsXG4gICAgfSlcbiAgICBpZiAocHJvcHMudG9vTWFueTV4eFJlc3BvbnNlc0Zyb21UYXJnZXRzQWxhcm0/LmVuYWJsZWQgPz8gdHJ1ZSkge1xuICAgICAgdG9vTWFueTV4eFJlc3BvbnNlc0Zyb21UYXJnZXRzQWxhcm0uYWRkQWxhcm1BY3Rpb24oXG4gICAgICAgIHByb3BzLnRvb01hbnk1eHhSZXNwb25zZXNGcm9tVGFyZ2V0c0FsYXJtPy5hY3Rpb24gPz8gdGhpcy5hY3Rpb24sXG4gICAgICApXG4gICAgICB0b29NYW55NXh4UmVzcG9uc2VzRnJvbVRhcmdldHNBbGFybS5hZGRPa0FjdGlvbihcbiAgICAgICAgcHJvcHMudG9vTWFueTV4eFJlc3BvbnNlc0Zyb21UYXJnZXRzQWxhcm0/LmFjdGlvbiA/PyB0aGlzLmFjdGlvbixcbiAgICAgIClcbiAgICB9XG5cbiAgICBjb25zdCB0YXJnZXRSZXNwb25zZVRpbWVBbGFybSA9IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICBtZXRyaWNOYW1lOiBcIlRhcmdldFJlc3BvbnNlVGltZVwiLFxuICAgICAgbmFtZXNwYWNlOiBcIkFXUy9BcHBsaWNhdGlvbkVMQlwiLFxuICAgICAgc3RhdGlzdGljOiBcInA5NVwiLFxuICAgICAgcGVyaW9kOiBwcm9wcy50YXJnZXRSZXNwb25zZVRpbWVBbGFybT8ucGVyaW9kID8/IGNkay5EdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgZGltZW5zaW9uc01hcDoge1xuICAgICAgICBMb2FkQmFsYW5jZXI6IHByb3BzLmxvYWRCYWxhbmNlckZ1bGxOYW1lLFxuICAgICAgICBUYXJnZXRHcm91cDogcHJvcHMudGFyZ2V0R3JvdXBGdWxsTmFtZSxcbiAgICAgIH0sXG4gICAgfSkuY3JlYXRlQWxhcm0odGhpcywgXCJUYXJnZXRSZXNwb25zZVRpbWVBbGFybVwiLCB7XG4gICAgICBhbGFybURlc2NyaXB0aW9uOlxuICAgICAgICBwcm9wcy50YXJnZXRSZXNwb25zZVRpbWVBbGFybT8uZGVzY3JpcHRpb24gPz9cbiAgICAgICAgYDUlIG9mIHJlc3BvbnNlcyBmcm9tIEVDUyBzZXJ2aWNlICcke1xuICAgICAgICAgIHRoaXMuc2VydmljZU5hbWVcbiAgICAgICAgfScgYXJlIHRha2luZyBsb25nZXIgdGhhbiB0aGUgZXhwZWN0ZWQgZHVyYXRpb24gb2YgJHsoXG4gICAgICAgICAgcHJvcHMudGFyZ2V0UmVzcG9uc2VUaW1lQWxhcm0/LnRocmVzaG9sZCA/PyBjZGsuRHVyYXRpb24ubWlsbGlzKDUwMClcbiAgICAgICAgKS50b01pbGxpc2Vjb25kcygpfSBtcy5gLFxuICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBjbG91ZHdhdGNoLkNvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fVEhSRVNIT0xELFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IHByb3BzLnRhcmdldFJlc3BvbnNlVGltZUFsYXJtPy5ldmFsdWF0aW9uUGVyaW9kcyA/PyAxLFxuICAgICAgdGhyZXNob2xkOiAoXG4gICAgICAgIHByb3BzLnRhcmdldFJlc3BvbnNlVGltZUFsYXJtPy50aHJlc2hvbGQgPz8gY2RrLkR1cmF0aW9uLm1pbGxpcyg1MDApXG4gICAgICApLnRvU2Vjb25kcyh7IGludGVncmFsOiBmYWxzZSB9KSxcbiAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5JR05PUkUsXG4gICAgfSlcbiAgICBpZiAocHJvcHMudGFyZ2V0UmVzcG9uc2VUaW1lQWxhcm0/LmVuYWJsZWQgPz8gdHJ1ZSkge1xuICAgICAgdGFyZ2V0UmVzcG9uc2VUaW1lQWxhcm0uYWRkQWxhcm1BY3Rpb24oXG4gICAgICAgIHByb3BzLnRhcmdldFJlc3BvbnNlVGltZUFsYXJtPy5hY3Rpb24gPz8gdGhpcy5hY3Rpb24sXG4gICAgICApXG4gICAgICB0YXJnZXRSZXNwb25zZVRpbWVBbGFybS5hZGRPa0FjdGlvbihcbiAgICAgICAgcHJvcHMudGFyZ2V0UmVzcG9uc2VUaW1lQWxhcm0/LmFjdGlvbiA/PyB0aGlzLmFjdGlvbixcbiAgICAgIClcbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import * as cdk from "aws-cdk-lib";
|
|
2
|
+
import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch";
|
|
3
|
+
import * as constructs from "constructs";
|
|
4
|
+
export interface SesAlarmsProps extends cdk.StackProps {
|
|
5
|
+
/**
|
|
6
|
+
* The default action to use for CloudWatch alarm state changes
|
|
7
|
+
*/
|
|
8
|
+
action: cloudwatch.IAlarmAction;
|
|
9
|
+
/**
|
|
10
|
+
* Configuration for an alarm for high rate bounced messages.
|
|
11
|
+
*
|
|
12
|
+
* @default Configured with reasonable defaults.
|
|
13
|
+
*/
|
|
14
|
+
bouncedMessagesAlarm?: {
|
|
15
|
+
/**
|
|
16
|
+
* @default true
|
|
17
|
+
*/
|
|
18
|
+
enabled?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* An action to use for CloudWatch alarm state changes instead of the default action
|
|
21
|
+
*/
|
|
22
|
+
action?: cloudwatch.IAlarmAction;
|
|
23
|
+
/**
|
|
24
|
+
* @default 10 minutes
|
|
25
|
+
*/
|
|
26
|
+
period?: cdk.Duration;
|
|
27
|
+
/**
|
|
28
|
+
* Threshold value for alarm as a percent
|
|
29
|
+
* @default 2.5(%)
|
|
30
|
+
* 5% is the threshold at which AWS considers putting an account under review
|
|
31
|
+
*/
|
|
32
|
+
threshold?: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Configuration for an alarm for high complaint rate.
|
|
36
|
+
*
|
|
37
|
+
* @default Configured with sane defaults.
|
|
38
|
+
*/
|
|
39
|
+
complaintRateAlarm?: {
|
|
40
|
+
/**
|
|
41
|
+
* @default true
|
|
42
|
+
*/
|
|
43
|
+
enabled?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* An action to use for CloudWatch alarm state changes instead of the default action
|
|
46
|
+
*/
|
|
47
|
+
action?: cloudwatch.IAlarmAction;
|
|
48
|
+
/**
|
|
49
|
+
* @default 10 minutes
|
|
50
|
+
*/
|
|
51
|
+
period?: cdk.Duration;
|
|
52
|
+
/**
|
|
53
|
+
* Threshold value for alarm as a percent
|
|
54
|
+
* @default 0.05(%)
|
|
55
|
+
* 0.10% is the threshold at which AWS considers putting an account under review
|
|
56
|
+
*/
|
|
57
|
+
threshold?: number;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
*
|
|
62
|
+
* Construct that configures various sensible CloudWatch alarms for AWS SES
|
|
63
|
+
*/
|
|
64
|
+
export declare class SesAlarms extends constructs.Construct {
|
|
65
|
+
private readonly action;
|
|
66
|
+
constructor(scope: constructs.Construct, id: string, props: SesAlarmsProps);
|
|
67
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SesAlarms = void 0;
|
|
4
|
+
const cdk = require("aws-cdk-lib");
|
|
5
|
+
const cloudwatch = require("aws-cdk-lib/aws-cloudwatch");
|
|
6
|
+
const constructs = require("constructs");
|
|
7
|
+
/**
|
|
8
|
+
*
|
|
9
|
+
* Construct that configures various sensible CloudWatch alarms for AWS SES
|
|
10
|
+
*/
|
|
11
|
+
class SesAlarms extends constructs.Construct {
|
|
12
|
+
constructor(scope, id, props) {
|
|
13
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
14
|
+
super(scope, id);
|
|
15
|
+
this.action = props.action;
|
|
16
|
+
const bouncedMessagesAlarm = new cloudwatch.Metric({
|
|
17
|
+
metricName: "Reputation.BounceRate",
|
|
18
|
+
namespace: "AWS/SES",
|
|
19
|
+
statistic: "Maximum",
|
|
20
|
+
period: (_b = (_a = props === null || props === void 0 ? void 0 : props.bouncedMessagesAlarm) === null || _a === void 0 ? void 0 : _a.period) !== null && _b !== void 0 ? _b : cdk.Duration.minutes(10),
|
|
21
|
+
}).createAlarm(this, "BouncedMessagesAlarm", {
|
|
22
|
+
alarmDescription: `The SES bounce rate is over ${(_d = (_c = props === null || props === void 0 ? void 0 : props.bouncedMessagesAlarm) === null || _c === void 0 ? void 0 : _c.threshold) !== null && _d !== void 0 ? _d : 2.5}%`,
|
|
23
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
24
|
+
evaluationPeriods: 1,
|
|
25
|
+
treatMissingData: cloudwatch.TreatMissingData.IGNORE,
|
|
26
|
+
threshold: ((_f = (_e = props === null || props === void 0 ? void 0 : props.bouncedMessagesAlarm) === null || _e === void 0 ? void 0 : _e.threshold) !== null && _f !== void 0 ? _f : 2.5) / 100,
|
|
27
|
+
});
|
|
28
|
+
if ((_h = (_g = props === null || props === void 0 ? void 0 : props.bouncedMessagesAlarm) === null || _g === void 0 ? void 0 : _g.enabled) !== null && _h !== void 0 ? _h : true) {
|
|
29
|
+
bouncedMessagesAlarm.addAlarmAction(((_j = props === null || props === void 0 ? void 0 : props.bouncedMessagesAlarm) === null || _j === void 0 ? void 0 : _j.action) || this.action);
|
|
30
|
+
}
|
|
31
|
+
const complaintMessagesAlarm = new cloudwatch.Metric({
|
|
32
|
+
metricName: "Reputation.ComplaintRate",
|
|
33
|
+
namespace: "AWS/SES",
|
|
34
|
+
statistic: "Maximum",
|
|
35
|
+
period: (_l = (_k = props === null || props === void 0 ? void 0 : props.complaintRateAlarm) === null || _k === void 0 ? void 0 : _k.period) !== null && _l !== void 0 ? _l : cdk.Duration.minutes(10),
|
|
36
|
+
}).createAlarm(this, "ComplaintMessagesAlarm", {
|
|
37
|
+
alarmDescription: `The SES complaint rate is over ${(_o = (_m = props === null || props === void 0 ? void 0 : props.complaintRateAlarm) === null || _m === void 0 ? void 0 : _m.threshold) !== null && _o !== void 0 ? _o : 0.05}%`,
|
|
38
|
+
comparisonOperator: cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
|
|
39
|
+
evaluationPeriods: 1,
|
|
40
|
+
threshold: ((_q = (_p = props === null || props === void 0 ? void 0 : props.complaintRateAlarm) === null || _p === void 0 ? void 0 : _p.threshold) !== null && _q !== void 0 ? _q : 0.05) / 100,
|
|
41
|
+
treatMissingData: cloudwatch.TreatMissingData.IGNORE,
|
|
42
|
+
});
|
|
43
|
+
if ((_s = (_r = props === null || props === void 0 ? void 0 : props.complaintRateAlarm) === null || _r === void 0 ? void 0 : _r.enabled) !== null && _s !== void 0 ? _s : true) {
|
|
44
|
+
complaintMessagesAlarm.addAlarmAction(((_t = props === null || props === void 0 ? void 0 : props.complaintRateAlarm) === null || _t === void 0 ? void 0 : _t.action) || this.action);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
exports.SesAlarms = SesAlarms;
|
|
49
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VzLWFsYXJtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hbGFybXMvc2VzLWFsYXJtcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtQ0FBa0M7QUFDbEMseURBQXdEO0FBQ3hELHlDQUF3QztBQTJEeEM7OztHQUdHO0FBQ0gsTUFBYSxTQUFVLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFHakQsWUFBWSxLQUEyQixFQUFFLEVBQVUsRUFBRSxLQUFxQjs7UUFDeEUsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQTtRQUVoQixJQUFJLENBQUMsTUFBTSxHQUFHLEtBQUssQ0FBQyxNQUFNLENBQUE7UUFFMUIsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFDakQsVUFBVSxFQUFFLHVCQUF1QjtZQUNuQyxTQUFTLEVBQUUsU0FBUztZQUNwQixTQUFTLEVBQUUsU0FBUztZQUNwQixNQUFNLEVBQUUsTUFBQSxNQUFBLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxvQkFBb0IsMENBQUUsTUFBTSxtQ0FBSSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7U0FDeEUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsc0JBQXNCLEVBQUU7WUFDM0MsZ0JBQWdCLEVBQUUsK0JBQ2hCLE1BQUEsTUFBQSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsb0JBQW9CLDBDQUFFLFNBQVMsbUNBQUksR0FDNUMsR0FBRztZQUNILGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxzQkFBc0I7WUFDeEUsaUJBQWlCLEVBQUUsQ0FBQztZQUNwQixnQkFBZ0IsRUFBRSxVQUFVLENBQUMsZ0JBQWdCLENBQUMsTUFBTTtZQUNwRCxTQUFTLEVBQUUsQ0FBQyxNQUFBLE1BQUEsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLG9CQUFvQiwwQ0FBRSxTQUFTLG1DQUFJLEdBQUcsQ0FBQyxHQUFHLEdBQUc7U0FDakUsQ0FBQyxDQUFBO1FBRUYsSUFBSSxNQUFBLE1BQUEsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLG9CQUFvQiwwQ0FBRSxPQUFPLG1DQUFJLElBQUksRUFBRSxDQUFDO1lBQ2pELG9CQUFvQixDQUFDLGNBQWMsQ0FDakMsQ0FBQSxNQUFBLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxvQkFBb0IsMENBQUUsTUFBTSxLQUFJLElBQUksQ0FBQyxNQUFNLENBQ25ELENBQUE7UUFDSCxDQUFDO1FBRUQsTUFBTSxzQkFBc0IsR0FBRyxJQUFJLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFDbkQsVUFBVSxFQUFFLDBCQUEwQjtZQUN0QyxTQUFTLEVBQUUsU0FBUztZQUNwQixTQUFTLEVBQUUsU0FBUztZQUNwQixNQUFNLEVBQUUsTUFBQSxNQUFBLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxrQkFBa0IsMENBQUUsTUFBTSxtQ0FBSSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7U0FDdEUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsd0JBQXdCLEVBQUU7WUFDN0MsZ0JBQWdCLEVBQUUsa0NBQ2hCLE1BQUEsTUFBQSxLQUFLLGFBQUwsS0FBSyx1QkFBTCxLQUFLLENBQUUsa0JBQWtCLDBDQUFFLFNBQVMsbUNBQUksSUFDMUMsR0FBRztZQUNILGtCQUFrQixFQUFFLFVBQVUsQ0FBQyxrQkFBa0IsQ0FBQyxzQkFBc0I7WUFDeEUsaUJBQWlCLEVBQUUsQ0FBQztZQUNwQixTQUFTLEVBQUUsQ0FBQyxNQUFBLE1BQUEsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGtCQUFrQiwwQ0FBRSxTQUFTLG1DQUFJLElBQUksQ0FBQyxHQUFHLEdBQUc7WUFDL0QsZ0JBQWdCLEVBQUUsVUFBVSxDQUFDLGdCQUFnQixDQUFDLE1BQU07U0FDckQsQ0FBQyxDQUFBO1FBRUYsSUFBSSxNQUFBLE1BQUEsS0FBSyxhQUFMLEtBQUssdUJBQUwsS0FBSyxDQUFFLGtCQUFrQiwwQ0FBRSxPQUFPLG1DQUFJLElBQUksRUFBRSxDQUFDO1lBQy9DLHNCQUFzQixDQUFDLGNBQWMsQ0FDbkMsQ0FBQSxNQUFBLEtBQUssYUFBTCxLQUFLLHVCQUFMLEtBQUssQ0FBRSxrQkFBa0IsMENBQUUsTUFBTSxLQUFJLElBQUksQ0FBQyxNQUFNLENBQ2pELENBQUE7UUFDSCxDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBbERELDhCQWtEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tIFwiYXdzLWNkay1saWJcIlxuaW1wb3J0ICogYXMgY2xvdWR3YXRjaCBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2hcIlxuaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tIFwiY29uc3RydWN0c1wiXG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VzQWxhcm1zUHJvcHMgZXh0ZW5kcyBjZGsuU3RhY2tQcm9wcyB7XG4gIC8qKlxuICAgKiBUaGUgZGVmYXVsdCBhY3Rpb24gdG8gdXNlIGZvciBDbG91ZFdhdGNoIGFsYXJtIHN0YXRlIGNoYW5nZXNcbiAgICovXG4gIGFjdGlvbjogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb25cbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gZm9yIGFuIGFsYXJtIGZvciBoaWdoIHJhdGUgYm91bmNlZCBtZXNzYWdlcy5cbiAgICpcbiAgICogQGRlZmF1bHQgQ29uZmlndXJlZCB3aXRoIHJlYXNvbmFibGUgZGVmYXVsdHMuXG4gICAqL1xuICBib3VuY2VkTWVzc2FnZXNBbGFybT86IHtcbiAgICAvKipcbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICovXG4gICAgZW5hYmxlZD86IGJvb2xlYW5cbiAgICAvKipcbiAgICAgKiBBbiBhY3Rpb24gdG8gdXNlIGZvciBDbG91ZFdhdGNoIGFsYXJtIHN0YXRlIGNoYW5nZXMgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBhY3Rpb25cbiAgICAgKi9cbiAgICBhY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxuICAgIC8qKlxuICAgICAqIEBkZWZhdWx0IDEwIG1pbnV0ZXNcbiAgICAgKi9cbiAgICBwZXJpb2Q/OiBjZGsuRHVyYXRpb25cbiAgICAvKipcbiAgICAgKiBUaHJlc2hvbGQgdmFsdWUgZm9yIGFsYXJtIGFzIGEgcGVyY2VudFxuICAgICAqIEBkZWZhdWx0IDIuNSglKVxuICAgICAqIDUlIGlzIHRoZSB0aHJlc2hvbGQgYXQgd2hpY2ggQVdTIGNvbnNpZGVycyBwdXR0aW5nIGFuIGFjY291bnQgdW5kZXIgcmV2aWV3XG4gICAgICovXG4gICAgdGhyZXNob2xkPzogbnVtYmVyXG4gIH1cbiAgLyoqXG4gICAqIENvbmZpZ3VyYXRpb24gZm9yIGFuIGFsYXJtIGZvciBoaWdoIGNvbXBsYWludCByYXRlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBDb25maWd1cmVkIHdpdGggc2FuZSBkZWZhdWx0cy5cbiAgICovXG4gIGNvbXBsYWludFJhdGVBbGFybT86IHtcbiAgICAvKipcbiAgICAgKiBAZGVmYXVsdCB0cnVlXG4gICAgICovXG4gICAgZW5hYmxlZD86IGJvb2xlYW5cbiAgICAvKipcbiAgICAgKiBBbiBhY3Rpb24gdG8gdXNlIGZvciBDbG91ZFdhdGNoIGFsYXJtIHN0YXRlIGNoYW5nZXMgaW5zdGVhZCBvZiB0aGUgZGVmYXVsdCBhY3Rpb25cbiAgICAgKi9cbiAgICBhY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxuICAgIC8qKlxuICAgICAqIEBkZWZhdWx0IDEwIG1pbnV0ZXNcbiAgICAgKi9cbiAgICBwZXJpb2Q/OiBjZGsuRHVyYXRpb25cbiAgICAvKipcbiAgICAgKiBUaHJlc2hvbGQgdmFsdWUgZm9yIGFsYXJtIGFzIGEgcGVyY2VudFxuICAgICAqIEBkZWZhdWx0IDAuMDUoJSlcbiAgICAgKiAwLjEwJSBpcyB0aGUgdGhyZXNob2xkIGF0IHdoaWNoIEFXUyBjb25zaWRlcnMgcHV0dGluZyBhbiBhY2NvdW50IHVuZGVyIHJldmlld1xuICAgICAqL1xuICAgIHRocmVzaG9sZD86IG51bWJlclxuICB9XG59XG5cbi8qKlxuICpcbiAqIENvbnN0cnVjdCB0aGF0IGNvbmZpZ3VyZXMgdmFyaW91cyBzZW5zaWJsZSBDbG91ZFdhdGNoIGFsYXJtcyBmb3IgQVdTIFNFU1xuICovXG5leHBvcnQgY2xhc3MgU2VzQWxhcm1zIGV4dGVuZHMgY29uc3RydWN0cy5Db25zdHJ1Y3Qge1xuICBwcml2YXRlIHJlYWRvbmx5IGFjdGlvbjogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb25cblxuICBjb25zdHJ1Y3RvcihzY29wZTogY29uc3RydWN0cy5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTZXNBbGFybXNQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcblxuICAgIHRoaXMuYWN0aW9uID0gcHJvcHMuYWN0aW9uXG5cbiAgICBjb25zdCBib3VuY2VkTWVzc2FnZXNBbGFybSA9IG5ldyBjbG91ZHdhdGNoLk1ldHJpYyh7XG4gICAgICBtZXRyaWNOYW1lOiBcIlJlcHV0YXRpb24uQm91bmNlUmF0ZVwiLFxuICAgICAgbmFtZXNwYWNlOiBcIkFXUy9TRVNcIixcbiAgICAgIHN0YXRpc3RpYzogXCJNYXhpbXVtXCIsXG4gICAgICBwZXJpb2Q6IHByb3BzPy5ib3VuY2VkTWVzc2FnZXNBbGFybT8ucGVyaW9kID8/IGNkay5EdXJhdGlvbi5taW51dGVzKDEwKSxcbiAgICB9KS5jcmVhdGVBbGFybSh0aGlzLCBcIkJvdW5jZWRNZXNzYWdlc0FsYXJtXCIsIHtcbiAgICAgIGFsYXJtRGVzY3JpcHRpb246IGBUaGUgU0VTIGJvdW5jZSByYXRlIGlzIG92ZXIgJHtcbiAgICAgICAgcHJvcHM/LmJvdW5jZWRNZXNzYWdlc0FsYXJtPy50aHJlc2hvbGQgPz8gMi41XG4gICAgICB9JWAsXG4gICAgICBjb21wYXJpc29uT3BlcmF0b3I6IGNsb3Vkd2F0Y2guQ29tcGFyaXNvbk9wZXJhdG9yLkdSRUFURVJfVEhBTl9USFJFU0hPTEQsXG4gICAgICBldmFsdWF0aW9uUGVyaW9kczogMSxcbiAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5JR05PUkUsXG4gICAgICB0aHJlc2hvbGQ6IChwcm9wcz8uYm91bmNlZE1lc3NhZ2VzQWxhcm0/LnRocmVzaG9sZCA/PyAyLjUpIC8gMTAwLFxuICAgIH0pXG5cbiAgICBpZiAocHJvcHM/LmJvdW5jZWRNZXNzYWdlc0FsYXJtPy5lbmFibGVkID8/IHRydWUpIHtcbiAgICAgIGJvdW5jZWRNZXNzYWdlc0FsYXJtLmFkZEFsYXJtQWN0aW9uKFxuICAgICAgICBwcm9wcz8uYm91bmNlZE1lc3NhZ2VzQWxhcm0/LmFjdGlvbiB8fCB0aGlzLmFjdGlvbixcbiAgICAgIClcbiAgICB9XG5cbiAgICBjb25zdCBjb21wbGFpbnRNZXNzYWdlc0FsYXJtID0gbmV3IGNsb3Vkd2F0Y2guTWV0cmljKHtcbiAgICAgIG1ldHJpY05hbWU6IFwiUmVwdXRhdGlvbi5Db21wbGFpbnRSYXRlXCIsXG4gICAgICBuYW1lc3BhY2U6IFwiQVdTL1NFU1wiLFxuICAgICAgc3RhdGlzdGljOiBcIk1heGltdW1cIixcbiAgICAgIHBlcmlvZDogcHJvcHM/LmNvbXBsYWludFJhdGVBbGFybT8ucGVyaW9kID8/IGNkay5EdXJhdGlvbi5taW51dGVzKDEwKSxcbiAgICB9KS5jcmVhdGVBbGFybSh0aGlzLCBcIkNvbXBsYWludE1lc3NhZ2VzQWxhcm1cIiwge1xuICAgICAgYWxhcm1EZXNjcmlwdGlvbjogYFRoZSBTRVMgY29tcGxhaW50IHJhdGUgaXMgb3ZlciAke1xuICAgICAgICBwcm9wcz8uY29tcGxhaW50UmF0ZUFsYXJtPy50aHJlc2hvbGQgPz8gMC4wNVxuICAgICAgfSVgLFxuICAgICAgY29tcGFyaXNvbk9wZXJhdG9yOiBjbG91ZHdhdGNoLkNvbXBhcmlzb25PcGVyYXRvci5HUkVBVEVSX1RIQU5fVEhSRVNIT0xELFxuICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgICB0aHJlc2hvbGQ6IChwcm9wcz8uY29tcGxhaW50UmF0ZUFsYXJtPy50aHJlc2hvbGQgPz8gMC4wNSkgLyAxMDAsXG4gICAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuSUdOT1JFLFxuICAgIH0pXG5cbiAgICBpZiAocHJvcHM/LmNvbXBsYWludFJhdGVBbGFybT8uZW5hYmxlZCA/PyB0cnVlKSB7XG4gICAgICBjb21wbGFpbnRNZXNzYWdlc0FsYXJtLmFkZEFsYXJtQWN0aW9uKFxuICAgICAgICBwcm9wcz8uY29tcGxhaW50UmF0ZUFsYXJtPy5hY3Rpb24gfHwgdGhpcy5hY3Rpb24sXG4gICAgICApXG4gICAgfVxuICB9XG59XG4iXX0=
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import * as constructs from "constructs";
|
|
2
|
+
import * as cloudwatchActions from "aws-cdk-lib/aws-cloudwatch-actions";
|
|
3
|
+
import * as sns from "aws-cdk-lib/aws-sns";
|
|
4
|
+
import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
|
|
5
|
+
export interface SlackAlarmProps {
|
|
6
|
+
projectName: string;
|
|
7
|
+
envName: string;
|
|
8
|
+
/**
|
|
9
|
+
* A plaintext secret containing the URL of a Slack incoming webhook.
|
|
10
|
+
* The webhook should be created through a Slack app, and only allows posting to one specific Slack channel.
|
|
11
|
+
* See Slack's official documentation (e.g., https://api.slack.com/messaging/webhooks) for more details.
|
|
12
|
+
*
|
|
13
|
+
* NOTE: Incoming webhooks created through legacy custom integrations in Slack are not supported.
|
|
14
|
+
*/
|
|
15
|
+
slackWebhookUrlSecret: secretsmanager.ISecret;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* SNS Topic that can be used to action alarms, with a Lambda
|
|
19
|
+
* that will send a message to Slack for the alarm.
|
|
20
|
+
*/
|
|
21
|
+
export declare class SlackAlarm extends constructs.Construct {
|
|
22
|
+
readonly alarmTopic: sns.Topic;
|
|
23
|
+
readonly snsAction: cloudwatchActions.SnsAction;
|
|
24
|
+
constructor(scope: constructs.Construct, id: string, props: SlackAlarmProps);
|
|
25
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SlackAlarm = void 0;
|
|
4
|
+
const constructs = require("constructs");
|
|
5
|
+
const cloudwatchActions = require("aws-cdk-lib/aws-cloudwatch-actions");
|
|
6
|
+
const iam = require("aws-cdk-lib/aws-iam");
|
|
7
|
+
const lambda = require("aws-cdk-lib/aws-lambda");
|
|
8
|
+
const sns = require("aws-cdk-lib/aws-sns");
|
|
9
|
+
const aws_cdk_lib_1 = require("aws-cdk-lib");
|
|
10
|
+
const path = require("path");
|
|
11
|
+
/**
|
|
12
|
+
* SNS Topic that can be used to action alarms, with a Lambda
|
|
13
|
+
* that will send a message to Slack for the alarm.
|
|
14
|
+
*/
|
|
15
|
+
class SlackAlarm extends constructs.Construct {
|
|
16
|
+
constructor(scope, id, props) {
|
|
17
|
+
super(scope, id);
|
|
18
|
+
this.alarmTopic = new sns.Topic(this, "Topic");
|
|
19
|
+
this.snsAction = new cloudwatchActions.SnsAction(this.alarmTopic);
|
|
20
|
+
const slackLambda = new lambda.Function(this, "Function", {
|
|
21
|
+
code: lambda.Code.fromAsset(path.join(__dirname, "../../assets/slack-alarm-lambda")),
|
|
22
|
+
description: "Receives CloudWatch Alarms through SNS and sends a formatted version to Slack",
|
|
23
|
+
handler: "index.handler",
|
|
24
|
+
memorySize: 128,
|
|
25
|
+
runtime: lambda.Runtime.PYTHON_3_11,
|
|
26
|
+
timeout: aws_cdk_lib_1.Duration.seconds(6),
|
|
27
|
+
environment: {
|
|
28
|
+
SLACK_URL_SECRET_NAME: props.slackWebhookUrlSecret.secretName,
|
|
29
|
+
PROJECT_NAME: props.projectName,
|
|
30
|
+
ENVIRONMENT_NAME: props.envName,
|
|
31
|
+
},
|
|
32
|
+
});
|
|
33
|
+
props.slackWebhookUrlSecret.grantRead(slackLambda);
|
|
34
|
+
slackLambda.addPermission("InvokePermission", {
|
|
35
|
+
action: "lambda:InvokeFunction",
|
|
36
|
+
principal: new iam.ServicePrincipal("sns.amazonaws.com"),
|
|
37
|
+
sourceArn: this.alarmTopic.topicArn,
|
|
38
|
+
});
|
|
39
|
+
new sns.Subscription(this, "Subscription", {
|
|
40
|
+
endpoint: slackLambda.functionArn,
|
|
41
|
+
protocol: sns.SubscriptionProtocol.LAMBDA,
|
|
42
|
+
topic: this.alarmTopic,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
exports.SlackAlarm = SlackAlarm;
|
|
47
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xhY2stYWxhcm0uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvYWxhcm1zL3NsYWNrLWFsYXJtLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHlDQUF3QztBQUN4Qyx3RUFBdUU7QUFDdkUsMkNBQTBDO0FBQzFDLGlEQUFnRDtBQUNoRCwyQ0FBMEM7QUFDMUMsNkNBQXNDO0FBQ3RDLDZCQUE0QjtBQWdCNUI7OztHQUdHO0FBQ0gsTUFBYSxVQUFXLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFJbEQsWUFBWSxLQUEyQixFQUFFLEVBQVUsRUFBRSxLQUFzQjtRQUN6RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRWhCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQTtRQUU5QyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksaUJBQWlCLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUVqRSxNQUFNLFdBQVcsR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLFVBQVUsRUFBRTtZQUN4RCxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQ3pCLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUFFLGlDQUFpQyxDQUFDLENBQ3hEO1lBQ0QsV0FBVyxFQUNULCtFQUErRTtZQUNqRixPQUFPLEVBQUUsZUFBZTtZQUN4QixVQUFVLEVBQUUsR0FBRztZQUNmLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFdBQVc7WUFDbkMsT0FBTyxFQUFFLHNCQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztZQUM1QixXQUFXLEVBQUU7Z0JBQ1gscUJBQXFCLEVBQUUsS0FBSyxDQUFDLHFCQUFxQixDQUFDLFVBQVU7Z0JBQzdELFlBQVksRUFBRSxLQUFLLENBQUMsV0FBVztnQkFDL0IsZ0JBQWdCLEVBQUUsS0FBSyxDQUFDLE9BQU87YUFDaEM7U0FDRixDQUFDLENBQUE7UUFFRixLQUFLLENBQUMscUJBQXFCLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1FBRWxELFdBQVcsQ0FBQyxhQUFhLENBQUMsa0JBQWtCLEVBQUU7WUFDNUMsTUFBTSxFQUFFLHVCQUF1QjtZQUMvQixTQUFTLEVBQUUsSUFBSSxHQUFHLENBQUMsZ0JBQWdCLENBQUMsbUJBQW1CLENBQUM7WUFDeEQsU0FBUyxFQUFFLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUTtTQUNwQyxDQUFDLENBQUE7UUFFRixJQUFJLEdBQUcsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLGNBQWMsRUFBRTtZQUN6QyxRQUFRLEVBQUUsV0FBVyxDQUFDLFdBQVc7WUFDakMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxvQkFBb0IsQ0FBQyxNQUFNO1lBQ3pDLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVTtTQUN2QixDQUFDLENBQUE7SUFDSixDQUFDO0NBQ0Y7QUExQ0QsZ0NBMENDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tIFwiY29uc3RydWN0c1wiXG5pbXBvcnQgKiBhcyBjbG91ZHdhdGNoQWN0aW9ucyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWNsb3Vkd2F0Y2gtYWN0aW9uc1wiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIlxuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbGFtYmRhXCJcbmltcG9ydCAqIGFzIHNucyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNuc1wiXG5pbXBvcnQgeyBEdXJhdGlvbiB9IGZyb20gXCJhd3MtY2RrLWxpYlwiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcbmltcG9ydCAqIGFzIHNlY3JldHNtYW5hZ2VyIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXJcIlxuXG5leHBvcnQgaW50ZXJmYWNlIFNsYWNrQWxhcm1Qcm9wcyB7XG4gIHByb2plY3ROYW1lOiBzdHJpbmdcbiAgZW52TmFtZTogc3RyaW5nXG4gIC8qKlxuICAgKiBBIHBsYWludGV4dCBzZWNyZXQgY29udGFpbmluZyB0aGUgVVJMIG9mIGEgU2xhY2sgaW5jb21pbmcgd2ViaG9vay5cbiAgICogVGhlIHdlYmhvb2sgc2hvdWxkIGJlIGNyZWF0ZWQgdGhyb3VnaCBhIFNsYWNrIGFwcCwgYW5kIG9ubHkgYWxsb3dzIHBvc3RpbmcgdG8gb25lIHNwZWNpZmljIFNsYWNrIGNoYW5uZWwuXG4gICAqIFNlZSBTbGFjaydzIG9mZmljaWFsIGRvY3VtZW50YXRpb24gKGUuZy4sIGh0dHBzOi8vYXBpLnNsYWNrLmNvbS9tZXNzYWdpbmcvd2ViaG9va3MpIGZvciBtb3JlIGRldGFpbHMuXG4gICAqXG4gICAqIE5PVEU6IEluY29taW5nIHdlYmhvb2tzIGNyZWF0ZWQgdGhyb3VnaCBsZWdhY3kgY3VzdG9tIGludGVncmF0aW9ucyBpbiBTbGFjayBhcmUgbm90IHN1cHBvcnRlZC5cbiAgICovXG4gIHNsYWNrV2ViaG9va1VybFNlY3JldDogc2VjcmV0c21hbmFnZXIuSVNlY3JldFxufVxuXG4vKipcbiAqIFNOUyBUb3BpYyB0aGF0IGNhbiBiZSB1c2VkIHRvIGFjdGlvbiBhbGFybXMsIHdpdGggYSBMYW1iZGFcbiAqIHRoYXQgd2lsbCBzZW5kIGEgbWVzc2FnZSB0byBTbGFjayBmb3IgdGhlIGFsYXJtLlxuICovXG5leHBvcnQgY2xhc3MgU2xhY2tBbGFybSBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcbiAgcHVibGljIHJlYWRvbmx5IGFsYXJtVG9waWM6IHNucy5Ub3BpY1xuICBwdWJsaWMgcmVhZG9ubHkgc25zQWN0aW9uOiBjbG91ZHdhdGNoQWN0aW9ucy5TbnNBY3Rpb25cblxuICBjb25zdHJ1Y3RvcihzY29wZTogY29uc3RydWN0cy5Db25zdHJ1Y3QsIGlkOiBzdHJpbmcsIHByb3BzOiBTbGFja0FsYXJtUHJvcHMpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICB0aGlzLmFsYXJtVG9waWMgPSBuZXcgc25zLlRvcGljKHRoaXMsIFwiVG9waWNcIilcblxuICAgIHRoaXMuc25zQWN0aW9uID0gbmV3IGNsb3Vkd2F0Y2hBY3Rpb25zLlNuc0FjdGlvbih0aGlzLmFsYXJtVG9waWMpXG5cbiAgICBjb25zdCBzbGFja0xhbWJkYSA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgXCJGdW5jdGlvblwiLCB7XG4gICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQoXG4gICAgICAgIHBhdGguam9pbihfX2Rpcm5hbWUsIFwiLi4vLi4vYXNzZXRzL3NsYWNrLWFsYXJtLWxhbWJkYVwiKSxcbiAgICAgICksXG4gICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgXCJSZWNlaXZlcyBDbG91ZFdhdGNoIEFsYXJtcyB0aHJvdWdoIFNOUyBhbmQgc2VuZHMgYSBmb3JtYXR0ZWQgdmVyc2lvbiB0byBTbGFja1wiLFxuICAgICAgaGFuZGxlcjogXCJpbmRleC5oYW5kbGVyXCIsXG4gICAgICBtZW1vcnlTaXplOiAxMjgsXG4gICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5QWVRIT05fM18xMSxcbiAgICAgIHRpbWVvdXQ6IER1cmF0aW9uLnNlY29uZHMoNiksXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBTTEFDS19VUkxfU0VDUkVUX05BTUU6IHByb3BzLnNsYWNrV2ViaG9va1VybFNlY3JldC5zZWNyZXROYW1lLFxuICAgICAgICBQUk9KRUNUX05BTUU6IHByb3BzLnByb2plY3ROYW1lLFxuICAgICAgICBFTlZJUk9OTUVOVF9OQU1FOiBwcm9wcy5lbnZOYW1lLFxuICAgICAgfSxcbiAgICB9KVxuXG4gICAgcHJvcHMuc2xhY2tXZWJob29rVXJsU2VjcmV0LmdyYW50UmVhZChzbGFja0xhbWJkYSlcblxuICAgIHNsYWNrTGFtYmRhLmFkZFBlcm1pc3Npb24oXCJJbnZva2VQZXJtaXNzaW9uXCIsIHtcbiAgICAgIGFjdGlvbjogXCJsYW1iZGE6SW52b2tlRnVuY3Rpb25cIixcbiAgICAgIHByaW5jaXBhbDogbmV3IGlhbS5TZXJ2aWNlUHJpbmNpcGFsKFwic25zLmFtYXpvbmF3cy5jb21cIiksXG4gICAgICBzb3VyY2VBcm46IHRoaXMuYWxhcm1Ub3BpYy50b3BpY0FybixcbiAgICB9KVxuXG4gICAgbmV3IHNucy5TdWJzY3JpcHRpb24odGhpcywgXCJTdWJzY3JpcHRpb25cIiwge1xuICAgICAgZW5kcG9pbnQ6IHNsYWNrTGFtYmRhLmZ1bmN0aW9uQXJuLFxuICAgICAgcHJvdG9jb2w6IHNucy5TdWJzY3JpcHRpb25Qcm90b2NvbC5MQU1CREEsXG4gICAgICB0b3BpYzogdGhpcy5hbGFybVRvcGljLFxuICAgIH0pXG4gIH1cbn1cbiJdfQ==
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as constructs from "constructs";
|
|
2
|
+
import * as ec2 from "aws-cdk-lib/aws-ec2";
|
|
3
|
+
interface Props {
|
|
4
|
+
vpc: ec2.IVpc;
|
|
5
|
+
/**
|
|
6
|
+
* The security group used for the EC2 instance.
|
|
7
|
+
*
|
|
8
|
+
* @default - a security group will be created
|
|
9
|
+
*/
|
|
10
|
+
securityGroup?: ec2.ISecurityGroup;
|
|
11
|
+
/**
|
|
12
|
+
* The subnets to place the bastion host.
|
|
13
|
+
*
|
|
14
|
+
* Note that if placed inside private subnet, the VPC must have
|
|
15
|
+
* VPC endpoints to access relevant AWS services for Systems Manager
|
|
16
|
+
* to work in order to be able to connect to the instance.
|
|
17
|
+
*
|
|
18
|
+
* See https://aws.amazon.com/premiumsupport/knowledge-center/ec2-systems-manager-vpc-endpoints/
|
|
19
|
+
*
|
|
20
|
+
* @default - public subnets
|
|
21
|
+
*/
|
|
22
|
+
subnetSelection?: ec2.SubnetSelection;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* This creates a EC2 bastion host that can be used to connect
|
|
26
|
+
* to database instances and other internal resources.
|
|
27
|
+
*
|
|
28
|
+
* The instance is supposed to have no open ingress ports, and users
|
|
29
|
+
* are supposed to connect only through SSM Session Manager.
|
|
30
|
+
*
|
|
31
|
+
* The resources that the bastion host should be allowed to access
|
|
32
|
+
* must have the bastion host security group as allowed ingress.
|
|
33
|
+
*
|
|
34
|
+
* For more internal details, see
|
|
35
|
+
* https://confluence.capraconsulting.no/x/q8UBC
|
|
36
|
+
*/
|
|
37
|
+
export declare class BastionHost extends constructs.Construct {
|
|
38
|
+
readonly securityGroup: ec2.ISecurityGroup;
|
|
39
|
+
constructor(scope: constructs.Construct, id: string, props: Props);
|
|
40
|
+
}
|
|
41
|
+
export {};
|