@liflig/cdk 3.12.1 → 3.13.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,310 @@
1
+ ## Validate using https://www.otelbin.io/#distro=adot%7E&distroVersion=v0.43.1%7E .
2
+ ##
3
+ ## Original copyright is Apache 2.0 to AWS (aws-observability on GitHub).
4
+ ## https://github.com/aws-observability/aws-otel-collector/blob/14833d4af543da709c77cf9dc6827351dbd529b1/config/ecs/container-insights/otel-task-metrics-config.yaml
5
+ ##
6
+ ## This is a modified version of `./etc/ecs/container-insights/otel-task-metrics-config.yaml`
7
+ ## where we add `resource_to_telemetry_conversion` so the otel resource `service.name`
8
+ ## can be added to the metric. This is useful because you can filter in metrics based on service,
9
+ ## instead of grouping e.g. all services' memory usage under the same metric.
10
+ ##
11
+ ## Search for `# THIS IS WHAT LIFLIG ADDED` to find our modifications.
12
+ ##
13
+ ##
14
+ ## @see https://aws-otel.github.io/docs/setup/ecs/config-through-ssm
15
+ extensions:
16
+ health_check:
17
+
18
+ ## These ports are also set in `taskDefinition.defaultContainer` as
19
+ ## `OTEL_EXPORTER_OTLP_ENDPOINT` and so on.
20
+ ## Changes must happen in both places.
21
+ receivers:
22
+ otlp:
23
+ protocols:
24
+ grpc:
25
+ endpoint: 0.0.0.0:4317
26
+ http:
27
+ endpoint: 0.0.0.0:4318
28
+ awsxray:
29
+ endpoint: 0.0.0.0:2000
30
+ transport: udp
31
+ awsecscontainermetrics:
32
+
33
+ processors:
34
+ batch/traces:
35
+ timeout: 1s
36
+ send_batch_size: 50
37
+ batch/metrics:
38
+ timeout: 60s
39
+ filter:
40
+ metrics:
41
+ include:
42
+ match_type: strict
43
+ metric_names:
44
+ - ecs.task.memory.reserved
45
+ - ecs.task.memory.utilized
46
+ - ecs.task.cpu.reserved
47
+ - ecs.task.cpu.utilized
48
+ - ecs.task.network.rate.rx
49
+ - ecs.task.network.rate.tx
50
+ - ecs.task.storage.read_bytes
51
+ - ecs.task.storage.write_bytes
52
+ - container.duration
53
+ metricstransform:
54
+ transforms:
55
+ - include: ecs.task.memory.utilized
56
+ action: update
57
+ new_name: MemoryUtilized
58
+ - include: ecs.task.memory.reserved
59
+ action: update
60
+ new_name: MemoryReserved
61
+ - include: ecs.task.cpu.utilized
62
+ action: update
63
+ new_name: CpuUtilized
64
+ - include: ecs.task.cpu.reserved
65
+ action: update
66
+ new_name: CpuReserved
67
+ - include: ecs.task.network.rate.rx
68
+ action: update
69
+ new_name: NetworkRxBytes
70
+ - include: ecs.task.network.rate.tx
71
+ action: update
72
+ new_name: NetworkTxBytes
73
+ - include: ecs.task.storage.read_bytes
74
+ action: update
75
+ new_name: StorageReadBytes
76
+ - include: ecs.task.storage.write_bytes
77
+ action: update
78
+ new_name: StorageWriteBytes
79
+ ## THIS IS WHAT LIFLIG ADDED
80
+ filter/application:
81
+ error_mode: ignore
82
+ metrics:
83
+ metric:
84
+ - 'resource.attributes["http.target"] == "/health"'
85
+ - 'resource.attributes["net.peer.name"] == "169.254.170.2"' # EC2 Metadata Endpoint
86
+ filter/traces:
87
+ error_mode: ignore
88
+ traces:
89
+ span:
90
+ - 'attributes["http.route"] == "health"'
91
+ - 'attributes["http.url"] == "/health"'
92
+ - 'name == "GET health"'
93
+ attributes/application:
94
+ actions:
95
+ # Http adds lots of high cardinality, which xray creates 1 metric per. Expensive.
96
+ - key: http.url
97
+ action: delete
98
+ - key: http.target
99
+ action: delete
100
+ - key: http.client_ip
101
+ action: delete
102
+ - key: http.response_content_length
103
+ action: delete
104
+ - key: http.request_content_length
105
+ action: delete
106
+ - key: net.host.name
107
+ action: delete
108
+ - key: net.sock.peer.addr
109
+ action: delete
110
+ - key: net.sock.peer.port
111
+ action: delete
112
+ - key: net.sock.host.addr
113
+ action: delete
114
+ - key: net.sock.host.port
115
+ action: delete
116
+ - key: user_agent.original
117
+ action: delete
118
+ resource/application:
119
+ attributes:
120
+ - key: cloud.provider
121
+ action: delete
122
+ - key: host.arch
123
+ action: delete
124
+ - key: aws.ecs.container.image.id
125
+ action: delete
126
+ - key: aws.ecs.task.arn
127
+ action: delete
128
+ - key: aws.log.stream.names
129
+ action: delete
130
+ - key: aws.log.stream.arns
131
+ action: delete
132
+ - key: cloud.platform
133
+ action: delete
134
+ - key: container.name
135
+ action: delete
136
+ - key: process.executable.path
137
+ action: delete
138
+ - key: process.runtime.version
139
+ action: delete
140
+ - key: telemetry.auto.version
141
+ action: delete
142
+ - key: telemetry.sdk.name
143
+ action: delete
144
+ - key: container.id
145
+ action: delete
146
+ - key: container.image.tag
147
+ action: delete
148
+ - key: process.runtime.name
149
+ action: delete
150
+ - key: service.namespace
151
+ action: delete
152
+ - key: telemetry.sdk.version
153
+ action: delete
154
+ - key: aws.ecs.task.family
155
+ action: delete
156
+ - key: aws.ecs.task.revision
157
+ action: delete
158
+ - key: aws.log.group.arns
159
+ action: delete
160
+ - key: container.image.name
161
+ action: delete
162
+ - key: os.description
163
+ action: delete
164
+ - key: os.type
165
+ action: delete
166
+ - key: process.runtime.description
167
+ action: delete
168
+ - key: version
169
+ action: delete
170
+ - key: aws.ecs.launchtype
171
+ action: delete
172
+ - key: aws.log.group.names
173
+ action: delete
174
+ - key: host.name
175
+ action: delete
176
+ - key: process.pid
177
+ action: delete
178
+ - key: telemetry.sdk.language
179
+ action: delete
180
+ - key: aws.ecs.container.arn
181
+ action: delete
182
+ - key: service.version
183
+ action: delete
184
+ - key: process.command_args
185
+ action: delete
186
+ - key: service
187
+ action: delete
188
+ ## END OF LIFLIG CHANGES
189
+ resource:
190
+ attributes:
191
+ - key: ClusterName
192
+ from_attribute: aws.ecs.cluster.name
193
+ action: insert
194
+ - key: aws.ecs.cluster.name
195
+ action: delete
196
+ - key: ServiceName
197
+ from_attribute: aws.ecs.service.name
198
+ action: insert
199
+ - key: aws.ecs.service.name
200
+ action: delete
201
+ ## THIS IS WHAT LIFLIG ADDED (bunch of sporadic removals)
202
+ - key: aws.ecs.task.id
203
+ action: delete
204
+ - key: TaskDefinitionFamily
205
+ from_attribute: aws.ecs.task.family
206
+ action: insert
207
+ - key: aws.ecs.task.family
208
+ action: delete
209
+ - key: aws.ecs.task.arn
210
+ action: delete
211
+ - key: aws.ecs.docker.name
212
+ action: delete
213
+ - key: aws.ecs.task.version
214
+ action: delete
215
+ - key: aws.ecs.task.pull_started_at
216
+ action: delete
217
+ - key: aws.ecs.task.pull_stopped_at
218
+ action: delete
219
+ - key: AvailabilityZone
220
+ from_attribute: cloud.zone
221
+ action: insert
222
+ - key: cloud.zone
223
+ action: delete
224
+ - key: aws.ecs.task.launch_type
225
+ action: delete
226
+ - key: Region
227
+ from_attribute: cloud.region
228
+ action: insert
229
+ - key: cloud.region
230
+ action: delete
231
+ - key: AccountId
232
+ from_attribute: cloud.account.id
233
+ action: insert
234
+ - key: cloud.account.id
235
+ action: delete
236
+ - key: container.id
237
+ action: delete
238
+ - key: container.name
239
+ action: delete
240
+ - key: container.image.name
241
+ action: delete
242
+ - key: aws.ecs.container.image.id
243
+ action: delete
244
+ - key: aws.ecs.container.exit_code
245
+ action: delete
246
+ - key: aws.ecs.container.created_at
247
+ action: delete
248
+ - key: aws.ecs.container.started_at
249
+ action: delete
250
+ - key: aws.ecs.container.finished_at
251
+ action: delete
252
+ - key: container.image.tag
253
+ action: delete
254
+ ## END OF LIFLIG CHANGES
255
+
256
+ exporters:
257
+ awsxray:
258
+ ## THIS IS WHAT LIFLIG ADDED
259
+ indexed_attributes: ["otel.resource.service.name"] # Max 50 attributes
260
+ ## END OF LIFLIG CHANGES
261
+ awsemf/application:
262
+ namespace: ECS/AWSOTel/Application
263
+ log_group_name: '/aws/ecs/application/metrics'
264
+ ## THIS IS WHAT LIFLIG ADDED
265
+ ## Config docs at https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/main/exporter/awsemfexporter/README.md
266
+ ## log retention is days to keep the emf metric logs.
267
+ log_retention: 365
268
+ resource_to_telemetry_conversion:
269
+ enabled: true
270
+ dimension_rollup_option: NoDimensionRollup
271
+ ## No rollup means we keep all the dimensions on the metric, instead of merging similar metrics to one in CloudWatch
272
+ ## END OF LIFLIG CHANGES
273
+ awsemf/performance:
274
+ namespace: ECS/ContainerInsights
275
+ log_group_name: '/aws/ecs/containerinsights/{ClusterName}/performance'
276
+ log_stream_name: '{TaskId}'
277
+ resource_to_telemetry_conversion:
278
+ enabled: true
279
+ dimension_rollup_option: NoDimensionRollup
280
+ metric_declarations:
281
+ - dimensions: [ [ ClusterName ], [ ClusterName, TaskDefinitionFamily ] ]
282
+ metric_name_selectors:
283
+ - MemoryUtilized
284
+ - MemoryReserved
285
+ - CpuUtilized
286
+ - CpuReserved
287
+ - NetworkRxBytes
288
+ - NetworkTxBytes
289
+ - StorageReadBytes
290
+ - StorageWriteBytes
291
+ - metric_name_selectors: [container.*]
292
+
293
+ service:
294
+ pipelines:
295
+ traces:
296
+ receivers: [otlp,awsxray]
297
+ ## THIS IS WHAT LIFLIG ADDED
298
+ processors: [filter/traces, batch/traces]
299
+ exporters: [awsxray]
300
+ metrics/application:
301
+ receivers: [otlp]
302
+ processors: [filter/application, resource/application, attributes/application, batch/metrics]
303
+ exporters: [awsemf/application]
304
+ ## END OF LIFLIG CHANGES
305
+ metrics/performance:
306
+ receivers: [awsecscontainermetrics ]
307
+ processors: [filter, metricstransform, resource]
308
+ exporters: [ awsemf/performance ]
309
+
310
+ extensions: [health_check]
@@ -1,6 +1,8 @@
1
1
  export { Cluster } from "./cluster";
2
2
  export { FargateService } from "./fargate-service";
3
3
  export { ListenerRule } from "./listener-rule";
4
+ export { OpenTelemetryCollectors } from "./open-telemetry";
4
5
  export type { ClusterProps } from "./cluster";
5
6
  export type { FargateServiceProps } from "./fargate-service";
6
7
  export type { ListenerRuleProps } from "./listener-rule";
8
+ export type { OpenTelemetryCollectorsProps } from "./open-telemetry";
package/lib/ecs/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { Cluster } from "./cluster";
2
2
  export { FargateService } from "./fargate-service";
3
3
  export { ListenerRule } from "./listener-rule";
4
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZWNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDbkMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IENsdXN0ZXIgfSBmcm9tIFwiLi9jbHVzdGVyXCJcbmV4cG9ydCB7IEZhcmdhdGVTZXJ2aWNlIH0gZnJvbSBcIi4vZmFyZ2F0ZS1zZXJ2aWNlXCJcbmV4cG9ydCB7IExpc3RlbmVyUnVsZSB9IGZyb20gXCIuL2xpc3RlbmVyLXJ1bGVcIlxuZXhwb3J0IHR5cGUgeyBDbHVzdGVyUHJvcHMgfSBmcm9tIFwiLi9jbHVzdGVyXCJcbmV4cG9ydCB0eXBlIHsgRmFyZ2F0ZVNlcnZpY2VQcm9wcyB9IGZyb20gXCIuL2ZhcmdhdGUtc2VydmljZVwiXG5leHBvcnQgdHlwZSB7IExpc3RlbmVyUnVsZVByb3BzIH0gZnJvbSBcIi4vbGlzdGVuZXItcnVsZVwiXG4iXX0=
4
+ export { OpenTelemetryCollectors } from "./open-telemetry";
5
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZWNzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxXQUFXLENBQUE7QUFDbkMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFBO0FBQ2xELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQTtBQUM5QyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQSIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IENsdXN0ZXIgfSBmcm9tIFwiLi9jbHVzdGVyXCJcbmV4cG9ydCB7IEZhcmdhdGVTZXJ2aWNlIH0gZnJvbSBcIi4vZmFyZ2F0ZS1zZXJ2aWNlXCJcbmV4cG9ydCB7IExpc3RlbmVyUnVsZSB9IGZyb20gXCIuL2xpc3RlbmVyLXJ1bGVcIlxuZXhwb3J0IHsgT3BlblRlbGVtZXRyeUNvbGxlY3RvcnMgfSBmcm9tIFwiLi9vcGVuLXRlbGVtZXRyeVwiXG5leHBvcnQgdHlwZSB7IENsdXN0ZXJQcm9wcyB9IGZyb20gXCIuL2NsdXN0ZXJcIlxuZXhwb3J0IHR5cGUgeyBGYXJnYXRlU2VydmljZVByb3BzIH0gZnJvbSBcIi4vZmFyZ2F0ZS1zZXJ2aWNlXCJcbmV4cG9ydCB0eXBlIHsgTGlzdGVuZXJSdWxlUHJvcHMgfSBmcm9tIFwiLi9saXN0ZW5lci1ydWxlXCJcbmV4cG9ydCB0eXBlIHsgT3BlblRlbGVtZXRyeUNvbGxlY3RvcnNQcm9wcyB9IGZyb20gXCIuL29wZW4tdGVsZW1ldHJ5XCJcbiJdfQ==
@@ -0,0 +1,98 @@
1
+ import * as constructs from "constructs";
2
+ import * as ecs from "aws-cdk-lib/aws-ecs";
3
+ import { RetentionDays } from "aws-cdk-lib/aws-logs";
4
+ import { FargateService } from "./fargate-service";
5
+ export interface OpenTelemetryCollectorsProps {
6
+ service: FargateService;
7
+ /** @default 6 months **/
8
+ logRetention?: RetentionDays;
9
+ /** @default "amazon/aws-otel-collector:v0.43.1" */
10
+ dockerImage?: string;
11
+ /** Should be kept as `undefined` unless you know what you are doing.
12
+ * This is the YAML config for the OpenTelemetry collector sidecar.
13
+ *
14
+ * An example of a config can be found at https://github.com/aws-observability/aws-otel-collector/blob/0ae198c7e7b8c43bcc8715f54e52c879c04407b6/config/ecs/container-insights/otel-task-metrics-config.yaml
15
+ *
16
+ * @default a file in `assets` tuned to work for aws and strips known high-cardinality metrics (like those containing IP addresses and ports)
17
+ */
18
+ awsOtelConfig?: string;
19
+ /** Overrides for the sidecar container.
20
+ * You do not need to specify this.
21
+ *
22
+ * Defaults:
23
+ * - cpu: 32 units
24
+ * - memory reservation: 24 MiB
25
+ * - memory limit: 256 MiB
26
+ */
27
+ containerProps?: SidecarContainerProps;
28
+ }
29
+ /**
30
+ * Methods to enable collection of Open Telemetry (otel) data of a {@link FargateService}
31
+ * using a docker container with an otel agent.
32
+ *
33
+ *
34
+ * An example of a Java auto-instrumentation agent in Docker can be found
35
+ * [in liflig-rest-baseline Dockerfile](https://github.com/capralifecycle/liflig-rest-service-baseline/blob/a29b5a472c982aa7ce04d09d0e7cfdc92a6cc977/docker/Dockerfile#L9-L29).
36
+ *
37
+ * The agent must be configured to output metrics to a collector.
38
+ * That collector is what this construct provides.
39
+ * Usually, the agent is specified in the Dockerfile or as a dependency/library,
40
+ * and configured in the Dockerfile or in the application source code.
41
+ *
42
+ * Use this construct on a {@link FargateService} by constructing a new instance of {@link OpenTelemetryCollectors}
43
+ * and calling the {@link addOpenTelemetryCollectorSidecar} method on it.
44
+ *
45
+ * ```ts
46
+ * const service = FargateService(...);
47
+ *
48
+ * new OpenTelemetryCollectors(this, "OtelSidecar").addOpenTelemetryCollectorSidecar(service)
49
+ * ```
50
+ *
51
+ * The sidecar exposes these ports to your service:
52
+ * - udp 2000 : AWS XRay
53
+ * - tcp 4317 : OpenTelemetry collection GRPC
54
+ * - tcp 4318 : OpenTelemetry collection HTTP
55
+ *
56
+ * ---
57
+ *
58
+ * You can also disable the OpenTelemetry instrumentation agent
59
+ * for Java-based services,
60
+ * by setting the appropriate environment variable with {@link disableOpenTelemetryJavaAgent}:
61
+ * ```ts
62
+ * const service = FargateService(...);
63
+ *
64
+ * OpenTelemetryCollectors.disableOpenTelemetryJavaAgent(service)
65
+ * ```
66
+ *
67
+ * @see OpenTelemetryCollectors.addOpenTelemetryCollectorSidecar
68
+ */
69
+ export declare class OpenTelemetryCollectors extends constructs.Construct {
70
+ private readonly props;
71
+ constructor(scope: constructs.Construct, id: string, props: OpenTelemetryCollectorsProps);
72
+ /**
73
+ * The OpenTelemetry Java agent may run by default in the Docker image.
74
+ * This method will tell the agent to disable itself.
75
+ *
76
+ * You might want to do this to avoid overhead or error logs from failed
77
+ * connection attempts to the otel collector.
78
+ */
79
+ disableOpenTelemetryJavaAgent(): void;
80
+ /**
81
+ * The OpenTelemetry Java agent may run by default in the Docker image.
82
+ * This method will tell the agent to disable itself.
83
+ *
84
+ * You might want to do this to avoid overhead or error logs from failed
85
+ * connection attempts to the otel collector.
86
+ * @param service
87
+ */
88
+ static disableOpenTelemetryJavaAgent(service: FargateService): void;
89
+ /**
90
+ * Adds a sidecar with an AWS Distro OpenTelemetry Collector.
91
+ * https://aws-otel.github.io/docs/setup/ecs
92
+ *
93
+ * You also need to add either the Java SDK for OTel or a Java agent,
94
+ * to capture telemetry and send to this collector.
95
+ */
96
+ addOpenTelemetryCollectorSidecar(): void;
97
+ }
98
+ export type SidecarContainerProps = Pick<ecs.ContainerDefinitionProps, "cpu" | "memoryReservationMiB" | "memoryLimitMiB">;
@@ -0,0 +1,211 @@
1
+ import * as constructs from "constructs";
2
+ import * as ecs from "aws-cdk-lib/aws-ecs";
3
+ import * as iam from "aws-cdk-lib/aws-iam";
4
+ import * as logs from "aws-cdk-lib/aws-logs";
5
+ import { RetentionDays } from "aws-cdk-lib/aws-logs";
6
+ import { RemovalPolicy } from "aws-cdk-lib";
7
+ import { readFileSync } from "fs";
8
+ import { fileURLToPath } from "url";
9
+ import * as path from "path";
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+ /**
13
+ * Methods to enable collection of Open Telemetry (otel) data of a {@link FargateService}
14
+ * using a docker container with an otel agent.
15
+ *
16
+ *
17
+ * An example of a Java auto-instrumentation agent in Docker can be found
18
+ * [in liflig-rest-baseline Dockerfile](https://github.com/capralifecycle/liflig-rest-service-baseline/blob/a29b5a472c982aa7ce04d09d0e7cfdc92a6cc977/docker/Dockerfile#L9-L29).
19
+ *
20
+ * The agent must be configured to output metrics to a collector.
21
+ * That collector is what this construct provides.
22
+ * Usually, the agent is specified in the Dockerfile or as a dependency/library,
23
+ * and configured in the Dockerfile or in the application source code.
24
+ *
25
+ * Use this construct on a {@link FargateService} by constructing a new instance of {@link OpenTelemetryCollectors}
26
+ * and calling the {@link addOpenTelemetryCollectorSidecar} method on it.
27
+ *
28
+ * ```ts
29
+ * const service = FargateService(...);
30
+ *
31
+ * new OpenTelemetryCollectors(this, "OtelSidecar").addOpenTelemetryCollectorSidecar(service)
32
+ * ```
33
+ *
34
+ * The sidecar exposes these ports to your service:
35
+ * - udp 2000 : AWS XRay
36
+ * - tcp 4317 : OpenTelemetry collection GRPC
37
+ * - tcp 4318 : OpenTelemetry collection HTTP
38
+ *
39
+ * ---
40
+ *
41
+ * You can also disable the OpenTelemetry instrumentation agent
42
+ * for Java-based services,
43
+ * by setting the appropriate environment variable with {@link disableOpenTelemetryJavaAgent}:
44
+ * ```ts
45
+ * const service = FargateService(...);
46
+ *
47
+ * OpenTelemetryCollectors.disableOpenTelemetryJavaAgent(service)
48
+ * ```
49
+ *
50
+ * @see OpenTelemetryCollectors.addOpenTelemetryCollectorSidecar
51
+ */
52
+ export class OpenTelemetryCollectors extends constructs.Construct {
53
+ props;
54
+ constructor(scope, id, props) {
55
+ super(scope, id);
56
+ this.props = props;
57
+ }
58
+ /**
59
+ * The OpenTelemetry Java agent may run by default in the Docker image.
60
+ * This method will tell the agent to disable itself.
61
+ *
62
+ * You might want to do this to avoid overhead or error logs from failed
63
+ * connection attempts to the otel collector.
64
+ */
65
+ disableOpenTelemetryJavaAgent() {
66
+ OpenTelemetryCollectors.disableOpenTelemetryJavaAgent(this.props.service);
67
+ }
68
+ /**
69
+ * The OpenTelemetry Java agent may run by default in the Docker image.
70
+ * This method will tell the agent to disable itself.
71
+ *
72
+ * You might want to do this to avoid overhead or error logs from failed
73
+ * connection attempts to the otel collector.
74
+ * @param service
75
+ */
76
+ static disableOpenTelemetryJavaAgent(service) {
77
+ service.taskDefinition.defaultContainer?.addEnvironment("OTEL_JAVAAGENT_ENABLED", "false");
78
+ }
79
+ /**
80
+ * Adds a sidecar with an AWS Distro OpenTelemetry Collector.
81
+ * https://aws-otel.github.io/docs/setup/ecs
82
+ *
83
+ * You also need to add either the Java SDK for OTel or a Java agent,
84
+ * to capture telemetry and send to this collector.
85
+ */
86
+ addOpenTelemetryCollectorSidecar() {
87
+ new OpenTelemetryPolicies(this, "OpenTelemetryPolicies", {
88
+ taskDefinition: this.props.service.taskDefinition,
89
+ });
90
+ this.props.service.taskDefinition.addExtension(new OpenTelemetryCollectorSidecar(this, this.props.logRetention, this.props.dockerImage, this.props.awsOtelConfig, this.props.containerProps));
91
+ }
92
+ }
93
+ /**
94
+ * Adds a sidecar with an AWS Distro OpenTelemetry Collector.
95
+ * https://aws-otel.github.io/docs/setup/ecs
96
+ *
97
+ * You also need to add either the Java SDK for OTel or a Java agent,
98
+ * to capture telemetry and send to this collector.
99
+ */
100
+ class OpenTelemetryCollectorSidecar {
101
+ construct;
102
+ logRetention;
103
+ dockerImage;
104
+ awsOtelConfig;
105
+ containerProps;
106
+ constructor(construct, logRetention, dockerImage, awsOtelConfig, containerProps) {
107
+ this.construct = construct;
108
+ this.logRetention = logRetention;
109
+ this.dockerImage = dockerImage;
110
+ this.awsOtelConfig = awsOtelConfig;
111
+ this.containerProps = containerProps;
112
+ }
113
+ extend(taskDefinition) {
114
+ if (taskDefinition.networkMode !== ecs.NetworkMode.AWS_VPC) {
115
+ throw new Error("Task NetworkMode must be AWS_VPC: " + taskDefinition.networkMode);
116
+ }
117
+ const commands = {
118
+ metricsAndTraces: "--config=/etc/ecs/ecs-default-config.yaml",
119
+ metricsAndTracesAndContainerResources: "--config=/etc/ecs/container-insights/otel-task-metrics-config.yaml",
120
+ };
121
+ const logGroup = new logs.LogGroup(this.construct, "CollectorLogGroup", {
122
+ retention: this.logRetention ?? RetentionDays.SIX_MONTHS,
123
+ removalPolicy: RemovalPolicy.DESTROY,
124
+ });
125
+ const sidecarImage = this.dockerImage ?? "amazon/aws-otel-collector:v0.43.1";
126
+ const sidecar = taskDefinition.addContainer("aws-opentelemetry-collector", {
127
+ cpu: this.containerProps?.cpu ?? 32,
128
+ memoryReservationMiB: this.containerProps?.memoryReservationMiB ?? 24,
129
+ memoryLimitMiB: this.containerProps?.memoryLimitMiB ?? 256,
130
+ image: ecs.ContainerImage.fromRegistry(sidecarImage),
131
+ command: [commands.metricsAndTracesAndContainerResources], // This is not used when the AOT_CONFIG_CONTENT is set!
132
+ environment: {
133
+ // You can alternatively create an SSM parameter with the config, and pass it to the `secrets` option
134
+ AOT_CONFIG_CONTENT: this.awsOtelConfig ?? awsOtelCustomConfigYaml,
135
+ },
136
+ logging: ecs.LogDrivers.awsLogs({
137
+ logGroup: logGroup,
138
+ streamPrefix: "ecs",
139
+ }),
140
+ });
141
+ // A dependency should be added to all containers that export metrics.
142
+ // We are currently assuming that this is only the default container
143
+ taskDefinition.defaultContainer?.addContainerDependencies({
144
+ container: sidecar,
145
+ condition: ecs.ContainerDependencyCondition.START,
146
+ });
147
+ /*
148
+ * aws-otel-collector exposes these ports, and more:
149
+ * - udp 2000 : AWS XRay
150
+ * - tcp 4317 : OpenTelemetry collection GRPC
151
+ * - tcp 4318 : OpenTelemetry collection HTTP
152
+ *
153
+ * These are defined in the yaml config for the collector.
154
+ */
155
+ taskDefinition.defaultContainer?.addEnvironment("AWS_XRAY_DAEMON_ADDRESS", "http://localhost:2000");
156
+ taskDefinition.defaultContainer?.addEnvironment("OTEL_EXPORTER_OTLP_ENDPOINT", "http://localhost:4317");
157
+ taskDefinition.defaultContainer?.addEnvironment("OTEL_JAVAAGENT_ENABLED", "true");
158
+ if (!taskDefinition.isFargateCompatible) {
159
+ // This extension is made for the FargateService, so this is a requirement.
160
+ throw new Error("This task definition can not be ran on fargate! " +
161
+ taskDefinition.node.id);
162
+ }
163
+ }
164
+ }
165
+ /**
166
+ * Grants the sidecar permissions to create logs, metrics and XRay traces by extending the task roles.
167
+ */
168
+ class OpenTelemetryPolicies extends constructs.Construct {
169
+ constructor(scope, id, props) {
170
+ super(scope, id);
171
+ const awsDistroOpenTelemetryPolicyStatement = new iam.PolicyStatement({
172
+ effect: iam.Effect.ALLOW,
173
+ resources: ["*"],
174
+ actions: [
175
+ "logs:PutLogEvents",
176
+ "logs:CreateLogGroup",
177
+ "logs:CreateLogStream",
178
+ "logs:DescribeLogStreams",
179
+ "logs:DescribeLogGroups",
180
+ "logs:PutRetentionPolicy",
181
+ "xray:PutTraceSegments",
182
+ "xray:PutTelemetryRecords",
183
+ "xray:GetSamplingRules",
184
+ "xray:GetSamplingTargets",
185
+ "xray:GetSamplingStatisticSummaries",
186
+ "cloudwatch:PutMetricData",
187
+ "ec2:DescribeVolumes",
188
+ "ec2:DescribeTags",
189
+ "ssm:GetParameters",
190
+ ],
191
+ });
192
+ props.taskDefinition.addToTaskRolePolicy(awsDistroOpenTelemetryPolicyStatement);
193
+ props.taskDefinition.addToExecutionRolePolicy(awsDistroOpenTelemetryPolicyStatement);
194
+ props.taskDefinition.executionRole?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("CloudWatchLogsFullAccess"));
195
+ props.taskDefinition.executionRole?.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName("AmazonSSMReadOnlyAccess"));
196
+ }
197
+ }
198
+ /**
199
+ * This is a modified version of `./etc/ecs/container-insights/otel-task-metrics-config.yaml`
200
+ * where we add `resource_to_telemetry_conversion` so the otel resource `service.name`
201
+ * can be added to the metric. This is useful because you can filter in metrics based on service,
202
+ * instead of grouping e.g. all services' memory usage under the same metric.
203
+ *
204
+ * @see https://aws-otel.github.io/docs/setup/ecs/config-through-ssm
205
+ * @see https://aws-otel.github.io/docs/getting-started/cloudwatch-metrics#cloudwatch-emf-exporter-awsemf
206
+ */
207
+ const awsOtelCustomConfigYaml = readFileSync(path.resolve(__dirname, "..", "..", "assets", "open-telemetry", "otel-collector-task-metrics-config.yaml"), "utf-8")
208
+ .split("\n")
209
+ .filter((line) => !/^\s*##/.test(line)) // Skip comments starting with ##
210
+ .join("\n");
211
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3Blbi10ZWxlbWV0cnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZWNzL29wZW4tdGVsZW1ldHJ5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxVQUFVLE1BQU0sWUFBWSxDQUFBO0FBQ3hDLE9BQU8sS0FBSyxHQUFHLE1BQU0scUJBQXFCLENBQUE7QUFDMUMsT0FBTyxLQUFLLEdBQUcsTUFBTSxxQkFBcUIsQ0FBQTtBQUMxQyxPQUFPLEtBQUssSUFBSSxNQUFNLHNCQUFzQixDQUFBO0FBQzVDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQTtBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sYUFBYSxDQUFBO0FBRTNDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxJQUFJLENBQUE7QUFDakMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLEtBQUssQ0FBQTtBQUNuQyxPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQTtBQUU1QixNQUFNLFVBQVUsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQTtBQUNqRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFBO0FBK0IxQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBdUNHO0FBQ0gsTUFBTSxPQUFPLHVCQUF3QixTQUFRLFVBQVUsQ0FBQyxTQUFTO0lBSTVDO0lBSG5CLFlBQ0UsS0FBMkIsRUFDM0IsRUFBVSxFQUNPLEtBQW1DO1FBRXBELEtBQUssQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLENBQUE7UUFGQyxVQUFLLEdBQUwsS0FBSyxDQUE4QjtJQUd0RCxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ksNkJBQTZCO1FBQ2xDLHVCQUF1QixDQUFDLDZCQUE2QixDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFD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QkFBeUI7Z0JBQ3pCLG9DQUFvQztnQkFDcEMsMEJBQTBCO2dCQUMxQixxQkFBcUI7Z0JBQ3JCLGtCQUFrQjtnQkFDbEIsbUJBQW1CO2FBQ3BCO1NBQ0YsQ0FBQyxDQUFBO1FBRUYsS0FBSyxDQUFDLGNBQWMsQ0FBQyxtQkFBbUIsQ0FDdEMscUNBQXFDLENBQ3RDLENBQUE7UUFFRCxLQUFLLENBQUMsY0FBYyxDQUFDLHdCQUF3QixDQUMzQyxxQ0FBcUMsQ0FDdEMsQ0FBQTtRQUNELEtBQUssQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFLGdCQUFnQixDQUNsRCxHQUFHLENBQUMsYUFBYSxDQUFDLHdCQUF3QixDQUFDLDBCQUEwQixDQUFDLENBQ3ZFLENBQUE7UUFDRCxLQUFLLENBQUMsY0FBYyxDQUFDLGFBQWEsRUFBRSxnQkFBZ0IsQ0FDbEQsR0FBRyxDQUFDLGFBQWEsQ0FBQyx3QkFBd0IsQ0FBQyx5QkFBeUIsQ0FBQyxDQUN0RSxDQUFBO0lBQ0gsQ0FBQztDQUNGO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLHVCQUF1QixHQUFHLFlBQVksQ0FDMUMsSUFBSSxDQUFDLE9BQU8sQ0FDVixTQUFTLEVBQ1QsSUFBSSxFQUNKLElBQUksRUFDSixRQUFRLEVBQ1IsZ0JBQWdCLEVBQ2hCLHlDQUF5QyxDQUMxQyxFQUNELE9BQU8sQ0FDUjtLQUNFLEtBQUssQ0FBQyxJQUFJLENBQUM7S0FDWCxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLGlDQUFpQztLQUN4RSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjb25zdHJ1Y3RzIGZyb20gXCJjb25zdHJ1Y3RzXCJcbmltcG9ydCAqIGFzIGVjcyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWVjc1wiXG5pbXBvcnQgKiBhcyBpYW0gZnJvbSBcImF3cy1jZGstbGliL2F3cy1pYW1cIlxuaW1wb3J0ICogYXMgbG9ncyBmcm9tIFwiYXdzLWNkay1saWIvYXdzLWxvZ3NcIlxuaW1wb3J0IHsgUmV0ZW50aW9uRGF5cyB9IGZyb20gXCJhd3MtY2RrLWxpYi9hd3MtbG9nc1wiXG5pbXBvcnQgeyBSZW1vdmFsUG9saWN5IH0gZnJvbSBcImF3cy1jZGstbGliXCJcbmltcG9ydCB7IEZhcmdhdGVTZXJ2aWNlIH0gZnJvbSBcIi4vZmFyZ2F0ZS1zZXJ2aWNlXCJcbmltcG9ydCB7IHJlYWRGaWxlU3luYyB9IGZyb20gXCJmc1wiXG5pbXBvcnQgeyBmaWxlVVJMVG9QYXRoIH0gZnJvbSBcInVybFwiXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCJcblxuY29uc3QgX19maWxlbmFtZSA9IGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKVxuY29uc3QgX19kaXJuYW1lID0gcGF0aC5kaXJuYW1lKF9fZmlsZW5hbWUpXG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlblRlbGVtZXRyeUNvbGxlY3RvcnNQcm9wcyB7XG4gIHNlcnZpY2U6IEZhcmdhdGVTZXJ2aWNlXG5cbiAgLyoqIEBkZWZhdWx0IDYgbW9udGhzICoqL1xuICBsb2dSZXRlbnRpb24/OiBSZXRlbnRpb25EYXlzXG5cbiAgLyoqIEBkZWZhdWx0IFwiYW1hem9uL2F3cy1vdGVsLWNvbGxlY3Rvcjp2MC40My4xXCIgKi9cbiAgZG9ja2VySW1hZ2U/OiBzdHJpbmdcblxuICAvKiogU2hvdWxkIGJlIGtlcHQgYXMgYHVuZGVmaW5lZGAgdW5sZXNzIHlvdSBrbm93IHdoYXQgeW91IGFyZSBkb2luZy5cbiAgICogVGhpcyBpcyB0aGUgWUFNTCBjb25maWcgZm9yIHRoZSBPcGVuVGVsZW1ldHJ5IGNvbGxlY3RvciBzaWRlY2FyLlxuICAgKlxuICAgKiBBbiBleGFtcGxlIG9mIGEgY29uZmlnIGNhbiBiZSBmb3VuZCBhdCBodHRwczovL2dpdGh1Yi5jb20vYXdzLW9ic2VydmFiaWxpdHkvYXdzLW90ZWwtY29sbGVjdG9yL2Jsb2IvMGFlMTk4YzdlN2I4YzQzYmNjODcxNWY1NGU1MmM4NzljMDQ0MDdiNi9jb25maWcvZWNzL2NvbnRhaW5lci1pbnNpZ2h0cy9vdGVsLXRhc2stbWV0cmljcy1jb25maWcueWFtbFxuICAgKlxuICAgKiBAZGVmYXVsdCBhIGZpbGUgaW4gYGFzc2V0c2AgdHVuZWQgdG8gd29yayBmb3IgYXdzIGFuZCBzdHJpcHMga25vd24gaGlnaC1jYXJkaW5hbGl0eSBtZXRyaWNzIChsaWtlIHRob3NlIGNvbnRhaW5pbmcgSVAgYWRkcmVzc2VzIGFuZCBwb3J0cylcbiAgICovXG4gIGF3c090ZWxDb25maWc/OiBzdHJpbmdcblxuICAvKiogT3ZlcnJpZGVzIGZvciB0aGUgc2lkZWNhciBjb250YWluZXIuXG4gICAqIFlvdSBkbyBub3QgbmVlZCB0byBzcGVjaWZ5IHRoaXMuXG4gICAqXG4gICAqIERlZmF1bHRzOlxuICAgKiAtIGNwdTogMzIgdW5pdHNcbiAgICogLSBtZW1vcnkgcmVzZXJ2YXRpb246IDI0IE1pQlxuICAgKiAtIG1lbW9yeSBsaW1pdDogMjU2IE1pQlxuICAgKi9cbiAgY29udGFpbmVyUHJvcHM/OiBTaWRlY2FyQ29udGFpbmVyUHJvcHNcbn1cblxuLyoqXG4gKiBNZXRob2RzIHRvIGVuYWJsZSBjb2xsZWN0aW9uIG9mIE9wZW4gVGVsZW1ldHJ5IChvdGVsKSBkYXRhIG9mIGEge0BsaW5rIEZhcmdhdGVTZXJ2aWNlfVxuICogdXNpbmcgYSBkb2NrZXIgY29udGFpbmVyIHdpdGggYW4gb3RlbCBhZ2VudC5cbiAqXG4gKlxuICogQW4gZXhhbXBsZSBvZiBhIEphdmEgYXV0by1pbnN0cnVtZW50YXRpb24gYWdlbnQgaW4gRG9ja2VyIGNhbiBiZSBmb3VuZFxuICogW2luIGxpZmxpZy1yZXN0LWJhc2VsaW5lIERvY2tlcmZpbGVdKGh0dHBzOi8vZ2l0aHViLmNvbS9jYXByYWxpZmVjeWNsZS9saWZsaWctcmVzdC1zZXJ2aWNlLWJhc2VsaW5lL2Jsb2IvYTI5YjVhNDcyYzk4MmFhN2NlMDRkMDlkMGU3Y2ZkYzkyYTZjYzk3Ny9kb2NrZXIvRG9ja2VyZmlsZSNMOS1MMjkpLlxuICpcbiAqIFRoZSBhZ2VudCBtdXN0IGJlIGNvbmZpZ3VyZWQgdG8gb3V0cHV0IG1ldHJpY3MgdG8gYSBjb2xsZWN0b3IuXG4gKiBUaGF0IGNvbGxlY3RvciBpcyB3aGF0IHRoaXMgY29uc3RydWN0IHByb3ZpZGVzLlxuICogVXN1YWxseSwgdGhlIGFnZW50IGlzIHNwZWNpZmllZCBpbiB0aGUgRG9ja2VyZmlsZSBvciBhcyBhIGRlcGVuZGVuY3kvbGlicmFyeSxcbiAqIGFuZCBjb25maWd1cmVkIGluIHRoZSBEb2NrZXJmaWxlIG9yIGluIHRoZSBhcHBsaWNhdGlvbiBzb3VyY2UgY29kZS5cbiAqXG4gKiBVc2UgdGhpcyBjb25zdHJ1Y3Qgb24gYSB7QGxpbmsgRmFyZ2F0ZVNlcnZpY2V9IGJ5IGNvbnN0cnVjdGluZyBhIG5ldyBpbnN0YW5jZSBvZiB7QGxpbmsgT3BlblRlbGVtZXRyeUNvbGxlY3RvcnN9XG4gKiBhbmQgY2FsbGluZyB0aGUge0BsaW5rIGFkZE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JTaWRlY2FyfSBtZXRob2Qgb24gaXQuXG4gKlxuICogYGBgdHNcbiAqIGNvbnN0IHNlcnZpY2UgPSBGYXJnYXRlU2VydmljZSguLi4pO1xuICpcbiAqIG5ldyBPcGVuVGVsZW1ldHJ5Q29sbGVjdG9ycyh0aGlzLCBcIk90ZWxTaWRlY2FyXCIpLmFkZE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JTaWRlY2FyKHNlcnZpY2UpXG4gKiBgYGBcbiAqXG4gKiBUaGUgc2lkZWNhciBleHBvc2VzIHRoZXNlIHBvcnRzIHRvIHlvdXIgc2VydmljZTpcbiAqIC0gdWRwIDIwMDAgOiBBV1MgWFJheVxuICogLSB0Y3AgNDMxNyA6IE9wZW5UZWxlbWV0cnkgY29sbGVjdGlvbiBHUlBDXG4gKiAtIHRjcCA0MzE4IDogT3BlblRlbGVtZXRyeSBjb2xsZWN0aW9uIEhUVFBcbiAqXG4gKiAtLS1cbiAqXG4gKiBZb3UgY2FuIGFsc28gZGlzYWJsZSB0aGUgT3BlblRlbGVtZXRyeSBpbnN0cnVtZW50YXRpb24gYWdlbnRcbiAqIGZvciBKYXZhLWJhc2VkIHNlcnZpY2VzLFxuICogYnkgc2V0dGluZyB0aGUgYXBwcm9wcmlhdGUgZW52aXJvbm1lbnQgdmFyaWFibGUgd2l0aCB7QGxpbmsgZGlzYWJsZU9wZW5UZWxlbWV0cnlKYXZhQWdlbnR9OlxuICogYGBgdHNcbiAqIGNvbnN0IHNlcnZpY2UgPSBGYXJnYXRlU2VydmljZSguLi4pO1xuICpcbiAqIE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JzLmRpc2FibGVPcGVuVGVsZW1ldHJ5SmF2YUFnZW50KHNlcnZpY2UpXG4gKiBgYGBcbiAqXG4gKiBAc2VlIE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JzLmFkZE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JTaWRlY2FyXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVuVGVsZW1ldHJ5Q29sbGVjdG9ycyBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcm9wczogT3BlblRlbGVtZXRyeUNvbGxlY3RvcnNQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkKVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBPcGVuVGVsZW1ldHJ5IEphdmEgYWdlbnQgbWF5IHJ1biBieSBkZWZhdWx0IGluIHRoZSBEb2NrZXIgaW1hZ2UuXG4gICAqIFRoaXMgbWV0aG9kIHdpbGwgdGVsbCB0aGUgYWdlbnQgdG8gZGlzYWJsZSBpdHNlbGYuXG4gICAqXG4gICAqIFlvdSBtaWdodCB3YW50IHRvIGRvIHRoaXMgdG8gYXZvaWQgb3ZlcmhlYWQgb3IgZXJyb3IgbG9ncyBmcm9tIGZhaWxlZFxuICAgKiBjb25uZWN0aW9uIGF0dGVtcHRzIHRvIHRoZSBvdGVsIGNvbGxlY3Rvci5cbiAgICovXG4gIHB1YmxpYyBkaXNhYmxlT3BlblRlbGVtZXRyeUphdmFBZ2VudCgpIHtcbiAgICBPcGVuVGVsZW1ldHJ5Q29sbGVjdG9ycy5kaXNhYmxlT3BlblRlbGVtZXRyeUphdmFBZ2VudCh0aGlzLnByb3BzLnNlcnZpY2UpXG4gIH1cblxuICAvKipcbiAgICogVGhlIE9wZW5UZWxlbWV0cnkgSmF2YSBhZ2VudCBtYXkgcnVuIGJ5IGRlZmF1bHQgaW4gdGhlIERvY2tlciBpbWFnZS5cbiAgICogVGhpcyBtZXRob2Qgd2lsbCB0ZWxsIHRoZSBhZ2VudCB0byBkaXNhYmxlIGl0c2VsZi5cbiAgICpcbiAgICogWW91IG1pZ2h0IHdhbnQgdG8gZG8gdGhpcyB0byBhdm9pZCBvdmVyaGVhZCBvciBlcnJvciBsb2dzIGZyb20gZmFpbGVkXG4gICAqIGNvbm5lY3Rpb24gYXR0ZW1wdHMgdG8gdGhlIG90ZWwgY29sbGVjdG9yLlxuICAgKiBAcGFyYW0gc2VydmljZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBkaXNhYmxlT3BlblRlbGVtZXRyeUphdmFBZ2VudChzZXJ2aWNlOiBGYXJnYXRlU2VydmljZSkge1xuICAgIHNlcnZpY2UudGFza0RlZmluaXRpb24uZGVmYXVsdENvbnRhaW5lcj8uYWRkRW52aXJvbm1lbnQoXG4gICAgICBcIk9URUxfSkFWQUFHRU5UX0VOQUJMRURcIixcbiAgICAgIFwiZmFsc2VcIixcbiAgICApXG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHNpZGVjYXIgd2l0aCBhbiBBV1MgRGlzdHJvIE9wZW5UZWxlbWV0cnkgQ29sbGVjdG9yLlxuICAgKiBodHRwczovL2F3cy1vdGVsLmdpdGh1Yi5pby9kb2NzL3NldHVwL2Vjc1xuICAgKlxuICAgKiBZb3UgYWxzbyBuZWVkIHRvIGFkZCBlaXRoZXIgdGhlIEphdmEgU0RLIGZvciBPVGVsIG9yIGEgSmF2YSBhZ2VudCxcbiAgICogdG8gY2FwdHVyZSB0ZWxlbWV0cnkgYW5kIHNlbmQgdG8gdGhpcyBjb2xsZWN0b3IuXG4gICAqL1xuICBwdWJsaWMgYWRkT3BlblRlbGVtZXRyeUNvbGxlY3RvclNpZGVjYXIoKSB7XG4gICAgbmV3IE9wZW5UZWxlbWV0cnlQb2xpY2llcyh0aGlzLCBcIk9wZW5UZWxlbWV0cnlQb2xpY2llc1wiLCB7XG4gICAgICB0YXNrRGVmaW5pdGlvbjogdGhpcy5wcm9wcy5zZXJ2aWNlLnRhc2tEZWZpbml0aW9uLFxuICAgIH0pXG5cbiAgICB0aGlzLnByb3BzLnNlcnZpY2UudGFza0RlZmluaXRpb24uYWRkRXh0ZW5zaW9uKFxuICAgICAgbmV3IE9wZW5UZWxlbWV0cnlDb2xsZWN0b3JTaWRlY2FyKFxuICAgICAgICB0aGlzLFxuICAgICAgICB0aGlzLnByb3BzLmxvZ1JldGVudGlvbixcbiAgICAgICAgdGhpcy5wcm9wcy5kb2NrZXJJbWFnZSxcbiAgICAgICAgdGhpcy5wcm9wcy5hd3NPdGVsQ29uZmlnLFxuICAgICAgICB0aGlzLnByb3BzLmNvbnRhaW5lclByb3BzLFxuICAgICAgKSxcbiAgICApXG4gIH1cbn1cblxuZXhwb3J0IHR5cGUgU2lkZWNhckNvbnRhaW5lclByb3BzID0gUGljazxcbiAgZWNzLkNvbnRhaW5lckRlZmluaXRpb25Qcm9wcyxcbiAgXCJjcHVcIiB8IFwibWVtb3J5UmVzZXJ2YXRpb25NaUJcIiB8IFwibWVtb3J5TGltaXRNaUJcIlxuPlxuXG4vKipcbiAqIEFkZHMgYSBzaWRlY2FyIHdpdGggYW4gQVdTIERpc3RybyBPcGVuVGVsZW1ldHJ5IENvbGxlY3Rvci5cbiAqIGh0dHBzOi8vYXdzLW90ZWwuZ2l0aHViLmlvL2RvY3Mvc2V0dXAvZWNzXG4gKlxuICogWW91IGFsc28gbmVlZCB0byBhZGQgZWl0aGVyIHRoZSBKYXZhIFNESyBmb3IgT1RlbCBvciBhIEphdmEgYWdlbnQsXG4gKiB0byBjYXB0dXJlIHRlbGVtZXRyeSBhbmQgc2VuZCB0byB0aGlzIGNvbGxlY3Rvci5cbiAqL1xuY2xhc3MgT3BlblRlbGVtZXRyeUNvbGxlY3RvclNpZGVjYXIgaW1wbGVtZW50cyBlY3MuSVRhc2tEZWZpbml0aW9uRXh0ZW5zaW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb25zdHJ1Y3Q6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbG9nUmV0ZW50aW9uPzogUmV0ZW50aW9uRGF5cyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGRvY2tlckltYWdlPzogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYXdzT3RlbENvbmZpZz86IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNvbnRhaW5lclByb3BzPzogU2lkZWNhckNvbnRhaW5lclByb3BzLFxuICApIHt9XG5cbiAgZXh0ZW5kKHRhc2tEZWZpbml0aW9uOiBlY3MuVGFza0RlZmluaXRpb24pOiB2b2lkIHtcbiAgICBpZiAodGFza0RlZmluaXRpb24ubmV0d29ya01vZGUgIT09IGVjcy5OZXR3b3JrTW9kZS5BV1NfVlBDKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiVGFzayBOZXR3b3JrTW9kZSBtdXN0IGJlIEFXU19WUEM6IFwiICsgdGFza0RlZmluaXRpb24ubmV0d29ya01vZGUsXG4gICAgICApXG4gICAgfVxuXG4gICAgY29uc3QgY29tbWFuZHMgPSB7XG4gICAgICBtZXRyaWNzQW5kVHJhY2VzOiBcIi0tY29uZmlnPS9ldGMvZWNzL2Vjcy1kZWZhdWx0LWNvbmZpZy55YW1sXCIsXG4gICAgICBtZXRyaWNzQW5kVHJhY2VzQW5kQ29udGFpbmVyUmVzb3VyY2VzOlxuICAgICAgICBcIi0tY29uZmlnPS9ldGMvZWNzL2NvbnRhaW5lci1pbnNpZ2h0cy9vdGVsLXRhc2stbWV0cmljcy1jb25maWcueWFtbFwiLFxuICAgIH1cblxuICAgIGNvbnN0IGxvZ0dyb3VwID0gbmV3IGxvZ3MuTG9nR3JvdXAodGhpcy5jb25zdHJ1Y3QsIFwiQ29sbGVjdG9yTG9nR3JvdXBcIiwge1xuICAgICAgcmV0ZW50aW9uOiB0aGlzLmxvZ1JldGVudGlvbiA/PyBSZXRlbnRpb25EYXlzLlNJWF9NT05USFMsXG4gICAgICByZW1vdmFsUG9saWN5OiBSZW1vdmFsUG9saWN5LkRFU1RST1ksXG4gICAgfSlcblxuICAgIGNvbnN0IHNpZGVjYXJJbWFnZSA9IHRoaXMuZG9ja2VySW1hZ2UgPz8gXCJhbWF6b24vYXdzLW90ZWwtY29sbGVjdG9yOnYwLjQzLjFcIlxuICAgIGNvbnN0IHNpZGVjYXIgPSB0YXNrRGVmaW5pdGlvbi5hZGRDb250YWluZXIoXCJhd3Mtb3BlbnRlbGVtZXRyeS1jb2xsZWN0b3JcIiwge1xuICAgICAgY3B1OiB0aGlzLmNvbnRhaW5lclByb3BzPy5jcHUgPz8gMzIsXG4gICAgICBtZW1vcnlSZXNlcnZhdGlvbk1pQjogdGhpcy5jb250YWluZXJQcm9wcz8ubWVtb3J5UmVzZXJ2YXRpb25NaUIgPz8gMjQsXG4gICAgICBtZW1vcnlMaW1pdE1pQjogdGhpcy5jb250YWluZXJQcm9wcz8ubWVtb3J5TGltaXRNaUIgPz8gMjU2LFxuICAgICAgaW1hZ2U6IGVjcy5Db250YWluZXJJbWFnZS5mcm9tUmVnaXN0cnkoc2lkZWNhckltYWdlKSxcbiAgICAgIGNvbW1hbmQ6IFtjb21tYW5kcy5tZXRyaWNzQW5kVHJhY2VzQW5kQ29udGFpbmVyUmVzb3VyY2VzXSwgLy8gVGhpcyBpcyBub3QgdXNlZCB3aGVuIHRoZSBBT1RfQ09ORklHX0NPTlRFTlQgaXMgc2V0IVxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgLy8gWW91IGNhbiBhbHRlcm5hdGl2ZWx5IGNyZWF0ZSBhbiBTU00gcGFyYW1ldGVyIHdpdGggdGhlIGNvbmZpZywgYW5kIHBhc3MgaXQgdG8gdGhlIGBzZWNyZXRzYCBvcHRpb25cbiAgICAgICAgQU9UX0NPTkZJR19DT05URU5UOiB0aGlzLmF3c090ZWxDb25maWcgPz8gYXdzT3RlbEN1c3RvbUNvbmZpZ1lhbWwsXG4gICAgICB9LFxuICAgICAgbG9nZ2luZzogZWNzLkxvZ0RyaXZlcnMuYXdzTG9ncyh7XG4gICAgICAgIGxvZ0dyb3VwOiBsb2dHcm91cCxcbiAgICAgICAgc3RyZWFtUHJlZml4OiBcImVjc1wiLFxuICAgICAgfSksXG4gICAgfSlcblxuICAgIC8vIEEgZGVwZW5kZW5jeSBzaG91bGQgYmUgYWRkZWQgdG8gYWxsIGNvbnRhaW5lcnMgdGhhdCBleHBvcnQgbWV0cmljcy5cbiAgICAvLyBXZSBhcmUgY3VycmVudGx5IGFzc3VtaW5nIHRoYXQgdGhpcyBpcyBvbmx5IHRoZSBkZWZhdWx0IGNvbnRhaW5lclxuICAgIHRhc2tEZWZpbml0aW9uLmRlZmF1bHRDb250YWluZXI/LmFkZENvbnRhaW5lckRlcGVuZGVuY2llcyh7XG4gICAgICBjb250YWluZXI6IHNpZGVjYXIsXG4gICAgICBjb25kaXRpb246IGVjcy5Db250YWluZXJEZXBlbmRlbmN5Q29uZGl0aW9uLlNUQVJULFxuICAgIH0pXG5cbiAgICAvKlxuICAgICAqIGF3cy1vdGVsLWNvbGxlY3RvciBleHBvc2VzIHRoZXNlIHBvcnRzLCBhbmQgbW9yZTpcbiAgICAgKiAtIHVkcCAyMDAwIDogQVdTIFhSYXlcbiAgICAgKiAtIHRjcCA0MzE3IDogT3BlblRlbGVtZXRyeSBjb2xsZWN0aW9uIEdSUENcbiAgICAgKiAtIHRjcCA0MzE4IDogT3BlblRlbGVtZXRyeSBjb2xsZWN0aW9uIEhUVFBcbiAgICAgKlxuICAgICAqIFRoZXNlIGFyZSBkZWZpbmVkIGluIHRoZSB5YW1sIGNvbmZpZyBmb3IgdGhlIGNvbGxlY3Rvci5cbiAgICAgKi9cbiAgICB0YXNrRGVmaW5pdGlvbi5kZWZhdWx0Q29udGFpbmVyPy5hZGRFbnZpcm9ubWVudChcbiAgICAgIFwiQVdTX1hSQVlfREFFTU9OX0FERFJFU1NcIixcbiAgICAgIFwiaHR0cDovL2xvY2FsaG9zdDoyMDAwXCIsXG4gICAgKVxuICAgIHRhc2tEZWZpbml0aW9uLmRlZmF1bHRDb250YWluZXI/LmFkZEVudmlyb25tZW50KFxuICAgICAgXCJPVEVMX0VYUE9SVEVSX09UTFBfRU5EUE9JTlRcIixcbiAgICAgIFwiaHR0cDovL2xvY2FsaG9zdDo0MzE3XCIsXG4gICAgKVxuICAgIHRhc2tEZWZpbml0aW9uLmRlZmF1bHRDb250YWluZXI/LmFkZEVudmlyb25tZW50KFxuICAgICAgXCJPVEVMX0pBVkFBR0VOVF9FTkFCTEVEXCIsXG4gICAgICBcInRydWVcIixcbiAgICApXG5cbiAgICBpZiAoIXRhc2tEZWZpbml0aW9uLmlzRmFyZ2F0ZUNvbXBhdGlibGUpIHtcbiAgICAgIC8vIFRoaXMgZXh0ZW5zaW9uIGlzIG1hZGUgZm9yIHRoZSBGYXJnYXRlU2VydmljZSwgc28gdGhpcyBpcyBhIHJlcXVpcmVtZW50LlxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBcIlRoaXMgdGFzayBkZWZpbml0aW9uIGNhbiBub3QgYmUgcmFuIG9uIGZhcmdhdGUhIFwiICtcbiAgICAgICAgICB0YXNrRGVmaW5pdGlvbi5ub2RlLmlkLFxuICAgICAgKVxuICAgIH1cbiAgfVxufVxuXG5pbnRlcmZhY2UgT3BlblRlbGVtZXRyeVBvbGljaWVzUHJvcHMge1xuICB0YXNrRGVmaW5pdGlvbjogZWNzLlRhc2tEZWZpbml0aW9uXG59XG5cbi8qKlxuICogR3JhbnRzIHRoZSBzaWRlY2FyIHBlcm1pc3Npb25zIHRvIGNyZWF0ZSBsb2dzLCBtZXRyaWNzIGFuZCBYUmF5IHRyYWNlcyBieSBleHRlbmRpbmcgdGhlIHRhc2sgcm9sZXMuXG4gKi9cbmNsYXNzIE9wZW5UZWxlbWV0cnlQb2xpY2llcyBleHRlbmRzIGNvbnN0cnVjdHMuQ29uc3RydWN0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgc2NvcGU6IGNvbnN0cnVjdHMuQ29uc3RydWN0LFxuICAgIGlkOiBzdHJpbmcsXG4gICAgcHJvcHM6IE9wZW5UZWxlbWV0cnlQb2xpY2llc1Byb3BzLFxuICApIHtcbiAgICBzdXBlcihzY29wZSwgaWQpXG5cbiAgICBjb25zdCBhd3NEaXN0cm9PcGVuVGVsZW1ldHJ5UG9saWN5U3RhdGVtZW50ID0gbmV3IGlhbS5Qb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgZWZmZWN0OiBpYW0uRWZmZWN0LkFMTE9XLFxuICAgICAgcmVzb3VyY2VzOiBbXCIqXCJdLFxuICAgICAgYWN0aW9uczogW1xuICAgICAgICBcImxvZ3M6UHV0TG9nRXZlbnRzXCIsXG4gICAgICAgIFwibG9nczpDcmVhdGVMb2dHcm91cFwiLFxuICAgICAgICBcImxvZ3M6Q3JlYXRlTG9nU3RyZWFtXCIsXG4gICAgICAgIFwibG9nczpEZXNjcmliZUxvZ1N0cmVhbXNcIixcbiAgICAgICAgXCJsb2dzOkRlc2NyaWJlTG9nR3JvdXBzXCIsXG4gICAgICAgIFwibG9nczpQdXRSZXRlbnRpb25Qb2xpY3lcIixcbiAgICAgICAgXCJ4cmF5OlB1dFRyYWNlU2VnbWVudHNcIixcbiAgICAgICAgXCJ4cmF5OlB1dFRlbGVtZXRyeVJlY29yZHNcIixcbiAgICAgICAgXCJ4cmF5OkdldFNhbXBsaW5nUnVsZXNcIixcbiAgICAgICAgXCJ4cmF5OkdldFNhbXBsaW5nVGFyZ2V0c1wiLFxuICAgICAgICBcInhyYXk6R2V0U2FtcGxpbmdTdGF0aXN0aWNTdW1tYXJpZXNcIixcbiAgICAgICAgXCJjbG91ZHdhdGNoOlB1dE1ldHJpY0RhdGFcIixcbiAgICAgICAgXCJlYzI6RGVzY3JpYmVWb2x1bWVzXCIsXG4gICAgICAgIFwiZWMyOkRlc2NyaWJlVGFnc1wiLFxuICAgICAgICBcInNzbTpHZXRQYXJhbWV0ZXJzXCIsXG4gICAgICBdLFxuICAgIH0pXG5cbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5hZGRUb1Rhc2tSb2xlUG9saWN5KFxuICAgICAgYXdzRGlzdHJvT3BlblRlbGVtZXRyeVBvbGljeVN0YXRlbWVudCxcbiAgICApXG5cbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5hZGRUb0V4ZWN1dGlvblJvbGVQb2xpY3koXG4gICAgICBhd3NEaXN0cm9PcGVuVGVsZW1ldHJ5UG9saWN5U3RhdGVtZW50LFxuICAgIClcbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5leGVjdXRpb25Sb2xlPy5hZGRNYW5hZ2VkUG9saWN5KFxuICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFwiQ2xvdWRXYXRjaExvZ3NGdWxsQWNjZXNzXCIpLFxuICAgIClcbiAgICBwcm9wcy50YXNrRGVmaW5pdGlvbi5leGVjdXRpb25Sb2xlPy5hZGRNYW5hZ2VkUG9saWN5KFxuICAgICAgaWFtLk1hbmFnZWRQb2xpY3kuZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKFwiQW1hem9uU1NNUmVhZE9ubHlBY2Nlc3NcIiksXG4gICAgKVxuICB9XG59XG5cbi8qKlxuICogVGhpcyBpcyBhIG1vZGlmaWVkIHZlcnNpb24gb2YgYC4vZXRjL2Vjcy9jb250YWluZXItaW5zaWdodHMvb3RlbC10YXNrLW1ldHJpY3MtY29uZmlnLnlhbWxgXG4gKiB3aGVyZSB3ZSBhZGQgYHJlc291cmNlX3RvX3RlbGVtZXRyeV9jb252ZXJzaW9uYCBzbyB0aGUgb3RlbCByZXNvdXJjZSBgc2VydmljZS5uYW1lYFxuICogY2FuIGJlIGFkZGVkIHRvIHRoZSBtZXRyaWMuIFRoaXMgaXMgdXNlZnVsIGJlY2F1c2UgeW91IGNhbiBmaWx0ZXIgaW4gbWV0cmljcyBiYXNlZCBvbiBzZXJ2aWNlLFxuICogaW5zdGVhZCBvZiBncm91cGluZyBlLmcuIGFsbCBzZXJ2aWNlcycgbWVtb3J5IHVzYWdlIHVuZGVyIHRoZSBzYW1lIG1ldHJpYy5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vYXdzLW90ZWwuZ2l0aHViLmlvL2RvY3Mvc2V0dXAvZWNzL2NvbmZpZy10aHJvdWdoLXNzbVxuICogQHNlZSBodHRwczovL2F3cy1vdGVsLmdpdGh1Yi5pby9kb2NzL2dldHRpbmctc3RhcnRlZC9jbG91ZHdhdGNoLW1ldHJpY3MjY2xvdWR3YXRjaC1lbWYtZXhwb3J0ZXItYXdzZW1mXG4gKi9cbmNvbnN0IGF3c090ZWxDdXN0b21Db25maWdZYW1sID0gcmVhZEZpbGVTeW5jKFxuICBwYXRoLnJlc29sdmUoXG4gICAgX19kaXJuYW1lLFxuICAgIFwiLi5cIixcbiAgICBcIi4uXCIsXG4gICAgXCJhc3NldHNcIixcbiAgICBcIm9wZW4tdGVsZW1ldHJ5XCIsXG4gICAgXCJvdGVsLWNvbGxlY3Rvci10YXNrLW1ldHJpY3MtY29uZmlnLnlhbWxcIixcbiAgKSxcbiAgXCJ1dGYtOFwiLFxuKVxuICAuc3BsaXQoXCJcXG5cIilcbiAgLmZpbHRlcigobGluZSkgPT4gIS9eXFxzKiMjLy50ZXN0KGxpbmUpKSAvLyBTa2lwIGNvbW1lbnRzIHN0YXJ0aW5nIHdpdGggIyNcbiAgLmpvaW4oXCJcXG5cIilcbiJdfQ==
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liflig/cdk",
3
- "version": "3.12.1",
3
+ "version": "3.13.0",
4
4
  "description": "CDK library for Liflig",
5
5
  "type": "module",
6
6
  "repository": {
@@ -55,7 +55,7 @@
55
55
  "@commitlint/cli": "19.8.1",
56
56
  "@commitlint/config-conventional": "19.8.1",
57
57
  "@eslint/eslintrc": "3.3.1",
58
- "@eslint/js": "9.31.0",
58
+ "@eslint/js": "9.32.0",
59
59
  "@types/aws-lambda": "8.10.152",
60
60
  "@types/jest": "30.0.0",
61
61
  "@types/node": "24.1.0",
@@ -65,7 +65,7 @@
65
65
  "aws-cdk-lib": "2.207.0",
66
66
  "constructs": "10.4.2",
67
67
  "esbuild": "0.25.8",
68
- "eslint": "9.31.0",
68
+ "eslint": "9.32.0",
69
69
  "eslint-config-prettier": "10.1.8",
70
70
  "eslint-plugin-prettier": "5.5.3",
71
71
  "husky": "9.1.7",
@@ -75,7 +75,7 @@
75
75
  "semantic-release": "24.2.7",
76
76
  "ts-jest": "29.4.0",
77
77
  "tsx": "4.20.3",
78
- "typedoc": "0.28.7",
78
+ "typedoc": "0.28.8",
79
79
  "typescript": "5.8.3"
80
80
  },
81
81
  "dependencies": {