@liflig/cdk 1.50.0 → 1.51.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,249 @@
1
+ #!/usr/bin/env python
2
+
3
+ """
4
+ Transform CloudTrail events to payloads formatted for Slack's API, and send them
5
+ directly to Slack or through an SQS FIFO queue for deduplication.
6
+
7
+ The code below contains entrypoints for two Lambda functions (prefixed with `handler_`).
8
+ """
9
+
10
+ import os
11
+ import logging
12
+ import json
13
+ import urllib.request
14
+ import boto3
15
+
16
+ logger = logging.getLogger()
17
+ logger.setLevel(logging.INFO)
18
+
19
+
20
+ def get_slack_payload_for_assume_role_event(event, account_friendly_names):
21
+ """Parse a CloudTrail event related to the API call sts:AssumeRole,
22
+ and return a Slack-formatted attachment"""
23
+ event_account_id = event["account"]
24
+ event_detail = event["detail"]
25
+ request_parameters = event_detail.get("requestParameters", {}) or {}
26
+
27
+ timestamp = event_detail["eventTime"]
28
+ user_identity = event_detail["userIdentity"]
29
+ principal_id = user_identity["principalId"]
30
+ principal_account_id = user_identity["accountId"]
31
+ source_identity = request_parameters.get("sourceIdentity", "")
32
+ source_ip = event_detail.get("sourceIPAddress", "")
33
+ role_arn = request_parameters.get("roleArn", "")
34
+
35
+ fallback = f"Sensitive role accessed in '{event_account_id}'"
36
+ pretext_messages = [f":warning: Sensitive role in `{event_account_id}` assumed by"]
37
+ if principal_id.startswith("AIDA"):
38
+ pretext_messages.append("IAM user")
39
+ elif principal_id.startswith("AROA"):
40
+ pretext_messages.append("IAM role")
41
+ else:
42
+ pretext_messages.append("principal")
43
+ pretext_messages.append(f"in `{principal_account_id}`")
44
+ pretext = " ".join(pretext_messages)
45
+
46
+ text = [
47
+ f"*Role ARN:* `{role_arn}`",
48
+ f"*Principal Account ID:* `{principal_account_id}`",
49
+ f"*Principal ID:* `{principal_id}`",
50
+ f"*Source IP:* `{source_ip}`",
51
+ f"*Source Identity:* `{source_identity}`" if source_identity else "",
52
+ f"*Timestamp:* `{timestamp}`",
53
+ ]
54
+ text = "\n".join(line for line in text if line)
55
+ for account_id, friendly_name in account_friendly_names.items():
56
+ pretext = pretext.replace(account_id, friendly_name)
57
+ fallback = fallback.replace(account_id, friendly_name)
58
+ return {
59
+ "attachments": [
60
+ {
61
+ "pretext": pretext,
62
+ "color": "warning",
63
+ "text": text,
64
+ "fallback": fallback,
65
+ "mrkdwn_in": ["pretext", "text"],
66
+ }
67
+ ]
68
+ }
69
+
70
+
71
+ def get_fallback_slack_payload_for_event(
72
+ event, account_friendly_names, fallback_parse_behavior=""
73
+ ):
74
+ """Parse a generic CloudTrail event related to an API call
75
+ and return a Slack-formatted attachment"""
76
+ event_account_id = event["account"]
77
+ event_detail = event["detail"]
78
+ event_name = event_detail["eventName"]
79
+ event_type = event_detail["eventType"]
80
+ event_time = event_detail["eventTime"]
81
+ pretext = f":warning: CloudTrail event in account `{event_account_id}`"
82
+ fallback = f"CloudTrail event in account '{event_account_id}'"
83
+ if fallback_parse_behavior == "DUMP_EVENT":
84
+ text = "\n".join(
85
+ ["*Event:*", "```", json.dumps(event, sort_keys=True, indent=2), "```"]
86
+ )
87
+ else:
88
+ error_message = event_detail.get("errorMessage", "")
89
+ # This may be None, in which case we force it to an empty dict instead
90
+ response_element = (event_detail.get("responseElements", {}) or {}).get(
91
+ event_name, ""
92
+ )
93
+ user_identity = event_detail["userIdentity"]
94
+ principal_id = user_identity.get("principalId", "")
95
+ principal_type = user_identity.get("type", "")
96
+ principal_account_id = user_identity.get("accountId", "")
97
+ principal_arn = user_identity.get("arn", "")
98
+ source_ip = event_detail.get("sourceIPAddress", "")
99
+ resources = event_detail.get("resources", []) or []
100
+ text = [
101
+ f"*Event Type:* `{event_type}`",
102
+ f"*Event Name:* `{event_name}`",
103
+ f"*Event Time:* `{event_time}`",
104
+ f"*Error Message:* `{error_message}`" if error_message else "",
105
+ f"*Response Code:* `{response_element}`" if response_element else "",
106
+ f"*Principal Type:* `{principal_type}`" if principal_type else "",
107
+ f"*Principal Account ID:* `{principal_account_id}`"
108
+ if principal_account_id
109
+ else "",
110
+ f"*Principal ARN:* `{principal_arn}`" if principal_arn else "",
111
+ f"*Principal ID:* `{principal_id}`" if principal_id else "",
112
+ f"*Source IP:* `{source_ip}`" if source_ip else "",
113
+ f"*Resources:*\n```{json.dumps(resources, indent=2, sort_keys=True)}\n```"
114
+ if len(resources)
115
+ else "",
116
+ ]
117
+ # Filter out empty strings
118
+ text = "\n".join(line for line in text if line)
119
+
120
+ for account_id, friendly_name in account_friendly_names.items():
121
+ pretext = pretext.replace(account_id, friendly_name)
122
+ fallback = fallback.replace(account_id, friendly_name)
123
+ return {
124
+ "attachments": [
125
+ {
126
+ "pretext": pretext,
127
+ "color": "warning",
128
+ "text": text,
129
+ "fallback": fallback,
130
+ "mrkdwn_in": ["pretext", "text"],
131
+ }
132
+ ]
133
+ }
134
+
135
+
136
+ def get_augmented_account_friendly_names(event, account_friendly_names):
137
+ """Return an augmented dictionary containing the alias of the current
138
+ AWS account if relevant"""
139
+ augmented_account_friendly_names = {**account_friendly_names}
140
+ try:
141
+ event_account_id = event["account"]
142
+ event_detail = event["detail"]
143
+ recipient_account_id = event_detail["recipientAccountId"]
144
+ if (
145
+ not augmented_account_friendly_names.get(event_account_id, "")
146
+ and event_account_id == recipient_account_id
147
+ ):
148
+ logger.info(
149
+ "No friendly name was supplied for current account '%s', so looking up account alias",
150
+ event_account_id,
151
+ )
152
+ iam = boto3.client("iam")
153
+ aliases = iam.list_account_aliases()["AccountAliases"]
154
+ if len(aliases):
155
+ augmented_account_friendly_names[event_account_id] = aliases[0]
156
+ except:
157
+ logger.exception("Failed to look up alias of current AWS account")
158
+
159
+ return augmented_account_friendly_names
160
+
161
+
162
+ def post_to_slack(slack_payload, slack_webhook_url):
163
+ """Post a payload to Slack's webhook API"""
164
+ encoded_slack_payload = json.dumps(slack_payload).encode("utf-8")
165
+ try:
166
+ slack_request = urllib.request.Request(
167
+ slack_webhook_url,
168
+ data=encoded_slack_payload,
169
+ headers={"Content-Type": "application/json"},
170
+ )
171
+ urllib.request.urlopen(slack_request)
172
+ except:
173
+ logger.exception("Failed to post to Slack")
174
+ raise
175
+
176
+
177
+ def handler_event_transformer(event, context):
178
+ """Lambda handler for the event transformer Lambda"""
179
+ logger.info("Triggered with event: %s", json.dumps(event, indent=2))
180
+
181
+ account_friendly_names = json.loads(os.environ["ACCOUNT_FRIENDLY_NAMES"])
182
+ slack_webhook_url = os.environ["SLACK_WEBHOOK_URL"]
183
+ slack_channel = os.environ["SLACK_CHANNEL"]
184
+ sqs_queue_url = os.environ.get("SQS_QUEUE_URL", "")
185
+ fallback_parse_behavior = os.environ.get("FALLBACK_PARSE_BEHAVIOR", "")
186
+ deduplicate_events = os.environ.get("DEDUPLICATE_EVENTS", "false") == "true"
187
+
188
+ account_friendly_names = get_augmented_account_friendly_names(
189
+ event, account_friendly_names
190
+ )
191
+
192
+ if not event["detail-type"].endswith("via CloudTrail"):
193
+ logger.warn("Invalid event received")
194
+ return
195
+
196
+ slack_payload = {}
197
+ try:
198
+ if event["detail"]["eventName"] == "AssumeRole":
199
+ slack_payload = get_slack_payload_for_assume_role_event(
200
+ event, account_friendly_names
201
+ )
202
+ except:
203
+ logger.exception("Failed to parse event using predefined schema")
204
+ if not slack_payload:
205
+ logger.warn("Using a fallback schema to parse event")
206
+ slack_payload = get_fallback_slack_payload_for_event(
207
+ event,
208
+ account_friendly_names,
209
+ fallback_parse_behavior=fallback_parse_behavior,
210
+ )
211
+ slack_payload = {**slack_payload, "channel": slack_channel}
212
+
213
+ if deduplicate_events and sqs_queue_url:
214
+ logger.info("Sending message to SQS for deduplication")
215
+ deduplication_id = (
216
+ event["detail"].get("requestID", "")
217
+ or event["detail"].get("eventID", "")
218
+ or event["id"]
219
+ )
220
+ body = {
221
+ "slackWebhookUrl": slack_webhook_url,
222
+ "slackPayload": slack_payload,
223
+ }
224
+
225
+ sqs = boto3.client("sqs")
226
+ sqs.send_message(
227
+ QueueUrl=sqs_queue_url,
228
+ MessageBody=json.dumps(body),
229
+ MessageDeduplicationId=deduplication_id,
230
+ MessageGroupId=deduplication_id,
231
+ )
232
+ else:
233
+ logger.info("Sending message directly to Slack")
234
+ post_to_slack(slack_payload, slack_webhook_url)
235
+
236
+
237
+ def handler_slack_forwarder(event, context):
238
+ """Lambda handler for the Slack forwarder Lambda"""
239
+ logger.info("Triggered with event: %s", json.dumps(event, indent=2))
240
+ records = event["Records"]
241
+ for record in records:
242
+ body = json.loads(record["body"])
243
+ slack_channel = body.get("slackChannel", "")
244
+ slack_webhook_url = body.get("slackWebhookUrl", "")
245
+ slack_payload = {
246
+ **body["slackPayload"],
247
+ **({"channel": slack_channel} if slack_channel else {}),
248
+ }
249
+ post_to_slack(slack_payload, slack_webhook_url)
@@ -69,4 +69,4 @@ const startDeployHandler = async (event, context) => {
69
69
  };
70
70
  };
71
71
  exports.startDeployHandler = startDeployHandler;
72
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQtZGVwbG95LWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2RrLWRlcGxveS9zdGFydC1kZXBsb3ktaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFhQSxtREFBbUQ7QUFDbkQsNkJBQTZCO0FBQ3RCLE1BQU0sa0JBQWtCLEdBQzdCLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQ3ZCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUU5QixNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQW9CLENBQUE7SUFDdkQsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxFQUFhLENBQUE7SUFFbEMsU0FBUyxVQUFVLENBQUMsSUFBWTtRQUM5QixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQy9CLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUMsQ0FBQTtTQUNuQztRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUM5QyxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDNUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQTtJQUV4RCx5REFBeUQ7SUFDekQsdURBQXVEO0lBQ3ZELE1BQU0sY0FBYyxHQUFHLDBCQUEwQixDQUFBO0lBRWpELE1BQU0sV0FBVyxHQUFHLEdBQUcsT0FBTyxDQUFDLFlBQVksR0FBRyxDQUFBO0lBRTlDLHNCQUFzQjtJQUN0QixJQUNFLE9BQU8sS0FBSyxDQUFDLFVBQVUsS0FBSyxRQUFRO1FBQ3BDLE9BQU8sS0FBSyxDQUFDLFNBQVMsS0FBSyxRQUFRO1FBQ25DLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQ2hDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQ3JCLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxRQUFRLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FDMUQsRUFDRDtRQUNBLE1BQU0sSUFBSSxLQUFLLENBQ2IsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUMzRCxDQUFBO0tBQ0Y7SUFFRCxLQUFLLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxJQUFpQjtRQUNoRCxNQUFNLEVBQUU7YUFDTCxTQUFTLENBQUM7WUFDVCxNQUFNLEVBQUUsVUFBVTtZQUNsQixHQUFHLEVBQUUsR0FBRyxXQUFXLEdBQUcsSUFBSSxFQUFFO1lBQzVCLElBQUksRUFBRSxJQUFJO1NBQ1gsQ0FBQzthQUNELE9BQU8sRUFBRSxDQUFBO0lBQ2QsQ0FBQztJQUVELE1BQU0sR0FBRyxDQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDeEQsMERBQTBEO0lBQzFELE1BQU0sR0FBRyxDQUNQLFVBQVUsRUFDVixJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ2IsT0FBTyxFQUFFLFVBQVU7S0FDcEIsQ0FBQyxDQUNILENBQUE7SUFFRCxNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVM7U0FDMUIsVUFBVSxDQUFDO1FBQ1YsV0FBVztRQUNYLGtCQUFrQixFQUFFLElBQUk7UUFDeEIsc0JBQXNCLEVBQUUsR0FBRyxVQUFVLElBQUksV0FBVyxFQUFFO1FBQ3RELHdCQUF3QixFQUFFO1lBQ3hCO2dCQUNFLElBQUksRUFBRSxJQUFJO2dCQUNWLFFBQVEsRUFBRSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRTtnQkFDbEQsZ0JBQWdCLEVBQUUsZUFBZTthQUNsQztTQUNGO0tBQ0YsQ0FBQztTQUNELE9BQU8sRUFBRSxDQUFBO0lBRVosTUFBTSxPQUFPLEdBQUcsTUFBQSxLQUFLLENBQUMsS0FBSywwQ0FBRSxFQUFFLENBQUE7SUFDL0IsSUFBSSxPQUFPLElBQUksSUFBSSxFQUFFO1FBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtLQUNwQztJQUVELE9BQU87UUFDTCxpRUFBaUU7UUFDakUsb0VBQW9FO1FBQ3BFLG9DQUFvQztRQUNwQyxLQUFLLEVBQUUsT0FBTztLQUNmLENBQUE7QUFDSCxDQUFDLENBQUE7QUFwRlUsUUFBQSxrQkFBa0Isc0JBb0Y1QiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudCAqL1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1jYWxsICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMgKi9cbmltcG9ydCB7IEhhbmRsZXIgfSBmcm9tIFwiYXdzLWxhbWJkYVwiXG5pbXBvcnQgdHlwZSAqIGFzIF9BV1MgZnJvbSBcImF3cy1zZGtcIlxuXG5pbnRlcmZhY2UgU3RhcnREZXBsb3lFeHBlY3RlZElucHV0IHtcbiAgYnVja2V0TmFtZTogc3RyaW5nXG4gIGJ1Y2tldEtleTogc3RyaW5nXG4gIHN0YWNrTmFtZXM6IHN0cmluZ1tdXG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgaW5saW5lLWNvbXBpbGVkIGZvciB0aGUgbGFtYmRhLlxuLy8gSXQgbXVzdCBiZSBzZWxmLWNvbnRhaW5lZC5cbmV4cG9ydCBjb25zdCBzdGFydERlcGxveUhhbmRsZXI6IEhhbmRsZXI8UGFydGlhbDxTdGFydERlcGxveUV4cGVjdGVkSW5wdXQ+PiA9XG4gIGFzeW5jIChldmVudCwgY29udGV4dCkgPT4ge1xuICAgIGNvbnN0IEFXUyA9IHJlcXVpcmUoXCJhd3Mtc2RrXCIpXG5cbiAgICBjb25zdCBjb2RlYnVpbGQgPSBuZXcgQVdTLkNvZGVCdWlsZCgpIGFzIF9BV1MuQ29kZUJ1aWxkXG4gICAgY29uc3QgczMgPSBuZXcgQVdTLlMzKCkgYXMgX0FXUy5TM1xuXG4gICAgZnVuY3Rpb24gcmVxdWlyZUVudihuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgICAgY29uc3QgdmFsdWUgPSBwcm9jZXNzLmVudltuYW1lXVxuICAgICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBNaXNzaW5nICR7bmFtZX1gKVxuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlXG4gICAgfVxuXG4gICAgY29uc3QgcHJvamVjdE5hbWUgPSByZXF1aXJlRW52KFwiUFJPSkVDVF9OQU1FXCIpXG4gICAgY29uc3QgYnVja2V0TmFtZSA9IHJlcXVpcmVFbnYoXCJCVUNLRVRfTkFNRVwiKVxuICAgIGNvbnN0IGNka0NvbnRleHQgPSBKU09OLnBhcnNlKHJlcXVpcmVFbnYoXCJDREtfQ09OVEVYVFwiKSlcblxuICAgIC8vIFNpbmNlIHdlIHBhc3MgdGhlIHN0YWNrIG5hbWVzIGFzIHN0cmluZ3MgdG8gdGhlIHNoZWxsLFxuICAgIC8vIGJlIGEgYml0IHJlc3RyaWN0aXZlIG9mIHRoZSB2YWxpZCB2YWx1ZXMgd2UgY2FuIHVzZS5cbiAgICBjb25zdCB2YWxpZFN0YWNrTmFtZSA9IC9eW2EtejAtOV9dW2EtejAtOVxcLV9dKiQvaVxuXG4gICAgY29uc3QgczNLZXlQcmVmaXggPSBgJHtjb250ZXh0LmF3c1JlcXVlc3RJZH0vYFxuXG4gICAgLy8gVmFsaWRhdGUgdGhlIGlucHV0LlxuICAgIGlmIChcbiAgICAgIHR5cGVvZiBldmVudC5idWNrZXROYW1lICE9PSBcInN0cmluZ1wiIHx8XG4gICAgICB0eXBlb2YgZXZlbnQuYnVja2V0S2V5ICE9PSBcInN0cmluZ1wiIHx8XG4gICAgICAhQXJyYXkuaXNBcnJheShldmVudC5zdGFja05hbWVzKSB8fFxuICAgICAgIWV2ZW50LnN0YWNrTmFtZXMuZXZlcnkoXG4gICAgICAgIChpdCkgPT4gdHlwZW9mIGl0ID09PSBcInN0cmluZ1wiICYmIHZhbGlkU3RhY2tOYW1lLnRlc3QoaXQpLFxuICAgICAgKVxuICAgICkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIklucHV0IGludmFsaWQ6IFwiICsgSlNPTi5zdHJpbmdpZnkoZXZlbnQsIHVuZGVmaW5lZCwgXCIgIFwiKSxcbiAgICAgIClcbiAgICB9XG5cbiAgICBhc3luYyBmdW5jdGlvbiBwdXQobmFtZTogc3RyaW5nLCBkYXRhOiBBV1MuUzMuQm9keSkge1xuICAgICAgYXdhaXQgczNcbiAgICAgICAgLnB1dE9iamVjdCh7XG4gICAgICAgICAgQnVja2V0OiBidWNrZXROYW1lLFxuICAgICAgICAgIEtleTogYCR7czNLZXlQcmVmaXh9JHtuYW1lfWAsXG4gICAgICAgICAgQm9keTogZGF0YSxcbiAgICAgICAgfSlcbiAgICAgICAgLnByb21pc2UoKVxuICAgIH1cblxuICAgIGF3YWl0IHB1dChcInN0YWNrLW5hbWVzLnR4dFwiLCBldmVudC5zdGFja05hbWVzLmpvaW4oXCIgXCIpKVxuICAgIC8vIEVuc3VyZSB0aGF0IHdlIHJ1biB0aGUgc2NyaXB0IHVzaW5nIHNhbWUgZmVhdHVyZSBmbGFncy5cbiAgICBhd2FpdCBwdXQoXG4gICAgICBcImNkay5qc29uXCIsXG4gICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGNvbnRleHQ6IGNka0NvbnRleHQsXG4gICAgICB9KSxcbiAgICApXG5cbiAgICBjb25zdCBidWlsZCA9IGF3YWl0IGNvZGVidWlsZFxuICAgICAgLnN0YXJ0QnVpbGQoe1xuICAgICAgICBwcm9qZWN0TmFtZSxcbiAgICAgICAgc291cmNlVHlwZU92ZXJyaWRlOiBcIlMzXCIsXG4gICAgICAgIHNvdXJjZUxvY2F0aW9uT3ZlcnJpZGU6IGAke2J1Y2tldE5hbWV9LyR7czNLZXlQcmVmaXh9YCxcbiAgICAgICAgc2Vjb25kYXJ5U291cmNlc092ZXJyaWRlOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogXCJTM1wiLFxuICAgICAgICAgICAgbG9jYXRpb246IGAke2V2ZW50LmJ1Y2tldE5hbWV9LyR7ZXZlbnQuYnVja2V0S2V5fWAsXG4gICAgICAgICAgICBzb3VyY2VJZGVudGlmaWVyOiBcIkNMT1VEQVNTRU1CTFlcIixcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSlcbiAgICAgIC5wcm9taXNlKClcblxuICAgIGNvbnN0IGJ1aWxkSWQgPSBidWlsZC5idWlsZD8uaWRcbiAgICBpZiAoYnVpbGRJZCA9PSBudWxsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmtub3duIGJ1aWxkIElEXCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIC8vIFRoaXMgaXMgdGhlIHZhbHVlIHRoZSBjYWxsZXIgd2lsbCB1c2UgdG8gZmV0Y2ggdXBkYXRlZCBzdGF0dXMuXG4gICAgICAvLyBBdm9pZCBleHBvc2luZyB3aGF0IGtpbmQgb2YgSUQgdGhpcyBpcywgYmVjYXVzZSB3ZSBzaG91bGQgYmUgZnJlZVxuICAgICAgLy8gdG8gY2hhbmdlIGltcGxlbWVudGF0aW9uIGRldGFpbHMuXG4gICAgICBqb2JJZDogYnVpbGRJZCxcbiAgICB9XG4gIH1cbiJdfQ==
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhcnQtZGVwbG95LWhhbmRsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2RrLWRlcGxveS9zdGFydC1kZXBsb3ktaGFuZGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFhQSxtREFBbUQ7QUFDbkQsNkJBQTZCO0FBQ3RCLE1BQU0sa0JBQWtCLEdBRTNCLEtBQUssRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUU7O0lBQzNCLE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQTtJQUU5QixNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsQ0FBQyxTQUFTLEVBQW9CLENBQUE7SUFDdkQsTUFBTSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUMsRUFBRSxFQUFhLENBQUE7SUFFbEMsU0FBUyxVQUFVLENBQUMsSUFBWTtRQUM5QixNQUFNLEtBQUssR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQy9CLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRTtZQUN2QixNQUFNLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUMsQ0FBQTtTQUNuQztRQUNELE9BQU8sS0FBSyxDQUFBO0lBQ2QsQ0FBQztJQUVELE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxjQUFjLENBQUMsQ0FBQTtJQUM5QyxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUE7SUFDNUMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQTtJQUV4RCx5REFBeUQ7SUFDekQsdURBQXVEO0lBQ3ZELE1BQU0sY0FBYyxHQUFHLDBCQUEwQixDQUFBO0lBRWpELE1BQU0sV0FBVyxHQUFHLEdBQUcsT0FBTyxDQUFDLFlBQVksR0FBRyxDQUFBO0lBRTlDLHNCQUFzQjtJQUN0QixJQUNFLE9BQU8sS0FBSyxDQUFDLFVBQVUsS0FBSyxRQUFRO1FBQ3BDLE9BQU8sS0FBSyxDQUFDLFNBQVMsS0FBSyxRQUFRO1FBQ25DLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBQ2hDLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQ3JCLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxPQUFPLEVBQUUsS0FBSyxRQUFRLElBQUksY0FBYyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FDMUQsRUFDRDtRQUNBLE1BQU0sSUFBSSxLQUFLLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUE7S0FDNUU7SUFFRCxLQUFLLFVBQVUsR0FBRyxDQUFDLElBQVksRUFBRSxJQUFpQjtRQUNoRCxNQUFNLEVBQUU7YUFDTCxTQUFTLENBQUM7WUFDVCxNQUFNLEVBQUUsVUFBVTtZQUNsQixHQUFHLEVBQUUsR0FBRyxXQUFXLEdBQUcsSUFBSSxFQUFFO1lBQzVCLElBQUksRUFBRSxJQUFJO1NBQ1gsQ0FBQzthQUNELE9BQU8sRUFBRSxDQUFBO0lBQ2QsQ0FBQztJQUVELE1BQU0sR0FBRyxDQUFDLGlCQUFpQixFQUFFLEtBQUssQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUE7SUFDeEQsMERBQTBEO0lBQzFELE1BQU0sR0FBRyxDQUNQLFVBQVUsRUFDVixJQUFJLENBQUMsU0FBUyxDQUFDO1FBQ2IsT0FBTyxFQUFFLFVBQVU7S0FDcEIsQ0FBQyxDQUNILENBQUE7SUFFRCxNQUFNLEtBQUssR0FBRyxNQUFNLFNBQVM7U0FDMUIsVUFBVSxDQUFDO1FBQ1YsV0FBVztRQUNYLGtCQUFrQixFQUFFLElBQUk7UUFDeEIsc0JBQXNCLEVBQUUsR0FBRyxVQUFVLElBQUksV0FBVyxFQUFFO1FBQ3RELHdCQUF3QixFQUFFO1lBQ3hCO2dCQUNFLElBQUksRUFBRSxJQUFJO2dCQUNWLFFBQVEsRUFBRSxHQUFHLEtBQUssQ0FBQyxVQUFVLElBQUksS0FBSyxDQUFDLFNBQVMsRUFBRTtnQkFDbEQsZ0JBQWdCLEVBQUUsZUFBZTthQUNsQztTQUNGO0tBQ0YsQ0FBQztTQUNELE9BQU8sRUFBRSxDQUFBO0lBRVosTUFBTSxPQUFPLEdBQUcsTUFBQSxLQUFLLENBQUMsS0FBSywwQ0FBRSxFQUFFLENBQUE7SUFDL0IsSUFBSSxPQUFPLElBQUksSUFBSSxFQUFFO1FBQ25CLE1BQU0sSUFBSSxLQUFLLENBQUMsa0JBQWtCLENBQUMsQ0FBQTtLQUNwQztJQUVELE9BQU87UUFDTCxpRUFBaUU7UUFDakUsb0VBQW9FO1FBQ3BFLG9DQUFvQztRQUNwQyxLQUFLLEVBQUUsT0FBTztLQUNmLENBQUE7QUFDSCxDQUFDLENBQUE7QUFuRlksUUFBQSxrQkFBa0Isc0JBbUY5QiIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnNhZmUtYXNzaWdubWVudCAqL1xuLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVuc2FmZS1jYWxsICovXG4vKiBlc2xpbnQtZGlzYWJsZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW5zYWZlLW1lbWJlci1hY2Nlc3MgKi9cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXMgKi9cbmltcG9ydCB7IEhhbmRsZXIgfSBmcm9tIFwiYXdzLWxhbWJkYVwiXG5pbXBvcnQgdHlwZSAqIGFzIF9BV1MgZnJvbSBcImF3cy1zZGtcIlxuXG5pbnRlcmZhY2UgU3RhcnREZXBsb3lFeHBlY3RlZElucHV0IHtcbiAgYnVja2V0TmFtZTogc3RyaW5nXG4gIGJ1Y2tldEtleTogc3RyaW5nXG4gIHN0YWNrTmFtZXM6IHN0cmluZ1tdXG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gaXMgaW5saW5lLWNvbXBpbGVkIGZvciB0aGUgbGFtYmRhLlxuLy8gSXQgbXVzdCBiZSBzZWxmLWNvbnRhaW5lZC5cbmV4cG9ydCBjb25zdCBzdGFydERlcGxveUhhbmRsZXI6IEhhbmRsZXI8XG4gIFBhcnRpYWw8U3RhcnREZXBsb3lFeHBlY3RlZElucHV0PlxuPiA9IGFzeW5jIChldmVudCwgY29udGV4dCkgPT4ge1xuICBjb25zdCBBV1MgPSByZXF1aXJlKFwiYXdzLXNka1wiKVxuXG4gIGNvbnN0IGNvZGVidWlsZCA9IG5ldyBBV1MuQ29kZUJ1aWxkKCkgYXMgX0FXUy5Db2RlQnVpbGRcbiAgY29uc3QgczMgPSBuZXcgQVdTLlMzKCkgYXMgX0FXUy5TM1xuXG4gIGZ1bmN0aW9uIHJlcXVpcmVFbnYobmFtZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBjb25zdCB2YWx1ZSA9IHByb2Nlc3MuZW52W25hbWVdXG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTWlzc2luZyAke25hbWV9YClcbiAgICB9XG4gICAgcmV0dXJuIHZhbHVlXG4gIH1cblxuICBjb25zdCBwcm9qZWN0TmFtZSA9IHJlcXVpcmVFbnYoXCJQUk9KRUNUX05BTUVcIilcbiAgY29uc3QgYnVja2V0TmFtZSA9IHJlcXVpcmVFbnYoXCJCVUNLRVRfTkFNRVwiKVxuICBjb25zdCBjZGtDb250ZXh0ID0gSlNPTi5wYXJzZShyZXF1aXJlRW52KFwiQ0RLX0NPTlRFWFRcIikpXG5cbiAgLy8gU2luY2Ugd2UgcGFzcyB0aGUgc3RhY2sgbmFtZXMgYXMgc3RyaW5ncyB0byB0aGUgc2hlbGwsXG4gIC8vIGJlIGEgYml0IHJlc3RyaWN0aXZlIG9mIHRoZSB2YWxpZCB2YWx1ZXMgd2UgY2FuIHVzZS5cbiAgY29uc3QgdmFsaWRTdGFja05hbWUgPSAvXlthLXowLTlfXVthLXowLTlcXC1fXSokL2lcblxuICBjb25zdCBzM0tleVByZWZpeCA9IGAke2NvbnRleHQuYXdzUmVxdWVzdElkfS9gXG5cbiAgLy8gVmFsaWRhdGUgdGhlIGlucHV0LlxuICBpZiAoXG4gICAgdHlwZW9mIGV2ZW50LmJ1Y2tldE5hbWUgIT09IFwic3RyaW5nXCIgfHxcbiAgICB0eXBlb2YgZXZlbnQuYnVja2V0S2V5ICE9PSBcInN0cmluZ1wiIHx8XG4gICAgIUFycmF5LmlzQXJyYXkoZXZlbnQuc3RhY2tOYW1lcykgfHxcbiAgICAhZXZlbnQuc3RhY2tOYW1lcy5ldmVyeShcbiAgICAgIChpdCkgPT4gdHlwZW9mIGl0ID09PSBcInN0cmluZ1wiICYmIHZhbGlkU3RhY2tOYW1lLnRlc3QoaXQpLFxuICAgIClcbiAgKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSW5wdXQgaW52YWxpZDogXCIgKyBKU09OLnN0cmluZ2lmeShldmVudCwgdW5kZWZpbmVkLCBcIiAgXCIpKVxuICB9XG5cbiAgYXN5bmMgZnVuY3Rpb24gcHV0KG5hbWU6IHN0cmluZywgZGF0YTogQVdTLlMzLkJvZHkpIHtcbiAgICBhd2FpdCBzM1xuICAgICAgLnB1dE9iamVjdCh7XG4gICAgICAgIEJ1Y2tldDogYnVja2V0TmFtZSxcbiAgICAgICAgS2V5OiBgJHtzM0tleVByZWZpeH0ke25hbWV9YCxcbiAgICAgICAgQm9keTogZGF0YSxcbiAgICAgIH0pXG4gICAgICAucHJvbWlzZSgpXG4gIH1cblxuICBhd2FpdCBwdXQoXCJzdGFjay1uYW1lcy50eHRcIiwgZXZlbnQuc3RhY2tOYW1lcy5qb2luKFwiIFwiKSlcbiAgLy8gRW5zdXJlIHRoYXQgd2UgcnVuIHRoZSBzY3JpcHQgdXNpbmcgc2FtZSBmZWF0dXJlIGZsYWdzLlxuICBhd2FpdCBwdXQoXG4gICAgXCJjZGsuanNvblwiLFxuICAgIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIGNvbnRleHQ6IGNka0NvbnRleHQsXG4gICAgfSksXG4gIClcblxuICBjb25zdCBidWlsZCA9IGF3YWl0IGNvZGVidWlsZFxuICAgIC5zdGFydEJ1aWxkKHtcbiAgICAgIHByb2plY3ROYW1lLFxuICAgICAgc291cmNlVHlwZU92ZXJyaWRlOiBcIlMzXCIsXG4gICAgICBzb3VyY2VMb2NhdGlvbk92ZXJyaWRlOiBgJHtidWNrZXROYW1lfS8ke3MzS2V5UHJlZml4fWAsXG4gICAgICBzZWNvbmRhcnlTb3VyY2VzT3ZlcnJpZGU6IFtcbiAgICAgICAge1xuICAgICAgICAgIHR5cGU6IFwiUzNcIixcbiAgICAgICAgICBsb2NhdGlvbjogYCR7ZXZlbnQuYnVja2V0TmFtZX0vJHtldmVudC5idWNrZXRLZXl9YCxcbiAgICAgICAgICBzb3VyY2VJZGVudGlmaWVyOiBcIkNMT1VEQVNTRU1CTFlcIixcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSlcbiAgICAucHJvbWlzZSgpXG5cbiAgY29uc3QgYnVpbGRJZCA9IGJ1aWxkLmJ1aWxkPy5pZFxuICBpZiAoYnVpbGRJZCA9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiVW5rbm93biBidWlsZCBJRFwiKVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAvLyBUaGlzIGlzIHRoZSB2YWx1ZSB0aGUgY2FsbGVyIHdpbGwgdXNlIHRvIGZldGNoIHVwZGF0ZWQgc3RhdHVzLlxuICAgIC8vIEF2b2lkIGV4cG9zaW5nIHdoYXQga2luZCBvZiBJRCB0aGlzIGlzLCBiZWNhdXNlIHdlIHNob3VsZCBiZSBmcmVlXG4gICAgLy8gdG8gY2hhbmdlIGltcGxlbWVudGF0aW9uIGRldGFpbHMuXG4gICAgam9iSWQ6IGJ1aWxkSWQsXG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,43 @@
1
+ import * as cdk from "@aws-cdk/core";
2
+ import * as cloudwatch from "@aws-cdk/aws-cloudwatch";
3
+ export interface CloudTrailSlackIntegrationProps extends cdk.StackProps {
4
+ /**
5
+ * A key-value pair of AWS account IDs and friendly names of these accounts
6
+ * to use when sending messages to Slack.
7
+ */
8
+ accountFriendlyNames?: {
9
+ [key: string]: string;
10
+ };
11
+ slackWebhookUrl: string;
12
+ slackChannel: string;
13
+ /**
14
+ * A list of ARNs of roles in the current account to monitor usage of.
15
+ */
16
+ rolesToMonitor?: string[];
17
+ /**
18
+ * Whether to monitor various IAM API calls associated with the current account's root user (e.g., console login, password reset, etc.)
19
+ *
20
+ * @default true
21
+ */
22
+ monitorRootUserActions?: boolean;
23
+ /**
24
+ * Whether to set up additional AWS infrastructure to deduplicate CloudTrail events in order to avoid duplicate Slack messages. May be used to decrease noise.
25
+ *
26
+ * @default false
27
+ */
28
+ deduplicateEvents?: boolean;
29
+ /**
30
+ * If supplied, CloudWatch alarms will be created for the construct's underlying infrastructure (e.g., Lambda functions) and the action will be used to notify on OK and ALARM actions.
31
+ */
32
+ infrastructureAlarmAction?: cloudwatch.IAlarmAction;
33
+ }
34
+ /**
35
+ * Forward a predefined set of CloudTrail API events to Slack using EventBridge, Lambda
36
+ * and an optional SQS FIFO queue for deduplicating events.
37
+ * The API events are limited to monitoring access to the current account's root user and/or specific IAM roles.
38
+ *
39
+ * NOTE: The construct needs to be provisioned in us-east-1, and requires an existing CloudTrail set up in that region.
40
+ */
41
+ export declare class CloudTrailSlackIntegration extends cdk.Construct {
42
+ constructor(scope: cdk.Construct, id: string, props: CloudTrailSlackIntegrationProps);
43
+ }
@@ -0,0 +1,210 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CloudTrailSlackIntegration = void 0;
4
+ const cdk = require("@aws-cdk/core");
5
+ const iam = require("@aws-cdk/aws-iam");
6
+ const logs = require("@aws-cdk/aws-logs");
7
+ const cloudwatch = require("@aws-cdk/aws-cloudwatch");
8
+ const lambda = require("@aws-cdk/aws-lambda");
9
+ const events = require("@aws-cdk/aws-events");
10
+ const sources = require("@aws-cdk/aws-lambda-event-sources");
11
+ const sqs = require("@aws-cdk/aws-sqs");
12
+ const targets = require("@aws-cdk/aws-events-targets");
13
+ const path = require("path");
14
+ /**
15
+ * Forward a predefined set of CloudTrail API events to Slack using EventBridge, Lambda
16
+ * and an optional SQS FIFO queue for deduplicating events.
17
+ * The API events are limited to monitoring access to the current account's root user and/or specific IAM roles.
18
+ *
19
+ * NOTE: The construct needs to be provisioned in us-east-1, and requires an existing CloudTrail set up in that region.
20
+ */
21
+ class CloudTrailSlackIntegration extends cdk.Construct {
22
+ constructor(scope, id, props) {
23
+ super(scope, id);
24
+ const eventTransformer = new lambda.Function(this, "EventTransformerLambda", {
25
+ code: lambda.Code.fromAsset(path.join(__dirname, "../../assets/cloudtrail-slack-integration-lambda")),
26
+ description: "Formats CloudTrail API calls sent through EventBridge, and posts them directly to Slack or first to an SQS FIFO queue for deduplication",
27
+ handler: "main.handler_event_transformer",
28
+ runtime: lambda.Runtime.PYTHON_3_9,
29
+ timeout: cdk.Duration.seconds(15),
30
+ logRetention: logs.RetentionDays.SIX_MONTHS,
31
+ environment: {
32
+ SLACK_CHANNEL: props.slackChannel,
33
+ DEDUPLICATE_EVENTS: JSON.stringify(!!props.deduplicateEvents),
34
+ ACCOUNT_FRIENDLY_NAMES: JSON.stringify(props.accountFriendlyNames || {}),
35
+ SLACK_WEBHOOK_URL: props.slackWebhookUrl,
36
+ },
37
+ });
38
+ eventTransformer.addToRolePolicy(new iam.PolicyStatement({
39
+ actions: ["iam:ListAccountAliases"],
40
+ resources: ["*"],
41
+ }));
42
+ if (props.infrastructureAlarmAction) {
43
+ const eventTransformerAlarm = eventTransformer
44
+ .metricErrors({
45
+ period: cdk.Duration.minutes(5),
46
+ statistic: cloudwatch.Statistic.SUM,
47
+ })
48
+ .createAlarm(this, "EventTransformerErrorAlarm", {
49
+ threshold: 1,
50
+ evaluationPeriods: 1,
51
+ alarmDescription: "Triggers if the Lambda function that transforms CloudTrail API calls received through EventBridge fails (e.g., it fails to process the event)",
52
+ datapointsToAlarm: 1,
53
+ treatMissingData: cloudwatch.TreatMissingData.IGNORE,
54
+ });
55
+ eventTransformerAlarm.addOkAction(props.infrastructureAlarmAction);
56
+ eventTransformerAlarm.addAlarmAction(props.infrastructureAlarmAction);
57
+ }
58
+ if (props.deduplicateEvents) {
59
+ const deduplicationQueue = new sqs.Queue(this, "Queue", {
60
+ // We explicitly give the queue a name due to bug https://github.com/aws/aws-cdk/issues/5860
61
+ queueName: `${this.node.id.substring(0, 33)}${this.node.addr}`.substring(0, 75) +
62
+ ".fifo",
63
+ fifo: true,
64
+ });
65
+ eventTransformer.addEnvironment("SQS_QUEUE_URL", deduplicationQueue.queueUrl);
66
+ deduplicationQueue.grantSendMessages(eventTransformer);
67
+ const slackForwarder = new lambda.Function(this, "SlackForwarderLambda", {
68
+ code: lambda.Code.fromAsset(path.join(__dirname, "../../assets/cloudtrail-slack-integration-lambda")),
69
+ description: "Polls from an SQS FIFO queue containing formatted CloudTrail API calls and sends them to Slack.",
70
+ handler: "main.handler_slack_forwarder",
71
+ runtime: lambda.Runtime.PYTHON_3_9,
72
+ timeout: cdk.Duration.seconds(15),
73
+ logRetention: logs.RetentionDays.TWO_WEEKS,
74
+ });
75
+ if (props.infrastructureAlarmAction) {
76
+ const slackForwarderAlarm = slackForwarder
77
+ .metricErrors({
78
+ period: cdk.Duration.minutes(5),
79
+ statistic: cloudwatch.Statistic.SUM,
80
+ })
81
+ .createAlarm(this, "SlackForwarderErrorAlarm", {
82
+ threshold: 1,
83
+ alarmDescription: "Triggers if the Lambda function that polls from SQS and posts deduplicated CloudTrail API calls received through EventBridge to Slack fails (e.g., invalid Slack webhook URL)",
84
+ evaluationPeriods: 1,
85
+ datapointsToAlarm: 1,
86
+ treatMissingData: cloudwatch.TreatMissingData.IGNORE,
87
+ });
88
+ slackForwarderAlarm.addOkAction(props.infrastructureAlarmAction);
89
+ slackForwarderAlarm.addAlarmAction(props.infrastructureAlarmAction);
90
+ }
91
+ slackForwarder.addEventSource(new sources.SqsEventSource(deduplicationQueue));
92
+ }
93
+ if (props.rolesToMonitor && props.rolesToMonitor.length > 0) {
94
+ new events.Rule(this, "RuleForAssumeRole", {
95
+ enabled: true,
96
+ targets: [new targets.LambdaFunction(eventTransformer)],
97
+ eventPattern: {
98
+ detail: {
99
+ eventName: ["AssumeRole"],
100
+ requestParameters: {
101
+ roleArn: props.rolesToMonitor,
102
+ },
103
+ },
104
+ },
105
+ });
106
+ }
107
+ if (props.monitorRootUserActions !== false) {
108
+ // Triggers when the root password has been changed
109
+ new events.Rule(this, "RuleForRootUserPasswordChange", {
110
+ enabled: true,
111
+ targets: [new targets.LambdaFunction(eventTransformer)],
112
+ eventPattern: {
113
+ detail: {
114
+ userIdentity: {
115
+ type: ["Root"],
116
+ },
117
+ eventName: ["PasswordUpdated"],
118
+ eventType: ["AwsConsoleSignIn"],
119
+ },
120
+ },
121
+ });
122
+ // Triggers when MFA for the root user has been set up
123
+ new events.Rule(this, "RuleForRootUserMfaChange", {
124
+ enabled: true,
125
+ targets: [new targets.LambdaFunction(eventTransformer)],
126
+ eventPattern: {
127
+ detail: {
128
+ userIdentity: {
129
+ type: ["Root"],
130
+ },
131
+ eventName: ["EnableMFADevice"],
132
+ requestParameters: {
133
+ userName: ["AWS ROOT USER"],
134
+ },
135
+ },
136
+ },
137
+ });
138
+ // Triggers when a root user succesfully logs in to the console
139
+ new events.Rule(this, "RuleForRootUserSuccessfulLogin", {
140
+ enabled: true,
141
+ targets: [new targets.LambdaFunction(eventTransformer)],
142
+ eventPattern: {
143
+ detail: {
144
+ userIdentity: {
145
+ type: ["Root"],
146
+ },
147
+ eventName: ["ConsoleLogin"],
148
+ eventType: ["AwsConsoleSignIn"],
149
+ responseElements: {
150
+ ConsoleLogin: ["Success"],
151
+ },
152
+ },
153
+ },
154
+ });
155
+ // Triggers for bad login attemps for root user (e.g., wrong password)
156
+ new events.Rule(this, "RuleForRootUserUnsuccessfulLogin", {
157
+ enabled: true,
158
+ targets: [new targets.LambdaFunction(eventTransformer)],
159
+ eventPattern: {
160
+ detail: {
161
+ userIdentity: {
162
+ type: ["Root"],
163
+ },
164
+ eventName: ["ConsoleLogin"],
165
+ eventType: ["AwsConsoleSignIn"],
166
+ responseElements: {
167
+ ConsoleLogin: ["Failure"],
168
+ },
169
+ },
170
+ },
171
+ });
172
+ // Triggered when password reset has been requested
173
+ new events.Rule(this, "RuleForRootUserPasswordRecoveryRequest", {
174
+ enabled: true,
175
+ targets: [new targets.LambdaFunction(eventTransformer)],
176
+ eventPattern: {
177
+ detail: {
178
+ userIdentity: {
179
+ type: ["Root"],
180
+ },
181
+ eventName: ["PasswordRecoveryRequested"],
182
+ eventType: ["AwsConsoleSignIn"],
183
+ responseElements: {
184
+ PasswordRecoveryRequested: ["Success"],
185
+ },
186
+ },
187
+ },
188
+ });
189
+ // Triggered when password has been successfully reset
190
+ new events.Rule(this, "RuleForRootUserPasswordRecoveryComplete", {
191
+ enabled: true,
192
+ targets: [new targets.LambdaFunction(eventTransformer)],
193
+ eventPattern: {
194
+ detail: {
195
+ userIdentity: {
196
+ type: ["Root"],
197
+ },
198
+ eventName: ["PasswordRecoveryCompleted"],
199
+ eventType: ["AwsConsoleSignIn"],
200
+ responseElements: {
201
+ PasswordRecoveryCompleted: ["Success"],
202
+ },
203
+ },
204
+ },
205
+ });
206
+ }
207
+ }
208
+ }
209
+ exports.CloudTrailSlackIntegration = CloudTrailSlackIntegration;
210
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uL2Nsb3VkdHJhaWwtc2xhY2staW50ZWdyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEscUNBQW9DO0FBQ3BDLHdDQUF1QztBQUN2QywwQ0FBeUM7QUFDekMsc0RBQXFEO0FBQ3JELDhDQUE2QztBQUM3Qyw4Q0FBNkM7QUFDN0MsNkRBQTREO0FBQzVELHdDQUF1QztBQUN2Qyx1REFBc0Q7QUFDdEQsNkJBQTRCO0FBa0M1Qjs7Ozs7O0dBTUc7QUFDSCxNQUFhLDBCQUEyQixTQUFRLEdBQUcsQ0FBQyxTQUFTO0lBQzNELFlBQ0UsS0FBb0IsRUFDcEIsRUFBVSxFQUNWLEtBQXNDO1FBRXRDLEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFaEIsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQzFDLElBQUksRUFDSix3QkFBd0IsRUFDeEI7WUFDRSxJQUFJLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQ3pCLElBQUksQ0FBQyxJQUFJLENBQ1AsU0FBUyxFQUNULGtEQUFrRCxDQUNuRCxDQUNGO1lBQ0QsV0FBVyxFQUNULHlJQUF5STtZQUMzSSxPQUFPLEVBQUUsZ0NBQWdDO1lBQ3pDLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTyxDQUFDLFVBQVU7WUFDbEMsT0FBTyxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxZQUFZLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVO1lBQzNDLFdBQVcsRUFBRTtnQkFDWCxhQUFhLEVBQUUsS0FBSyxDQUFDLFlBQVk7Z0JBQ2pDLGtCQUFrQixFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxp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QUUsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxjQUFjLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztnQkFDdkQsWUFBWSxFQUFFO29CQUNaLE1BQU0sRUFBRTt3QkFDTixZQUFZLEVBQUU7NEJBQ1osSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDO3lCQUNmO3dCQUNELFNBQVMsRUFBRSxDQUFDLDJCQUEyQixDQUFDO3dCQUN4QyxTQUFTLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQzt3QkFDL0IsZ0JBQWdCLEVBQUU7NEJBQ2hCLHlCQUF5QixFQUFFLENBQUMsU0FBUyxDQUFDO3lCQUN2QztxQkFDRjtpQkFDRjthQUNGLENBQUMsQ0FBQTtTQUNIO0lBQ0gsQ0FBQztDQUNGO0FBcE9ELGdFQW9PQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tIFwiQGF3cy1jZGsvY29yZVwiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcIkBhd3MtY2RrL2F3cy1pYW1cIlxuaW1wb3J0ICogYXMgbG9ncyBmcm9tIFwiQGF3cy1jZGsvYXdzLWxvZ3NcIlxuaW1wb3J0ICogYXMgY2xvdWR3YXRjaCBmcm9tIFwiQGF3cy1jZGsvYXdzLWNsb3Vkd2F0Y2hcIlxuaW1wb3J0ICogYXMgbGFtYmRhIGZyb20gXCJAYXdzLWNkay9hd3MtbGFtYmRhXCJcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tIFwiQGF3cy1jZGsvYXdzLWV2ZW50c1wiXG5pbXBvcnQgKiBhcyBzb3VyY2VzIGZyb20gXCJAYXdzLWNkay9hd3MtbGFtYmRhLWV2ZW50LXNvdXJjZXNcIlxuaW1wb3J0ICogYXMgc3FzIGZyb20gXCJAYXdzLWNkay9hd3Mtc3FzXCJcbmltcG9ydCAqIGFzIHRhcmdldHMgZnJvbSBcIkBhd3MtY2RrL2F3cy1ldmVudHMtdGFyZ2V0c1wiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcblxuZXhwb3J0IGludGVyZmFjZSBDbG91ZFRyYWlsU2xhY2tJbnRlZ3JhdGlvblByb3BzIGV4dGVuZHMgY2RrLlN0YWNrUHJvcHMge1xuICAvKipcbiAgICogQSBrZXktdmFsdWUgcGFpciBvZiBBV1MgYWNjb3VudCBJRHMgYW5kIGZyaWVuZGx5IG5hbWVzIG9mIHRoZXNlIGFjY291bnRzXG4gICAqIHRvIHVzZSB3aGVuIHNlbmRpbmcgbWVzc2FnZXMgdG8gU2xhY2suXG4gICAqL1xuICBhY2NvdW50RnJpZW5kbHlOYW1lcz86IHtcbiAgICBba2V5OiBzdHJpbmddOiBzdHJpbmdcbiAgfVxuICBzbGFja1dlYmhvb2tVcmw6IHN0cmluZ1xuICBzbGFja0NoYW5uZWw6IHN0cmluZ1xuICAvKipcbiAgICogQSBsaXN0IG9mIEFSTnMgb2Ygcm9sZXMgaW4gdGhlIGN1cnJlbnQgYWNjb3VudCB0byBtb25pdG9yIHVzYWdlIG9mLlxuICAgKi9cbiAgcm9sZXNUb01vbml0b3I/OiBzdHJpbmdbXVxuICAvKipcbiAgICogV2hldGhlciB0byBtb25pdG9yIHZhcmlvdXMgSUFNIEFQSSBjYWxscyBhc3NvY2lhdGVkIHdpdGggdGhlIGN1cnJlbnQgYWNjb3VudCdzIHJvb3QgdXNlciAoZS5nLiwgY29uc29sZSBsb2dpbiwgcGFzc3dvcmQgcmVzZXQsIGV0Yy4pXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIG1vbml0b3JSb290VXNlckFjdGlvbnM/OiBib29sZWFuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIHNldCB1cCBhZGRpdGlvbmFsIEFXUyBpbmZyYXN0cnVjdHVyZSB0byBkZWR1cGxpY2F0ZSBDbG91ZFRyYWlsIGV2ZW50cyBpbiBvcmRlciB0byBhdm9pZCBkdXBsaWNhdGUgU2xhY2sgbWVzc2FnZXMuIE1heSBiZSB1c2VkIHRvIGRlY3JlYXNlIG5vaXNlLlxuICAgKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgZGVkdXBsaWNhdGVFdmVudHM/OiBib29sZWFuXG4gIC8qKlxuICAgKiBJZiBzdXBwbGllZCwgQ2xvdWRXYXRjaCBhbGFybXMgd2lsbCBiZSBjcmVhdGVkIGZvciB0aGUgY29uc3RydWN0J3MgdW5kZXJseWluZyBpbmZyYXN0cnVjdHVyZSAoZS5nLiwgTGFtYmRhIGZ1bmN0aW9ucykgYW5kIHRoZSBhY3Rpb24gd2lsbCBiZSB1c2VkIHRvIG5vdGlmeSBvbiBPSyBhbmQgQUxBUk0gYWN0aW9ucy5cbiAgICovXG4gIGluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24/OiBjbG91ZHdhdGNoLklBbGFybUFjdGlvblxufVxuXG4vKipcbiAqIEZvcndhcmQgYSBwcmVkZWZpbmVkIHNldCBvZiBDbG91ZFRyYWlsIEFQSSBldmVudHMgdG8gU2xhY2sgdXNpbmcgRXZlbnRCcmlkZ2UsIExhbWJkYVxuICogYW5kIGFuIG9wdGlvbmFsIFNRUyBGSUZPIHF1ZXVlIGZvciBkZWR1cGxpY2F0aW5nIGV2ZW50cy5cbiAqIFRoZSBBUEkgZXZlbnRzIGFyZSBsaW1pdGVkIHRvIG1vbml0b3JpbmcgYWNjZXNzIHRvIHRoZSBjdXJyZW50IGFjY291bnQncyByb290IHVzZXIgYW5kL29yIHNwZWNpZmljIElBTSByb2xlcy5cbiAqXG4gKiBOT1RFOiBUaGUgY29uc3RydWN0IG5lZWRzIHRvIGJlIHByb3Zpc2lvbmVkIGluIHVzLWVhc3QtMSwgYW5kIHJlcXVpcmVzIGFuIGV4aXN0aW5nIENsb3VkVHJhaWwgc2V0IHVwIGluIHRoYXQgcmVnaW9uLlxuICovXG5leHBvcnQgY2xhc3MgQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb24gZXh0ZW5kcyBjZGsuQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNkay5Db25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb25Qcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKVxuXG4gICAgY29uc3QgZXZlbnRUcmFuc2Zvcm1lciA9IG5ldyBsYW1iZGEuRnVuY3Rpb24oXG4gICAgICB0aGlzLFxuICAgICAgXCJFdmVudFRyYW5zZm9ybWVyTGFtYmRhXCIsXG4gICAgICB7XG4gICAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChcbiAgICAgICAgICBwYXRoLmpvaW4oXG4gICAgICAgICAgICBfX2Rpcm5hbWUsXG4gICAgICAgICAgICBcIi4uLy4uL2Fzc2V0cy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uLWxhbWJkYVwiLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgIFwiRm9ybWF0cyBDbG91ZFRyYWlsIEFQSSBjYWxscyBzZW50IHRocm91Z2ggRXZlbnRCcmlkZ2UsIGFuZCBwb3N0cyB0aGVtIGRpcmVjdGx5IHRvIFNsYWNrIG9yIGZpcnN0IHRvIGFuIFNRUyBGSUZPIHF1ZXVlIGZvciBkZWR1cGxpY2F0aW9uXCIsXG4gICAgICAgIGhhbmRsZXI6IFwibWFpbi5oYW5kbGVyX2V2ZW50X3RyYW5zZm9ybWVyXCIsXG4gICAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLlBZVEhPTl8zXzksXG4gICAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5zZWNvbmRzKDE1KSxcbiAgICAgICAgbG9nUmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuU0lYX01PTlRIUyxcbiAgICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgICBTTEFDS19DSEFOTkVMOiBwcm9wcy5zbGFja0NoYW5uZWwsXG4gICAgICAgICAgREVEVVBMSUNBVEVfRVZFTlRTOiBKU09OLnN0cmluZ2lmeSghIXByb3BzLmRlZHVwbGljYXRlRXZlbnRzKSxcbiAgICAgICAgICBBQ0NPVU5UX0ZSSUVORExZX05BTUVTOiBKU09OLnN0cmluZ2lmeShcbiAgICAgICAgICAgIHByb3BzLmFjY291bnRGcmllbmRseU5hbWVzIHx8IHt9LFxuICAgICAgICAgICksXG4gICAgICAgICAgU0xBQ0tfV0VCSE9PS19VUkw6IHByb3BzLnNsYWNrV2ViaG9va1VybCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgKVxuICAgIGV2ZW50VHJhbnNmb3JtZXIuYWRkVG9Sb2xlUG9saWN5KFxuICAgICAgbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBhY3Rpb25zOiBbXCJpYW06TGlzdEFjY291bnRBbGlhc2VzXCJdLFxuICAgICAgICByZXNvdXJjZXM6IFtcIipcIl0sXG4gICAgICB9KSxcbiAgICApXG4gICAgaWYgKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pIHtcbiAgICAgIGNvbnN0IGV2ZW50VHJhbnNmb3JtZXJBbGFybSA9IGV2ZW50VHJhbnNmb3JtZXJcbiAgICAgICAgLm1ldHJpY0Vycm9ycyh7XG4gICAgICAgICAgcGVyaW9kOiBjZGsuRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgICBzdGF0aXN0aWM6IGNsb3Vkd2F0Y2guU3RhdGlzdGljLlNVTSxcbiAgICAgICAgfSlcbiAgICAgICAgLmNyZWF0ZUFsYXJtKHRoaXMsIFwiRXZlbnRUcmFuc2Zvcm1lckVycm9yQWxhcm1cIiwge1xuICAgICAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogMSxcbiAgICAgICAgICBhbGFybURlc2NyaXB0aW9uOlxuICAgICAgICAgICAgXCJUcmlnZ2VycyBpZiB0aGUgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgdHJhbnNmb3JtcyBDbG91ZFRyYWlsIEFQSSBjYWxscyByZWNlaXZlZCB0aHJvdWdoIEV2ZW50QnJpZGdlIGZhaWxzIChlLmcuLCBpdCBmYWlscyB0byBwcm9jZXNzIHRoZSBldmVudClcIixcbiAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogMSxcbiAgICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuSUdOT1JFLFxuICAgICAgICB9KVxuICAgICAgZXZlbnRUcmFuc2Zvcm1lckFsYXJtLmFkZE9rQWN0aW9uKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pXG4gICAgICBldmVudFRyYW5zZm9ybWVyQWxhcm0uYWRkQWxhcm1BY3Rpb24ocHJvcHMuaW5mcmFzdHJ1Y3R1cmVBbGFybUFjdGlvbilcbiAgICB9XG4gICAgaWYgKHByb3BzLmRlZHVwbGljYXRlRXZlbnRzKSB7XG4gICAgICBjb25zdCBkZWR1cGxpY2F0aW9uUXVldWUgPSBuZXcgc3FzLlF1ZXVlKHRoaXMsIFwiUXVldWVcIiwge1xuICAgICAgICAvLyBXZSBleHBsaWNpdGx5IGdpdmUgdGhlIHF1ZXVlIGEgbmFtZSBkdWUgdG8gYnVnIGh0dHBzOi8vZ2l0aHViLmNvbS9hd3MvYXdzLWNkay9pc3N1ZXMvNTg2MFxuICAgICAgICBxdWV1ZU5hbWU6XG4gICAgICAgICAgYCR7dGhpcy5ub2RlLmlkLnN1YnN0cmluZygwLCAzMyl9JHt0aGlzLm5vZGUuYWRkcn1gLnN1YnN0cmluZygwLCA3NSkgK1xuICAgICAgICAgIFwiLmZpZm9cIixcbiAgICAgICAgZmlmbzogdHJ1ZSxcbiAgICAgIH0pXG4gICAgICBldmVudFRyYW5zZm9ybWVyLmFkZEVudmlyb25tZW50KFxuICAgICAgICBcIlNRU19RVUVVRV9VUkxcIixcbiAgICAgICAgZGVkdXBsaWNhdGlvblF1ZXVlLnF1ZXVlVXJsLFxuICAgICAgKVxuICAgICAgZGVkdXBsaWNhdGlvblF1ZXVlLmdyYW50U2VuZE1lc3NhZ2VzKGV2ZW50VHJhbnNmb3JtZXIpXG4gICAgICBjb25zdCBzbGFja0ZvcndhcmRlciA9IG5ldyBsYW1iZGEuRnVuY3Rpb24odGhpcywgXCJTbGFja0ZvcndhcmRlckxhbWJkYVwiLCB7XG4gICAgICAgIGNvZGU6IGxhbWJkYS5Db2RlLmZyb21Bc3NldChcbiAgICAgICAgICBwYXRoLmpvaW4oXG4gICAgICAgICAgICBfX2Rpcm5hbWUsXG4gICAgICAgICAgICBcIi4uLy4uL2Fzc2V0cy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uLWxhbWJkYVwiLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAgIFwiUG9sbHMgZnJvbSBhbiBTUVMgRklGTyBxdWV1ZSBjb250YWluaW5nIGZvcm1hdHRlZCBDbG91ZFRyYWlsIEFQSSBjYWxscyBhbmQgc2VuZHMgdGhlbSB0byBTbGFjay5cIixcbiAgICAgICAgaGFuZGxlcjogXCJtYWluLmhhbmRsZXJfc2xhY2tfZm9yd2FyZGVyXCIsXG4gICAgICAgIHJ1bnRpbWU6IGxhbWJkYS5SdW50aW1lLlBZVEhPTl8zXzksXG4gICAgICAgIHRpbWVvdXQ6IGNkay5EdXJhdGlvbi5zZWNvbmRzKDE1KSxcbiAgICAgICAgbG9nUmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuVFdPX1dFRUtTLFxuICAgICAgfSlcblxuICAgICAgaWYgKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pIHtcbiAgICAgICAgY29uc3Qgc2xhY2tGb3J3YXJkZXJBbGFybSA9IHNsYWNrRm9yd2FyZGVyXG4gICAgICAgICAgLm1ldHJpY0Vycm9ycyh7XG4gICAgICAgICAgICBwZXJpb2Q6IGNkay5EdXJhdGlvbi5taW51dGVzKDUpLFxuICAgICAgICAgICAgc3RhdGlzdGljOiBjbG91ZHdhdGNoLlN0YXRpc3RpYy5TVU0sXG4gICAgICAgICAgfSlcbiAgICAgICAgICAuY3JlYXRlQWxhcm0odGhpcywgXCJTbGFja0ZvcndhcmRlckVycm9yQWxhcm1cIiwge1xuICAgICAgICAgICAgdGhyZXNob2xkOiAxLFxuICAgICAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjpcbiAgICAgICAgICAgICAgXCJUcmlnZ2VycyBpZiB0aGUgTGFtYmRhIGZ1bmN0aW9uIHRoYXQgcG9sbHMgZnJvbSBTUVMgYW5kIHBvc3RzIGRlZHVwbGljYXRlZCBDbG91ZFRyYWlsIEFQSSBjYWxscyByZWNlaXZlZCB0aHJvdWdoIEV2ZW50QnJpZGdlIHRvIFNsYWNrIGZhaWxzIChlLmcuLCBpbnZhbGlkIFNsYWNrIHdlYmhvb2sgVVJMKVwiLFxuICAgICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgICAgICAgICBkYXRhcG9pbnRzVG9BbGFybTogMSxcbiAgICAgICAgICAgIHRyZWF0TWlzc2luZ0RhdGE6IGNsb3Vkd2F0Y2guVHJlYXRNaXNzaW5nRGF0YS5JR05PUkUsXG4gICAgICAgICAgfSlcbiAgICAgICAgc2xhY2tGb3J3YXJkZXJBbGFybS5hZGRPa0FjdGlvbihwcm9wcy5pbmZyYXN0cnVjdHVyZUFsYXJtQWN0aW9uKVxuICAgICAgICBzbGFja0ZvcndhcmRlckFsYXJtLmFkZEFsYXJtQWN0aW9uKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pXG4gICAgICB9XG4gICAgICBzbGFja0ZvcndhcmRlci5hZGRFdmVudFNvdXJjZShcbiAgICAgICAgbmV3IHNvdXJjZXMuU3FzRXZlbnRTb3VyY2UoZGVkdXBsaWNhdGlvblF1ZXVlKSxcbiAgICAgIClcbiAgICB9XG5cbiAgICBpZiAocHJvcHMucm9sZXNUb01vbml0b3IgJiYgcHJvcHMucm9sZXNUb01vbml0b3IubGVuZ3RoID4gMCkge1xuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvckFzc3VtZVJvbGVcIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiQXNzdW1lUm9sZVwiXSxcbiAgICAgICAgICAgIHJlcXVlc3RQYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgICAgIHJvbGVBcm46IHByb3BzLnJvbGVzVG9Nb25pdG9yLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAocHJvcHMubW9uaXRvclJvb3RVc2VyQWN0aW9ucyAhPT0gZmFsc2UpIHtcbiAgICAgIC8vIFRyaWdnZXJzIHdoZW4gdGhlIHJvb3QgcGFzc3dvcmQgaGFzIGJlZW4gY2hhbmdlZFxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyUGFzc3dvcmRDaGFuZ2VcIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIHVzZXJJZGVudGl0eToge1xuICAgICAgICAgICAgICB0eXBlOiBbXCJSb290XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiUGFzc3dvcmRVcGRhdGVkXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VycyB3aGVuIE1GQSBmb3IgdGhlIHJvb3QgdXNlciBoYXMgYmVlbiBzZXQgdXBcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlck1mYUNoYW5nZVwiLCB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHRhcmdldHM6IFtuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihldmVudFRyYW5zZm9ybWVyKV0sXG4gICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgdXNlcklkZW50aXR5OiB7XG4gICAgICAgICAgICAgIHR5cGU6IFtcIlJvb3RcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lOiBbXCJFbmFibGVNRkFEZXZpY2VcIl0sXG4gICAgICAgICAgICByZXF1ZXN0UGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICB1c2VyTmFtZTogW1wiQVdTIFJPT1QgVVNFUlwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFRyaWdnZXJzIHdoZW4gYSByb290IHVzZXIgc3VjY2VzZnVsbHkgbG9ncyBpbiB0byB0aGUgY29uc29sZVxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyU3VjY2Vzc2Z1bExvZ2luXCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICB1c2VySWRlbnRpdHk6IHtcbiAgICAgICAgICAgICAgdHlwZTogW1wiUm9vdFwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIkNvbnNvbGVMb2dpblwiXSxcbiAgICAgICAgICAgIGV2ZW50VHlwZTogW1wiQXdzQ29uc29sZVNpZ25JblwiXSxcbiAgICAgICAgICAgIHJlc3BvbnNlRWxlbWVudHM6IHtcbiAgICAgICAgICAgICAgQ29uc29sZUxvZ2luOiBbXCJTdWNjZXNzXCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gVHJpZ2dlcnMgZm9yIGJhZCBsb2dpbiBhdHRlbXBzIGZvciByb290IHVzZXIgKGUuZy4sIHdyb25nIHBhc3N3b3JkKVxuICAgICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiUnVsZUZvclJvb3RVc2VyVW5zdWNjZXNzZnVsTG9naW5cIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIHVzZXJJZGVudGl0eToge1xuICAgICAgICAgICAgICB0eXBlOiBbXCJSb290XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiQ29uc29sZUxvZ2luXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgICAgcmVzcG9uc2VFbGVtZW50czoge1xuICAgICAgICAgICAgICBDb25zb2xlTG9naW46IFtcIkZhaWx1cmVcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VyZWQgd2hlbiBwYXNzd29yZCByZXNldCBoYXMgYmVlbiByZXF1ZXN0ZWRcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0XCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICB1c2VySWRlbnRpdHk6IHtcbiAgICAgICAgICAgICAgdHlwZTogW1wiUm9vdFwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIlBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0ZWRcIl0sXG4gICAgICAgICAgICBldmVudFR5cGU6IFtcIkF3c0NvbnNvbGVTaWduSW5cIl0sXG4gICAgICAgICAgICByZXNwb25zZUVsZW1lbnRzOiB7XG4gICAgICAgICAgICAgIFBhc3N3b3JkUmVjb3ZlcnlSZXF1ZXN0ZWQ6IFtcIlN1Y2Nlc3NcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VyZWQgd2hlbiBwYXNzd29yZCBoYXMgYmVlbiBzdWNjZXNzZnVsbHkgcmVzZXRcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclBhc3N3b3JkUmVjb3ZlcnlDb21wbGV0ZVwiLCB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHRhcmdldHM6IFtuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihldmVudFRyYW5zZm9ybWVyKV0sXG4gICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgdXNlcklkZW50aXR5OiB7XG4gICAgICAgICAgICAgIHR5cGU6IFtcIlJvb3RcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lOiBbXCJQYXNzd29yZFJlY292ZXJ5Q29tcGxldGVkXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgICAgcmVzcG9uc2VFbGVtZW50czoge1xuICAgICAgICAgICAgICBQYXNzd29yZFJlY292ZXJ5Q29tcGxldGVkOiBbXCJTdWNjZXNzXCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1 @@
1
+ export { CloudTrailSlackIntegration, CloudTrailSlackIntegrationProps, } from "./cloudtrail-slack-integration";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CloudTrailSlackIntegration = void 0;
4
+ var cloudtrail_slack_integration_1 = require("./cloudtrail-slack-integration");
5
+ Object.defineProperty(exports, "CloudTrailSlackIntegration", { enumerable: true, get: function () { return cloudtrail_slack_integration_1.CloudTrailSlackIntegration; } });
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvbi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSwrRUFHdUM7QUFGckMsMElBQUEsMEJBQTBCLE9BQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQge1xuICBDbG91ZFRyYWlsU2xhY2tJbnRlZ3JhdGlvbixcbiAgQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb25Qcm9wcyxcbn0gZnJvbSBcIi4vY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvblwiXG4iXX0=
package/lib/index.d.ts CHANGED
@@ -7,6 +7,7 @@ import * as webapp from "./webapp";
7
7
  import * as configureParameters from "./configure-parameters";
8
8
  import * as ecs from "./ecs";
9
9
  import * as loadBalancer from "./load-balancer";
10
+ import * as cloudTrailSlackIntegration from "./cloudtrail-slack-integration";
10
11
  import * as rds from "./rds";
11
12
  import * as platform from "./platform";
12
13
  export { BastionHost } from "./bastion-host";
@@ -20,7 +21,7 @@ export { SsmParameterBackedResource } from "./ssm-parameter-backed-resource";
20
21
  export { SsmParameterReader } from "./ssm-parameter-reader";
21
22
  export { tagResources } from "./tags";
22
23
  export { WebappDeployViaRole } from "./webapp-deploy-via-role";
23
- export { alarms, cdkPipelines, griid, pipelines, ses, webapp, configureParameters, ecs, loadBalancer, rds, platform, };
24
+ export { alarms, cdkPipelines, griid, pipelines, ses, webapp, configureParameters, ecs, loadBalancer, rds, platform, cloudTrailSlackIntegration, };
24
25
  /**
25
26
  * Check if we are synthesizing a snapshot by setting IS_SNAPSHOT
26
27
  * environment variable to true.
package/lib/index.js CHANGED
@@ -10,7 +10,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
10
10
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
11
11
  };
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.isSnapshot = exports.platform = exports.rds = exports.loadBalancer = exports.ecs = exports.configureParameters = exports.webapp = exports.ses = exports.pipelines = exports.griid = exports.cdkPipelines = exports.alarms = exports.WebappDeployViaRole = exports.tagResources = exports.SsmParameterReader = exports.SsmParameterBackedResource = exports.createCloudAssemblySnapshot = exports.HostedZoneWithParam = exports.CrossRegionSsmParameter = exports.BastionHost = void 0;
13
+ exports.isSnapshot = exports.cloudTrailSlackIntegration = exports.platform = exports.rds = exports.loadBalancer = exports.ecs = exports.configureParameters = exports.webapp = exports.ses = exports.pipelines = exports.griid = exports.cdkPipelines = exports.alarms = exports.WebappDeployViaRole = exports.tagResources = exports.SsmParameterReader = exports.SsmParameterBackedResource = exports.createCloudAssemblySnapshot = exports.HostedZoneWithParam = exports.CrossRegionSsmParameter = exports.BastionHost = void 0;
14
14
  const alarms = require("./alarms");
15
15
  exports.alarms = alarms;
16
16
  const cdkPipelines = require("./cdk-pipelines");
@@ -29,6 +29,8 @@ const ecs = require("./ecs");
29
29
  exports.ecs = ecs;
30
30
  const loadBalancer = require("./load-balancer");
31
31
  exports.loadBalancer = loadBalancer;
32
+ const cloudTrailSlackIntegration = require("./cloudtrail-slack-integration");
33
+ exports.cloudTrailSlackIntegration = cloudTrailSlackIntegration;
32
34
  const rds = require("./rds");
33
35
  exports.rds = rds;
34
36
  const platform = require("./platform");
@@ -62,4 +64,4 @@ Object.defineProperty(exports, "WebappDeployViaRole", { enumerable: true, get: f
62
64
  * happen during snapshot creation.
63
65
  */
64
66
  exports.isSnapshot = process.env.IS_SNAPSHOT === "true";
65
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFBLG1DQUFrQztBQTRCaEMsd0JBQU07QUEzQlIsZ0RBQStDO0FBNEI3QyxvQ0FBWTtBQTNCZCxpQ0FBZ0M7QUE0QjlCLHNCQUFLO0FBM0JQLHlDQUF3QztBQTRCdEMsOEJBQVM7QUEzQlgsNkJBQTRCO0FBNEIxQixrQkFBRztBQTNCTCxtQ0FBa0M7QUE0QmhDLHdCQUFNO0FBM0JSLDhEQUE2RDtBQTRCM0Qsa0RBQW1CO0FBM0JyQiw2QkFBNEI7QUE0QjFCLGtCQUFHO0FBM0JMLGdEQUErQztBQTRCN0Msb0NBQVk7QUEzQmQsNkJBQTRCO0FBNEIxQixrQkFBRztBQTNCTCx1Q0FBc0M7QUE0QnBDLDRCQUFRO0FBMUJWLGdFQUFnRTtBQUNoRSx1Q0FBdUM7QUFFdkMsK0NBQTRDO0FBQW5DLDJHQUFBLFdBQVcsT0FBQTtBQUNwQixvREFBaUM7QUFDakMsK0NBQTRCO0FBQzVCLDJFQUFzRTtBQUE3RCxxSUFBQSx1QkFBdUIsT0FBQTtBQUNoQyxxREFBa0M7QUFDbEMsbUVBQThEO0FBQXJELDZIQUFBLG1CQUFtQixPQUFBO0FBQzVCLHlDQUF5RDtBQUFoRCx3SEFBQSwyQkFBMkIsT0FBQTtBQUNwQyxpRkFBNEU7QUFBbkUsMklBQUEsMEJBQTBCLE9BQUE7QUFDbkMsK0RBQTJEO0FBQWxELDBIQUFBLGtCQUFrQixPQUFBO0FBQzNCLCtCQUFxQztBQUE1QixvR0FBQSxZQUFZLE9BQUE7QUFDckIsbUVBQThEO0FBQXJELDZIQUFBLG1CQUFtQixPQUFBO0FBZ0I1Qjs7Ozs7O0dBTUc7QUFDVSxRQUFBLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsS0FBSyxNQUFNLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBhbGFybXMgZnJvbSBcIi4vYWxhcm1zXCJcbmltcG9ydCAqIGFzIGNka1BpcGVsaW5lcyBmcm9tIFwiLi9jZGstcGlwZWxpbmVzXCJcbmltcG9ydCAqIGFzIGdyaWlkIGZyb20gXCIuL2dyaWlkXCJcbmltcG9ydCAqIGFzIHBpcGVsaW5lcyBmcm9tIFwiLi9waXBlbGluZXNcIlxuaW1wb3J0ICogYXMgc2VzIGZyb20gXCIuL3Nlc1wiXG5pbXBvcnQgKiBhcyB3ZWJhcHAgZnJvbSBcIi4vd2ViYXBwXCJcbmltcG9ydCAqIGFzIGNvbmZpZ3VyZVBhcmFtZXRlcnMgZnJvbSBcIi4vY29uZmlndXJlLXBhcmFtZXRlcnNcIlxuaW1wb3J0ICogYXMgZWNzIGZyb20gXCIuL2Vjc1wiXG5pbXBvcnQgKiBhcyBsb2FkQmFsYW5jZXIgZnJvbSBcIi4vbG9hZC1iYWxhbmNlclwiXG5pbXBvcnQgKiBhcyByZHMgZnJvbSBcIi4vcmRzXCJcbmltcG9ydCAqIGFzIHBsYXRmb3JtIGZyb20gXCIuL3BsYXRmb3JtXCJcblxuLy8gVE9ETzogV2Ugd2FudCB0byBzd2l0Y2ggZXhwb3J0cyBzbyB0aGV5IGV2ZXJ5IGNvbnN0cnVjdCB1bmRlclxuLy8gIGEgbmFtZXNwYWNlIHN1Y2ggYXMgdGhlIHNucyBleHBvcnQuXG5cbmV4cG9ydCB7IEJhc3Rpb25Ib3N0IH0gZnJvbSBcIi4vYmFzdGlvbi1ob3N0XCJcbmV4cG9ydCAqIGZyb20gXCIuL2J1aWxkLWFydGlmYWN0c1wiXG5leHBvcnQgKiBmcm9tIFwiLi9jZGstZGVwbG95XCJcbmV4cG9ydCB7IENyb3NzUmVnaW9uU3NtUGFyYW1ldGVyIH0gZnJvbSBcIi4vY3Jvc3MtcmVnaW9uLXNzbS1wYXJhbWV0ZXJcIlxuZXhwb3J0ICogZnJvbSBcIi4vZWNzLXVwZGF0ZS1pbWFnZVwiXG5leHBvcnQgeyBIb3N0ZWRab25lV2l0aFBhcmFtIH0gZnJvbSBcIi4vaG9zdGVkLXpvbmUtd2l0aC1wYXJhbVwiXG5leHBvcnQgeyBjcmVhdGVDbG91ZEFzc2VtYmx5U25hcHNob3QgfSBmcm9tIFwiLi9zbmFwc2hvdHNcIlxuZXhwb3J0IHsgU3NtUGFyYW1ldGVyQmFja2VkUmVzb3VyY2UgfSBmcm9tIFwiLi9zc20tcGFyYW1ldGVyLWJhY2tlZC1yZXNvdXJjZVwiXG5leHBvcnQgeyBTc21QYXJhbWV0ZXJSZWFkZXIgfSBmcm9tIFwiLi9zc20tcGFyYW1ldGVyLXJlYWRlclwiXG5leHBvcnQgeyB0YWdSZXNvdXJjZXMgfSBmcm9tIFwiLi90YWdzXCJcbmV4cG9ydCB7IFdlYmFwcERlcGxveVZpYVJvbGUgfSBmcm9tIFwiLi93ZWJhcHAtZGVwbG95LXZpYS1yb2xlXCJcblxuZXhwb3J0IHtcbiAgYWxhcm1zLFxuICBjZGtQaXBlbGluZXMsXG4gIGdyaWlkLFxuICBwaXBlbGluZXMsXG4gIHNlcyxcbiAgd2ViYXBwLFxuICBjb25maWd1cmVQYXJhbWV0ZXJzLFxuICBlY3MsXG4gIGxvYWRCYWxhbmNlcixcbiAgcmRzLFxuICBwbGF0Zm9ybSxcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB3ZSBhcmUgc3ludGhlc2l6aW5nIGEgc25hcHNob3QgYnkgc2V0dGluZyBJU19TTkFQU0hPVFxuICogZW52aXJvbm1lbnQgdmFyaWFibGUgdG8gdHJ1ZS5cbiAqXG4gKiBUaGlzIGFsbG93cyBmb3Igc3BlY2lhbCBjb25kaXRpb25hbCBsb2dpYyB0aGF0IHNob3VsZCBvbmx5XG4gKiBoYXBwZW4gZHVyaW5nIHNuYXBzaG90IGNyZWF0aW9uLlxuICovXG5leHBvcnQgY29uc3QgaXNTbmFwc2hvdCA9IHByb2Nlc3MuZW52LklTX1NOQVBTSE9UID09PSBcInRydWVcIlxuIl19
67
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztBQUFBLG1DQUFrQztBQTZCaEMsd0JBQU07QUE1QlIsZ0RBQStDO0FBNkI3QyxvQ0FBWTtBQTVCZCxpQ0FBZ0M7QUE2QjlCLHNCQUFLO0FBNUJQLHlDQUF3QztBQTZCdEMsOEJBQVM7QUE1QlgsNkJBQTRCO0FBNkIxQixrQkFBRztBQTVCTCxtQ0FBa0M7QUE2QmhDLHdCQUFNO0FBNUJSLDhEQUE2RDtBQTZCM0Qsa0RBQW1CO0FBNUJyQiw2QkFBNEI7QUE2QjFCLGtCQUFHO0FBNUJMLGdEQUErQztBQTZCN0Msb0NBQVk7QUE1QmQsNkVBQTRFO0FBK0IxRSxnRUFBMEI7QUE5QjVCLDZCQUE0QjtBQTRCMUIsa0JBQUc7QUEzQkwsdUNBQXNDO0FBNEJwQyw0QkFBUTtBQTFCVixnRUFBZ0U7QUFDaEUsdUNBQXVDO0FBRXZDLCtDQUE0QztBQUFuQywyR0FBQSxXQUFXLE9BQUE7QUFDcEIsb0RBQWlDO0FBQ2pDLCtDQUE0QjtBQUM1QiwyRUFBc0U7QUFBN0QscUlBQUEsdUJBQXVCLE9BQUE7QUFDaEMscURBQWtDO0FBQ2xDLG1FQUE4RDtBQUFyRCw2SEFBQSxtQkFBbUIsT0FBQTtBQUM1Qix5Q0FBeUQ7QUFBaEQsd0hBQUEsMkJBQTJCLE9BQUE7QUFDcEMsaUZBQTRFO0FBQW5FLDJJQUFBLDBCQUEwQixPQUFBO0FBQ25DLCtEQUEyRDtBQUFsRCwwSEFBQSxrQkFBa0IsT0FBQTtBQUMzQiwrQkFBcUM7QUFBNUIsb0dBQUEsWUFBWSxPQUFBO0FBQ3JCLG1FQUE4RDtBQUFyRCw2SEFBQSxtQkFBbUIsT0FBQTtBQWlCNUI7Ozs7OztHQU1HO0FBQ1UsUUFBQSxVQUFVLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEtBQUssTUFBTSxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgYWxhcm1zIGZyb20gXCIuL2FsYXJtc1wiXG5pbXBvcnQgKiBhcyBjZGtQaXBlbGluZXMgZnJvbSBcIi4vY2RrLXBpcGVsaW5lc1wiXG5pbXBvcnQgKiBhcyBncmlpZCBmcm9tIFwiLi9ncmlpZFwiXG5pbXBvcnQgKiBhcyBwaXBlbGluZXMgZnJvbSBcIi4vcGlwZWxpbmVzXCJcbmltcG9ydCAqIGFzIHNlcyBmcm9tIFwiLi9zZXNcIlxuaW1wb3J0ICogYXMgd2ViYXBwIGZyb20gXCIuL3dlYmFwcFwiXG5pbXBvcnQgKiBhcyBjb25maWd1cmVQYXJhbWV0ZXJzIGZyb20gXCIuL2NvbmZpZ3VyZS1wYXJhbWV0ZXJzXCJcbmltcG9ydCAqIGFzIGVjcyBmcm9tIFwiLi9lY3NcIlxuaW1wb3J0ICogYXMgbG9hZEJhbGFuY2VyIGZyb20gXCIuL2xvYWQtYmFsYW5jZXJcIlxuaW1wb3J0ICogYXMgY2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb24gZnJvbSBcIi4vY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvblwiXG5pbXBvcnQgKiBhcyByZHMgZnJvbSBcIi4vcmRzXCJcbmltcG9ydCAqIGFzIHBsYXRmb3JtIGZyb20gXCIuL3BsYXRmb3JtXCJcblxuLy8gVE9ETzogV2Ugd2FudCB0byBzd2l0Y2ggZXhwb3J0cyBzbyB0aGV5IGV2ZXJ5IGNvbnN0cnVjdCB1bmRlclxuLy8gIGEgbmFtZXNwYWNlIHN1Y2ggYXMgdGhlIHNucyBleHBvcnQuXG5cbmV4cG9ydCB7IEJhc3Rpb25Ib3N0IH0gZnJvbSBcIi4vYmFzdGlvbi1ob3N0XCJcbmV4cG9ydCAqIGZyb20gXCIuL2J1aWxkLWFydGlmYWN0c1wiXG5leHBvcnQgKiBmcm9tIFwiLi9jZGstZGVwbG95XCJcbmV4cG9ydCB7IENyb3NzUmVnaW9uU3NtUGFyYW1ldGVyIH0gZnJvbSBcIi4vY3Jvc3MtcmVnaW9uLXNzbS1wYXJhbWV0ZXJcIlxuZXhwb3J0ICogZnJvbSBcIi4vZWNzLXVwZGF0ZS1pbWFnZVwiXG5leHBvcnQgeyBIb3N0ZWRab25lV2l0aFBhcmFtIH0gZnJvbSBcIi4vaG9zdGVkLXpvbmUtd2l0aC1wYXJhbVwiXG5leHBvcnQgeyBjcmVhdGVDbG91ZEFzc2VtYmx5U25hcHNob3QgfSBmcm9tIFwiLi9zbmFwc2hvdHNcIlxuZXhwb3J0IHsgU3NtUGFyYW1ldGVyQmFja2VkUmVzb3VyY2UgfSBmcm9tIFwiLi9zc20tcGFyYW1ldGVyLWJhY2tlZC1yZXNvdXJjZVwiXG5leHBvcnQgeyBTc21QYXJhbWV0ZXJSZWFkZXIgfSBmcm9tIFwiLi9zc20tcGFyYW1ldGVyLXJlYWRlclwiXG5leHBvcnQgeyB0YWdSZXNvdXJjZXMgfSBmcm9tIFwiLi90YWdzXCJcbmV4cG9ydCB7IFdlYmFwcERlcGxveVZpYVJvbGUgfSBmcm9tIFwiLi93ZWJhcHAtZGVwbG95LXZpYS1yb2xlXCJcblxuZXhwb3J0IHtcbiAgYWxhcm1zLFxuICBjZGtQaXBlbGluZXMsXG4gIGdyaWlkLFxuICBwaXBlbGluZXMsXG4gIHNlcyxcbiAgd2ViYXBwLFxuICBjb25maWd1cmVQYXJhbWV0ZXJzLFxuICBlY3MsXG4gIGxvYWRCYWxhbmNlcixcbiAgcmRzLFxuICBwbGF0Zm9ybSxcbiAgY2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb24sXG59XG5cbi8qKlxuICogQ2hlY2sgaWYgd2UgYXJlIHN5bnRoZXNpemluZyBhIHNuYXBzaG90IGJ5IHNldHRpbmcgSVNfU05BUFNIT1RcbiAqIGVudmlyb25tZW50IHZhcmlhYmxlIHRvIHRydWUuXG4gKlxuICogVGhpcyBhbGxvd3MgZm9yIHNwZWNpYWwgY29uZGl0aW9uYWwgbG9naWMgdGhhdCBzaG91bGQgb25seVxuICogaGFwcGVuIGR1cmluZyBzbmFwc2hvdCBjcmVhdGlvbi5cbiAqL1xuZXhwb3J0IGNvbnN0IGlzU25hcHNob3QgPSBwcm9jZXNzLmVudi5JU19TTkFQU0hPVCA9PT0gXCJ0cnVlXCJcbiJdfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liflig/cdk",
3
- "version": "1.50.0",
3
+ "version": "1.51.0",
4
4
  "description": "Experimental CDK library for Liflig",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,7 +9,7 @@
9
9
  "scripts": {
10
10
  "build": "tsc",
11
11
  "watch": "tsc -w",
12
- "test": "jest",
12
+ "test": "jest --runInBand",
13
13
  "lint": "eslint .",
14
14
  "lint:fix": "eslint --fix .",
15
15
  "prepare": "npm run build && husky install",
@@ -34,50 +34,51 @@
34
34
  "access": "public"
35
35
  },
36
36
  "devDependencies": {
37
- "@aws-cdk/assert": "1.128.0",
38
- "@aws-cdk/aws-certificatemanager": "1.128.0",
39
- "@aws-cdk/aws-cloudfront": "1.128.0",
40
- "@aws-cdk/aws-cloudfront-origins": "1.128.0",
41
- "@aws-cdk/aws-cloudwatch": "1.128.0",
42
- "@aws-cdk/aws-cloudwatch-actions": "1.128.0",
43
- "@aws-cdk/aws-codebuild": "1.128.0",
44
- "@aws-cdk/aws-codepipeline": "1.128.0",
45
- "@aws-cdk/aws-codepipeline-actions": "1.128.0",
46
- "@aws-cdk/aws-ecs": "1.128.0",
47
- "@aws-cdk/aws-events-targets": "1.128.0",
48
- "@aws-cdk/aws-iam": "1.128.0",
49
- "@aws-cdk/aws-lambda": "1.128.0",
50
- "@aws-cdk/aws-logs": "1.128.0",
51
- "@aws-cdk/aws-rds": "1.128.0",
52
- "@aws-cdk/aws-route53": "1.128.0",
53
- "@aws-cdk/aws-route53-targets": "1.128.0",
54
- "@aws-cdk/aws-s3": "1.128.0",
55
- "@aws-cdk/aws-ses": "1.128.0",
56
- "@aws-cdk/aws-sns": "1.128.0",
57
- "@aws-cdk/aws-stepfunctions": "1.128.0",
58
- "@aws-cdk/aws-stepfunctions-tasks": "1.128.0",
59
- "@aws-cdk/core": "1.128.0",
60
- "@aws-cdk/custom-resources": "1.128.0",
61
- "@aws-cdk/pipelines": "1.128.0",
62
- "@commitlint/cli": "13.2.1",
63
- "@commitlint/config-conventional": "13.2.0",
64
- "@types/aws-lambda": "8.10.85",
37
+ "@aws-cdk/assert": "1.135.0",
38
+ "@aws-cdk/aws-certificatemanager": "1.135.0",
39
+ "@aws-cdk/aws-cloudfront": "1.135.0",
40
+ "@aws-cdk/aws-cloudfront-origins": "1.135.0",
41
+ "@aws-cdk/aws-cloudwatch": "1.135.0",
42
+ "@aws-cdk/aws-cloudwatch-actions": "1.135.0",
43
+ "@aws-cdk/aws-codebuild": "1.135.0",
44
+ "@aws-cdk/aws-codepipeline": "1.135.0",
45
+ "@aws-cdk/aws-codepipeline-actions": "1.135.0",
46
+ "@aws-cdk/aws-ecs": "1.135.0",
47
+ "@aws-cdk/aws-events-targets": "1.135.0",
48
+ "@aws-cdk/aws-iam": "1.135.0",
49
+ "@aws-cdk/aws-lambda": "1.135.0",
50
+ "@aws-cdk/aws-lambda-event-sources": "1.135.0",
51
+ "@aws-cdk/aws-logs": "1.135.0",
52
+ "@aws-cdk/aws-rds": "1.135.0",
53
+ "@aws-cdk/aws-route53": "1.135.0",
54
+ "@aws-cdk/aws-route53-targets": "1.135.0",
55
+ "@aws-cdk/aws-s3": "1.135.0",
56
+ "@aws-cdk/aws-ses": "1.135.0",
57
+ "@aws-cdk/aws-sns": "1.135.0",
58
+ "@aws-cdk/aws-stepfunctions": "1.135.0",
59
+ "@aws-cdk/aws-stepfunctions-tasks": "1.135.0",
60
+ "@aws-cdk/core": "1.135.0",
61
+ "@aws-cdk/custom-resources": "1.135.0",
62
+ "@aws-cdk/pipelines": "1.135.0",
63
+ "@commitlint/cli": "15.0.0",
64
+ "@commitlint/config-conventional": "15.0.0",
65
+ "@types/aws-lambda": "8.10.88",
65
66
  "@types/jest": "27.0.3",
66
- "@types/node": "16.11.11",
67
- "@typescript-eslint/eslint-plugin": "5.6.0",
68
- "@typescript-eslint/parser": "5.6.0",
69
- "aws-cdk": "1.128.0",
70
- "eslint": "8.4.1",
67
+ "@types/node": "16.11.14",
68
+ "@typescript-eslint/eslint-plugin": "5.7.0",
69
+ "@typescript-eslint/parser": "5.7.0",
70
+ "aws-cdk": "1.135.0",
71
+ "eslint": "8.5.0",
71
72
  "eslint-config-prettier": "8.3.0",
72
73
  "eslint-plugin-prettier": "4.0.0",
73
74
  "husky": "7.0.4",
74
- "jest": "27.3.1",
75
+ "jest": "27.4.5",
75
76
  "jest-cdk-snapshot": "1.4.2",
76
- "prettier": "2.4.1",
77
+ "prettier": "2.5.1",
77
78
  "semantic-release": "18.0.1",
78
- "ts-jest": "27.0.7",
79
+ "ts-jest": "27.1.2",
79
80
  "ts-node": "10.4.0",
80
- "typescript": "4.5.2"
81
+ "typescript": "4.5.4"
81
82
  },
82
83
  "dependencies": {
83
84
  "@capraconsulting/webapp-deploy-lambda": "^1.2.1",
@@ -104,6 +105,7 @@
104
105
  "@aws-cdk/aws-events-targets": "^1.108.1",
105
106
  "@aws-cdk/aws-iam": "^1.108.1",
106
107
  "@aws-cdk/aws-lambda": "^1.108.1",
108
+ "@aws-cdk/aws-lambda-event-sources": "^1.108.1",
107
109
  "@aws-cdk/aws-logs": "^1.108.1",
108
110
  "@aws-cdk/aws-rds": "^1.108.1",
109
111
  "@aws-cdk/aws-route53": "^1.108.1",