cdk-factory 0.13.2__py3-none-any.whl → 0.13.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.
Potentially problematic release.
This version of cdk-factory might be problematic. Click here for more details.
- cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py +43 -2
- cdk_factory/lambdas/edge/ip_gate/handler.py +15 -5
- cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +18 -3
- cdk_factory/version.py +1 -1
- {cdk_factory-0.13.2.dist-info → cdk_factory-0.13.5.dist-info}/METADATA +1 -1
- {cdk_factory-0.13.2.dist-info → cdk_factory-0.13.5.dist-info}/RECORD +9 -9
- {cdk_factory-0.13.2.dist-info → cdk_factory-0.13.5.dist-info}/WHEEL +0 -0
- {cdk_factory-0.13.2.dist-info → cdk_factory-0.13.5.dist-info}/entry_points.txt +0 -0
- {cdk_factory-0.13.2.dist-info → cdk_factory-0.13.5.dist-info}/licenses/LICENSE +0 -0
|
@@ -118,11 +118,17 @@ class CloudFrontDistributionConstruct(Construct):
|
|
|
118
118
|
origin_access_identity=self.oai,
|
|
119
119
|
)
|
|
120
120
|
|
|
121
|
+
# Get comment from config, or use default
|
|
122
|
+
comment = "CloudFront Distribution generated via the CDK Factory"
|
|
123
|
+
if self.stack_config and isinstance(self.stack_config, StackConfig):
|
|
124
|
+
cloudfront_config = self.stack_config.dictionary.get("cloudfront", {})
|
|
125
|
+
comment = cloudfront_config.get("comment", comment)
|
|
126
|
+
|
|
121
127
|
distribution = cloudfront.Distribution(
|
|
122
128
|
self,
|
|
123
129
|
"cloudfront-dist",
|
|
124
130
|
domain_names=self.aliases,
|
|
125
|
-
comment=
|
|
131
|
+
comment=comment,
|
|
126
132
|
certificate=self.certificate,
|
|
127
133
|
default_behavior=cloudfront.BehaviorOptions(
|
|
128
134
|
origin=origin,
|
|
@@ -228,6 +234,15 @@ class CloudFrontDistributionConstruct(Construct):
|
|
|
228
234
|
"""
|
|
229
235
|
Get the Lambda@Edge associations for the distribution from config.
|
|
230
236
|
|
|
237
|
+
Supports two configuration methods:
|
|
238
|
+
1. Convenience flag: "enable_ip_gating": true
|
|
239
|
+
- Automatically adds Lambda@Edge IP gating function
|
|
240
|
+
- Uses auto-derived SSM parameter path: /{env}/{workload}/lambda-edge/version-arn
|
|
241
|
+
|
|
242
|
+
2. Manual configuration: "lambda_edge_associations": [...]
|
|
243
|
+
- Full control over Lambda@Edge associations
|
|
244
|
+
- Can specify custom ARNs, event types, etc.
|
|
245
|
+
|
|
231
246
|
Returns:
|
|
232
247
|
List[cloudfront.EdgeLambda] or None: list of Lambda@Edge associations
|
|
233
248
|
"""
|
|
@@ -235,7 +250,33 @@ class CloudFrontDistributionConstruct(Construct):
|
|
|
235
250
|
|
|
236
251
|
if self.stack_config and isinstance(self.stack_config, StackConfig):
|
|
237
252
|
cloudfront_config = self.stack_config.dictionary.get("cloudfront", {})
|
|
238
|
-
|
|
253
|
+
|
|
254
|
+
# Check for convenience IP gating flag
|
|
255
|
+
enable_ip_gating = cloudfront_config.get("enable_ip_gating", False)
|
|
256
|
+
if enable_ip_gating:
|
|
257
|
+
logger.info("IP gating enabled via convenience flag - adding Lambda@Edge association")
|
|
258
|
+
|
|
259
|
+
# Extract environment and workload name from config
|
|
260
|
+
# These come from the workload/deployment configuration
|
|
261
|
+
workload_dict = self.stack_config.workload
|
|
262
|
+
environment = workload_dict.get("deployment", {}).get("environment", "dev")
|
|
263
|
+
workload_name = workload_dict.get("name", "workload")
|
|
264
|
+
|
|
265
|
+
# Auto-derive SSM parameter path or use override
|
|
266
|
+
default_ssm_path = f"/{environment}/{workload_name}/lambda-edge/version-arn"
|
|
267
|
+
ip_gate_ssm_path = cloudfront_config.get("ip_gate_function_ssm_path", default_ssm_path)
|
|
268
|
+
|
|
269
|
+
logger.info(f"Using IP gate Lambda ARN from SSM: {ip_gate_ssm_path}")
|
|
270
|
+
|
|
271
|
+
# Add the IP gating Lambda@Edge association
|
|
272
|
+
lambda_edge_associations = [{
|
|
273
|
+
"event_type": "origin-request",
|
|
274
|
+
"lambda_arn": f"{{{{ssm:{ip_gate_ssm_path}}}}}",
|
|
275
|
+
"include_body": False
|
|
276
|
+
}]
|
|
277
|
+
else:
|
|
278
|
+
# Use manual configuration
|
|
279
|
+
lambda_edge_associations = cloudfront_config.get("lambda_edge_associations", [])
|
|
239
280
|
|
|
240
281
|
for association in lambda_edge_associations:
|
|
241
282
|
event_type_str = association.get("event_type", "origin-request")
|
|
@@ -20,12 +20,14 @@ def get_ssm_parameter(parameter_name: str, region: str = 'us-east-1') -> str:
|
|
|
20
20
|
Fetch SSM parameter with caching.
|
|
21
21
|
Lambda@Edge cannot use environment variables, so we fetch from SSM.
|
|
22
22
|
|
|
23
|
+
The sentinel value 'NONE' indicates an explicitly unset/disabled parameter.
|
|
24
|
+
|
|
23
25
|
Args:
|
|
24
26
|
parameter_name: Name of the SSM parameter
|
|
25
27
|
region: AWS region (default us-east-1)
|
|
26
28
|
|
|
27
29
|
Returns:
|
|
28
|
-
Parameter value
|
|
30
|
+
Parameter value, or empty string if value is 'NONE'
|
|
29
31
|
"""
|
|
30
32
|
global ssm
|
|
31
33
|
if ssm is None:
|
|
@@ -33,7 +35,14 @@ def get_ssm_parameter(parameter_name: str, region: str = 'us-east-1') -> str:
|
|
|
33
35
|
|
|
34
36
|
try:
|
|
35
37
|
response = ssm.get_parameter(Name=parameter_name, WithDecryption=False)
|
|
36
|
-
|
|
38
|
+
value = response['Parameter']['Value']
|
|
39
|
+
|
|
40
|
+
# Treat 'NONE' sentinel as empty/unset
|
|
41
|
+
if value == 'NONE':
|
|
42
|
+
print(f"SSM parameter {parameter_name} is set to 'NONE' (explicitly disabled)")
|
|
43
|
+
return ''
|
|
44
|
+
|
|
45
|
+
return value
|
|
37
46
|
except Exception as e:
|
|
38
47
|
print(f"Error fetching SSM parameter {parameter_name}: {str(e)}")
|
|
39
48
|
raise
|
|
@@ -140,15 +149,16 @@ def lambda_handler(event, context):
|
|
|
140
149
|
gate_enabled = get_ssm_parameter(f'/{env}/{function_name}/gate-enabled', 'us-east-1')
|
|
141
150
|
|
|
142
151
|
# If gating is disabled, allow all traffic
|
|
143
|
-
|
|
144
|
-
|
|
152
|
+
# Empty string (from 'NONE' sentinel) is treated as disabled
|
|
153
|
+
if not gate_enabled or gate_enabled.lower() not in ('true', '1', 'yes'):
|
|
154
|
+
print(f"IP gating is disabled (GATE_ENABLED={gate_enabled or 'NONE'})")
|
|
145
155
|
return request
|
|
146
156
|
|
|
147
157
|
# Get allowed CIDRs and maintenance host
|
|
148
158
|
allow_cidrs_str = get_ssm_parameter(f'/{env}/{function_name}/allow-cidrs', 'us-east-1')
|
|
149
159
|
maint_cf_host = get_ssm_parameter(f'/{env}/{function_name}/maint-cf-host', 'us-east-1')
|
|
150
160
|
|
|
151
|
-
# Parse allowed CIDRs
|
|
161
|
+
# Parse allowed CIDRs (empty string results in empty list)
|
|
152
162
|
allowed_cidrs = [cidr.strip() for cidr in allow_cidrs_str.split(',') if cidr.strip()]
|
|
153
163
|
|
|
154
164
|
# Get client IP
|
|
@@ -87,7 +87,10 @@ class LambdaEdgeStack(IStack, EnhancedSsmParameterMixin):
|
|
|
87
87
|
deployment
|
|
88
88
|
)
|
|
89
89
|
|
|
90
|
-
|
|
90
|
+
# Use the Lambda function name from config (supports template variables)
|
|
91
|
+
# e.g., "{{WORKLOAD_NAME}}-{{ENVIRONMENT}}-ip-gate" becomes "tech-talk-dev-ip-gate"
|
|
92
|
+
function_name = self.edge_config.name
|
|
93
|
+
logger.info(f"Lambda function name: '{function_name}'")
|
|
91
94
|
|
|
92
95
|
# Create Lambda function
|
|
93
96
|
self._create_lambda_function(function_name)
|
|
@@ -181,9 +184,10 @@ class LambdaEdgeStack(IStack, EnhancedSsmParameterMixin):
|
|
|
181
184
|
|
|
182
185
|
# Create runtime configuration file for Lambda@Edge
|
|
183
186
|
# Since Lambda@Edge doesn't support environment variables, we bundle a config file
|
|
187
|
+
# Use the full function_name (e.g., "tech-talk-dev-ip-gate") not just the base name
|
|
184
188
|
runtime_config = {
|
|
185
189
|
'environment': self.deployment.environment,
|
|
186
|
-
'function_name':
|
|
190
|
+
'function_name': function_name,
|
|
187
191
|
'region': self.deployment.region
|
|
188
192
|
}
|
|
189
193
|
|
|
@@ -364,10 +368,21 @@ class LambdaEdgeStack(IStack, EnhancedSsmParameterMixin):
|
|
|
364
368
|
resolved_env = self._resolve_environment_variables()
|
|
365
369
|
for env_key, ssm_path in env_ssm_exports.items():
|
|
366
370
|
if env_key in resolved_env:
|
|
371
|
+
env_value = resolved_env[env_key]
|
|
372
|
+
|
|
373
|
+
# Handle empty values - SSM doesn't allow empty strings
|
|
374
|
+
# Use sentinel value "NONE" to indicate explicitly unset
|
|
375
|
+
if not env_value or (isinstance(env_value, str) and env_value.strip() == ""):
|
|
376
|
+
env_value = "NONE"
|
|
377
|
+
logger.info(
|
|
378
|
+
f"Environment variable {env_key} is empty - setting SSM parameter to 'NONE'. "
|
|
379
|
+
f"Lambda function should treat 'NONE' as unset/disabled."
|
|
380
|
+
)
|
|
381
|
+
|
|
367
382
|
self.export_ssm_parameter(
|
|
368
383
|
self,
|
|
369
384
|
f"env-{env_key}-param",
|
|
370
|
-
|
|
385
|
+
env_value,
|
|
371
386
|
ssm_path,
|
|
372
387
|
description=f"Configuration for Lambda@Edge: {env_key}"
|
|
373
388
|
)
|
cdk_factory/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.13.
|
|
1
|
+
__version__ = "0.13.5"
|
|
@@ -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=
|
|
5
|
+
cdk_factory/version.py,sha256=SPNxRvWdZ_wlG_AeFzA45_LV_z5u-nzgOJwVcknxEJ8,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
|
|
@@ -50,7 +50,7 @@ cdk_factory/configurations/resources/security_group.py,sha256=8kQtaaRVEn2aDm8XoC
|
|
|
50
50
|
cdk_factory/configurations/resources/security_group_full_stack.py,sha256=x5MIMCa_olO7prFBKx9zVOfvsVdKo-2mWyhrCy27dFw,2031
|
|
51
51
|
cdk_factory/configurations/resources/sqs.py,sha256=fAh2dqttJ6PX46enFRULuiLEu3TEj0Vb2xntAOgUpYE,4346
|
|
52
52
|
cdk_factory/configurations/resources/vpc.py,sha256=sNn6w76bHFwmt6N76gZZhqpsuNB9860C1SZu6tebaXY,3835
|
|
53
|
-
cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py,sha256=
|
|
53
|
+
cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py,sha256=MS3xrjm1I4gnUZorh2Orc6oi_fZE_ZPU29czDDhiD_A,20072
|
|
54
54
|
cdk_factory/constructs/ecr/ecr_construct.py,sha256=JLz3gWrsjlM0XghvbgxuoGlF-VIo_7IYxtgX7mTkidE,10660
|
|
55
55
|
cdk_factory/constructs/lambdas/lambda_function_construct.py,sha256=SQ5SEXn4kezVAzXuv_A_JB3o_svyBXOMi-htvfB9HQs,4516
|
|
56
56
|
cdk_factory/constructs/lambdas/lambda_function_docker_construct.py,sha256=aSyn3eh1YnuIahZ7CbZ5WswwPL8u70ZibMoS24QQifc,9907
|
|
@@ -66,7 +66,7 @@ cdk_factory/interfaces/istack.py,sha256=bhTBs-o9FgKwvJMSuwxjUV6D3nUlvZHVzfm27jP9
|
|
|
66
66
|
cdk_factory/interfaces/live_ssm_resolver.py,sha256=3FIr9a02SXqZmbFs3RT0WxczWEQR_CF7QSt7kWbDrVE,8163
|
|
67
67
|
cdk_factory/interfaces/ssm_parameter_mixin.py,sha256=uA2j8HmAOpuEA9ynRj51s0WjUHMVLsbLQN-QS9NKyHA,12089
|
|
68
68
|
cdk_factory/lambdas/health_handler.py,sha256=dd40ykKMxWCFEIyp2ZdQvAGNjw_ylI9CSm1N24Hp2ME,196
|
|
69
|
-
cdk_factory/lambdas/edge/ip_gate/handler.py,sha256=
|
|
69
|
+
cdk_factory/lambdas/edge/ip_gate/handler.py,sha256=4ijbIMdMId-9XQzerejWhizd8r-gm6cKlsnDIwftXow,6879
|
|
70
70
|
cdk_factory/pipeline/path_utils.py,sha256=fvWdrcb4onmpIu1APkHLhXg8zWfK74HcW3Ra2ynxfXM,2586
|
|
71
71
|
cdk_factory/pipeline/pipeline_factory.py,sha256=rvtkdlTPJG477nTVRN8S2ksWt4bwpd9eVLFd9WO02pM,17248
|
|
72
72
|
cdk_factory/pipeline/stage.py,sha256=Be7ExMB9A-linRM18IQDOzQ-cP_I2_ThRNzlT4FIrUg,437
|
|
@@ -95,7 +95,7 @@ cdk_factory/stack_library/ecr/ecr_stack.py,sha256=1xA68sxFVyqreYjXrP_7U9I8RF9RtF
|
|
|
95
95
|
cdk_factory/stack_library/ecs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
96
96
|
cdk_factory/stack_library/ecs/ecs_service_stack.py,sha256=zuGdZEP5KmeVDTJb-H47LYhvs-85-Fi4Xb78nsA-lF4,24685
|
|
97
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=
|
|
98
|
+
cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py,sha256=CdId_1kcZmYr1lLI9AD3-KqtE6voC3641PIloJmWiNI,16414
|
|
99
99
|
cdk_factory/stack_library/load_balancer/__init__.py,sha256=wZpKw2OecLJGdF5mPayCYAEhu2H3c2gJFFIxwXftGDU,52
|
|
100
100
|
cdk_factory/stack_library/load_balancer/load_balancer_stack.py,sha256=t5JUe5lMUbQCRFZR08k8nO-g-53yWY8gKB9v8ZnedBs,24391
|
|
101
101
|
cdk_factory/stack_library/monitoring/__init__.py,sha256=k1G_KDx47Aw0UugaL99PN_TKlyLK4nkJVApCaAK7GJg,153
|
|
@@ -129,8 +129,8 @@ cdk_factory/utilities/lambda_function_utilities.py,sha256=S1GvBsY_q2cyUiaud3HORJ
|
|
|
129
129
|
cdk_factory/utilities/os_execute.py,sha256=5Op0LY_8Y-pUm04y1k8MTpNrmQvcLmQHPQITEP7EuSU,1019
|
|
130
130
|
cdk_factory/utils/api_gateway_utilities.py,sha256=If7Xu5s_UxmuV-kL3JkXxPLBdSVUKoLtohm0IUFoiV8,4378
|
|
131
131
|
cdk_factory/workload/workload_factory.py,sha256=mM8GU_5mKq_0OyK060T3JrUSUiGAcKf0eqNlT9mfaws,6028
|
|
132
|
-
cdk_factory-0.13.
|
|
133
|
-
cdk_factory-0.13.
|
|
134
|
-
cdk_factory-0.13.
|
|
135
|
-
cdk_factory-0.13.
|
|
136
|
-
cdk_factory-0.13.
|
|
132
|
+
cdk_factory-0.13.5.dist-info/METADATA,sha256=nSjC-eYm9AeWwM3ICwdPTJl46PuprLmxIDHsxleN9T0,2451
|
|
133
|
+
cdk_factory-0.13.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
134
|
+
cdk_factory-0.13.5.dist-info/entry_points.txt,sha256=S1DPe0ORcdiwEALMN_WIo3UQrW_g4YdQCLEsc_b0Swg,53
|
|
135
|
+
cdk_factory-0.13.5.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
|
|
136
|
+
cdk_factory-0.13.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|