cdk-factory 0.9.11__py3-none-any.whl → 0.10.0__py3-none-any.whl

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.

Potentially problematic release.


This version of cdk-factory might be problematic. Click here for more details.

Files changed (24) hide show
  1. cdk_factory/app.py +39 -8
  2. cdk_factory/configurations/resources/auto_scaling.py +27 -0
  3. cdk_factory/configurations/resources/cloudfront.py +101 -11
  4. cdk_factory/configurations/resources/ecs_service.py +12 -0
  5. cdk_factory/configurations/resources/lambda_edge.py +92 -0
  6. cdk_factory/configurations/resources/monitoring.py +74 -0
  7. cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py +51 -1
  8. cdk_factory/lambdas/edge/ip_gate/handler.py +104 -0
  9. cdk_factory/pipeline/pipeline_factory.py +1 -0
  10. cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +99 -0
  11. cdk_factory/stack_library/cloudfront/__init__.py +6 -0
  12. cdk_factory/stack_library/cloudfront/cloudfront_stack.py +627 -0
  13. cdk_factory/stack_library/ecs/ecs_service_stack.py +90 -0
  14. cdk_factory/stack_library/lambda_edge/__init__.py +6 -0
  15. cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +217 -0
  16. cdk_factory/stack_library/monitoring/__init__.py +6 -0
  17. cdk_factory/stack_library/monitoring/monitoring_stack.py +492 -0
  18. cdk_factory/version.py +1 -1
  19. cdk_factory/workload/workload_factory.py +2 -0
  20. {cdk_factory-0.9.11.dist-info → cdk_factory-0.10.0.dist-info}/METADATA +1 -1
  21. {cdk_factory-0.9.11.dist-info → cdk_factory-0.10.0.dist-info}/RECORD +24 -15
  22. {cdk_factory-0.9.11.dist-info → cdk_factory-0.10.0.dist-info}/WHEEL +0 -0
  23. {cdk_factory-0.9.11.dist-info → cdk_factory-0.10.0.dist-info}/entry_points.txt +0 -0
  24. {cdk_factory-0.9.11.dist-info → cdk_factory-0.10.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,492 @@
1
+ """
2
+ Monitoring Stack - CloudWatch Alarms and Dashboards
3
+ Geek Cafe, LLC
4
+ Maintainers: Eric Wilson
5
+ MIT License. See Project Root for the license information.
6
+ """
7
+
8
+ import logging
9
+ from typing import Dict, List, Any, Optional
10
+
11
+ from aws_cdk import (
12
+ Duration,
13
+ aws_cloudwatch as cloudwatch,
14
+ aws_cloudwatch_actions as cw_actions,
15
+ aws_sns as sns,
16
+ aws_sns_subscriptions as subscriptions,
17
+ aws_ssm as ssm,
18
+ aws_logs as logs,
19
+ CfnOutput,
20
+ )
21
+ from constructs import Construct
22
+
23
+ from cdk_factory.interfaces.istack import IStack
24
+ from cdk_factory.stack.stack_module_registry import register_stack
25
+ from cdk_factory.configurations.stack import StackConfig
26
+ from cdk_factory.configurations.resources.monitoring import MonitoringConfig
27
+
28
+ logger = logging.getLogger(__name__)
29
+
30
+
31
+ @register_stack("monitoring_library_module")
32
+ class MonitoringStack(IStack):
33
+ """
34
+ Monitoring Stack with CloudWatch Alarms and Dashboards
35
+
36
+ Supports:
37
+ - SNS topics for notifications
38
+ - CloudWatch alarms (metric, composite, anomaly detection)
39
+ - CloudWatch dashboards
40
+ - Log metric filters
41
+ - Email/Slack/PagerDuty subscriptions
42
+ """
43
+
44
+ def __init__(
45
+ self,
46
+ scope: Construct,
47
+ id: str,
48
+ stack_config: StackConfig,
49
+ deployment,
50
+ **kwargs,
51
+ ) -> None:
52
+ super().__init__(scope, id, **kwargs)
53
+
54
+ self.stack_config = stack_config
55
+ self.deployment = deployment
56
+
57
+ # Monitoring config
58
+ monitoring_dict = stack_config.dictionary.get("monitoring", {})
59
+ self.monitoring_config = MonitoringConfig(monitoring_dict, deployment)
60
+
61
+ # Resources
62
+ self.sns_topics: Dict[str, sns.Topic] = {}
63
+ self.alarms: Dict[str, cloudwatch.Alarm] = {}
64
+ self.dashboards: Dict[str, cloudwatch.Dashboard] = {}
65
+
66
+ def build(
67
+ self,
68
+ vpc=None,
69
+ target_groups=None,
70
+ security_groups=None,
71
+ shared=None,
72
+ ):
73
+ """Build monitoring resources"""
74
+
75
+ logger.info(f"Building monitoring stack: {self.monitoring_config.name}")
76
+
77
+ # Create SNS topics first
78
+ self._create_sns_topics()
79
+
80
+ # Create log metric filters
81
+ self._create_log_metric_filters()
82
+
83
+ # Create alarms
84
+ self._create_alarms()
85
+
86
+ # Create composite alarms
87
+ self._create_composite_alarms()
88
+
89
+ # Create dashboards
90
+ self._create_dashboards()
91
+
92
+ # Export SSM parameters
93
+ self._export_ssm_parameters()
94
+
95
+ # Create outputs
96
+ self._create_outputs()
97
+
98
+ return self
99
+
100
+ def _create_sns_topics(self) -> None:
101
+ """Create SNS topics for alarm notifications"""
102
+ topics_config = self.monitoring_config.sns_topics
103
+
104
+ for topic_config in topics_config:
105
+ topic_name = topic_config.get("name")
106
+ if not topic_name:
107
+ logger.warning("SNS topic name is required, skipping")
108
+ continue
109
+
110
+ # Create topic
111
+ topic = sns.Topic(
112
+ self,
113
+ f"Topic-{topic_name}",
114
+ topic_name=topic_name,
115
+ display_name=topic_config.get("display_name", topic_name),
116
+ )
117
+
118
+ # Add subscriptions
119
+ subscriptions_config = topic_config.get("subscriptions", [])
120
+ for sub_config in subscriptions_config:
121
+ protocol = sub_config.get("protocol", "email")
122
+ endpoint = sub_config.get("endpoint")
123
+
124
+ if not endpoint:
125
+ logger.warning(f"Subscription endpoint required for {topic_name}, skipping")
126
+ continue
127
+
128
+ if protocol == "email":
129
+ topic.add_subscription(subscriptions.EmailSubscription(endpoint))
130
+ elif protocol == "sms":
131
+ topic.add_subscription(subscriptions.SmsSubscription(endpoint))
132
+ elif protocol == "https":
133
+ topic.add_subscription(subscriptions.UrlSubscription(endpoint))
134
+ elif protocol == "lambda":
135
+ # Lambda ARN as endpoint
136
+ logger.warning(f"Lambda subscriptions not yet implemented for {topic_name}")
137
+ else:
138
+ logger.warning(f"Unsupported protocol {protocol} for {topic_name}")
139
+
140
+ self.sns_topics[topic_name] = topic
141
+ logger.info(f"Created SNS topic: {topic_name}")
142
+
143
+ def _create_log_metric_filters(self) -> None:
144
+ """Create CloudWatch Logs metric filters"""
145
+ filters_config = self.monitoring_config.log_metric_filters
146
+
147
+ for filter_config in filters_config:
148
+ filter_name = filter_config.get("name")
149
+ log_group_name = filter_config.get("log_group_name")
150
+ filter_pattern = filter_config.get("filter_pattern")
151
+ metric_namespace = filter_config.get("metric_namespace", "CustomMetrics")
152
+ metric_name = filter_config.get("metric_name")
153
+
154
+ if not all([filter_name, log_group_name, filter_pattern, metric_name]):
155
+ logger.warning(f"Missing required fields for metric filter {filter_name}, skipping")
156
+ continue
157
+
158
+ # Import log group
159
+ log_group = logs.LogGroup.from_log_group_name(
160
+ self,
161
+ f"LogGroup-{filter_name}",
162
+ log_group_name=log_group_name
163
+ )
164
+
165
+ # Create metric filter
166
+ logs.MetricFilter(
167
+ self,
168
+ f"MetricFilter-{filter_name}",
169
+ log_group=log_group,
170
+ filter_pattern=logs.FilterPattern.literal(filter_pattern),
171
+ metric_namespace=metric_namespace,
172
+ metric_name=metric_name,
173
+ metric_value=filter_config.get("metric_value", "1"),
174
+ default_value=filter_config.get("default_value", 0),
175
+ )
176
+
177
+ logger.info(f"Created metric filter: {filter_name}")
178
+
179
+ def _create_alarms(self) -> None:
180
+ """Create CloudWatch alarms"""
181
+ alarms_config = self.monitoring_config.alarms
182
+
183
+ for alarm_config in alarms_config:
184
+ alarm_name = alarm_config.get("name")
185
+ if not alarm_name:
186
+ logger.warning("Alarm name is required, skipping")
187
+ continue
188
+
189
+ # Determine alarm type
190
+ alarm_type = alarm_config.get("type", "metric")
191
+
192
+ if alarm_type == "metric":
193
+ alarm = self._create_metric_alarm(alarm_config)
194
+ elif alarm_type == "anomaly":
195
+ alarm = self._create_anomaly_alarm(alarm_config)
196
+ else:
197
+ logger.warning(f"Unsupported alarm type: {alarm_type}")
198
+ continue
199
+
200
+ if alarm:
201
+ self.alarms[alarm_name] = alarm
202
+ logger.info(f"Created alarm: {alarm_name}")
203
+
204
+ def _create_metric_alarm(self, config: Dict[str, Any]) -> Optional[cloudwatch.Alarm]:
205
+ """Create a metric-based alarm"""
206
+ alarm_name = config.get("name")
207
+
208
+ # Get metric configuration
209
+ metric_config = config.get("metric", {})
210
+
211
+ # Check if using SSM import for resource
212
+ namespace = metric_config.get("namespace")
213
+ metric_name = metric_config.get("metric_name")
214
+ dimensions = metric_config.get("dimensions", {})
215
+
216
+ # Resolve SSM parameters in dimensions
217
+ resolved_dimensions = {}
218
+ for dim_name, dim_value in dimensions.items():
219
+ if isinstance(dim_value, str) and dim_value.startswith("{{ssm:") and dim_value.endswith("}}"):
220
+ ssm_param = dim_value[6:-2]
221
+ dim_value = ssm.StringParameter.value_from_lookup(self, ssm_param)
222
+ resolved_dimensions[dim_name] = dim_value
223
+
224
+ # Create metric
225
+ metric = cloudwatch.Metric(
226
+ namespace=namespace,
227
+ metric_name=metric_name,
228
+ dimensions_map=resolved_dimensions if resolved_dimensions else None,
229
+ statistic=metric_config.get("statistic", "Average"),
230
+ period=Duration.seconds(metric_config.get("period", 300)),
231
+ )
232
+
233
+ # Comparison operator
234
+ comparison_op_map = {
235
+ "GreaterThanThreshold": cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD,
236
+ "GreaterThanOrEqualToThreshold": cloudwatch.ComparisonOperator.GREATER_THAN_OR_EQUAL_TO_THRESHOLD,
237
+ "LessThanThreshold": cloudwatch.ComparisonOperator.LESS_THAN_THRESHOLD,
238
+ "LessThanOrEqualToThreshold": cloudwatch.ComparisonOperator.LESS_THAN_OR_EQUAL_TO_THRESHOLD,
239
+ }
240
+ comparison_op = comparison_op_map.get(
241
+ config.get("comparison_operator", "GreaterThanThreshold"),
242
+ cloudwatch.ComparisonOperator.GREATER_THAN_THRESHOLD
243
+ )
244
+
245
+ # Treat missing data
246
+ treat_missing_data_map = {
247
+ "breaching": cloudwatch.TreatMissingData.BREACHING,
248
+ "notBreaching": cloudwatch.TreatMissingData.NOT_BREACHING,
249
+ "ignore": cloudwatch.TreatMissingData.IGNORE,
250
+ "missing": cloudwatch.TreatMissingData.MISSING,
251
+ }
252
+ treat_missing_data = treat_missing_data_map.get(
253
+ config.get("treat_missing_data", "notBreaching"),
254
+ cloudwatch.TreatMissingData.NOT_BREACHING
255
+ )
256
+
257
+ # Create alarm
258
+ alarm = cloudwatch.Alarm(
259
+ self,
260
+ f"Alarm-{alarm_name}",
261
+ alarm_name=alarm_name,
262
+ alarm_description=config.get("description", ""),
263
+ metric=metric,
264
+ threshold=config.get("threshold", 0),
265
+ evaluation_periods=config.get("evaluation_periods", 1),
266
+ datapoints_to_alarm=config.get("datapoints_to_alarm"),
267
+ comparison_operator=comparison_op,
268
+ treat_missing_data=treat_missing_data,
269
+ actions_enabled=config.get("actions_enabled", True),
270
+ )
271
+
272
+ # Add alarm actions (SNS topics)
273
+ actions = config.get("actions", [])
274
+ for action in actions:
275
+ if action in self.sns_topics:
276
+ alarm.add_alarm_action(cw_actions.SnsAction(self.sns_topics[action]))
277
+
278
+ # Add OK actions
279
+ ok_actions = config.get("ok_actions", [])
280
+ for action in ok_actions:
281
+ if action in self.sns_topics:
282
+ alarm.add_ok_action(cw_actions.SnsAction(self.sns_topics[action]))
283
+
284
+ # Add insufficient data actions
285
+ insufficient_data_actions = config.get("insufficient_data_actions", [])
286
+ for action in insufficient_data_actions:
287
+ if action in self.sns_topics:
288
+ alarm.add_insufficient_data_action(cw_actions.SnsAction(self.sns_topics[action]))
289
+
290
+ return alarm
291
+
292
+ def _create_anomaly_alarm(self, config: Dict[str, Any]) -> Optional[cloudwatch.Alarm]:
293
+ """Create an anomaly detection alarm"""
294
+ # Anomaly detection alarms use a different approach
295
+ # For now, log and skip - can be implemented later
296
+ logger.info(f"Anomaly detection alarm {config.get('name')} - implementation pending")
297
+ return None
298
+
299
+ def _create_composite_alarms(self) -> None:
300
+ """Create composite alarms (combine multiple alarms)"""
301
+ composite_config = self.monitoring_config.composite_alarms
302
+
303
+ for comp_config in composite_config:
304
+ comp_name = comp_config.get("name")
305
+ if not comp_name:
306
+ logger.warning("Composite alarm name is required, skipping")
307
+ continue
308
+
309
+ # Build alarm rule
310
+ alarm_rule = comp_config.get("alarm_rule")
311
+ if not alarm_rule:
312
+ logger.warning(f"Alarm rule required for {comp_name}, skipping")
313
+ continue
314
+
315
+ # Replace alarm names with ARNs in the rule
316
+ # This is a simplified version - full implementation would parse the rule
317
+ # For now, just pass through
318
+
319
+ composite_alarm = cloudwatch.CompositeAlarm(
320
+ self,
321
+ f"CompositeAlarm-{comp_name}",
322
+ composite_alarm_name=comp_name,
323
+ alarm_description=comp_config.get("description", ""),
324
+ alarm_rule=cloudwatch.AlarmRule.from_string(alarm_rule),
325
+ actions_enabled=comp_config.get("actions_enabled", True),
326
+ )
327
+
328
+ # Add actions
329
+ actions = comp_config.get("actions", [])
330
+ for action in actions:
331
+ if action in self.sns_topics:
332
+ composite_alarm.add_alarm_action(cw_actions.SnsAction(self.sns_topics[action]))
333
+
334
+ logger.info(f"Created composite alarm: {comp_name}")
335
+
336
+ def _create_dashboards(self) -> None:
337
+ """Create CloudWatch dashboards"""
338
+ dashboards_config = self.monitoring_config.dashboards
339
+
340
+ for dashboard_config in dashboards_config:
341
+ dashboard_name = dashboard_config.get("name")
342
+ if not dashboard_name:
343
+ logger.warning("Dashboard name is required, skipping")
344
+ continue
345
+
346
+ # Create dashboard
347
+ dashboard = cloudwatch.Dashboard(
348
+ self,
349
+ f"Dashboard-{dashboard_name}",
350
+ dashboard_name=dashboard_name,
351
+ )
352
+
353
+ # Add widgets
354
+ widgets_config = dashboard_config.get("widgets", [])
355
+ for widget_config in widgets_config:
356
+ widget = self._create_widget(widget_config)
357
+ if widget:
358
+ # Add to dashboard (position will be auto-calculated)
359
+ dashboard.add_widgets(widget)
360
+
361
+ self.dashboards[dashboard_name] = dashboard
362
+ logger.info(f"Created dashboard: {dashboard_name}")
363
+
364
+ def _create_widget(self, config: Dict[str, Any]) -> Optional[cloudwatch.IWidget]:
365
+ """Create a dashboard widget"""
366
+ widget_type = config.get("type", "graph")
367
+
368
+ if widget_type == "graph":
369
+ return self._create_graph_widget(config)
370
+ elif widget_type == "number":
371
+ return self._create_single_value_widget(config)
372
+ elif widget_type == "log":
373
+ return self._create_log_widget(config)
374
+ elif widget_type == "alarm":
375
+ return self._create_alarm_widget(config)
376
+ else:
377
+ logger.warning(f"Unsupported widget type: {widget_type}")
378
+ return None
379
+
380
+ def _create_graph_widget(self, config: Dict[str, Any]) -> cloudwatch.GraphWidget:
381
+ """Create a graph widget"""
382
+ metrics_config = config.get("metrics", [])
383
+ metrics = []
384
+
385
+ for metric_config in metrics_config:
386
+ metric = cloudwatch.Metric(
387
+ namespace=metric_config.get("namespace"),
388
+ metric_name=metric_config.get("metric_name"),
389
+ dimensions_map=metric_config.get("dimensions", {}),
390
+ statistic=metric_config.get("statistic", "Average"),
391
+ period=Duration.seconds(metric_config.get("period", 300)),
392
+ label=metric_config.get("label"),
393
+ )
394
+ metrics.append(metric)
395
+
396
+ return cloudwatch.GraphWidget(
397
+ title=config.get("title", ""),
398
+ left=metrics,
399
+ width=config.get("width", 12),
400
+ height=config.get("height", 6),
401
+ legend_position=cloudwatch.LegendPosition.BOTTOM,
402
+ )
403
+
404
+ def _create_single_value_widget(self, config: Dict[str, Any]) -> cloudwatch.SingleValueWidget:
405
+ """Create a single value widget"""
406
+ metrics_config = config.get("metrics", [])
407
+ metrics = []
408
+
409
+ for metric_config in metrics_config:
410
+ metric = cloudwatch.Metric(
411
+ namespace=metric_config.get("namespace"),
412
+ metric_name=metric_config.get("metric_name"),
413
+ dimensions_map=metric_config.get("dimensions", {}),
414
+ statistic=metric_config.get("statistic", "Average"),
415
+ period=Duration.seconds(metric_config.get("period", 300)),
416
+ )
417
+ metrics.append(metric)
418
+
419
+ return cloudwatch.SingleValueWidget(
420
+ title=config.get("title", ""),
421
+ metrics=metrics,
422
+ width=config.get("width", 6),
423
+ height=config.get("height", 3),
424
+ )
425
+
426
+ def _create_log_widget(self, config: Dict[str, Any]) -> cloudwatch.LogQueryWidget:
427
+ """Create a log query widget"""
428
+ log_group_names = config.get("log_group_names", [])
429
+ query_string = config.get("query_string", "")
430
+
431
+ return cloudwatch.LogQueryWidget(
432
+ title=config.get("title", ""),
433
+ log_group_names=log_group_names,
434
+ query_string=query_string,
435
+ width=config.get("width", 24),
436
+ height=config.get("height", 6),
437
+ )
438
+
439
+ def _create_alarm_widget(self, config: Dict[str, Any]) -> cloudwatch.AlarmWidget:
440
+ """Create an alarm status widget"""
441
+ alarm_names = config.get("alarm_names", [])
442
+ alarms = [self.alarms[name] for name in alarm_names if name in self.alarms]
443
+
444
+ if not alarms:
445
+ logger.warning(f"No alarms found for alarm widget")
446
+ return None
447
+
448
+ return cloudwatch.AlarmWidget(
449
+ title=config.get("title", "Alarms"),
450
+ alarms=alarms,
451
+ width=config.get("width", 12),
452
+ height=config.get("height", 6),
453
+ )
454
+
455
+ def _export_ssm_parameters(self) -> None:
456
+ """Export monitoring resources to SSM Parameter Store"""
457
+ ssm_exports = self.monitoring_config.ssm_exports
458
+
459
+ if not ssm_exports:
460
+ return
461
+
462
+ # Export SNS topic ARNs
463
+ for topic_name, topic in self.sns_topics.items():
464
+ param_name = ssm_exports.get(f"sns_topic_{topic_name}")
465
+ if param_name:
466
+ ssm.StringParameter(
467
+ self,
468
+ f"SnsTopicParam-{topic_name}",
469
+ parameter_name=param_name,
470
+ string_value=topic.topic_arn,
471
+ description=f"SNS Topic ARN for {topic_name}",
472
+ )
473
+
474
+ def _create_outputs(self) -> None:
475
+ """Create CloudFormation outputs"""
476
+ # Output SNS topic ARNs
477
+ for topic_name, topic in self.sns_topics.items():
478
+ CfnOutput(
479
+ self,
480
+ f"SnsTopicArn-{topic_name}",
481
+ value=topic.topic_arn,
482
+ description=f"SNS Topic ARN: {topic_name}",
483
+ )
484
+
485
+ # Output dashboard URLs
486
+ for dashboard_name, dashboard in self.dashboards.items():
487
+ CfnOutput(
488
+ self,
489
+ f"DashboardUrl-{dashboard_name}",
490
+ value=f"https://console.aws.amazon.com/cloudwatch/home?region={self.region}#dashboards:name={dashboard_name}",
491
+ description=f"Dashboard URL: {dashboard_name}",
492
+ )
cdk_factory/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.9.11"
1
+ __version__ = "0.10.0"
@@ -42,6 +42,8 @@ class WorkloadFactory:
42
42
  runtime_directory=runtime_directory,
43
43
  paths=paths,
44
44
  )
45
+ # TODO: do we need to get other settings like configs, environment vars, etc?
46
+ outdir = outdir or "./cdk.out"
45
47
  self.workload: WorkloadConfig = WorkloadConfig(config=self.cdk_config.config)
46
48
  self.workload.paths = paths or []
47
49
  self.workload.cdk_app_file = cdk_app_file or __file__
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdk_factory
3
- Version: 0.9.11
3
+ Version: 0.10.0
4
4
  Summary: CDK Factory. A QuickStarter and best practices setup for CDK projects
5
5
  Author-email: Eric Wilson <eric.wilson@geekcafe.com>
6
6
  License: MIT License
@@ -1,8 +1,8 @@
1
1
  cdk_factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- cdk_factory/app.py,sha256=Hszv0nQAaCOULvOKWitxLyKnU9keUnb9MOKGPe0RaFo,9060
2
+ cdk_factory/app.py,sha256=RnX0-pwdTAPAdKJK_j13Zl8anf9zYKBwboR0KA8K8xM,10346
3
3
  cdk_factory/cdk.json,sha256=SKZKhJ2PBpFH78j-F8S3VDYW-lf76--Q2I3ON-ZIQfw,3106
4
4
  cdk_factory/cli.py,sha256=FGbCTS5dYCNsfp-etshzvFlGDCjC28r6rtzYbe7KoHI,6407
5
- cdk_factory/version.py,sha256=hCWvJmnndbpxCyOQ7z-g5qleaxwixXNqkmkxuORqf1I,23
5
+ cdk_factory/version.py,sha256=v4zmKjsKOPZbp6BrWoz7iK4ST0sdZdUh9bQSJmluZ5o,23
6
6
  cdk_factory/builds/README.md,sha256=9BBWd7bXpyKdMU_g2UljhQwrC9i5O_Tvkb6oPvndoZk,90
7
7
  cdk_factory/commands/command_loader.py,sha256=QbLquuP_AdxtlxlDy-2IWCQ6D-7qa58aphnDPtp_uTs,3744
8
8
  cdk_factory/configurations/base_config.py,sha256=JKjhNsy0RCUZy1s8n5D_aXXI-upR9izaLtCTfKYiV9k,9624
@@ -20,8 +20,8 @@ cdk_factory/configurations/workload.py,sha256=sM-B6UKOdOn5_H-eWmW03J9oa8YZZmO0bv
20
20
  cdk_factory/configurations/resources/_resources.py,sha256=tnXGn4kEC0JPQaTWB3QpAZG-2hIGBtugHTzuKn1OTvE,2548
21
21
  cdk_factory/configurations/resources/api_gateway.py,sha256=-k4hMGszIdQLb5DGmWBIPy49YGutp8zczafRh-Vob0I,4904
22
22
  cdk_factory/configurations/resources/apigateway_route_config.py,sha256=6ytn_nwKwlfpBtHL5sV6gxMpgAJ3p6QFGumMoW4CTHM,2351
23
- cdk_factory/configurations/resources/auto_scaling.py,sha256=OAVl8iUdHiOYVzme1qNDwA3w2raxDNUo_W2_Vebqtx8,5005
24
- cdk_factory/configurations/resources/cloudfront.py,sha256=xwDIrYQDqQMgekXSJ5vrgNXIUCfY6O8aiybE5ewwijw,1055
23
+ cdk_factory/configurations/resources/auto_scaling.py,sha256=rY-lZBZIS3bq0Lzf4IGbmMxhgiD_tknjjTZhh4Z6yFI,5922
24
+ cdk_factory/configurations/resources/cloudfront.py,sha256=oCWa9I8hbXVu114t-IO5frW6hgvPoovFgDbipDqFoGs,3848
25
25
  cdk_factory/configurations/resources/cloudwatch_widget.py,sha256=EdEQSXUkDtoY_Mg_cJBWo1Hp84jSiK7U9tsd3k1VhKI,1271
26
26
  cdk_factory/configurations/resources/code_artifact.py,sha256=P2X2i6NEcePitEf2wkN6lFTjIbXasn0uzrlPOT0tEac,3253
27
27
  cdk_factory/configurations/resources/code_artifact_login.py,sha256=mKd8Bx0WypmSspfibwXbgubbIzW-6gGdQqIHvOnDAYQ,6066
@@ -30,12 +30,14 @@ cdk_factory/configurations/resources/cognito.py,sha256=udX2AJ1ITLhy4f1XiJQwrva6F
30
30
  cdk_factory/configurations/resources/docker.py,sha256=hUbuxkuhcQu9LnLX7I8_57eTmHefEAGVnOHO37MkqC4,2166
31
31
  cdk_factory/configurations/resources/dynamodb.py,sha256=HsZMOaRwfuNPwKIzokeeE3f5zAQLTB5hRb_GzYq2ibg,2903
32
32
  cdk_factory/configurations/resources/ecr.py,sha256=o9hHzEBVPoxUvWZGXGbRJ-98FmP6fMLY5a1-qg42jL0,8253
33
- cdk_factory/configurations/resources/ecs_service.py,sha256=kEzSlasDejobl1ZxZtgtM7kVYF11AT3vCGsDInQNY3I,4319
33
+ cdk_factory/configurations/resources/ecs_service.py,sha256=NlFkSgWhO58QtCGZZRFQECA3km7O5D_Ee0BIfAcfDxE,4729
34
34
  cdk_factory/configurations/resources/exisiting.py,sha256=EVOLnkB-DGfTlmDgyQ5DD5k2zYfpFxqI3gugDR7mifI,478
35
+ cdk_factory/configurations/resources/lambda_edge.py,sha256=2rcwk2MlvW9mW2qHbNg7CsSNilZrJlmDXDjitKr5xyM,3256
35
36
  cdk_factory/configurations/resources/lambda_function.py,sha256=VENZ9-ABJ5mjcN8J8wdLH4KHDYr1kWO0iFDH0B2mJXA,14659
36
37
  cdk_factory/configurations/resources/lambda_layers.py,sha256=gVeP_-LC3Eq0lkPaG_JfFUwboM5evRPr99SfKj53m7A,633
37
38
  cdk_factory/configurations/resources/lambda_triggers.py,sha256=MD7cdMNKEulNBhtMLIFnWJuJ5R-yyIqa0LHUgbSQerA,834
38
39
  cdk_factory/configurations/resources/load_balancer.py,sha256=DHVKuEDaTfbB0UKYBt7UQQCPCM4FY-ThT1T52lcwg_E,4897
40
+ cdk_factory/configurations/resources/monitoring.py,sha256=zsfDMa7yph33Ql8iP7lIqqLAyixh-Mesi0imtZJFdcE,2310
39
41
  cdk_factory/configurations/resources/rds.py,sha256=vHmR1zpDmV8HqgYhLgWi26w0S3lJN9hpgFboomiQgY8,4315
40
42
  cdk_factory/configurations/resources/resource_mapping.py,sha256=cwv3n63RJ6E59ErsmSTdkW4i-g8huhHtKI0ExbRhJxA,2182
41
43
  cdk_factory/configurations/resources/resource_naming.py,sha256=VE9S2cpzp11qqPL2z1sX79wXH0o1SntO2OG74nEmWC8,5508
@@ -48,7 +50,7 @@ cdk_factory/configurations/resources/security_group.py,sha256=8kQtaaRVEn2aDm8XoC
48
50
  cdk_factory/configurations/resources/security_group_full_stack.py,sha256=x5MIMCa_olO7prFBKx9zVOfvsVdKo-2mWyhrCy27dFw,2031
49
51
  cdk_factory/configurations/resources/sqs.py,sha256=fAh2dqttJ6PX46enFRULuiLEu3TEj0Vb2xntAOgUpYE,4346
50
52
  cdk_factory/configurations/resources/vpc.py,sha256=sNn6w76bHFwmt6N76gZZhqpsuNB9860C1SZu6tebaXY,3835
51
- cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py,sha256=7uDkDbFigeUOuYgsQ9ghA4dGlx63rUCa6Iiq4RWokEA,14627
53
+ cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py,sha256=Eu30OITGGZaSoMq9Nj7tFGohgDO0-Ls7yKjpwYI2HrQ,16956
52
54
  cdk_factory/constructs/ecr/ecr_construct.py,sha256=JLz3gWrsjlM0XghvbgxuoGlF-VIo_7IYxtgX7mTkidE,10660
53
55
  cdk_factory/constructs/lambdas/lambda_function_construct.py,sha256=SQ5SEXn4kezVAzXuv_A_JB3o_svyBXOMi-htvfB9HQs,4516
54
56
  cdk_factory/constructs/lambdas/lambda_function_docker_construct.py,sha256=aSyn3eh1YnuIahZ7CbZ5WswwPL8u70ZibMoS24QQifc,9907
@@ -64,8 +66,9 @@ cdk_factory/interfaces/istack.py,sha256=bhTBs-o9FgKwvJMSuwxjUV6D3nUlvZHVzfm27jP9
64
66
  cdk_factory/interfaces/live_ssm_resolver.py,sha256=3FIr9a02SXqZmbFs3RT0WxczWEQR_CF7QSt7kWbDrVE,8163
65
67
  cdk_factory/interfaces/ssm_parameter_mixin.py,sha256=uA2j8HmAOpuEA9ynRj51s0WjUHMVLsbLQN-QS9NKyHA,12089
66
68
  cdk_factory/lambdas/health_handler.py,sha256=dd40ykKMxWCFEIyp2ZdQvAGNjw_ylI9CSm1N24Hp2ME,196
69
+ cdk_factory/lambdas/edge/ip_gate/handler.py,sha256=MPSAOQGYVMSALdH6f9QTXqMSKKJ1tva-yidtaDTbXsg,3241
67
70
  cdk_factory/pipeline/path_utils.py,sha256=fvWdrcb4onmpIu1APkHLhXg8zWfK74HcW3Ra2ynxfXM,2586
68
- cdk_factory/pipeline/pipeline_factory.py,sha256=miIJZFV7BLmL1r0Pv8ZNH8hu2j0SdXVcuScajIBCZYk,17163
71
+ cdk_factory/pipeline/pipeline_factory.py,sha256=rvtkdlTPJG477nTVRN8S2ksWt4bwpd9eVLFd9WO02pM,17248
69
72
  cdk_factory/pipeline/stage.py,sha256=Be7ExMB9A-linRM18IQDOzQ-cP_I2_ThRNzlT4FIrUg,437
70
73
  cdk_factory/pipeline/security/policies.py,sha256=H3-S6nipz3UtF9Pc5eJYr4-aREUTCaJWMjOUyd6Rdv4,4406
71
74
  cdk_factory/pipeline/security/roles.py,sha256=ZB_O5H_BXgotvVspS2kVad9EMcY-a_-vU7Nm1_Z5MB8,4985
@@ -78,19 +81,25 @@ cdk_factory/stack_library/__init__.py,sha256=5Y9TpIe8ZK1688G60PGcuP-hM0RvYEY_3Hl
78
81
  cdk_factory/stack_library/stack_base.py,sha256=tTleSFmlf26DuKVF_ytftf8P7IVWb5iex8cYfYupfvQ,4940
79
82
  cdk_factory/stack_library/api_gateway/api_gateway_stack.py,sha256=l6J5uurBQqbhj9JuvQitV9PiIHS5kqa-dFWifCeA3GM,39347
80
83
  cdk_factory/stack_library/auto_scaling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
- cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py,sha256=UsFqUb_3XPJAlmZ6F75nXna3elOggD1KuFmmdmhi0Lg,19070
84
+ cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py,sha256=XPTPGF-W8ARvzW8UYd4yPJ7xFUw-2BrdxQOYk9I-v3g,23490
82
85
  cdk_factory/stack_library/aws_lambdas/lambda_stack.py,sha256=SFbBPvvCopbyiuYtq-O5sQkFCf94Wzua6aDUXiFDSB4,26161
83
86
  cdk_factory/stack_library/buckets/README.md,sha256=XkK3UNVtRLE7NtUvbhCOBBYUYi8hlrrSaI1s3GJVrqI,78
84
87
  cdk_factory/stack_library/buckets/bucket_stack.py,sha256=SLoZqSffAqmeBBEVUQg54D_8Ad5UKdkjEAmKAVgAqQo,1778
88
+ cdk_factory/stack_library/cloudfront/__init__.py,sha256=Zfx50q4xIJ4ZEoVIzUBDTKbRE9DKDM6iyVIFhtQXvww,153
89
+ cdk_factory/stack_library/cloudfront/cloudfront_stack.py,sha256=-mw24FbvwLUzAa1NNKCKGFILZpNXtsuSdxNSNtEz6D8,26804
85
90
  cdk_factory/stack_library/code_artifact/code_artifact_stack.py,sha256=vySYIjWGTdVfMcUOyJdW6gTL1maHWq9ThzfrN_rVL5A,6290
86
91
  cdk_factory/stack_library/cognito/cognito_stack.py,sha256=zEHkKVCIeyZywPs_GIMXCXyCux9RAKdl5kba3wy8wtQ,24608
87
92
  cdk_factory/stack_library/dynamodb/dynamodb_stack.py,sha256=TVyOrUhgaSuN8uymkpaQcpOaSA0lkYJ8QUMgakTCKus,6771
88
93
  cdk_factory/stack_library/ecr/README.md,sha256=xw2wPx9WN03Y4BBwqvbi9lAFGNyaD1FUNpqxVJX14Oo,179
89
94
  cdk_factory/stack_library/ecr/ecr_stack.py,sha256=1xA68sxFVyqreYjXrP_7U9I8RF9RtFeR6KeEfSWuC2U,2118
90
95
  cdk_factory/stack_library/ecs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
91
- cdk_factory/stack_library/ecs/ecs_service_stack.py,sha256=mFanYtkZ9GpgT8g31D9tj-2yYbmmcuHN7ADaRD-ri9o,20638
96
+ cdk_factory/stack_library/ecs/ecs_service_stack.py,sha256=zuGdZEP5KmeVDTJb-H47LYhvs-85-Fi4Xb78nsA-lF4,24685
97
+ cdk_factory/stack_library/lambda_edge/__init__.py,sha256=ByBJ_CWdc4UtTmFBZH-6pzBMNkjkdtE65AmnB0Fs6lM,156
98
+ cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py,sha256=m87aaeGNEG-LN2mr6Kj6O3WmeXcmh-ACp8oXdlqOI1E,8070
92
99
  cdk_factory/stack_library/load_balancer/__init__.py,sha256=wZpKw2OecLJGdF5mPayCYAEhu2H3c2gJFFIxwXftGDU,52
93
100
  cdk_factory/stack_library/load_balancer/load_balancer_stack.py,sha256=t5JUe5lMUbQCRFZR08k8nO-g-53yWY8gKB9v8ZnedBs,24391
101
+ cdk_factory/stack_library/monitoring/__init__.py,sha256=k1G_KDx47Aw0UugaL99PN_TKlyLK4nkJVApCaAK7GJg,153
102
+ cdk_factory/stack_library/monitoring/monitoring_stack.py,sha256=N_1YvEXE7fboH_S3kv_dSKZsufxMuPdFMjGzlNFpuSo,19283
94
103
  cdk_factory/stack_library/rds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
95
104
  cdk_factory/stack_library/rds/rds_stack.py,sha256=-IQFmacO_UgedAN72Uo0ZGlcmqGcDinr3tquBdhQZXw,8559
96
105
  cdk_factory/stack_library/route53/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -119,9 +128,9 @@ cdk_factory/utilities/json_loading_utility.py,sha256=YRgzA1I-B_HwZm1eWJTeQ1JLkeb
119
128
  cdk_factory/utilities/lambda_function_utilities.py,sha256=S1GvBsY_q2cyUiaud3HORJMnLhI5cRi31fbeaktY-_Q,15826
120
129
  cdk_factory/utilities/os_execute.py,sha256=5Op0LY_8Y-pUm04y1k8MTpNrmQvcLmQHPQITEP7EuSU,1019
121
130
  cdk_factory/utils/api_gateway_utilities.py,sha256=If7Xu5s_UxmuV-kL3JkXxPLBdSVUKoLtohm0IUFoiV8,4378
122
- cdk_factory/workload/workload_factory.py,sha256=yBUDGIuB8-5p_mGcVFxsD2ZoZIziak3yh3LL3JvS0M4,5903
123
- cdk_factory-0.9.11.dist-info/METADATA,sha256=IGWNlOy29lMWoiIqxscoErO82WTWoCcYoabgefQMgw0,2451
124
- cdk_factory-0.9.11.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
125
- cdk_factory-0.9.11.dist-info/entry_points.txt,sha256=S1DPe0ORcdiwEALMN_WIo3UQrW_g4YdQCLEsc_b0Swg,53
126
- cdk_factory-0.9.11.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
127
- cdk_factory-0.9.11.dist-info/RECORD,,
131
+ cdk_factory/workload/workload_factory.py,sha256=mM8GU_5mKq_0OyK060T3JrUSUiGAcKf0eqNlT9mfaws,6028
132
+ cdk_factory-0.10.0.dist-info/METADATA,sha256=HZeUq_9_oU9e86iAoXouf2uIJNXlJMSk9P36L1vEBns,2451
133
+ cdk_factory-0.10.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
134
+ cdk_factory-0.10.0.dist-info/entry_points.txt,sha256=S1DPe0ORcdiwEALMN_WIo3UQrW_g4YdQCLEsc_b0Swg,53
135
+ cdk_factory-0.10.0.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
136
+ cdk_factory-0.10.0.dist-info/RECORD,,