@liflig/cdk 2.18.4 → 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.
Files changed (140) hide show
  1. package/assets/cloudtrail-slack-integration-lambda/main.py +267 -0
  2. package/assets/pipeline-slack-notification-lambda/index.py +300 -0
  3. package/assets/prepare-cdk-source-lambda/index.py +159 -0
  4. package/assets/slack-alarm-lambda/index.py +103 -0
  5. package/lib/alarms/database-alarms.d.ts +125 -0
  6. package/lib/alarms/database-alarms.js +171 -0
  7. package/lib/alarms/index.d.ts +3 -0
  8. package/lib/alarms/index.js +10 -0
  9. package/lib/alarms/service-alarms.d.ts +145 -0
  10. package/lib/alarms/service-alarms.js +148 -0
  11. package/lib/alarms/ses-alarms.d.ts +67 -0
  12. package/lib/alarms/ses-alarms.js +49 -0
  13. package/lib/alarms/slack-alarm.d.ts +25 -0
  14. package/lib/alarms/slack-alarm.js +47 -0
  15. package/lib/bastion-host.d.ts +41 -0
  16. package/lib/bastion-host.js +86 -0
  17. package/lib/bin/cdk-create-snapshots.d.ts +2 -0
  18. package/lib/bin/fetch-pipeline-variables.d.ts +2 -0
  19. package/lib/build-artifacts/index.d.ts +68 -0
  20. package/lib/build-artifacts/index.js +118 -0
  21. package/lib/cdk-deploy/cdk-deploy.d.ts +63 -0
  22. package/lib/cdk-deploy/cdk-deploy.js +175 -0
  23. package/lib/cdk-deploy/index.d.ts +1 -0
  24. package/lib/cdk-deploy/index.js +6 -0
  25. package/lib/cdk-deploy/start-deploy-handler.d.ts +8 -0
  26. package/lib/cdk-deploy/start-deploy-handler.js +72 -0
  27. package/lib/cdk-deploy/status-handler.d.ts +6 -0
  28. package/lib/cdk-deploy/status-handler.js +83 -0
  29. package/lib/cdk-pipelines/cloud-assembly-lookup-handler.d.ts +6 -0
  30. package/lib/cdk-pipelines/cloud-assembly-lookup-handler.js +63 -0
  31. package/lib/cdk-pipelines/index.d.ts +3 -0
  32. package/lib/cdk-pipelines/index.js +10 -0
  33. package/lib/cdk-pipelines/liflig-cdk-pipeline.d.ts +110 -0
  34. package/lib/cdk-pipelines/liflig-cdk-pipeline.js +232 -0
  35. package/lib/cdk-pipelines/slack-notification.d.ts +51 -0
  36. package/lib/cdk-pipelines/slack-notification.js +54 -0
  37. package/lib/cdk-pipelines/variables.d.ts +15 -0
  38. package/lib/cdk-pipelines/variables.js +80 -0
  39. package/lib/cloudtrail-slack-integration/cloudtrail-slack-integration.d.ts +47 -0
  40. package/lib/cloudtrail-slack-integration/cloudtrail-slack-integration.js +211 -0
  41. package/lib/cloudtrail-slack-integration/index.d.ts +1 -0
  42. package/lib/cloudtrail-slack-integration/index.js +6 -0
  43. package/lib/configure-parameters/configure-parameters.d.ts +61 -0
  44. package/lib/configure-parameters/configure-parameters.js +94 -0
  45. package/lib/configure-parameters/index.d.ts +1 -0
  46. package/lib/configure-parameters/index.js +6 -0
  47. package/lib/cross-region-ssm-parameter.d.ts +13 -0
  48. package/lib/cross-region-ssm-parameter.js +46 -0
  49. package/lib/ecs/cluster.d.ts +25 -0
  50. package/lib/ecs/cluster.js +70 -0
  51. package/lib/ecs/fargate-service.d.ts +63 -0
  52. package/lib/ecs/fargate-service.js +98 -0
  53. package/lib/ecs/index.d.ts +3 -0
  54. package/lib/ecs/index.js +10 -0
  55. package/lib/ecs/listener-rule.d.ts +25 -0
  56. package/lib/ecs/listener-rule.js +27 -0
  57. package/lib/ecs-update-image/artifact-status.d.ts +39 -0
  58. package/lib/ecs-update-image/artifact-status.js +41 -0
  59. package/lib/ecs-update-image/ecs-update-image.d.ts +41 -0
  60. package/lib/ecs-update-image/ecs-update-image.js +98 -0
  61. package/lib/ecs-update-image/index.d.ts +3 -0
  62. package/lib/ecs-update-image/index.js +10 -0
  63. package/lib/ecs-update-image/start-deploy-handler.d.ts +6 -0
  64. package/lib/ecs-update-image/start-deploy-handler.js +104 -0
  65. package/lib/ecs-update-image/status-handler.d.ts +11 -0
  66. package/lib/ecs-update-image/status-handler.js +74 -0
  67. package/lib/ecs-update-image/tag.d.ts +47 -0
  68. package/lib/ecs-update-image/tag.js +67 -0
  69. package/lib/feature-flags.d.ts +18 -0
  70. package/lib/feature-flags.js +48 -0
  71. package/lib/griid/artefact-bucket.d.ts +7 -0
  72. package/lib/griid/artefact-bucket.js +30 -0
  73. package/lib/griid/index.d.ts +4 -0
  74. package/lib/griid/index.js +18 -0
  75. package/lib/hosted-zone-with-param.d.ts +29 -0
  76. package/lib/hosted-zone-with-param.js +65 -0
  77. package/lib/index.d.ts +32 -0
  78. package/lib/kinesis/index.d.ts +1 -0
  79. package/lib/kinesis/index.js +6 -0
  80. package/lib/kinesis/kinesis-to-datadog-stream.d.ts +28 -0
  81. package/lib/kinesis/kinesis-to-datadog-stream.js +126 -0
  82. package/lib/load-balancer/index.d.ts +1 -0
  83. package/lib/load-balancer/index.js +6 -0
  84. package/lib/load-balancer/load-balancer.d.ts +16 -0
  85. package/lib/load-balancer/load-balancer.js +60 -0
  86. package/lib/pipelines/conventions.d.ts +14 -0
  87. package/lib/pipelines/conventions.js +24 -0
  88. package/lib/pipelines/deploy-env.d.ts +18 -0
  89. package/lib/pipelines/deploy-env.js +96 -0
  90. package/lib/pipelines/index.d.ts +2 -0
  91. package/lib/pipelines/index.js +8 -0
  92. package/lib/pipelines/liflig-cdk-deployer-deps.d.ts +13 -0
  93. package/lib/pipelines/liflig-cdk-deployer-deps.js +35 -0
  94. package/lib/pipelines/pipeline.d.ts +78 -0
  95. package/lib/pipelines/pipeline.js +224 -0
  96. package/lib/platform/index.d.ts +1 -0
  97. package/lib/platform/index.js +7 -0
  98. package/lib/platform/platform.d.ts +37 -0
  99. package/lib/platform/platform.js +57 -0
  100. package/lib/rds/database.d.ts +49 -0
  101. package/lib/rds/database.js +60 -0
  102. package/lib/rds/index.d.ts +1 -0
  103. package/lib/rds/index.js +6 -0
  104. package/lib/ses/configurationsetdeliveryoptions/index.d.ts +26 -0
  105. package/lib/ses/configurationsetdeliveryoptions/index.js +48 -0
  106. package/lib/ses/configurationsetsnsdestination/handler.d.ts +17 -0
  107. package/lib/ses/configurationsetsnsdestination/handler.js +75 -0
  108. package/lib/ses/configurationsetsnsdestination/index.d.ts +29 -0
  109. package/lib/ses/configurationsetsnsdestination/index.js +75 -0
  110. package/lib/ses/index.d.ts +4 -0
  111. package/lib/ses/index.js +12 -0
  112. package/lib/ses/sesdomain/handler.d.ts +10 -0
  113. package/lib/ses/sesdomain/handler.js +82 -0
  114. package/lib/ses/sesdomain/index.d.ts +57 -0
  115. package/lib/ses/sesdomain/index.js +94 -0
  116. package/lib/ses/sesverifyemail/handler.d.ts +9 -0
  117. package/lib/ses/sesverifyemail/handler.js +25 -0
  118. package/lib/ses/sesverifyemail/index.d.ts +13 -0
  119. package/lib/ses/sesverifyemail/index.js +51 -0
  120. package/lib/snapshots.d.ts +4 -0
  121. package/lib/snapshots.js +214 -0
  122. package/lib/ssm-parameter-backed-resource.d.ts +45 -0
  123. package/lib/ssm-parameter-backed-resource.js +67 -0
  124. package/lib/ssm-parameter-reader.d.ts +21 -0
  125. package/lib/ssm-parameter-reader.js +48 -0
  126. package/lib/tags.d.ts +8 -0
  127. package/lib/tags.js +36 -0
  128. package/lib/utils.d.ts +2 -0
  129. package/lib/utils.js +17 -0
  130. package/lib/webapp/index.d.ts +3 -0
  131. package/lib/webapp/index.js +10 -0
  132. package/lib/webapp/monitor.d.ts +187 -0
  133. package/lib/webapp/monitor.js +156 -0
  134. package/lib/webapp/security-headers.d.ts +38 -0
  135. package/lib/webapp/security-headers.js +129 -0
  136. package/lib/webapp/webapp.d.ts +116 -0
  137. package/lib/webapp/webapp.js +118 -0
  138. package/lib/webapp-deploy-via-role.d.ts +25 -0
  139. package/lib/webapp-deploy-via-role.js +32 -0
  140. package/package.json +4 -3
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CloudTrailSlackIntegration = void 0;
4
+ const constructs = require("constructs");
5
+ const cdk = require("aws-cdk-lib");
6
+ const iam = require("aws-cdk-lib/aws-iam");
7
+ const logs = require("aws-cdk-lib/aws-logs");
8
+ const cloudwatch = require("aws-cdk-lib/aws-cloudwatch");
9
+ const lambda = require("aws-cdk-lib/aws-lambda");
10
+ const events = require("aws-cdk-lib/aws-events");
11
+ const sources = require("aws-cdk-lib/aws-lambda-event-sources");
12
+ const sqs = require("aws-cdk-lib/aws-sqs");
13
+ const targets = require("aws-cdk-lib/aws-events-targets");
14
+ const path = require("path");
15
+ /**
16
+ * Forward a predefined set of CloudTrail API events to Slack using EventBridge, Lambda
17
+ * and an optional SQS FIFO queue for deduplicating events.
18
+ * The API events are limited to monitoring access to the current account's root user and/or specific IAM roles.
19
+ *
20
+ * NOTE: The construct needs to be provisioned in us-east-1, and requires an existing CloudTrail set up in that region.
21
+ */
22
+ class CloudTrailSlackIntegration extends constructs.Construct {
23
+ constructor(scope, id, props) {
24
+ super(scope, id);
25
+ const eventTransformer = new lambda.Function(this, "EventTransformerLambda", {
26
+ code: lambda.Code.fromAsset(path.join(__dirname, "../../assets/cloudtrail-slack-integration-lambda")),
27
+ description: "Formats CloudTrail API calls sent through EventBridge, and posts them directly to Slack or first to an SQS FIFO queue for deduplication",
28
+ handler: "main.handler_event_transformer",
29
+ runtime: lambda.Runtime.PYTHON_3_9,
30
+ timeout: cdk.Duration.seconds(15),
31
+ logRetention: logs.RetentionDays.SIX_MONTHS,
32
+ environment: {
33
+ SLACK_CHANNEL: props.slackChannel,
34
+ DEDUPLICATE_EVENTS: JSON.stringify(!!props.deduplicateEvents),
35
+ FRIENDLY_NAMES: JSON.stringify(props.friendlyNames || {}),
36
+ SLACK_WEBHOOK_URL: props.slackWebhookUrl,
37
+ },
38
+ });
39
+ eventTransformer.addToRolePolicy(new iam.PolicyStatement({
40
+ actions: ["iam:ListAccountAliases"],
41
+ resources: ["*"],
42
+ }));
43
+ if (props.infrastructureAlarmAction) {
44
+ const eventTransformerAlarm = eventTransformer
45
+ .metricErrors({
46
+ period: cdk.Duration.minutes(5),
47
+ statistic: cloudwatch.Statistic.SUM,
48
+ })
49
+ .createAlarm(this, "EventTransformerErrorAlarm", {
50
+ threshold: 1,
51
+ evaluationPeriods: 1,
52
+ alarmDescription: "Triggers if the Lambda function that transforms CloudTrail API calls received through EventBridge fails (e.g., it fails to process the event)",
53
+ datapointsToAlarm: 1,
54
+ treatMissingData: cloudwatch.TreatMissingData.IGNORE,
55
+ });
56
+ eventTransformerAlarm.addOkAction(props.infrastructureAlarmAction);
57
+ eventTransformerAlarm.addAlarmAction(props.infrastructureAlarmAction);
58
+ }
59
+ if (props.deduplicateEvents) {
60
+ const deduplicationQueue = new sqs.Queue(this, "Queue", {
61
+ // We explicitly give the queue a name due to bug https://github.com/aws/aws-cdk/issues/5860
62
+ queueName: `${this.node.id.substring(0, 33)}${this.node.addr}`.substring(0, 75) +
63
+ ".fifo",
64
+ fifo: true,
65
+ });
66
+ eventTransformer.addEnvironment("SQS_QUEUE_URL", deduplicationQueue.queueUrl);
67
+ deduplicationQueue.grantSendMessages(eventTransformer);
68
+ const slackForwarder = new lambda.Function(this, "SlackForwarderLambda", {
69
+ code: lambda.Code.fromAsset(path.join(__dirname, "../../assets/cloudtrail-slack-integration-lambda")),
70
+ description: "Polls from an SQS FIFO queue containing formatted CloudTrail API calls and sends them to Slack.",
71
+ handler: "main.handler_slack_forwarder",
72
+ runtime: lambda.Runtime.PYTHON_3_9,
73
+ timeout: cdk.Duration.seconds(15),
74
+ logRetention: logs.RetentionDays.TWO_WEEKS,
75
+ });
76
+ if (props.infrastructureAlarmAction) {
77
+ const slackForwarderAlarm = slackForwarder
78
+ .metricErrors({
79
+ period: cdk.Duration.minutes(5),
80
+ statistic: cloudwatch.Statistic.SUM,
81
+ })
82
+ .createAlarm(this, "SlackForwarderErrorAlarm", {
83
+ threshold: 1,
84
+ 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)",
85
+ evaluationPeriods: 1,
86
+ datapointsToAlarm: 1,
87
+ treatMissingData: cloudwatch.TreatMissingData.IGNORE,
88
+ });
89
+ slackForwarderAlarm.addOkAction(props.infrastructureAlarmAction);
90
+ slackForwarderAlarm.addAlarmAction(props.infrastructureAlarmAction);
91
+ }
92
+ slackForwarder.addEventSource(new sources.SqsEventSource(deduplicationQueue));
93
+ }
94
+ if (props.rolesToMonitor && props.rolesToMonitor.length > 0) {
95
+ new events.Rule(this, "RuleForAssumeRole", {
96
+ enabled: true,
97
+ targets: [new targets.LambdaFunction(eventTransformer)],
98
+ eventPattern: {
99
+ detail: {
100
+ eventName: ["AssumeRole"],
101
+ requestParameters: {
102
+ roleArn: props.rolesToMonitor,
103
+ },
104
+ },
105
+ },
106
+ });
107
+ }
108
+ if (props.monitorRootUserActions !== false) {
109
+ // Triggers when the root password has been changed
110
+ new events.Rule(this, "RuleForRootUserPasswordChange", {
111
+ enabled: true,
112
+ targets: [new targets.LambdaFunction(eventTransformer)],
113
+ eventPattern: {
114
+ detail: {
115
+ userIdentity: {
116
+ type: ["Root"],
117
+ },
118
+ eventName: ["PasswordUpdated"],
119
+ eventType: ["AwsConsoleSignIn"],
120
+ },
121
+ },
122
+ });
123
+ // Triggers when MFA for the root user has been set up
124
+ new events.Rule(this, "RuleForRootUserMfaChange", {
125
+ enabled: true,
126
+ targets: [new targets.LambdaFunction(eventTransformer)],
127
+ eventPattern: {
128
+ detail: {
129
+ userIdentity: {
130
+ type: ["Root"],
131
+ },
132
+ eventName: ["EnableMFADevice"],
133
+ requestParameters: {
134
+ userName: ["AWS ROOT USER"],
135
+ },
136
+ },
137
+ },
138
+ });
139
+ // Triggers when a root user succesfully logs in to the console
140
+ new events.Rule(this, "RuleForRootUserSuccessfulLogin", {
141
+ enabled: true,
142
+ targets: [new targets.LambdaFunction(eventTransformer)],
143
+ eventPattern: {
144
+ detail: {
145
+ userIdentity: {
146
+ type: ["Root"],
147
+ },
148
+ eventName: ["ConsoleLogin"],
149
+ eventType: ["AwsConsoleSignIn"],
150
+ responseElements: {
151
+ ConsoleLogin: ["Success"],
152
+ },
153
+ },
154
+ },
155
+ });
156
+ // Triggers for bad login attemps for root user (e.g., wrong password)
157
+ new events.Rule(this, "RuleForRootUserUnsuccessfulLogin", {
158
+ enabled: true,
159
+ targets: [new targets.LambdaFunction(eventTransformer)],
160
+ eventPattern: {
161
+ detail: {
162
+ userIdentity: {
163
+ type: ["Root"],
164
+ },
165
+ eventName: ["ConsoleLogin"],
166
+ eventType: ["AwsConsoleSignIn"],
167
+ responseElements: {
168
+ ConsoleLogin: ["Failure"],
169
+ },
170
+ },
171
+ },
172
+ });
173
+ // Triggered when password reset has been requested
174
+ new events.Rule(this, "RuleForRootUserPasswordRecoveryRequest", {
175
+ enabled: true,
176
+ targets: [new targets.LambdaFunction(eventTransformer)],
177
+ eventPattern: {
178
+ detail: {
179
+ userIdentity: {
180
+ type: ["Root"],
181
+ },
182
+ eventName: ["PasswordRecoveryRequested"],
183
+ eventType: ["AwsConsoleSignIn"],
184
+ responseElements: {
185
+ PasswordRecoveryRequested: ["Success"],
186
+ },
187
+ },
188
+ },
189
+ });
190
+ // Triggered when password has been successfully reset
191
+ new events.Rule(this, "RuleForRootUserPasswordRecoveryComplete", {
192
+ enabled: true,
193
+ targets: [new targets.LambdaFunction(eventTransformer)],
194
+ eventPattern: {
195
+ detail: {
196
+ userIdentity: {
197
+ type: ["Root"],
198
+ },
199
+ eventName: ["PasswordRecoveryCompleted"],
200
+ eventType: ["AwsConsoleSignIn"],
201
+ responseElements: {
202
+ PasswordRecoveryCompleted: ["Success"],
203
+ },
204
+ },
205
+ },
206
+ });
207
+ }
208
+ }
209
+ }
210
+ exports.CloudTrailSlackIntegration = CloudTrailSlackIntegration;
211
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9jbG91ZHRyYWlsLXNsYWNrLWludGVncmF0aW9uL2Nsb3VkdHJhaWwtc2xhY2staW50ZWdyYXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUNBQXdDO0FBQ3hDLG1DQUFrQztBQUNsQywyQ0FBMEM7QUFDMUMsNkNBQTRDO0FBQzVDLHlEQUF3RDtBQUN4RCxpREFBZ0Q7QUFDaEQsaURBQWdEO0FBQ2hELGdFQUErRDtBQUMvRCwyQ0FBMEM7QUFDMUMsMERBQXlEO0FBQ3pELDZCQUE0QjtBQXFDNUI7Ozs7OztHQU1HO0FBQ0gsTUFBYSwwQkFBMkIsU0FBUSxVQUFVLENBQUMsU0FBUztJQUNsRSxZQUNFLEtBQTJCLEVBQzNCLEVBQVUsRUFDVixLQUFzQztRQUV0QyxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRWhCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUMxQyxJQUFJLEVBQ0osd0JBQXdCLEVBQ3hCO1lBQ0UsSUFBSSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUN6QixJQUFJLENBQUMsSUFBSSxDQUNQLFNBQVMsRUFDVCxrREFBa0QsQ0FDbkQsQ0FDRjtZQUNELFdBQVcsRUFDVCx5SUFBeUk7WUFDM0ksT0FBTyxFQUFFLGdDQUFnQztZQUN6QyxPQUFPLEVBQUUsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVO1lBQ2xDLE9BQU8sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDakMsWUFBWSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsVUFBVTtZQUMzQyxXQUFXLEVBQUU7Z0JBQ1gsYUFBYSxFQUFFLEtBQUssQ0FBQyxZQUFZO2dCQUNqQyxrQkFBa0IsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FB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LEVBQUUseUNBQXlDLEVBQUU7Z0JBQy9ELE9BQU8sRUFBRSxJQUFJO2dCQUNiLE9BQU8sRUFBRSxDQUFDLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO2dCQUN2RCxZQUFZLEVBQUU7b0JBQ1osTUFBTSxFQUFFO3dCQUNOLFlBQVksRUFBRTs0QkFDWixJQUFJLEVBQUUsQ0FBQyxNQUFNLENBQUM7eUJBQ2Y7d0JBQ0QsU0FBUyxFQUFFLENBQUMsMkJBQTJCLENBQUM7d0JBQ3hDLFNBQVMsRUFBRSxDQUFDLGtCQUFrQixDQUFDO3dCQUMvQixnQkFBZ0IsRUFBRTs0QkFDaEIseUJBQXlCLEVBQUUsQ0FBQyxTQUFTLENBQUM7eUJBQ3ZDO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQyxDQUFBO1FBQ0osQ0FBQztJQUNILENBQUM7Q0FDRjtBQWxPRCxnRUFrT0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCAqIGFzIGNkayBmcm9tIFwiYXdzLWNkay1saWJcIlxuaW1wb3J0ICogYXMgaWFtIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCJcbmltcG9ydCAqIGFzIGxvZ3MgZnJvbSBcImF3cy1jZGstbGliL2F3cy1sb2dzXCJcbmltcG9ydCAqIGFzIGNsb3Vkd2F0Y2ggZnJvbSBcImF3cy1jZGstbGliL2F3cy1jbG91ZHdhdGNoXCJcbmltcG9ydCAqIGFzIGxhbWJkYSBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYVwiXG5pbXBvcnQgKiBhcyBldmVudHMgZnJvbSBcImF3cy1jZGstbGliL2F3cy1ldmVudHNcIlxuaW1wb3J0ICogYXMgc291cmNlcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxhbWJkYS1ldmVudC1zb3VyY2VzXCJcbmltcG9ydCAqIGFzIHNxcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLXNxc1wiXG5pbXBvcnQgKiBhcyB0YXJnZXRzIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZXZlbnRzLXRhcmdldHNcIlxuaW1wb3J0ICogYXMgcGF0aCBmcm9tIFwicGF0aFwiXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2xvdWRUcmFpbFNsYWNrSW50ZWdyYXRpb25Qcm9wcyBleHRlbmRzIGNkay5TdGFja1Byb3BzIHtcbiAgLyoqXG4gICAqIEEga2V5LXZhbHVlIHBhaXIgb2YgdmFsdWVzIHRvIGF1Z21lbnQgKGUuZy4sIEFXUyBhY2NvdW50IElEcywgcHJpbmNpcGFsIElEcykgd2l0aCBmcmllbmRseSBuYW1lc1xuICAgKiB0byB1c2Ugd2hlbiBzZW5kaW5nIG1lc3NhZ2VzIHRvIFNsYWNrLlxuICAgKlxuICAgKiBOT1RFOiBBIHNpbXBsZSBoZXVyaXN0aWMgaXMgdXNlZCB0byBhdm9pZCByZXBsYWNpbmcgdmFsdWVzIGluc2lkZSBvZiBBUk5zIGV0Yy4gYXMgdGhpcyBjYW5cbiAgICogbGVhZCB0byB1bnBsZWFzYW50IGZvcm1hdHRpbmcgb2YgdmFyaW91cyBmaWVsZHMgaW4gdGhlIFNsYWNrIG1lc3NhZ2UuXG4gICAqL1xuICBmcmllbmRseU5hbWVzPzoge1xuICAgIFtrZXk6IHN0cmluZ106IHN0cmluZ1xuICB9XG4gIHNsYWNrV2ViaG9va1VybDogc3RyaW5nXG4gIHNsYWNrQ2hhbm5lbDogc3RyaW5nXG4gIC8qKlxuICAgKiBBIGxpc3Qgb2YgQVJOcyBvZiByb2xlcyBpbiB0aGUgY3VycmVudCBhY2NvdW50IHRvIG1vbml0b3IgdXNhZ2Ugb2YuXG4gICAqL1xuICByb2xlc1RvTW9uaXRvcj86IHN0cmluZ1tdXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIG1vbml0b3IgdmFyaW91cyBJQU0gQVBJIGNhbGxzIGFzc29jaWF0ZWQgd2l0aCB0aGUgY3VycmVudCBhY2NvdW50J3Mgcm9vdCB1c2VyIChlLmcuLCBjb25zb2xlIGxvZ2luLCBwYXNzd29yZCByZXNldCwgZXRjLilcbiAgICpcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgbW9uaXRvclJvb3RVc2VyQWN0aW9ucz86IGJvb2xlYW5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdG8gc2V0IHVwIGFkZGl0aW9uYWwgQVdTIGluZnJhc3RydWN0dXJlIHRvIGRlZHVwbGljYXRlIENsb3VkVHJhaWwgZXZlbnRzIGluIG9yZGVyIHRvIGF2b2lkIGR1cGxpY2F0ZSBTbGFjayBtZXNzYWdlcy4gTWF5IGJlIHVzZWQgdG8gZGVjcmVhc2Ugbm9pc2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBkZWR1cGxpY2F0ZUV2ZW50cz86IGJvb2xlYW5cbiAgLyoqXG4gICAqIElmIHN1cHBsaWVkLCBDbG91ZFdhdGNoIGFsYXJtcyB3aWxsIGJlIGNyZWF0ZWQgZm9yIHRoZSBjb25zdHJ1Y3QncyB1bmRlcmx5aW5nIGluZnJhc3RydWN0dXJlIChlLmcuLCBMYW1iZGEgZnVuY3Rpb25zKSBhbmQgdGhlIGFjdGlvbiB3aWxsIGJlIHVzZWQgdG8gbm90aWZ5IG9uIE9LIGFuZCBBTEFSTSBhY3Rpb25zLlxuICAgKi9cbiAgaW5mcmFzdHJ1Y3R1cmVBbGFybUFjdGlvbj86IGNsb3Vkd2F0Y2guSUFsYXJtQWN0aW9uXG59XG5cbi8qKlxuICogRm9yd2FyZCBhIHByZWRlZmluZWQgc2V0IG9mIENsb3VkVHJhaWwgQVBJIGV2ZW50cyB0byBTbGFjayB1c2luZyBFdmVudEJyaWRnZSwgTGFtYmRhXG4gKiBhbmQgYW4gb3B0aW9uYWwgU1FTIEZJRk8gcXVldWUgZm9yIGRlZHVwbGljYXRpbmcgZXZlbnRzLlxuICogVGhlIEFQSSBldmVudHMgYXJlIGxpbWl0ZWQgdG8gbW9uaXRvcmluZyBhY2Nlc3MgdG8gdGhlIGN1cnJlbnQgYWNjb3VudCdzIHJvb3QgdXNlciBhbmQvb3Igc3BlY2lmaWMgSUFNIHJvbGVzLlxuICpcbiAqIE5PVEU6IFRoZSBjb25zdHJ1Y3QgbmVlZHMgdG8gYmUgcHJvdmlzaW9uZWQgaW4gdXMtZWFzdC0xLCBhbmQgcmVxdWlyZXMgYW4gZXhpc3RpbmcgQ2xvdWRUcmFpbCBzZXQgdXAgaW4gdGhhdCByZWdpb24uXG4gKi9cbmV4cG9ydCBjbGFzcyBDbG91ZFRyYWlsU2xhY2tJbnRlZ3JhdGlvbiBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IENsb3VkVHJhaWxTbGFja0ludGVncmF0aW9uUHJvcHMsXG4gICkge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcblxuICAgIGNvbnN0IGV2ZW50VHJhbnNmb3JtZXIgPSBuZXcgbGFtYmRhLkZ1bmN0aW9uKFxuICAgICAgdGhpcyxcbiAgICAgIFwiRXZlbnRUcmFuc2Zvcm1lckxhbWJkYVwiLFxuICAgICAge1xuICAgICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQoXG4gICAgICAgICAgcGF0aC5qb2luKFxuICAgICAgICAgICAgX19kaXJuYW1lLFxuICAgICAgICAgICAgXCIuLi8uLi9hc3NldHMvY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvbi1sYW1iZGFcIixcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICBcIkZvcm1hdHMgQ2xvdWRUcmFpbCBBUEkgY2FsbHMgc2VudCB0aHJvdWdoIEV2ZW50QnJpZGdlLCBhbmQgcG9zdHMgdGhlbSBkaXJlY3RseSB0byBTbGFjayBvciBmaXJzdCB0byBhbiBTUVMgRklGTyBxdWV1ZSBmb3IgZGVkdXBsaWNhdGlvblwiLFxuICAgICAgICBoYW5kbGVyOiBcIm1haW4uaGFuZGxlcl9ldmVudF90cmFuc2Zvcm1lclwiLFxuICAgICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5QWVRIT05fM185LFxuICAgICAgICB0aW1lb3V0OiBjZGsuRHVyYXRpb24uc2Vjb25kcygxNSksXG4gICAgICAgIGxvZ1JldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLlNJWF9NT05USFMsXG4gICAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgICAgU0xBQ0tfQ0hBTk5FTDogcHJvcHMuc2xhY2tDaGFubmVsLFxuICAgICAgICAgIERFRFVQTElDQVRFX0VWRU5UUzogSlNPTi5zdHJpbmdpZnkoISFwcm9wcy5kZWR1cGxpY2F0ZUV2ZW50cyksXG4gICAgICAgICAgRlJJRU5ETFlfTkFNRVM6IEpTT04uc3RyaW5naWZ5KHByb3BzLmZyaWVuZGx5TmFtZXMgfHwge30pLFxuICAgICAgICAgIFNMQUNLX1dFQkhPT0tfVVJMOiBwcm9wcy5zbGFja1dlYmhvb2tVcmwsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIClcbiAgICBldmVudFRyYW5zZm9ybWVyLmFkZFRvUm9sZVBvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgYWN0aW9uczogW1wiaWFtOkxpc3RBY2NvdW50QWxpYXNlc1wiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgfSksXG4gICAgKVxuICAgIGlmIChwcm9wcy5pbmZyYXN0cnVjdHVyZUFsYXJtQWN0aW9uKSB7XG4gICAgICBjb25zdCBldmVudFRyYW5zZm9ybWVyQWxhcm0gPSBldmVudFRyYW5zZm9ybWVyXG4gICAgICAgIC5tZXRyaWNFcnJvcnMoe1xuICAgICAgICAgIHBlcmlvZDogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoNSksXG4gICAgICAgICAgc3RhdGlzdGljOiBjbG91ZHdhdGNoLlN0YXRpc3RpYy5TVU0sXG4gICAgICAgIH0pXG4gICAgICAgIC5jcmVhdGVBbGFybSh0aGlzLCBcIkV2ZW50VHJhbnNmb3JtZXJFcnJvckFsYXJtXCIsIHtcbiAgICAgICAgICB0aHJlc2hvbGQ6IDEsXG4gICAgICAgICAgZXZhbHVhdGlvblBlcmlvZHM6IDEsXG4gICAgICAgICAgYWxhcm1EZXNjcmlwdGlvbjpcbiAgICAgICAgICAgIFwiVHJpZ2dlcnMgaWYgdGhlIExhbWJkYSBmdW5jdGlvbiB0aGF0IHRyYW5zZm9ybXMgQ2xvdWRUcmFpbCBBUEkgY2FsbHMgcmVjZWl2ZWQgdGhyb3VnaCBFdmVudEJyaWRnZSBmYWlscyAoZS5nLiwgaXQgZmFpbHMgdG8gcHJvY2VzcyB0aGUgZXZlbnQpXCIsXG4gICAgICAgICAgZGF0YXBvaW50c1RvQWxhcm06IDEsXG4gICAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLklHTk9SRSxcbiAgICAgICAgfSlcbiAgICAgIGV2ZW50VHJhbnNmb3JtZXJBbGFybS5hZGRPa0FjdGlvbihwcm9wcy5pbmZyYXN0cnVjdHVyZUFsYXJtQWN0aW9uKVxuICAgICAgZXZlbnRUcmFuc2Zvcm1lckFsYXJtLmFkZEFsYXJtQWN0aW9uKHByb3BzLmluZnJhc3RydWN0dXJlQWxhcm1BY3Rpb24pXG4gICAgfVxuICAgIGlmIChwcm9wcy5kZWR1cGxpY2F0ZUV2ZW50cykge1xuICAgICAgY29uc3QgZGVkdXBsaWNhdGlvblF1ZXVlID0gbmV3IHNxcy5RdWV1ZSh0aGlzLCBcIlF1ZXVlXCIsIHtcbiAgICAgICAgLy8gV2UgZXhwbGljaXRseSBnaXZlIHRoZSBxdWV1ZSBhIG5hbWUgZHVlIHRvIGJ1ZyBodHRwczovL2dpdGh1Yi5jb20vYXdzL2F3cy1jZGsvaXNzdWVzLzU4NjBcbiAgICAgICAgcXVldWVOYW1lOlxuICAgICAgICAgIGAke3RoaXMubm9kZS5pZC5zdWJzdHJpbmcoMCwgMzMpfSR7dGhpcy5ub2RlLmFkZHJ9YC5zdWJzdHJpbmcoMCwgNzUpICtcbiAgICAgICAgICBcIi5maWZvXCIsXG4gICAgICAgIGZpZm86IHRydWUsXG4gICAgICB9KVxuICAgICAgZXZlbnRUcmFuc2Zvcm1lci5hZGRFbnZpcm9ubWVudChcbiAgICAgICAgXCJTUVNfUVVFVUVfVVJMXCIsXG4gICAgICAgIGRlZHVwbGljYXRpb25RdWV1ZS5xdWV1ZVVybCxcbiAgICAgIClcbiAgICAgIGRlZHVwbGljYXRpb25RdWV1ZS5ncmFudFNlbmRNZXNzYWdlcyhldmVudFRyYW5zZm9ybWVyKVxuICAgICAgY29uc3Qgc2xhY2tGb3J3YXJkZXIgPSBuZXcgbGFtYmRhLkZ1bmN0aW9uKHRoaXMsIFwiU2xhY2tGb3J3YXJkZXJMYW1iZGFcIiwge1xuICAgICAgICBjb2RlOiBsYW1iZGEuQ29kZS5mcm9tQXNzZXQoXG4gICAgICAgICAgcGF0aC5qb2luKFxuICAgICAgICAgICAgX19kaXJuYW1lLFxuICAgICAgICAgICAgXCIuLi8uLi9hc3NldHMvY2xvdWR0cmFpbC1zbGFjay1pbnRlZ3JhdGlvbi1sYW1iZGFcIixcbiAgICAgICAgICApLFxuICAgICAgICApLFxuICAgICAgICBkZXNjcmlwdGlvbjpcbiAgICAgICAgICBcIlBvbGxzIGZyb20gYW4gU1FTIEZJRk8gcXVldWUgY29udGFpbmluZyBmb3JtYXR0ZWQgQ2xvdWRUcmFpbCBBUEkgY2FsbHMgYW5kIHNlbmRzIHRoZW0gdG8gU2xhY2suXCIsXG4gICAgICAgIGhhbmRsZXI6IFwibWFpbi5oYW5kbGVyX3NsYWNrX2ZvcndhcmRlclwiLFxuICAgICAgICBydW50aW1lOiBsYW1iZGEuUnVudGltZS5QWVRIT05fM185LFxuICAgICAgICB0aW1lb3V0OiBjZGsuRHVyYXRpb24uc2Vjb25kcygxNSksXG4gICAgICAgIGxvZ1JldGVudGlvbjogbG9ncy5SZXRlbnRpb25EYXlzLlRXT19XRUVLUyxcbiAgICAgIH0pXG5cbiAgICAgIGlmIChwcm9wcy5pbmZyYXN0cnVjdHVyZUFsYXJtQWN0aW9uKSB7XG4gICAgICAgIGNvbnN0IHNsYWNrRm9yd2FyZGVyQWxhcm0gPSBzbGFja0ZvcndhcmRlclxuICAgICAgICAgIC5tZXRyaWNFcnJvcnMoe1xuICAgICAgICAgICAgcGVyaW9kOiBjZGsuRHVyYXRpb24ubWludXRlcyg1KSxcbiAgICAgICAgICAgIHN0YXRpc3RpYzogY2xvdWR3YXRjaC5TdGF0aXN0aWMuU1VNLFxuICAgICAgICAgIH0pXG4gICAgICAgICAgLmNyZWF0ZUFsYXJtKHRoaXMsIFwiU2xhY2tGb3J3YXJkZXJFcnJvckFsYXJtXCIsIHtcbiAgICAgICAgICAgIHRocmVzaG9sZDogMSxcbiAgICAgICAgICAgIGFsYXJtRGVzY3JpcHRpb246XG4gICAgICAgICAgICAgIFwiVHJpZ2dlcnMgaWYgdGhlIExhbWJkYSBmdW5jdGlvbiB0aGF0IHBvbGxzIGZyb20gU1FTIGFuZCBwb3N0cyBkZWR1cGxpY2F0ZWQgQ2xvdWRUcmFpbCBBUEkgY2FsbHMgcmVjZWl2ZWQgdGhyb3VnaCBFdmVudEJyaWRnZSB0byBTbGFjayBmYWlscyAoZS5nLiwgaW52YWxpZCBTbGFjayB3ZWJob29rIFVSTClcIixcbiAgICAgICAgICAgIGV2YWx1YXRpb25QZXJpb2RzOiAxLFxuICAgICAgICAgICAgZGF0YXBvaW50c1RvQWxhcm06IDEsXG4gICAgICAgICAgICB0cmVhdE1pc3NpbmdEYXRhOiBjbG91ZHdhdGNoLlRyZWF0TWlzc2luZ0RhdGEuSUdOT1JFLFxuICAgICAgICAgIH0pXG4gICAgICAgIHNsYWNrRm9yd2FyZGVyQWxhcm0uYWRkT2tBY3Rpb24ocHJvcHMuaW5mcmFzdHJ1Y3R1cmVBbGFybUFjdGlvbilcbiAgICAgICAgc2xhY2tGb3J3YXJkZXJBbGFybS5hZGRBbGFybUFjdGlvbihwcm9wcy5pbmZyYXN0cnVjdHVyZUFsYXJtQWN0aW9uKVxuICAgICAgfVxuICAgICAgc2xhY2tGb3J3YXJkZXIuYWRkRXZlbnRTb3VyY2UoXG4gICAgICAgIG5ldyBzb3VyY2VzLlNxc0V2ZW50U291cmNlKGRlZHVwbGljYXRpb25RdWV1ZSksXG4gICAgICApXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnJvbGVzVG9Nb25pdG9yICYmIHByb3BzLnJvbGVzVG9Nb25pdG9yLmxlbmd0aCA+IDApIHtcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JBc3N1bWVSb2xlXCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIkFzc3VtZVJvbGVcIl0sXG4gICAgICAgICAgICByZXF1ZXN0UGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICByb2xlQXJuOiBwcm9wcy5yb2xlc1RvTW9uaXRvcixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfVxuXG4gICAgaWYgKHByb3BzLm1vbml0b3JSb290VXNlckFjdGlvbnMgIT09IGZhbHNlKSB7XG4gICAgICAvLyBUcmlnZ2VycyB3aGVuIHRoZSByb290IHBhc3N3b3JkIGhhcyBiZWVuIGNoYW5nZWRcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclBhc3N3b3JkQ2hhbmdlXCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICB1c2VySWRlbnRpdHk6IHtcbiAgICAgICAgICAgICAgdHlwZTogW1wiUm9vdFwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIlBhc3N3b3JkVXBkYXRlZFwiXSxcbiAgICAgICAgICAgIGV2ZW50VHlwZTogW1wiQXdzQ29uc29sZVNpZ25JblwiXSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gVHJpZ2dlcnMgd2hlbiBNRkEgZm9yIHRoZSByb290IHVzZXIgaGFzIGJlZW4gc2V0IHVwXG4gICAgICBuZXcgZXZlbnRzLlJ1bGUodGhpcywgXCJSdWxlRm9yUm9vdFVzZXJNZmFDaGFuZ2VcIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIHVzZXJJZGVudGl0eToge1xuICAgICAgICAgICAgICB0eXBlOiBbXCJSb290XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiRW5hYmxlTUZBRGV2aWNlXCJdLFxuICAgICAgICAgICAgcmVxdWVzdFBhcmFtZXRlcnM6IHtcbiAgICAgICAgICAgICAgdXNlck5hbWU6IFtcIkFXUyBST09UIFVTRVJcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KVxuXG4gICAgICAvLyBUcmlnZ2VycyB3aGVuIGEgcm9vdCB1c2VyIHN1Y2Nlc2Z1bGx5IGxvZ3MgaW4gdG8gdGhlIGNvbnNvbGVcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclN1Y2Nlc3NmdWxMb2dpblwiLCB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHRhcmdldHM6IFtuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihldmVudFRyYW5zZm9ybWVyKV0sXG4gICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgdXNlcklkZW50aXR5OiB7XG4gICAgICAgICAgICAgIHR5cGU6IFtcIlJvb3RcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lOiBbXCJDb25zb2xlTG9naW5cIl0sXG4gICAgICAgICAgICBldmVudFR5cGU6IFtcIkF3c0NvbnNvbGVTaWduSW5cIl0sXG4gICAgICAgICAgICByZXNwb25zZUVsZW1lbnRzOiB7XG4gICAgICAgICAgICAgIENvbnNvbGVMb2dpbjogW1wiU3VjY2Vzc1wiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG5cbiAgICAgIC8vIFRyaWdnZXJzIGZvciBiYWQgbG9naW4gYXR0ZW1wcyBmb3Igcm9vdCB1c2VyIChlLmcuLCB3cm9uZyBwYXNzd29yZClcbiAgICAgIG5ldyBldmVudHMuUnVsZSh0aGlzLCBcIlJ1bGVGb3JSb290VXNlclVuc3VjY2Vzc2Z1bExvZ2luXCIsIHtcbiAgICAgICAgZW5hYmxlZDogdHJ1ZSxcbiAgICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkxhbWJkYUZ1bmN0aW9uKGV2ZW50VHJhbnNmb3JtZXIpXSxcbiAgICAgICAgZXZlbnRQYXR0ZXJuOiB7XG4gICAgICAgICAgZGV0YWlsOiB7XG4gICAgICAgICAgICB1c2VySWRlbnRpdHk6IHtcbiAgICAgICAgICAgICAgdHlwZTogW1wiUm9vdFwiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBldmVudE5hbWU6IFtcIkNvbnNvbGVMb2dpblwiXSxcbiAgICAgICAgICAgIGV2ZW50VHlwZTogW1wiQXdzQ29uc29sZVNpZ25JblwiXSxcbiAgICAgICAgICAgIHJlc3BvbnNlRWxlbWVudHM6IHtcbiAgICAgICAgICAgICAgQ29uc29sZUxvZ2luOiBbXCJGYWlsdXJlXCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gVHJpZ2dlcmVkIHdoZW4gcGFzc3dvcmQgcmVzZXQgaGFzIGJlZW4gcmVxdWVzdGVkXG4gICAgICBuZXcgZXZlbnRzLlJ1bGUodGhpcywgXCJSdWxlRm9yUm9vdFVzZXJQYXNzd29yZFJlY292ZXJ5UmVxdWVzdFwiLCB7XG4gICAgICAgIGVuYWJsZWQ6IHRydWUsXG4gICAgICAgIHRhcmdldHM6IFtuZXcgdGFyZ2V0cy5MYW1iZGFGdW5jdGlvbihldmVudFRyYW5zZm9ybWVyKV0sXG4gICAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICAgIGRldGFpbDoge1xuICAgICAgICAgICAgdXNlcklkZW50aXR5OiB7XG4gICAgICAgICAgICAgIHR5cGU6IFtcIlJvb3RcIl0sXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgZXZlbnROYW1lOiBbXCJQYXNzd29yZFJlY292ZXJ5UmVxdWVzdGVkXCJdLFxuICAgICAgICAgICAgZXZlbnRUeXBlOiBbXCJBd3NDb25zb2xlU2lnbkluXCJdLFxuICAgICAgICAgICAgcmVzcG9uc2VFbGVtZW50czoge1xuICAgICAgICAgICAgICBQYXNzd29yZFJlY292ZXJ5UmVxdWVzdGVkOiBbXCJTdWNjZXNzXCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSlcblxuICAgICAgLy8gVHJpZ2dlcmVkIHdoZW4gcGFzc3dvcmQgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IHJlc2V0XG4gICAgICBuZXcgZXZlbnRzLlJ1bGUodGhpcywgXCJSdWxlRm9yUm9vdFVzZXJQYXNzd29yZFJlY292ZXJ5Q29tcGxldGVcIiwge1xuICAgICAgICBlbmFibGVkOiB0cnVlLFxuICAgICAgICB0YXJnZXRzOiBbbmV3IHRhcmdldHMuTGFtYmRhRnVuY3Rpb24oZXZlbnRUcmFuc2Zvcm1lcildLFxuICAgICAgICBldmVudFBhdHRlcm46IHtcbiAgICAgICAgICBkZXRhaWw6IHtcbiAgICAgICAgICAgIHVzZXJJZGVudGl0eToge1xuICAgICAgICAgICAgICB0eXBlOiBbXCJSb290XCJdLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGV2ZW50TmFtZTogW1wiUGFzc3dvcmRSZWNvdmVyeUNvbXBsZXRlZFwiXSxcbiAgICAgICAgICAgIGV2ZW50VHlwZTogW1wiQXdzQ29uc29sZVNpZ25JblwiXSxcbiAgICAgICAgICAgIHJlc3BvbnNlRWxlbWVudHM6IHtcbiAgICAgICAgICAgICAgUGFzc3dvcmRSZWNvdmVyeUNvbXBsZXRlZDogW1wiU3VjY2Vzc1wiXSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgfSxcbiAgICAgIH0pXG4gICAgfVxuICB9XG59XG4iXX0=
@@ -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=
@@ -0,0 +1,61 @@
1
+ import * as constructs from "constructs";
2
+ import * as iam from "aws-cdk-lib/aws-iam";
3
+ import * as secretsmanager from "aws-cdk-lib/aws-secretsmanager";
4
+ import * as ssm from "aws-cdk-lib/aws-ssm";
5
+ /**
6
+ * A plain text application parameter that will be stored
7
+ * in AWS Parameter Store. Only used for non-sensitive values,
8
+ * typically those commited directly in the IaC code.
9
+ */
10
+ export interface PlainTextParameter {
11
+ key: string;
12
+ value: string;
13
+ }
14
+ /**
15
+ * An AWS Secret that should hold a JSON object.
16
+ *
17
+ * This will provide a secret that liflig-properties can read. The final
18
+ * parameter seen by the application will be the key given here and the
19
+ * keys from the secret JSON object appended.
20
+ */
21
+ export interface SecretParameter {
22
+ key: string;
23
+ secret: secretsmanager.ISecret;
24
+ }
25
+ /**
26
+ * An AWS Secret that should hold a JSON object.
27
+ *
28
+ * This will provide a secret that liflig-properties can read. The final
29
+ * parameter seen by the application will be the key given here and the
30
+ * keys from the secret JSON object appended.
31
+ */
32
+ export interface SecretByNameParameter {
33
+ key: string;
34
+ secretName: string;
35
+ }
36
+ export type Parameter = PlainTextParameter | SecretParameter | SecretByNameParameter;
37
+ export interface ConfigureParametersProps {
38
+ /**
39
+ * Prefix used for parameter names.
40
+ * Should start with '/' and end without '/'.
41
+ */
42
+ ssmPrefix: string;
43
+ parameters: Parameter[];
44
+ }
45
+ export declare class ConfigureParameters {
46
+ parameters: ssm.IParameter[];
47
+ ssmPrefix: string;
48
+ private secrets;
49
+ private configParameters;
50
+ private secretParameters;
51
+ constructor(scope: constructs.Construct, props: ConfigureParametersProps);
52
+ grantRead(grantable: iam.IGrantable & constructs.IConstruct): void;
53
+ /**
54
+ * Produce a checksum-value that can be used as a kind of
55
+ * nonce to trigger redeployment on parameter changes.
56
+ *
57
+ * Note: If the parameter references a token no change will be visible,
58
+ * and a manual redeployment might be needed.
59
+ */
60
+ get hashValue(): string;
61
+ }
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigureParameters = void 0;
4
+ const iam = require("aws-cdk-lib/aws-iam");
5
+ const secretsmanager = require("aws-cdk-lib/aws-secretsmanager");
6
+ const ssm = require("aws-cdk-lib/aws-ssm");
7
+ const cdk = require("aws-cdk-lib");
8
+ const crypto = require("crypto");
9
+ class ConfigureParameters {
10
+ constructor(scope, props) {
11
+ if (!props.ssmPrefix.startsWith("/") || props.ssmPrefix.endsWith("/")) {
12
+ throw new Error("ssmPrefix should start with '/' and end without '/'");
13
+ }
14
+ this.ssmPrefix = props.ssmPrefix;
15
+ this.configParameters = [];
16
+ this.secretParameters = [];
17
+ for (const parameter of props.parameters) {
18
+ if ("value" in parameter) {
19
+ this.configParameters.push(parameter);
20
+ }
21
+ else if ("secret" in parameter) {
22
+ this.secretParameters.push(parameter);
23
+ }
24
+ else if ("secretName" in parameter) {
25
+ this.secretParameters.push({
26
+ key: parameter.key,
27
+ secret: secretsmanager.Secret.fromSecretNameV2(scope, `SecretRef${parameter.key}`, parameter.secretName),
28
+ });
29
+ }
30
+ }
31
+ const result = [];
32
+ this.configParameters.forEach((it) => {
33
+ const param = new ssm.StringParameter(scope, `Config${it.key}`, {
34
+ stringValue: it.value,
35
+ parameterName: `${this.ssmPrefix}/config/${it.key}`,
36
+ });
37
+ result.push(param);
38
+ });
39
+ this.secretParameters.forEach((it) => {
40
+ const param = new ssm.StringParameter(scope, `Secret${it.key}`, {
41
+ stringValue: it.secret.secretArn,
42
+ parameterName: `${this.ssmPrefix}/secrets/${it.key}`,
43
+ });
44
+ result.push(param);
45
+ });
46
+ this.secrets = this.secretParameters.map((it) => it.secret);
47
+ this.parameters = result;
48
+ }
49
+ grantRead(grantable) {
50
+ grantable.grantPrincipal.addToPrincipalPolicy(new iam.PolicyStatement({
51
+ effect: iam.Effect.ALLOW,
52
+ actions: ["ssm:GetParametersByPath"],
53
+ resources: [
54
+ `arn:aws:ssm:${cdk.Stack.of(grantable).region}:${cdk.Stack.of(grantable).account}:parameter${this.ssmPrefix}/*`,
55
+ ],
56
+ }));
57
+ for (const secret of this.secrets) {
58
+ secret.grantRead(grantable);
59
+ }
60
+ }
61
+ /**
62
+ * Produce a checksum-value that can be used as a kind of
63
+ * nonce to trigger redeployment on parameter changes.
64
+ *
65
+ * Note: If the parameter references a token no change will be visible,
66
+ * and a manual redeployment might be needed.
67
+ */
68
+ get hashValue() {
69
+ const hash = crypto.createHash("sha256");
70
+ if (this.configParameters) {
71
+ this.configParameters.forEach((it) => {
72
+ hash.update("|");
73
+ hash.update(it.key);
74
+ hash.update("|");
75
+ if (!cdk.Token.isUnresolved(it.value)) {
76
+ hash.update(it.value);
77
+ }
78
+ });
79
+ }
80
+ if (this.secretParameters) {
81
+ this.secretParameters.forEach((it) => {
82
+ hash.update("|");
83
+ hash.update(it.key);
84
+ hash.update("|");
85
+ if (!cdk.Token.isUnresolved(it.secret.secretArn)) {
86
+ hash.update(it.secret.secretArn);
87
+ }
88
+ });
89
+ }
90
+ return hash.digest("hex");
91
+ }
92
+ }
93
+ exports.ConfigureParameters = ConfigureParameters;
94
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uZmlndXJlLXBhcmFtZXRlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlndXJlLXBhcmFtZXRlcnMvY29uZmlndXJlLXBhcmFtZXRlcnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsMkNBQTBDO0FBQzFDLGlFQUFnRTtBQUNoRSwyQ0FBMEM7QUFDMUMsbUNBQWtDO0FBQ2xDLGlDQUFnQztBQWtEaEMsTUFBYSxtQkFBbUI7SUFROUIsWUFBWSxLQUEyQixFQUFFLEtBQStCO1FBQ3RFLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RFLE1BQU0sSUFBSSxLQUFLLENBQUMscURBQXFELENBQUMsQ0FBQTtRQUN4RSxDQUFDO1FBRUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFBO1FBRWhDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUE7UUFDMUIsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQTtRQUUxQixLQUFLLE1BQU0sU0FBUyxJQUFJLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN6QyxJQUFJLE9BQU8sSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDekIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQTtZQUN2QyxDQUFDO2lCQUFNLElBQUksUUFBUSxJQUFJLFNBQVMsRUFBRSxDQUFDO2dCQUNqQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFBO1lBQ3ZDLENBQUM7aUJBQU0sSUFBSSxZQUFZLElBQUksU0FBUyxFQUFFLENBQUM7Z0JBQ3JDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUM7b0JBQ3pCLEdBQUcsRUFBRSxTQUFTLENBQUMsR0FBRztvQkFDbEIsTUFBTSxFQUFFLGNBQWMsQ0FBQyxNQUFNLENBQUMsZ0JBQWdCLENBQzVDLEtBQUssRUFDTCxZQUFZLFNBQVMsQ0FBQyxHQUFHLEVBQUUsRUFDM0IsU0FBUyxDQUFDLFVBQVUsQ0FDckI7aUJBQ0YsQ0FBQyxDQUFBO1lBQ0osQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLE1BQU0sR0FBcUIsRUFBRSxDQUFBO1FBRW5DLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRTtZQUNuQyxNQUFNLEtBQUssR0FBRyxJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLFNBQVMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO2dCQUM5RCxXQUFXLEVBQUUsRUFBRSxDQUFDLEtBQUs7Z0JBQ3JCLGFBQWEsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLFdBQVcsRUFBRSxDQUFDLEdBQUcsRUFBRTthQUNwRCxDQUFDLENBQUE7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3BCLENBQUMsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFO1lBQ25DLE1BQU0sS0FBSyxHQUFHLElBQUksR0FBRyxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7Z0JBQzlELFdBQVcsRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVM7Z0JBQ2hDLGFBQWEsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLFlBQVksRUFBRSxDQUFDLEdBQUcsRUFBRTthQUNyRCxDQUFDLENBQUE7WUFDRixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO1FBQ3BCLENBQUMsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUE7UUFFM0QsSUFBSSxDQUFDLFVBQVUsR0FBRyxNQUFNLENBQUE7SUFDMUIsQ0FBQztJQUVELFNBQVMsQ0FBQyxTQUFpRDtRQUN6RCxTQUFTLENBQUMsY0FBYyxDQUFDLG9CQUFvQixDQUMzQyxJQUFJLEdBQUcsQ0FBQyxlQUFlLENBQUM7WUFDdEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSztZQUN4QixPQUFPLEVBQUUsQ0FBQyx5QkFBeUIsQ0FBQztZQUNwQyxTQUFTLEVBQUU7Z0JBQ1QsZUFBZSxHQUFHLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLElBQzNDLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE9BQzFCLGFBQWEsSUFBSSxDQUFDLFNBQVMsSUFBSTthQUNoQztTQUNGLENBQUMsQ0FDSCxDQUFBO1FBRUQsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDbEMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUM3QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILElBQUksU0FBUztRQUNYLE1BQU0sSUFBSSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUE7UUFFeEMsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7Z0JBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUVoQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7b0JBQ3RDLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFBO2dCQUN2QixDQUFDO1lBQ0gsQ0FBQyxDQUFDLENBQUE7UUFDSixDQUFDO1FBRUQsSUFBSSxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztZQUMxQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7Z0JBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLElBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUNuQixJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFBO2dCQUVoQixJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO29CQUNqRCxJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUE7Z0JBQ2xDLENBQUM7WUFDSCxDQUFDLENBQUMsQ0FBQTtRQUNKLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDM0IsQ0FBQztDQUNGO0FBaEhELGtEQWdIQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNvbnN0cnVjdHMgZnJvbSBcImNvbnN0cnVjdHNcIlxuaW1wb3J0ICogYXMgaWFtIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtaWFtXCJcbmltcG9ydCAqIGFzIHNlY3JldHNtYW5hZ2VyIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc2VjcmV0c21hbmFnZXJcIlxuaW1wb3J0ICogYXMgc3NtIGZyb20gXCJhd3MtY2RrLWxpYi9hd3Mtc3NtXCJcbmltcG9ydCAqIGFzIGNkayBmcm9tIFwiYXdzLWNkay1saWJcIlxuaW1wb3J0ICogYXMgY3J5cHRvIGZyb20gXCJjcnlwdG9cIlxuXG4vKipcbiAqIEEgcGxhaW4gdGV4dCBhcHBsaWNhdGlvbiBwYXJhbWV0ZXIgdGhhdCB3aWxsIGJlIHN0b3JlZFxuICogaW4gQVdTIFBhcmFtZXRlciBTdG9yZS4gT25seSB1c2VkIGZvciBub24tc2Vuc2l0aXZlIHZhbHVlcyxcbiAqIHR5cGljYWxseSB0aG9zZSBjb21taXRlZCBkaXJlY3RseSBpbiB0aGUgSWFDIGNvZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUGxhaW5UZXh0UGFyYW1ldGVyIHtcbiAga2V5OiBzdHJpbmdcbiAgdmFsdWU6IHN0cmluZ1xufVxuXG4vKipcbiAqIEFuIEFXUyBTZWNyZXQgdGhhdCBzaG91bGQgaG9sZCBhIEpTT04gb2JqZWN0LlxuICpcbiAqIFRoaXMgd2lsbCBwcm92aWRlIGEgc2VjcmV0IHRoYXQgbGlmbGlnLXByb3BlcnRpZXMgY2FuIHJlYWQuIFRoZSBmaW5hbFxuICogcGFyYW1ldGVyIHNlZW4gYnkgdGhlIGFwcGxpY2F0aW9uIHdpbGwgYmUgdGhlIGtleSBnaXZlbiBoZXJlIGFuZCB0aGVcbiAqIGtleXMgZnJvbSB0aGUgc2VjcmV0IEpTT04gb2JqZWN0IGFwcGVuZGVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlY3JldFBhcmFtZXRlciB7XG4gIGtleTogc3RyaW5nXG4gIHNlY3JldDogc2VjcmV0c21hbmFnZXIuSVNlY3JldFxufVxuXG4vKipcbiAqIEFuIEFXUyBTZWNyZXQgdGhhdCBzaG91bGQgaG9sZCBhIEpTT04gb2JqZWN0LlxuICpcbiAqIFRoaXMgd2lsbCBwcm92aWRlIGEgc2VjcmV0IHRoYXQgbGlmbGlnLXByb3BlcnRpZXMgY2FuIHJlYWQuIFRoZSBmaW5hbFxuICogcGFyYW1ldGVyIHNlZW4gYnkgdGhlIGFwcGxpY2F0aW9uIHdpbGwgYmUgdGhlIGtleSBnaXZlbiBoZXJlIGFuZCB0aGVcbiAqIGtleXMgZnJvbSB0aGUgc2VjcmV0IEpTT04gb2JqZWN0IGFwcGVuZGVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFNlY3JldEJ5TmFtZVBhcmFtZXRlciB7XG4gIGtleTogc3RyaW5nXG4gIHNlY3JldE5hbWU6IHN0cmluZ1xufVxuXG5leHBvcnQgdHlwZSBQYXJhbWV0ZXIgPVxuICB8IFBsYWluVGV4dFBhcmFtZXRlclxuICB8IFNlY3JldFBhcmFtZXRlclxuICB8IFNlY3JldEJ5TmFtZVBhcmFtZXRlclxuXG5leHBvcnQgaW50ZXJmYWNlIENvbmZpZ3VyZVBhcmFtZXRlcnNQcm9wcyB7XG4gIC8qKlxuICAgKiBQcmVmaXggdXNlZCBmb3IgcGFyYW1ldGVyIG5hbWVzLlxuICAgKiBTaG91bGQgc3RhcnQgd2l0aCAnLycgYW5kIGVuZCB3aXRob3V0ICcvJy5cbiAgICovXG4gIHNzbVByZWZpeDogc3RyaW5nXG4gIHBhcmFtZXRlcnM6IFBhcmFtZXRlcltdXG59XG5cbmV4cG9ydCBjbGFzcyBDb25maWd1cmVQYXJhbWV0ZXJzIHtcbiAgcHVibGljIHBhcmFtZXRlcnM6IHNzbS5JUGFyYW1ldGVyW11cbiAgcHVibGljIHNzbVByZWZpeDogc3RyaW5nXG4gIHByaXZhdGUgc2VjcmV0czogc2VjcmV0c21hbmFnZXIuSVNlY3JldFtdXG5cbiAgcHJpdmF0ZSBjb25maWdQYXJhbWV0ZXJzOiBQbGFpblRleHRQYXJhbWV0ZXJbXVxuICBwcml2YXRlIHNlY3JldFBhcmFtZXRlcnM6IFNlY3JldFBhcmFtZXRlcltdXG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LCBwcm9wczogQ29uZmlndXJlUGFyYW1ldGVyc1Byb3BzKSB7XG4gICAgaWYgKCFwcm9wcy5zc21QcmVmaXguc3RhcnRzV2l0aChcIi9cIikgfHwgcHJvcHMuc3NtUHJlZml4LmVuZHNXaXRoKFwiL1wiKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwic3NtUHJlZml4IHNob3VsZCBzdGFydCB3aXRoICcvJyBhbmQgZW5kIHdpdGhvdXQgJy8nXCIpXG4gICAgfVxuXG4gICAgdGhpcy5zc21QcmVmaXggPSBwcm9wcy5zc21QcmVmaXhcblxuICAgIHRoaXMuY29uZmlnUGFyYW1ldGVycyA9IFtdXG4gICAgdGhpcy5zZWNyZXRQYXJhbWV0ZXJzID0gW11cblxuICAgIGZvciAoY29uc3QgcGFyYW1ldGVyIG9mIHByb3BzLnBhcmFtZXRlcnMpIHtcbiAgICAgIGlmIChcInZhbHVlXCIgaW4gcGFyYW1ldGVyKSB7XG4gICAgICAgIHRoaXMuY29uZmlnUGFyYW1ldGVycy5wdXNoKHBhcmFtZXRlcilcbiAgICAgIH0gZWxzZSBpZiAoXCJzZWNyZXRcIiBpbiBwYXJhbWV0ZXIpIHtcbiAgICAgICAgdGhpcy5zZWNyZXRQYXJhbWV0ZXJzLnB1c2gocGFyYW1ldGVyKVxuICAgICAgfSBlbHNlIGlmIChcInNlY3JldE5hbWVcIiBpbiBwYXJhbWV0ZXIpIHtcbiAgICAgICAgdGhpcy5zZWNyZXRQYXJhbWV0ZXJzLnB1c2goe1xuICAgICAgICAgIGtleTogcGFyYW1ldGVyLmtleSxcbiAgICAgICAgICBzZWNyZXQ6IHNlY3JldHNtYW5hZ2VyLlNlY3JldC5mcm9tU2VjcmV0TmFtZVYyKFxuICAgICAgICAgICAgc2NvcGUsXG4gICAgICAgICAgICBgU2VjcmV0UmVmJHtwYXJhbWV0ZXIua2V5fWAsXG4gICAgICAgICAgICBwYXJhbWV0ZXIuc2VjcmV0TmFtZSxcbiAgICAgICAgICApLFxuICAgICAgICB9KVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHJlc3VsdDogc3NtLklQYXJhbWV0ZXJbXSA9IFtdXG5cbiAgICB0aGlzLmNvbmZpZ1BhcmFtZXRlcnMuZm9yRWFjaCgoaXQpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtID0gbmV3IHNzbS5TdHJpbmdQYXJhbWV0ZXIoc2NvcGUsIGBDb25maWcke2l0LmtleX1gLCB7XG4gICAgICAgIHN0cmluZ1ZhbHVlOiBpdC52YWx1ZSxcbiAgICAgICAgcGFyYW1ldGVyTmFtZTogYCR7dGhpcy5zc21QcmVmaXh9L2NvbmZpZy8ke2l0LmtleX1gLFxuICAgICAgfSlcbiAgICAgIHJlc3VsdC5wdXNoKHBhcmFtKVxuICAgIH0pXG5cbiAgICB0aGlzLnNlY3JldFBhcmFtZXRlcnMuZm9yRWFjaCgoaXQpID0+IHtcbiAgICAgIGNvbnN0IHBhcmFtID0gbmV3IHNzbS5TdHJpbmdQYXJhbWV0ZXIoc2NvcGUsIGBTZWNyZXQke2l0LmtleX1gLCB7XG4gICAgICAgIHN0cmluZ1ZhbHVlOiBpdC5zZWNyZXQuc2VjcmV0QXJuLFxuICAgICAgICBwYXJhbWV0ZXJOYW1lOiBgJHt0aGlzLnNzbVByZWZpeH0vc2VjcmV0cy8ke2l0LmtleX1gLFxuICAgICAgfSlcbiAgICAgIHJlc3VsdC5wdXNoKHBhcmFtKVxuICAgIH0pXG5cbiAgICB0aGlzLnNlY3JldHMgPSB0aGlzLnNlY3JldFBhcmFtZXRlcnMubWFwKChpdCkgPT4gaXQuc2VjcmV0KVxuXG4gICAgdGhpcy5wYXJhbWV0ZXJzID0gcmVzdWx0XG4gIH1cblxuICBncmFudFJlYWQoZ3JhbnRhYmxlOiBpYW0uSUdyYW50YWJsZSAmIGNvbnN0cnVjdHMuSUNvbnN0cnVjdCk6IHZvaWQge1xuICAgIGdyYW50YWJsZS5ncmFudFByaW5jaXBhbC5hZGRUb1ByaW5jaXBhbFBvbGljeShcbiAgICAgIG5ldyBpYW0uUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgICBhY3Rpb25zOiBbXCJzc206R2V0UGFyYW1ldGVyc0J5UGF0aFwiXSxcbiAgICAgICAgcmVzb3VyY2VzOiBbXG4gICAgICAgICAgYGFybjphd3M6c3NtOiR7Y2RrLlN0YWNrLm9mKGdyYW50YWJsZSkucmVnaW9ufToke1xuICAgICAgICAgICAgY2RrLlN0YWNrLm9mKGdyYW50YWJsZSkuYWNjb3VudFxuICAgICAgICAgIH06cGFyYW1ldGVyJHt0aGlzLnNzbVByZWZpeH0vKmAsXG4gICAgICAgIF0sXG4gICAgICB9KSxcbiAgICApXG5cbiAgICBmb3IgKGNvbnN0IHNlY3JldCBvZiB0aGlzLnNlY3JldHMpIHtcbiAgICAgIHNlY3JldC5ncmFudFJlYWQoZ3JhbnRhYmxlKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQcm9kdWNlIGEgY2hlY2tzdW0tdmFsdWUgdGhhdCBjYW4gYmUgdXNlZCBhcyBhIGtpbmQgb2ZcbiAgICogbm9uY2UgdG8gdHJpZ2dlciByZWRlcGxveW1lbnQgb24gcGFyYW1ldGVyIGNoYW5nZXMuXG4gICAqXG4gICAqIE5vdGU6IElmIHRoZSBwYXJhbWV0ZXIgcmVmZXJlbmNlcyBhIHRva2VuIG5vIGNoYW5nZSB3aWxsIGJlIHZpc2libGUsXG4gICAqIGFuZCBhIG1hbnVhbCByZWRlcGxveW1lbnQgbWlnaHQgYmUgbmVlZGVkLlxuICAgKi9cbiAgZ2V0IGhhc2hWYWx1ZSgpOiBzdHJpbmcge1xuICAgIGNvbnN0IGhhc2ggPSBjcnlwdG8uY3JlYXRlSGFzaChcInNoYTI1NlwiKVxuXG4gICAgaWYgKHRoaXMuY29uZmlnUGFyYW1ldGVycykge1xuICAgICAgdGhpcy5jb25maWdQYXJhbWV0ZXJzLmZvckVhY2goKGl0KSA9PiB7XG4gICAgICAgIGhhc2gudXBkYXRlKFwifFwiKVxuICAgICAgICBoYXNoLnVwZGF0ZShpdC5rZXkpXG4gICAgICAgIGhhc2gudXBkYXRlKFwifFwiKVxuXG4gICAgICAgIGlmICghY2RrLlRva2VuLmlzVW5yZXNvbHZlZChpdC52YWx1ZSkpIHtcbiAgICAgICAgICBoYXNoLnVwZGF0ZShpdC52YWx1ZSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5zZWNyZXRQYXJhbWV0ZXJzKSB7XG4gICAgICB0aGlzLnNlY3JldFBhcmFtZXRlcnMuZm9yRWFjaCgoaXQpID0+IHtcbiAgICAgICAgaGFzaC51cGRhdGUoXCJ8XCIpXG4gICAgICAgIGhhc2gudXBkYXRlKGl0LmtleSlcbiAgICAgICAgaGFzaC51cGRhdGUoXCJ8XCIpXG5cbiAgICAgICAgaWYgKCFjZGsuVG9rZW4uaXNVbnJlc29sdmVkKGl0LnNlY3JldC5zZWNyZXRBcm4pKSB7XG4gICAgICAgICAgaGFzaC51cGRhdGUoaXQuc2VjcmV0LnNlY3JldEFybilcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICB9XG5cbiAgICByZXR1cm4gaGFzaC5kaWdlc3QoXCJoZXhcIilcbiAgfVxufVxuIl19
@@ -0,0 +1 @@
1
+ export { ConfigureParameters, ConfigureParametersProps, PlainTextParameter, SecretParameter, SecretByNameParameter, Parameter, } from "./configure-parameters";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ConfigureParameters = void 0;
4
+ var configure_parameters_1 = require("./configure-parameters");
5
+ Object.defineProperty(exports, "ConfigureParameters", { enumerable: true, get: function () { return configure_parameters_1.ConfigureParameters; } });
6
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvY29uZmlndXJlLXBhcmFtZXRlcnMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0RBTytCO0FBTjdCLDJIQUFBLG1CQUFtQixPQUFBIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IHtcbiAgQ29uZmlndXJlUGFyYW1ldGVycyxcbiAgQ29uZmlndXJlUGFyYW1ldGVyc1Byb3BzLFxuICBQbGFpblRleHRQYXJhbWV0ZXIsXG4gIFNlY3JldFBhcmFtZXRlcixcbiAgU2VjcmV0QnlOYW1lUGFyYW1ldGVyLFxuICBQYXJhbWV0ZXIsXG59IGZyb20gXCIuL2NvbmZpZ3VyZS1wYXJhbWV0ZXJzXCJcbiJdfQ==
@@ -0,0 +1,13 @@
1
+ import * as constructs from "constructs";
2
+ interface Props {
3
+ region: string;
4
+ name: string;
5
+ value: string;
6
+ }
7
+ /**
8
+ * SSM Parameter stored in another region.
9
+ */
10
+ export declare class CrossRegionSsmParameter extends constructs.Construct {
11
+ constructor(scope: constructs.Construct, id: string, props: Props);
12
+ }
13
+ export {};
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CrossRegionSsmParameter = void 0;
4
+ const constructs = require("constructs");
5
+ const cr = require("aws-cdk-lib/custom-resources");
6
+ /**
7
+ * SSM Parameter stored in another region.
8
+ */
9
+ class CrossRegionSsmParameter extends constructs.Construct {
10
+ constructor(scope, id, props) {
11
+ super(scope, id);
12
+ const physicalResourceId = cr.PhysicalResourceId.of(props.name);
13
+ // TODO: Can we somehow propagate tags as well?
14
+ new cr.AwsCustomResource(this, "Resoure", {
15
+ onUpdate: {
16
+ service: "SSM",
17
+ action: "putParameter",
18
+ parameters: {
19
+ Name: props.name,
20
+ Value: props.value,
21
+ Type: "String",
22
+ Overwrite: true,
23
+ },
24
+ region: props.region,
25
+ physicalResourceId,
26
+ },
27
+ onDelete: {
28
+ service: "SSM",
29
+ action: "deleteParameter",
30
+ parameters: {
31
+ Name: props.name,
32
+ },
33
+ region: props.region,
34
+ physicalResourceId,
35
+ },
36
+ policy: cr.AwsCustomResourcePolicy.fromSdkCalls({
37
+ // We grant the Custom Resource access to write to any
38
+ // parameter, as this is needed to be able to rename
39
+ // a parameter later.
40
+ resources: cr.AwsCustomResourcePolicy.ANY_RESOURCE,
41
+ }),
42
+ });
43
+ }
44
+ }
45
+ exports.CrossRegionSsmParameter = CrossRegionSsmParameter;
46
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3Jvc3MtcmVnaW9uLXNzbS1wYXJhbWV0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvY3Jvc3MtcmVnaW9uLXNzbS1wYXJhbWV0ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEseUNBQXdDO0FBQ3hDLG1EQUFrRDtBQVFsRDs7R0FFRztBQUNILE1BQWEsdUJBQXdCLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFDL0QsWUFBWSxLQUEyQixFQUFFLEVBQVUsRUFBRSxLQUFZO1FBQy9ELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFFaEIsTUFBTSxrQkFBa0IsR0FBRyxFQUFFLENBQUMsa0JBQWtCLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQTtRQUUvRCwrQ0FBK0M7UUFDL0MsSUFBSSxFQUFFLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLFNBQVMsRUFBRTtZQUN4QyxRQUFRLEVBQUU7Z0JBQ1IsT0FBTyxFQUFFLEtBQUs7Z0JBQ2QsTUFBTSxFQUFFLGNBQWM7Z0JBQ3RCLFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7b0JBQ2hCLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztvQkFDbEIsSUFBSSxFQUFFLFFBQVE7b0JBQ2QsU0FBUyxFQUFFLElBQUk7aUJBQ2hCO2dCQUNELE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtnQkFDcEIsa0JBQWtCO2FBQ25CO1lBQ0QsUUFBUSxFQUFFO2dCQUNSLE9BQU8sRUFBRSxLQUFLO2dCQUNkLE1BQU0sRUFBRSxpQkFBaUI7Z0JBQ3pCLFVBQVUsRUFBRTtvQkFDVixJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUk7aUJBQ2pCO2dCQUNELE1BQU0sRUFBRSxLQUFLLENBQUMsTUFBTTtnQkFDcEIsa0JBQWtCO2FBQ25CO1lBQ0QsTUFBTSxFQUFFLEVBQUUsQ0FBQyx1QkFBdUIsQ0FBQyxZQUFZLENBQUM7Z0JBQzlDLHNEQUFzRDtnQkFDdEQsb0RBQW9EO2dCQUNwRCxxQkFBcUI7Z0JBQ3JCLFNBQVMsRUFBRSxFQUFFLENBQUMsdUJBQXVCLENBQUMsWUFBWTthQUNuRCxDQUFDO1NBQ0gsQ0FBQyxDQUFBO0lBQ0osQ0FBQztDQUNGO0FBckNELDBEQXFDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNvbnN0cnVjdHMgZnJvbSBcImNvbnN0cnVjdHNcIlxuaW1wb3J0ICogYXMgY3IgZnJvbSBcImF3cy1jZGstbGliL2N1c3RvbS1yZXNvdXJjZXNcIlxuXG5pbnRlcmZhY2UgUHJvcHMge1xuICByZWdpb246IHN0cmluZ1xuICBuYW1lOiBzdHJpbmdcbiAgdmFsdWU6IHN0cmluZ1xufVxuXG4vKipcbiAqIFNTTSBQYXJhbWV0ZXIgc3RvcmVkIGluIGFub3RoZXIgcmVnaW9uLlxuICovXG5leHBvcnQgY2xhc3MgQ3Jvc3NSZWdpb25Tc21QYXJhbWV0ZXIgZXh0ZW5kcyBjb25zdHJ1Y3RzLkNvbnN0cnVjdCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFByb3BzKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKVxuXG4gICAgY29uc3QgcGh5c2ljYWxSZXNvdXJjZUlkID0gY3IuUGh5c2ljYWxSZXNvdXJjZUlkLm9mKHByb3BzLm5hbWUpXG5cbiAgICAvLyBUT0RPOiBDYW4gd2Ugc29tZWhvdyBwcm9wYWdhdGUgdGFncyBhcyB3ZWxsP1xuICAgIG5ldyBjci5Bd3NDdXN0b21SZXNvdXJjZSh0aGlzLCBcIlJlc291cmVcIiwge1xuICAgICAgb25VcGRhdGU6IHtcbiAgICAgICAgc2VydmljZTogXCJTU01cIixcbiAgICAgICAgYWN0aW9uOiBcInB1dFBhcmFtZXRlclwiLFxuICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgTmFtZTogcHJvcHMubmFtZSxcbiAgICAgICAgICBWYWx1ZTogcHJvcHMudmFsdWUsXG4gICAgICAgICAgVHlwZTogXCJTdHJpbmdcIixcbiAgICAgICAgICBPdmVyd3JpdGU6IHRydWUsXG4gICAgICAgIH0sXG4gICAgICAgIHJlZ2lvbjogcHJvcHMucmVnaW9uLFxuICAgICAgICBwaHlzaWNhbFJlc291cmNlSWQsXG4gICAgICB9LFxuICAgICAgb25EZWxldGU6IHtcbiAgICAgICAgc2VydmljZTogXCJTU01cIixcbiAgICAgICAgYWN0aW9uOiBcImRlbGV0ZVBhcmFtZXRlclwiLFxuICAgICAgICBwYXJhbWV0ZXJzOiB7XG4gICAgICAgICAgTmFtZTogcHJvcHMubmFtZSxcbiAgICAgICAgfSxcbiAgICAgICAgcmVnaW9uOiBwcm9wcy5yZWdpb24sXG4gICAgICAgIHBoeXNpY2FsUmVzb3VyY2VJZCxcbiAgICAgIH0sXG4gICAgICBwb2xpY3k6IGNyLkF3c0N1c3RvbVJlc291cmNlUG9saWN5LmZyb21TZGtDYWxscyh7XG4gICAgICAgIC8vIFdlIGdyYW50IHRoZSBDdXN0b20gUmVzb3VyY2UgYWNjZXNzIHRvIHdyaXRlIHRvIGFueVxuICAgICAgICAvLyBwYXJhbWV0ZXIsIGFzIHRoaXMgaXMgbmVlZGVkIHRvIGJlIGFibGUgdG8gcmVuYW1lXG4gICAgICAgIC8vIGEgcGFyYW1ldGVyIGxhdGVyLlxuICAgICAgICByZXNvdXJjZXM6IGNyLkF3c0N1c3RvbVJlc291cmNlUG9saWN5LkFOWV9SRVNPVVJDRSxcbiAgICAgIH0pLFxuICAgIH0pXG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,25 @@
1
+ import * as constructs from "constructs";
2
+ import * as cloudwatch from "aws-cdk-lib/aws-cloudwatch";
3
+ import * as ec2 from "aws-cdk-lib/aws-ec2";
4
+ import * as ecs from "aws-cdk-lib/aws-ecs";
5
+ import * as logs from "aws-cdk-lib/aws-logs";
6
+ export interface ClusterProps {
7
+ /**
8
+ * @default will be generated
9
+ */
10
+ clusterName?: string;
11
+ vpc: ec2.IVpc;
12
+ /**
13
+ * @default no alarms will be set up
14
+ */
15
+ alarmAction?: cloudwatch.IAlarmAction;
16
+ }
17
+ export declare class Cluster extends constructs.Construct {
18
+ readonly cluster: ecs.Cluster;
19
+ readonly clusterEventLogs: logs.LogGroup;
20
+ constructor(scope: constructs.Construct, id: string, props: ClusterProps);
21
+ /**
22
+ * Monitor high number of restarts which typically signal a failing task.
23
+ */
24
+ private addRestartFrequencyAlarm;
25
+ }
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Cluster = void 0;
4
+ const constructs = require("constructs");
5
+ const cloudwatch = require("aws-cdk-lib/aws-cloudwatch");
6
+ const ecs = require("aws-cdk-lib/aws-ecs");
7
+ const events = require("aws-cdk-lib/aws-events");
8
+ const targets = require("aws-cdk-lib/aws-events-targets");
9
+ const logs = require("aws-cdk-lib/aws-logs");
10
+ const cdk = require("aws-cdk-lib");
11
+ class Cluster extends constructs.Construct {
12
+ constructor(scope, id, props) {
13
+ super(scope, id);
14
+ this.cluster = new ecs.Cluster(this, "Resource", {
15
+ clusterName: props.clusterName,
16
+ vpc: props.vpc,
17
+ executeCommandConfiguration: {
18
+ // The default would log to the same awslogs setup as
19
+ // the tasks, which would produce different types of
20
+ // outputs in the same log group.
21
+ // We have not set up specific logging for this.
22
+ logging: ecs.ExecuteCommandLogging.NONE,
23
+ },
24
+ });
25
+ // The details in ECS console is available only for short time,
26
+ // so we store it to S3 to improve insight.
27
+ this.clusterEventLogs = new logs.LogGroup(this, "EventLogs", {
28
+ retention: logs.RetentionDays.ONE_MONTH,
29
+ removalPolicy: cdk.RemovalPolicy.DESTROY,
30
+ });
31
+ new events.Rule(this, "StateRule", {
32
+ eventPattern: {
33
+ source: ["aws.ecs"],
34
+ detail: {
35
+ clusterArn: [this.cluster.clusterArn],
36
+ },
37
+ },
38
+ targets: [new targets.CloudWatchLogGroup(this.clusterEventLogs)],
39
+ });
40
+ if (props.alarmAction) {
41
+ this.addRestartFrequencyAlarm(props.alarmAction);
42
+ }
43
+ }
44
+ /**
45
+ * Monitor high number of restarts which typically signal a failing task.
46
+ */
47
+ addRestartFrequencyAlarm(action) {
48
+ const errorMetricFilter = this.clusterEventLogs.addMetricFilter("ProvisioningErrorMetricFilter", {
49
+ filterPattern: logs.FilterPattern.all(logs.FilterPattern.stringValue("$.detail-type", "=", "ECS Task State Change"), logs.FilterPattern.stringValue("$.detail.lastStatus", "=", "PROVISIONING")),
50
+ metricName: "Provisioning",
51
+ metricNamespace: `ECS/Cluster/${this.cluster.clusterName}`,
52
+ });
53
+ const alarm = errorMetricFilter
54
+ .metric()
55
+ .with({
56
+ statistic: "Sum",
57
+ period: cdk.Duration.minutes(10),
58
+ })
59
+ .createAlarm(this, "RestartFrequencyAlarm", {
60
+ alarmDescription: `Tasks in ${this.cluster.clusterName} is frequently provisioning`,
61
+ evaluationPeriods: 1,
62
+ threshold: 25,
63
+ treatMissingData: cloudwatch.TreatMissingData.NOT_BREACHING,
64
+ });
65
+ alarm.addAlarmAction(action);
66
+ alarm.addOkAction(action);
67
+ }
68
+ }
69
+ exports.Cluster = Cluster;
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2x1c3Rlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9lY3MvY2x1c3Rlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSx5Q0FBd0M7QUFDeEMseURBQXdEO0FBRXhELDJDQUEwQztBQUMxQyxpREFBZ0Q7QUFDaEQsMERBQXlEO0FBQ3pELDZDQUE0QztBQUM1QyxtQ0FBa0M7QUFjbEMsTUFBYSxPQUFRLFNBQVEsVUFBVSxDQUFDLFNBQVM7SUFJL0MsWUFBWSxLQUEyQixFQUFFLEVBQVUsRUFBRSxLQUFtQjtRQUN0RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFBO1FBRWhCLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDL0MsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO1lBQzlCLEdBQUcsRUFBRSxLQUFLLENBQUMsR0FBRztZQUNkLDJCQUEyQixFQUFFO2dCQUMzQixxREFBcUQ7Z0JBQ3JELG9EQUFvRDtnQkFDcEQsaUNBQWlDO2dCQUNqQyxnREFBZ0Q7Z0JBQ2hELE9BQU8sRUFBRSxHQUFHLENBQUMscUJBQXFCLENBQUMsSUFBSTthQUN4QztTQUNGLENBQUMsQ0FBQTtRQUVGLCtEQUErRDtRQUMvRCwyQ0FBMkM7UUFDM0MsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFO1lBQzNELFNBQVMsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVM7WUFDdkMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxhQUFhLENBQUMsT0FBTztTQUN6QyxDQUFDLENBQUE7UUFFRixJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLFdBQVcsRUFBRTtZQUNqQyxZQUFZLEVBQUU7Z0JBQ1osTUFBTSxFQUFFLENBQUMsU0FBUyxDQUFDO2dCQUNuQixNQUFNLEVBQUU7b0JBQ04sVUFBVSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUM7aUJBQ3RDO2FBQ0Y7WUFDRCxPQUFPLEVBQUUsQ0FBQyxJQUFJLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztTQUNqRSxDQUFDLENBQUE7UUFFRixJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN0QixJQUFJLENBQUMsd0JBQXdCLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxDQUFBO1FBQ2xELENBQUM7SUFDSCxDQUFDO0lBRUQ7O09BRUc7SUFDSyx3QkFBd0IsQ0FBQyxNQUErQjtRQUM5RCxNQUFNLGlCQUFpQixHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxlQUFlLENBQzdELCtCQUErQixFQUMvQjtZQUNFLGFBQWEsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsQ0FDbkMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQzVCLGVBQWUsRUFDZixHQUFHLEVBQ0gsdUJBQXVCLENBQ3hCLEVBQ0QsSUFBSSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQzVCLHFCQUFxQixFQUNyQixHQUFHLEVBQ0gsY0FBYyxDQUNmLENBQ0Y7WUFDRCxVQUFVLEVBQUUsY0FBYztZQUMxQixlQUFlLEVBQUUsZUFBZSxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRTtTQUMzRCxDQUNGLENBQUE7UUFFRCxNQUFNLEtBQUssR0FBRyxpQkFBaUI7YUFDNUIsTUFBTSxFQUFFO2FBQ1IsSUFBSSxDQUFDO1lBQ0osU0FBUyxFQUFFLEtBQUs7WUFDaEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxRQUFRLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztTQUNqQyxDQUFDO2FBQ0QsV0FBVyxDQUFDLElBQUksRUFBRSx1QkFBdUIsRUFBRTtZQUMxQyxnQkFBZ0IsRUFBRSxZQUFZLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyw2QkFBNkI7WUFDbkYsaUJBQWlCLEVBQUUsQ0FBQztZQUNwQixTQUFTLEVBQUUsRUFBRTtZQUNiLGdCQUFnQixFQUFFLFVBQVUsQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhO1NBQzVELENBQUMsQ0FBQTtRQUVKLEtBQUssQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLENBQUE7UUFDNUIsS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQTtJQUMzQixDQUFDO0NBQ0Y7QUFqRkQsMEJBaUZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY29uc3RydWN0cyBmcm9tIFwiY29uc3RydWN0c1wiXG5pbXBvcnQgKiBhcyBjbG91ZHdhdGNoIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtY2xvdWR3YXRjaFwiXG5pbXBvcnQgKiBhcyBlYzIgZnJvbSBcImF3cy1jZGstbGliL2F3cy1lYzJcIlxuaW1wb3J0ICogYXMgZWNzIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZWNzXCJcbmltcG9ydCAqIGFzIGV2ZW50cyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWV2ZW50c1wiXG5pbXBvcnQgKiBhcyB0YXJnZXRzIGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtZXZlbnRzLXRhcmdldHNcIlxuaW1wb3J0ICogYXMgbG9ncyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxvZ3NcIlxuaW1wb3J0ICogYXMgY2RrIGZyb20gXCJhd3MtY2RrLWxpYlwiXG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2x1c3RlclByb3BzIHtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IHdpbGwgYmUgZ2VuZXJhdGVkXG4gICAqL1xuICBjbHVzdGVyTmFtZT86IHN0cmluZ1xuICB2cGM6IGVjMi5JVnBjXG4gIC8qKlxuICAgKiBAZGVmYXVsdCBubyBhbGFybXMgd2lsbCBiZSBzZXQgdXBcbiAgICovXG4gIGFsYXJtQWN0aW9uPzogY2xvdWR3YXRjaC5JQWxhcm1BY3Rpb25cbn1cblxuZXhwb3J0IGNsYXNzIENsdXN0ZXIgZXh0ZW5kcyBjb25zdHJ1Y3RzLkNvbnN0cnVjdCB7XG4gIHB1YmxpYyByZWFkb25seSBjbHVzdGVyOiBlY3MuQ2x1c3RlclxuICBwdWJsaWMgcmVhZG9ubHkgY2x1c3RlckV2ZW50TG9nczogbG9ncy5Mb2dHcm91cFxuXG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBjb25zdHJ1Y3RzLkNvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IENsdXN0ZXJQcm9wcykge1xuICAgIHN1cGVyKHNjb3BlLCBpZClcblxuICAgIHRoaXMuY2x1c3RlciA9IG5ldyBlY3MuQ2x1c3Rlcih0aGlzLCBcIlJlc291cmNlXCIsIHtcbiAgICAgIGNsdXN0ZXJOYW1lOiBwcm9wcy5jbHVzdGVyTmFtZSxcbiAgICAgIHZwYzogcHJvcHMudnBjLFxuICAgICAgZXhlY3V0ZUNvbW1hbmRDb25maWd1cmF0aW9uOiB7XG4gICAgICAgIC8vIFRoZSBkZWZhdWx0IHdvdWxkIGxvZyB0byB0aGUgc2FtZSBhd3Nsb2dzIHNldHVwIGFzXG4gICAgICAgIC8vIHRoZSB0YXNrcywgd2hpY2ggd291bGQgcHJvZHVjZSBkaWZmZXJlbnQgdHlwZXMgb2ZcbiAgICAgICAgLy8gb3V0cHV0cyBpbiB0aGUgc2FtZSBsb2cgZ3JvdXAuXG4gICAgICAgIC8vIFdlIGhhdmUgbm90IHNldCB1cCBzcGVjaWZpYyBsb2dnaW5nIGZvciB0aGlzLlxuICAgICAgICBsb2dnaW5nOiBlY3MuRXhlY3V0ZUNvbW1hbmRMb2dnaW5nLk5PTkUsXG4gICAgICB9LFxuICAgIH0pXG5cbiAgICAvLyBUaGUgZGV0YWlscyBpbiBFQ1MgY29uc29sZSBpcyBhdmFpbGFibGUgb25seSBmb3Igc2hvcnQgdGltZSxcbiAgICAvLyBzbyB3ZSBzdG9yZSBpdCB0byBTMyB0byBpbXByb3ZlIGluc2lnaHQuXG4gICAgdGhpcy5jbHVzdGVyRXZlbnRMb2dzID0gbmV3IGxvZ3MuTG9nR3JvdXAodGhpcywgXCJFdmVudExvZ3NcIiwge1xuICAgICAgcmV0ZW50aW9uOiBsb2dzLlJldGVudGlvbkRheXMuT05FX01PTlRILFxuICAgICAgcmVtb3ZhbFBvbGljeTogY2RrLlJlbW92YWxQb2xpY3kuREVTVFJPWSxcbiAgICB9KVxuXG4gICAgbmV3IGV2ZW50cy5SdWxlKHRoaXMsIFwiU3RhdGVSdWxlXCIsIHtcbiAgICAgIGV2ZW50UGF0dGVybjoge1xuICAgICAgICBzb3VyY2U6IFtcImF3cy5lY3NcIl0sXG4gICAgICAgIGRldGFpbDoge1xuICAgICAgICAgIGNsdXN0ZXJBcm46IFt0aGlzLmNsdXN0ZXIuY2x1c3RlckFybl0sXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgdGFyZ2V0czogW25ldyB0YXJnZXRzLkNsb3VkV2F0Y2hMb2dHcm91cCh0aGlzLmNsdXN0ZXJFdmVudExvZ3MpXSxcbiAgICB9KVxuXG4gICAgaWYgKHByb3BzLmFsYXJtQWN0aW9uKSB7XG4gICAgICB0aGlzLmFkZFJlc3RhcnRGcmVxdWVuY3lBbGFybShwcm9wcy5hbGFybUFjdGlvbilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTW9uaXRvciBoaWdoIG51bWJlciBvZiByZXN0YXJ0cyB3aGljaCB0eXBpY2FsbHkgc2lnbmFsIGEgZmFpbGluZyB0YXNrLlxuICAgKi9cbiAgcHJpdmF0ZSBhZGRSZXN0YXJ0RnJlcXVlbmN5QWxhcm0oYWN0aW9uOiBjbG91ZHdhdGNoLklBbGFybUFjdGlvbik6IHZvaWQge1xuICAgIGNvbnN0IGVycm9yTWV0cmljRmlsdGVyID0gdGhpcy5jbHVzdGVyRXZlbnRMb2dzLmFkZE1ldHJpY0ZpbHRlcihcbiAgICAgIFwiUHJvdmlzaW9uaW5nRXJyb3JNZXRyaWNGaWx0ZXJcIixcbiAgICAgIHtcbiAgICAgICAgZmlsdGVyUGF0dGVybjogbG9ncy5GaWx0ZXJQYXR0ZXJuLmFsbChcbiAgICAgICAgICBsb2dzLkZpbHRlclBhdHRlcm4uc3RyaW5nVmFsdWUoXG4gICAgICAgICAgICBcIiQuZGV0YWlsLXR5cGVcIixcbiAgICAgICAgICAgIFwiPVwiLFxuICAgICAgICAgICAgXCJFQ1MgVGFzayBTdGF0ZSBDaGFuZ2VcIixcbiAgICAgICAgICApLFxuICAgICAgICAgIGxvZ3MuRmlsdGVyUGF0dGVybi5zdHJpbmdWYWx1ZShcbiAgICAgICAgICAgIFwiJC5kZXRhaWwubGFzdFN0YXR1c1wiLFxuICAgICAgICAgICAgXCI9XCIsXG4gICAgICAgICAgICBcIlBST1ZJU0lPTklOR1wiLFxuICAgICAgICAgICksXG4gICAgICAgICksXG4gICAgICAgIG1ldHJpY05hbWU6IFwiUHJvdmlzaW9uaW5nXCIsXG4gICAgICAgIG1ldHJpY05hbWVzcGFjZTogYEVDUy9DbHVzdGVyLyR7dGhpcy5jbHVzdGVyLmNsdXN0ZXJOYW1lfWAsXG4gICAgICB9LFxuICAgIClcblxuICAgIGNvbnN0IGFsYXJtID0gZXJyb3JNZXRyaWNGaWx0ZXJcbiAgICAgIC5tZXRyaWMoKVxuICAgICAgLndpdGgoe1xuICAgICAgICBzdGF0aXN0aWM6IFwiU3VtXCIsXG4gICAgICAgIHBlcmlvZDogY2RrLkR1cmF0aW9uLm1pbnV0ZXMoMTApLFxuICAgICAgfSlcbiAgICAgIC5jcmVhdGVBbGFybSh0aGlzLCBcIlJlc3RhcnRGcmVxdWVuY3lBbGFybVwiLCB7XG4gICAgICAgIGFsYXJtRGVzY3JpcHRpb246IGBUYXNrcyBpbiAke3RoaXMuY2x1c3Rlci5jbHVzdGVyTmFtZX0gaXMgZnJlcXVlbnRseSBwcm92aXNpb25pbmdgLFxuICAgICAgICBldmFsdWF0aW9uUGVyaW9kczogMSxcbiAgICAgICAgdGhyZXNob2xkOiAyNSxcbiAgICAgICAgdHJlYXRNaXNzaW5nRGF0YTogY2xvdWR3YXRjaC5UcmVhdE1pc3NpbmdEYXRhLk5PVF9CUkVBQ0hJTkcsXG4gICAgICB9KVxuXG4gICAgYWxhcm0uYWRkQWxhcm1BY3Rpb24oYWN0aW9uKVxuICAgIGFsYXJtLmFkZE9rQWN0aW9uKGFjdGlvbilcbiAgfVxufVxuIl19