cdk-factory 0.19.19__py3-none-any.whl → 0.20.5__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.
Files changed (20) hide show
  1. cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +122 -85
  2. cdk_factory/stack_library/ecs/ecs_cluster_stack.py +2 -2
  3. cdk_factory/stack_library/ecs/ecs_service_stack.py +2 -0
  4. cdk_factory/stack_library/lambda_edge/functions/README.md +0 -0
  5. cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/__init__.py +33 -0
  6. cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/app.py +30 -0
  7. cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/edge_log_retention.py +85 -0
  8. cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/requirements.txt +2 -0
  9. cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/test.py +22 -0
  10. cdk_factory/stack_library/lambda_edge/lambda_edge_log_retention_stack.py +0 -0
  11. cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +94 -8
  12. cdk_factory/stack_library/load_balancer/load_balancer_stack.py +4 -0
  13. cdk_factory/stack_library/route53/route53_stack.py +97 -133
  14. cdk_factory/version.py +1 -1
  15. {cdk_factory-0.19.19.dist-info → cdk_factory-0.20.5.dist-info}/METADATA +1 -1
  16. {cdk_factory-0.19.19.dist-info → cdk_factory-0.20.5.dist-info}/RECORD +19 -13
  17. cdk_factory/stack_library/lambda_edge/EDGE_LOG_RETENTION_TODO.md +0 -226
  18. {cdk_factory-0.19.19.dist-info → cdk_factory-0.20.5.dist-info}/WHEEL +0 -0
  19. {cdk_factory-0.19.19.dist-info → cdk_factory-0.20.5.dist-info}/entry_points.txt +0 -0
  20. {cdk_factory-0.19.19.dist-info → cdk_factory-0.20.5.dist-info}/licenses/LICENSE +0 -0
@@ -2,7 +2,7 @@ cdk_factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
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=7SkXrcCPPywUj5iTSUoEUN_6FonxdNwtTRVl_D3253s,24
5
+ cdk_factory/version.py,sha256=KohmrV3SWmyEbdcyopRMCctCtbthoMrxKM29jQ5Xa58,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=eJ3Pl3GWk1jVr_bYQaaWlw4_-ZiFGaiXllI_fOOX1i0,9323
@@ -86,7 +86,7 @@ cdk_factory/stack_library/acm/__init__.py,sha256=4FNRLykblcKZvq_wieYwvv9N_jgrZnJ
86
86
  cdk_factory/stack_library/acm/acm_stack.py,sha256=LW4QgzcMDvtSpqwfc4ykgpzDGvXe4udvWVE_DtBN4Zg,5414
87
87
  cdk_factory/stack_library/api_gateway/api_gateway_stack.py,sha256=PvLdGvcopGpLP0FwpfUcfXNiTIfYLTXqrG-TniE38yc,39643
88
88
  cdk_factory/stack_library/auto_scaling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
89
- cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py,sha256=G8OOgTAfsTDVArvuDfzuNpuGHzqz8kREHnnkMtjulAQ,25334
89
+ cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py,sha256=gjDxYWC4QZEZ4UOhGjgziggP7391dEMEe3vaslHSZ0c,25884
90
90
  cdk_factory/stack_library/aws_lambdas/lambda_stack.py,sha256=SFbBPvvCopbyiuYtq-O5sQkFCf94Wzua6aDUXiFDSB4,26161
91
91
  cdk_factory/stack_library/buckets/README.md,sha256=XkK3UNVtRLE7NtUvbhCOBBYUYi8hlrrSaI1s3GJVrqI,78
92
92
  cdk_factory/stack_library/buckets/bucket_stack.py,sha256=SLoZqSffAqmeBBEVUQg54D_8Ad5UKdkjEAmKAVgAqQo,1778
@@ -98,19 +98,25 @@ cdk_factory/stack_library/dynamodb/dynamodb_stack.py,sha256=-_Ij1zXIxUuZIWgdevam
98
98
  cdk_factory/stack_library/ecr/README.md,sha256=xw2wPx9WN03Y4BBwqvbi9lAFGNyaD1FUNpqxVJX14Oo,179
99
99
  cdk_factory/stack_library/ecr/ecr_stack.py,sha256=KLbd5WN5-ZiojsS5wJ4PX-tIL0cCylCSvXjO6sVrgWY,2102
100
100
  cdk_factory/stack_library/ecs/__init__.py,sha256=o5vGDtD_h-gVXb3-Ysr8xUNpEcMsnmMVgZv2Pupcdow,219
101
- cdk_factory/stack_library/ecs/ecs_cluster_stack.py,sha256=sAPTLU5CAwMoLTW_pNy_cd0OtVkfDR7IxxsSq5AE0yo,12091
102
- cdk_factory/stack_library/ecs/ecs_service_stack.py,sha256=KB4YCIsMm5JIGM9Bm-bKcr3eX5xXFgnoA7jST_ekK44,28209
103
- cdk_factory/stack_library/lambda_edge/EDGE_LOG_RETENTION_TODO.md,sha256=nD49nLm5OyrZUvcGNFBy9H1MfSUOuZ7sasHNI-IO0Zk,6635
101
+ cdk_factory/stack_library/ecs/ecs_cluster_stack.py,sha256=j0Cc7CyTK8MQDGCeZzo7XYrj1AM1hQBLH9DGXs7k-hQ,12165
102
+ cdk_factory/stack_library/ecs/ecs_service_stack.py,sha256=fm3Q2oeMN5JULatYFrQDfyTs58k283weQjPEuhpz1Sc,28297
104
103
  cdk_factory/stack_library/lambda_edge/__init__.py,sha256=ByBJ_CWdc4UtTmFBZH-6pzBMNkjkdtE65AmnB0Fs6lM,156
105
- cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py,sha256=b8PE4v5zGsqu_mVOaPejb8JKkV6b83N-VS0AxSlLTtk,20119
104
+ cdk_factory/stack_library/lambda_edge/lambda_edge_log_retention_stack.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
+ cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py,sha256=QxuyJ1mR8018HRqDXERkmsFMuEHd5YsVIACmXitYZDY,23344
106
+ cdk_factory/stack_library/lambda_edge/functions/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
+ cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/__init__.py,sha256=0JJIk47ubXY4QddDJ6hyyDMXBGYd0IzQyd3-SPqVikU,964
108
+ cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/app.py,sha256=i77H3f0KATiNhnPo0Ca8-B5OWPtDRT8def4HHiCp8Zw,858
109
+ cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/edge_log_retention.py,sha256=a-i0N_44RehzHA_hSx0Z9NFLfy4T-RZKA1sMS-CcYAw,3744
110
+ cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/requirements.txt,sha256=nJ0ZsOr7cuZEKNQd6e3EPStDJI7Y5Jnshi-FoydLE7o,46
111
+ cdk_factory/stack_library/lambda_edge/functions/log_retention_manager/test.py,sha256=CwjyMIjQ5kbeYicMUnAIK3eflBYbobEaM1noq-7Ck1Q,567
106
112
  cdk_factory/stack_library/load_balancer/__init__.py,sha256=wZpKw2OecLJGdF5mPayCYAEhu2H3c2gJFFIxwXftGDU,52
107
- cdk_factory/stack_library/load_balancer/load_balancer_stack.py,sha256=ApW5q3SAvSJtiK0RInNljmubqXqKZU5QBAaUoeIW-pM,28287
113
+ cdk_factory/stack_library/load_balancer/load_balancer_stack.py,sha256=iR-l5ujLS4zUReI-deWs8sDIUbmFYoWKt9kEZri1z2A,28441
108
114
  cdk_factory/stack_library/monitoring/__init__.py,sha256=k1G_KDx47Aw0UugaL99PN_TKlyLK4nkJVApCaAK7GJg,153
109
115
  cdk_factory/stack_library/monitoring/monitoring_stack.py,sha256=N_1YvEXE7fboH_S3kv_dSKZsufxMuPdFMjGzlNFpuSo,19283
110
116
  cdk_factory/stack_library/rds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
111
117
  cdk_factory/stack_library/rds/rds_stack.py,sha256=VToW-uFKAfilyhN4T8-TXaFW8f_VuXEIuUoBHvDN0Ns,14398
112
118
  cdk_factory/stack_library/route53/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
113
- cdk_factory/stack_library/route53/route53_stack.py,sha256=taREOw-s7i1NZcdR-za1lKkj-Cj8UPmr4BO5txS18fI,18348
119
+ cdk_factory/stack_library/route53/route53_stack.py,sha256=PaYpVVYC_jZ-pbsmK0vW_OVleJ4En0L2O_a92jlWi18,16601
114
120
  cdk_factory/stack_library/rum/__init__.py,sha256=gUrWQdzd4rZ2J0YzAQC8PsEGAS7QgyYjB2ZCUKWasy4,90
115
121
  cdk_factory/stack_library/rum/rum_stack.py,sha256=c67m0Jbyx8hx9TTx9TBBhZMDqtSK7QCqKx_Ec1t8LgY,14067
116
122
  cdk_factory/stack_library/security_group/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -137,8 +143,8 @@ cdk_factory/utilities/os_execute.py,sha256=5Op0LY_8Y-pUm04y1k8MTpNrmQvcLmQHPQITE
137
143
  cdk_factory/utils/api_gateway_utilities.py,sha256=If7Xu5s_UxmuV-kL3JkXxPLBdSVUKoLtohm0IUFoiV8,4378
138
144
  cdk_factory/validation/config_validator.py,sha256=Pb0TkLiPFzUplBOgMorhRCVm08vEzZhRU5xXCDTa5CA,17602
139
145
  cdk_factory/workload/workload_factory.py,sha256=yDI3cRhVI5ELNDcJPLpk9UY54Uind1xQoV3spzT4z7E,6068
140
- cdk_factory-0.19.19.dist-info/METADATA,sha256=syphI_KKN3_606LBfCKYQLU_3YX4ppprIwsKcAENNBk,2452
141
- cdk_factory-0.19.19.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
142
- cdk_factory-0.19.19.dist-info/entry_points.txt,sha256=S1DPe0ORcdiwEALMN_WIo3UQrW_g4YdQCLEsc_b0Swg,53
143
- cdk_factory-0.19.19.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
144
- cdk_factory-0.19.19.dist-info/RECORD,,
146
+ cdk_factory-0.20.5.dist-info/METADATA,sha256=a19HKUiZr8FOVgDbMbQj6mmhVd4QL1ESVrexE5yL7BY,2451
147
+ cdk_factory-0.20.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
148
+ cdk_factory-0.20.5.dist-info/entry_points.txt,sha256=S1DPe0ORcdiwEALMN_WIo3UQrW_g4YdQCLEsc_b0Swg,53
149
+ cdk_factory-0.20.5.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
150
+ cdk_factory-0.20.5.dist-info/RECORD,,
@@ -1,226 +0,0 @@
1
- # Lambda@Edge Log Retention - Implementation Plan
2
-
3
- ## 🚨 Current Status: DISABLED
4
-
5
- Lambda@Edge log retention configuration has been **disabled** because edge log groups are created on-demand when the function is invoked at edge locations, not during CloudFormation deployment.
6
-
7
- ## 🔍 Problem Analysis
8
-
9
- ### Why Deployment-Time Configuration Fails
10
- 1. **On-Demand Creation**: Lambda@Edge log groups are created only when the function is actually invoked at edge locations
11
- 2. **Timing Issue**: CloudFormation deployment happens before any edge invocations occur
12
- 3. **Error**: `The specified log group does not exist` when trying to set retention policies
13
-
14
- ### Log Group Naming Pattern
15
- ```
16
- Pattern: /aws/lambda/{edge-region}.{function-name}
17
- Example: /aws/lambda/eu-central-1.trav-talks-blue-green-edge-function
18
- Location: All edge log groups are created in us-east-1
19
- ```
20
-
21
- ## 💡 Proposed Solutions
22
-
23
- ### Solution 1: EventBridge + Lambda (Recommended)
24
- ```yaml
25
- # EventBridge rule to detect log group creation
26
- EventPattern:
27
- source: ["aws.logs"]
28
- detail-type: ["AWS API Call via CloudTrail"]
29
- detail:
30
- eventSource: ["logs.amazonaws.com"]
31
- eventName: ["CreateLogGroup"]
32
- requestParameters:
33
- logGroupName: ["/aws/lambda/*.edge-function"]
34
- ```
35
-
36
- **Implementation:**
37
- 1. Create EventBridge rule that triggers on log group creation
38
- 2. Lambda function receives event and sets retention policy
39
- 3. Automatic handling of new edge log groups
40
-
41
- **Pros:**
42
- - Automatic and real-time
43
- - No manual intervention required
44
- - Handles all edge regions
45
-
46
- **Cons:**
47
- - Additional Lambda function to maintain
48
- - Requires CloudTrail enabled for CloudWatch Logs
49
-
50
- ### Solution 2: Periodic Lambda Function
51
- ```python
52
- def lambda_handler(event, context):
53
- # Scan for edge log groups
54
- log_groups = logs.describe_log_groups(
55
- logGroupNamePrefix='/aws/lambda/eu-central-1.trav-talks-blue-green-edge-function'
56
- )
57
-
58
- # Apply retention policy
59
- for log_group in log_groups['logGroups']:
60
- logs.put_retention_policy(
61
- logGroupName=log_group['logGroupName'],
62
- retentionInDays=7
63
- )
64
- ```
65
-
66
- **Implementation:**
67
- 1. Create Lambda function on schedule (e.g., every hour)
68
- 2. Scan for edge log groups with function name pattern
69
- 3. Apply retention policy if not already set
70
-
71
- **Pros:**
72
- - Simple to implement
73
- - No CloudTrail dependency
74
- - Can handle existing log groups
75
-
76
- **Cons:**
77
- - Not real-time (delayed retention)
78
- - Runs periodically even when not needed
79
-
80
- ### Solution 3: Post-Deployment Script
81
- ```bash
82
- #!/bin/bash
83
- # Wait for edge log groups to appear
84
- function_name="trav-talks-blue-green-edge-function"
85
- edge_regions=("eu-central-1" "eu-west-1" "ap-southeast-1")
86
-
87
- for region in "${edge_regions[@]}"; do
88
- log_group="/aws/lambda/${region}.${function_name}"
89
-
90
- # Wait for log group to exist
91
- until aws logs describe-log-groups --log-group-name-prefix "$log_group" --region us-east-1; do
92
- echo "Waiting for log group: $log_group"
93
- sleep 30
94
- done
95
-
96
- # Set retention policy
97
- aws logs put-retention-policy --log-group-name "$log_group" --retention-in-days 7 --region us-east-1
98
- done
99
- ```
100
-
101
- **Implementation:**
102
- 1. Script runs after Lambda@Edge deployment
103
- 2. Waits for edge log groups to be created
104
- 3. Sets retention policies when they appear
105
-
106
- **Pros:**
107
- - Direct control over timing
108
- - No additional AWS resources needed
109
-
110
- **Cons:**
111
- - Manual process
112
- - Hard to determine when log groups will appear
113
- - Not automated
114
-
115
- ### Solution 4: CloudWatch Logs Subscription
116
- ```python
117
- # Lambda triggered by log group creation via subscription filter
118
- def lambda_handler(event, context):
119
- for record in event['Records']:
120
- log_group = record['logGroup']
121
- if 'edge-function' in log_group:
122
- # Set retention policy
123
- logs.put_retention_policy(
124
- logGroupName=log_group,
125
- retentionInDays=7
126
- )
127
- ```
128
-
129
- **Implementation:**
130
- 1. Create subscription filter on log group pattern
131
- 2. Lambda function triggered by log events
132
- 3. Set retention policy on first log event
133
-
134
- **Pros:**
135
- - Event-driven
136
- - No CloudTrail needed
137
-
138
- **Cons:**
139
- - Requires log group to exist first
140
- - Complex subscription filter setup
141
-
142
- ## 🎯 Recommended Implementation
143
-
144
- ### Phase 1: Quick Win (Solution 2)
145
- Implement periodic Lambda function as temporary solution:
146
- - Easy to implement quickly
147
- - Solves immediate problem
148
- - Can be replaced later with better solution
149
-
150
- ### Phase 2: Production Solution (Solution 1)
151
- Implement EventBridge + Lambda for production:
152
- - Real-time response
153
- - Automatic handling
154
- - Best long-term solution
155
-
156
- ## 📋 Implementation Steps for Solution 1
157
-
158
- ### 1. Create EventBridge Rule
159
- ```python
160
- event_rule = events.Rule(
161
- self, "EdgeLogGroupRule",
162
- event_pattern=events.EventPattern(
163
- source=["aws.logs"],
164
- detail_type=["AWS API Call via CloudTrail"],
165
- detail={
166
- "eventSource": ["logs.amazonaws.com"],
167
- "eventName": ["CreateLogGroup"],
168
- "requestParameters": {
169
- "logGroupName": [{"prefix": "/aws/lambda/"}]
170
- }
171
- }
172
- )
173
- )
174
- ```
175
-
176
- ### 2. Create Lambda Function
177
- ```python
178
- retention_handler = _lambda.Function(
179
- self, "EdgeLogRetentionHandler",
180
- runtime=_lambda.Runtime.PYTHON_3_9,
181
- handler="handler.lambda_handler",
182
- code=_lambda.Code.from_asset("lambda/edge_log_retention"),
183
- environment={
184
- "RETENTION_DAYS": "7",
185
- "FUNCTION_NAME_PATTERN": "*edge-function"
186
- }
187
- )
188
- ```
189
-
190
- ### 3. Add Permissions
191
- ```python
192
- retention_handler.add_to_role_policy(
193
- iam.PolicyStatement(
194
- actions=["logs:PutRetentionPolicy", "logs:DescribeLogGroups"],
195
- resources=["*"]
196
- )
197
- )
198
- ```
199
-
200
- ### 4. Connect EventBridge to Lambda
201
- ```python
202
- event_rule.add_target(targets.LambdaFunction(retention_handler))
203
- ```
204
-
205
- ## 🔧 Current Configuration
206
-
207
- The edge log retention configuration is currently **disabled** in the Lambda Edge stack:
208
-
209
- ```python
210
- def _configure_edge_log_retention(self, function_name: str) -> None:
211
- # DISABLED: See implementation plan above
212
- logger.warning("Edge log retention disabled - see TODO for implementation")
213
- return
214
- ```
215
-
216
- ## 📊 Configuration Impact
217
-
218
- | Setting | Current Behavior | Target Behavior |
219
- |---------|------------------|-----------------|
220
- | `edge_log_retention_days` | Warning logged, no action applied | Retention policy set on all edge log groups |
221
- | Edge log groups | Created with default retention (never expire) | Created with specified retention (e.g., 7 days) |
222
- | Cost impact | Potential high log storage costs | Controlled log storage costs |
223
-
224
- ---
225
-
226
- **Status**: Ready for implementation when edge log retention is required.