cdk-factory 0.16.15__py3-none-any.whl → 0.20.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.
- cdk_factory/configurations/base_config.py +23 -24
- cdk_factory/configurations/cdk_config.py +1 -1
- cdk_factory/configurations/deployment.py +12 -0
- cdk_factory/configurations/devops.py +1 -1
- cdk_factory/configurations/resources/acm.py +9 -2
- cdk_factory/configurations/resources/auto_scaling.py +7 -5
- cdk_factory/configurations/resources/cloudfront.py +7 -2
- cdk_factory/configurations/resources/ecr.py +1 -1
- cdk_factory/configurations/resources/ecs_cluster.py +12 -5
- cdk_factory/configurations/resources/ecs_service.py +30 -3
- cdk_factory/configurations/resources/lambda_edge.py +18 -4
- cdk_factory/configurations/resources/load_balancer.py +8 -9
- cdk_factory/configurations/resources/monitoring.py +8 -3
- cdk_factory/configurations/resources/rds.py +8 -9
- cdk_factory/configurations/resources/route53.py +5 -0
- cdk_factory/configurations/resources/rum.py +7 -2
- cdk_factory/configurations/resources/s3.py +10 -2
- cdk_factory/configurations/resources/security_group_full_stack.py +7 -8
- cdk_factory/configurations/resources/vpc.py +19 -0
- cdk_factory/configurations/workload.py +32 -2
- cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py +1 -1
- cdk_factory/constructs/ecr/ecr_construct.py +9 -2
- cdk_factory/constructs/lambdas/policies/policy_docs.py +4 -4
- cdk_factory/interfaces/istack.py +4 -4
- cdk_factory/interfaces/networked_stack_mixin.py +6 -6
- cdk_factory/interfaces/standardized_ssm_mixin.py +684 -0
- cdk_factory/interfaces/vpc_provider_mixin.py +64 -33
- cdk_factory/lambdas/edge/ip_gate/handler.py +42 -40
- cdk_factory/pipeline/pipeline_factory.py +3 -3
- cdk_factory/stack_library/__init__.py +3 -2
- cdk_factory/stack_library/acm/acm_stack.py +7 -17
- cdk_factory/stack_library/api_gateway/api_gateway_stack.py +84 -59
- cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +454 -537
- cdk_factory/stack_library/cloudfront/cloudfront_stack.py +76 -22
- cdk_factory/stack_library/code_artifact/code_artifact_stack.py +5 -27
- cdk_factory/stack_library/cognito/cognito_stack.py +152 -92
- cdk_factory/stack_library/dynamodb/dynamodb_stack.py +19 -15
- cdk_factory/stack_library/ecr/ecr_stack.py +2 -2
- cdk_factory/stack_library/ecs/__init__.py +1 -3
- cdk_factory/stack_library/ecs/ecs_cluster_stack.py +159 -75
- cdk_factory/stack_library/ecs/ecs_service_stack.py +59 -52
- cdk_factory/stack_library/lambda_edge/EDGE_LOG_RETENTION_TODO.md +226 -0
- cdk_factory/stack_library/lambda_edge/LAMBDA_EDGE_LOG_RETENTION_BLOG.md +215 -0
- cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +240 -83
- cdk_factory/stack_library/load_balancer/load_balancer_stack.py +139 -212
- cdk_factory/stack_library/rds/rds_stack.py +74 -98
- cdk_factory/stack_library/route53/route53_stack.py +246 -40
- cdk_factory/stack_library/rum/rum_stack.py +108 -91
- cdk_factory/stack_library/security_group/security_group_full_stack.py +10 -53
- cdk_factory/stack_library/security_group/security_group_stack.py +12 -19
- cdk_factory/stack_library/simple_queue_service/sqs_stack.py +1 -34
- cdk_factory/stack_library/stack_base.py +5 -0
- cdk_factory/stack_library/vpc/vpc_stack.py +171 -130
- cdk_factory/stack_library/websites/static_website_stack.py +7 -3
- cdk_factory/utilities/api_gateway_integration_utility.py +24 -16
- cdk_factory/utilities/environment_services.py +5 -5
- cdk_factory/utilities/json_loading_utility.py +1 -1
- cdk_factory/validation/config_validator.py +483 -0
- cdk_factory/version.py +1 -1
- {cdk_factory-0.16.15.dist-info → cdk_factory-0.20.0.dist-info}/METADATA +1 -1
- {cdk_factory-0.16.15.dist-info → cdk_factory-0.20.0.dist-info}/RECORD +64 -62
- cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +0 -321
- cdk_factory/interfaces/ssm_parameter_mixin.py +0 -454
- {cdk_factory-0.16.15.dist-info → cdk_factory-0.20.0.dist-info}/WHEEL +0 -0
- {cdk_factory-0.16.15.dist-info → cdk_factory-0.20.0.dist-info}/entry_points.txt +0 -0
- {cdk_factory-0.16.15.dist-info → cdk_factory-0.20.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -16,7 +16,7 @@ from cdk_factory.configurations.deployment import DeploymentConfig
|
|
|
16
16
|
from cdk_factory.configurations.resources.rum import RumConfig
|
|
17
17
|
from cdk_factory.configurations.stack import StackConfig
|
|
18
18
|
from cdk_factory.interfaces.istack import IStack
|
|
19
|
-
from cdk_factory.interfaces.
|
|
19
|
+
from cdk_factory.interfaces.standardized_ssm_mixin import StandardizedSsmMixin
|
|
20
20
|
from cdk_factory.stack.stack_module_registry import register_stack
|
|
21
21
|
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
22
22
|
|
|
@@ -25,7 +25,7 @@ logger = Logger(__name__)
|
|
|
25
25
|
|
|
26
26
|
@register_stack("rum_library_module")
|
|
27
27
|
@register_stack("rum_stack")
|
|
28
|
-
class RumStack(IStack,
|
|
28
|
+
class RumStack(IStack, StandardizedSsmMixin):
|
|
29
29
|
"""
|
|
30
30
|
RUM Stack - Creates a CloudWatch RUM app monitor with optional Cognito integration.
|
|
31
31
|
Can either use existing Cognito resources or create new ones if not provided.
|
|
@@ -51,17 +51,37 @@ class RumStack(IStack, EnhancedSsmParameterMixin):
|
|
|
51
51
|
self.stack_config = stack_config
|
|
52
52
|
self.deployment = deployment
|
|
53
53
|
self.rum_config = RumConfig(stack_config.dictionary.get("rum", {}))
|
|
54
|
-
|
|
54
|
+
|
|
55
55
|
logger.info(f"Building RUM stack: {self.rum_config.name}")
|
|
56
56
|
|
|
57
57
|
# Setup enhanced SSM integration
|
|
58
|
-
|
|
58
|
+
rum_config = stack_config.dictionary.get("rum", {}).copy()
|
|
59
|
+
|
|
60
|
+
# Configure SSM imports for cognito resources if needed
|
|
61
|
+
if not self.rum_config.cognito_identity_pool_id:
|
|
62
|
+
# Only add SSM imports if we have the required template variables
|
|
63
|
+
# Check if deployment has organization info for template resolution
|
|
64
|
+
if (hasattr(deployment, 'organization') and deployment.organization and
|
|
65
|
+
hasattr(deployment, 'environment') and deployment.environment):
|
|
66
|
+
# Add explicit import path for cognito identity pool using new pattern
|
|
67
|
+
if "ssm" not in rum_config:
|
|
68
|
+
rum_config["ssm"] = {}
|
|
69
|
+
if "imports" not in rum_config["ssm"]:
|
|
70
|
+
rum_config["ssm"]["imports"] = {}
|
|
71
|
+
rum_config["ssm"]["imports"][
|
|
72
|
+
"cognito_identity_pool_id"
|
|
73
|
+
] = "/{{ORGANIZATION}}/{{ENVIRONMENT}}/cognito/user-pool/identity-pool-id"
|
|
74
|
+
|
|
75
|
+
self.setup_ssm_integration(
|
|
59
76
|
scope=self,
|
|
60
|
-
config=
|
|
77
|
+
config=rum_config,
|
|
61
78
|
resource_type="rum",
|
|
62
|
-
resource_name=self.rum_config.name
|
|
79
|
+
resource_name=self.rum_config.name,
|
|
63
80
|
)
|
|
64
81
|
|
|
82
|
+
# Process SSM imports using standardized method
|
|
83
|
+
self.process_ssm_imports()
|
|
84
|
+
|
|
65
85
|
# Import or create Cognito resources
|
|
66
86
|
identity_pool_id, guest_role_arn = self._setup_cognito_integration()
|
|
67
87
|
|
|
@@ -84,14 +104,14 @@ class RumStack(IStack, EnhancedSsmParameterMixin):
|
|
|
84
104
|
identity_pool_id = self.rum_config.cognito_identity_pool_id
|
|
85
105
|
logger.info(f"Using existing Cognito Identity Pool: {identity_pool_id}")
|
|
86
106
|
else:
|
|
87
|
-
# Try to import from SSM using
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
107
|
+
# Try to import from SSM using standardized approach
|
|
108
|
+
cognito_identity_pool_id = self.get_ssm_imported_value("cognito_identity_pool_id")
|
|
109
|
+
|
|
110
|
+
if cognito_identity_pool_id:
|
|
111
|
+
identity_pool_id = cognito_identity_pool_id
|
|
112
|
+
logger.info(
|
|
113
|
+
f"Imported Cognito Identity Pool from SSM: {identity_pool_id}"
|
|
114
|
+
)
|
|
95
115
|
|
|
96
116
|
# If no existing identity pool found, create new Cognito resources
|
|
97
117
|
if not identity_pool_id and self.rum_config.create_cognito_identity_pool:
|
|
@@ -107,17 +127,21 @@ class RumStack(IStack, EnhancedSsmParameterMixin):
|
|
|
107
127
|
"""Create new Cognito User Pool and Identity Pool for RUM"""
|
|
108
128
|
logger.info("Creating new Cognito resources for RUM")
|
|
109
129
|
|
|
130
|
+
def _resource_name(name: str) -> str:
|
|
131
|
+
"""Helper to generate resource names"""
|
|
132
|
+
return f"{self.rum_config.name}-{name}"
|
|
133
|
+
|
|
110
134
|
# Create User Pool if needed
|
|
111
135
|
user_pool_id = self.rum_config.cognito_user_pool_id
|
|
112
136
|
if not user_pool_id and self.rum_config.create_cognito_user_pool:
|
|
113
137
|
self.user_pool = cognito.UserPool(
|
|
114
138
|
self,
|
|
115
|
-
id=
|
|
139
|
+
id=_resource_name("user-pool"),
|
|
116
140
|
user_pool_name=self.rum_config.cognito_user_pool_name,
|
|
117
141
|
self_sign_up_enabled=True,
|
|
118
142
|
sign_in_aliases=cognito.SignInAliases(email=True),
|
|
119
143
|
auto_verify=cognito.AutoVerifiedAttrs(email=True),
|
|
120
|
-
removal_policy=cdk.RemovalPolicy.DESTROY
|
|
144
|
+
removal_policy=cdk.RemovalPolicy.DESTROY,
|
|
121
145
|
)
|
|
122
146
|
user_pool_id = self.user_pool.user_pool_id
|
|
123
147
|
logger.info(f"Created Cognito User Pool: {user_pool_id}")
|
|
@@ -128,33 +152,34 @@ class RumStack(IStack, EnhancedSsmParameterMixin):
|
|
|
128
152
|
# Create User Pool Client for Identity Pool integration
|
|
129
153
|
user_pool_client = cognito.UserPoolClient(
|
|
130
154
|
self,
|
|
131
|
-
id=
|
|
155
|
+
id=_resource_name("user-pool-client"),
|
|
132
156
|
user_pool=self.user_pool,
|
|
133
157
|
generate_secret=False,
|
|
134
|
-
auth_flows=cognito.AuthFlow(
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
158
|
+
auth_flows=cognito.AuthFlow(user_srp=True, user_password=True),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
identity_pool_providers.append(
|
|
162
|
+
{
|
|
163
|
+
"providerName": f"cognito-idp.{self.region}.amazonaws.com/{user_pool_id}",
|
|
164
|
+
"providerType": "COGNITO_USER_POOLS",
|
|
165
|
+
"clientId": user_pool_client.user_pool_client_id,
|
|
166
|
+
}
|
|
138
167
|
)
|
|
139
|
-
|
|
140
|
-
identity_pool_providers.append({
|
|
141
|
-
"providerName": f"cognito-idp.{self.region}.amazonaws.com/{user_pool_id}",
|
|
142
|
-
"providerType": "COGNITO_USER_POOLS",
|
|
143
|
-
"clientId": user_pool_client.user_pool_client_id
|
|
144
|
-
})
|
|
145
168
|
|
|
146
169
|
self.identity_pool = cognito.CfnIdentityPool(
|
|
147
170
|
self,
|
|
148
|
-
id=
|
|
171
|
+
id=_resource_name("identity-pool"),
|
|
149
172
|
identity_pool_name=self.rum_config.cognito_identity_pool_name,
|
|
150
173
|
allow_unauthenticated_identities=True,
|
|
151
|
-
cognito_identity_providers=
|
|
174
|
+
cognito_identity_providers=(
|
|
175
|
+
identity_pool_providers if identity_pool_providers else None
|
|
176
|
+
),
|
|
152
177
|
)
|
|
153
178
|
|
|
154
179
|
# Create IAM role for unauthenticated users (guest role)
|
|
155
180
|
guest_role = iam.Role(
|
|
156
181
|
self,
|
|
157
|
-
id=
|
|
182
|
+
id=_resource_name("guest-role"),
|
|
158
183
|
assumed_by=iam.FederatedPrincipal(
|
|
159
184
|
"cognito-identity.amazonaws.com",
|
|
160
185
|
conditions={
|
|
@@ -163,52 +188,55 @@ class RumStack(IStack, EnhancedSsmParameterMixin):
|
|
|
163
188
|
},
|
|
164
189
|
"ForAnyValue:StringLike": {
|
|
165
190
|
"cognito-identity.amazonaws.com:amr": "unauthenticated"
|
|
166
|
-
}
|
|
167
|
-
}
|
|
191
|
+
},
|
|
192
|
+
},
|
|
168
193
|
),
|
|
169
194
|
inline_policies={
|
|
170
195
|
"RUMPolicy": iam.PolicyDocument(
|
|
171
196
|
statements=[
|
|
172
197
|
iam.PolicyStatement(
|
|
173
198
|
effect=iam.Effect.ALLOW,
|
|
174
|
-
actions=[
|
|
175
|
-
|
|
199
|
+
actions=["rum:PutRumEvents"],
|
|
200
|
+
resources=[
|
|
201
|
+
f"arn:aws:rum:{self.region}:{self.account}:appmonitor/{self.rum_config.name}"
|
|
176
202
|
],
|
|
177
|
-
resources=[f"arn:aws:rum:{self.region}:{self.account}:appmonitor/{self.rum_config.name}"]
|
|
178
203
|
)
|
|
179
204
|
]
|
|
180
205
|
)
|
|
181
|
-
}
|
|
206
|
+
},
|
|
182
207
|
)
|
|
183
208
|
|
|
184
209
|
# Attach the role to the identity pool
|
|
185
210
|
cognito.CfnIdentityPoolRoleAttachment(
|
|
186
211
|
self,
|
|
187
|
-
id=
|
|
212
|
+
id=_resource_name("role-attachment"),
|
|
188
213
|
identity_pool_id=self.identity_pool.ref,
|
|
189
|
-
roles={
|
|
190
|
-
"unauthenticated": guest_role.role_arn
|
|
191
|
-
}
|
|
214
|
+
roles={"unauthenticated": guest_role.role_arn},
|
|
192
215
|
)
|
|
193
216
|
|
|
194
217
|
logger.info(f"Created Cognito Identity Pool: {self.identity_pool.ref}")
|
|
195
218
|
return self.identity_pool.ref, guest_role.role_arn
|
|
196
219
|
|
|
197
220
|
def _create_minimal_identity_pool(self) -> tuple[str, str]:
|
|
198
|
-
"""Create a minimal
|
|
221
|
+
"""Create a minimal Identity Pool with just a guest role for RUM"""
|
|
199
222
|
logger.info("Creating minimal Cognito Identity Pool for RUM")
|
|
200
223
|
|
|
201
|
-
|
|
224
|
+
def _resource_name(name: str) -> str:
|
|
225
|
+
"""Helper to generate resource names"""
|
|
226
|
+
return f"{self.rum_config.name}-{name}"
|
|
227
|
+
|
|
228
|
+
# Create minimal Identity Pool
|
|
229
|
+
minimal_identity_pool = cognito.CfnIdentityPool(
|
|
202
230
|
self,
|
|
203
|
-
id=
|
|
231
|
+
id=_resource_name("minimal-identity-pool"),
|
|
204
232
|
identity_pool_name=f"{self.rum_config.name}_minimal_identity_pool",
|
|
205
|
-
allow_unauthenticated_identities=True
|
|
233
|
+
allow_unauthenticated_identities=True,
|
|
206
234
|
)
|
|
207
235
|
|
|
208
236
|
# Create minimal IAM role for unauthenticated users
|
|
209
237
|
guest_role = iam.Role(
|
|
210
238
|
self,
|
|
211
|
-
id=
|
|
239
|
+
id=_resource_name("minimal-guest-role"),
|
|
212
240
|
assumed_by=iam.FederatedPrincipal(
|
|
213
241
|
"cognito-identity.amazonaws.com",
|
|
214
242
|
conditions={
|
|
@@ -217,85 +245,74 @@ class RumStack(IStack, EnhancedSsmParameterMixin):
|
|
|
217
245
|
},
|
|
218
246
|
"ForAnyValue:StringLike": {
|
|
219
247
|
"cognito-identity.amazonaws.com:amr": "unauthenticated"
|
|
220
|
-
}
|
|
221
|
-
}
|
|
248
|
+
},
|
|
249
|
+
},
|
|
222
250
|
),
|
|
223
251
|
inline_policies={
|
|
224
252
|
"RUMPolicy": iam.PolicyDocument(
|
|
225
253
|
statements=[
|
|
226
254
|
iam.PolicyStatement(
|
|
227
255
|
effect=iam.Effect.ALLOW,
|
|
228
|
-
actions=[
|
|
229
|
-
|
|
256
|
+
actions=["rum:PutRumEvents"],
|
|
257
|
+
resources=[
|
|
258
|
+
f"arn:aws:rum:{self.region}:{self.account}:appmonitor/{self.rum_config.name}"
|
|
230
259
|
],
|
|
231
|
-
resources=[f"arn:aws:rum:{self.region}:{self.account}:appmonitor/{self.rum_config.name}"]
|
|
232
260
|
)
|
|
233
261
|
]
|
|
234
262
|
)
|
|
235
|
-
}
|
|
263
|
+
},
|
|
236
264
|
)
|
|
237
265
|
|
|
238
266
|
# Attach the role to the identity pool
|
|
239
267
|
cognito.CfnIdentityPoolRoleAttachment(
|
|
240
268
|
self,
|
|
241
|
-
id=
|
|
269
|
+
id=_resource_name("minimal-role-attachment"),
|
|
242
270
|
identity_pool_id=self.identity_pool.ref,
|
|
243
|
-
roles={
|
|
244
|
-
"unauthenticated": guest_role.role_arn
|
|
245
|
-
}
|
|
271
|
+
roles={"unauthenticated": guest_role.role_arn},
|
|
246
272
|
)
|
|
247
273
|
|
|
248
274
|
return self.identity_pool.ref, guest_role.role_arn
|
|
249
275
|
|
|
250
|
-
def _create_app_monitor(
|
|
276
|
+
def _create_app_monitor(
|
|
277
|
+
self, identity_pool_id: str, guest_role_arn: Optional[str]
|
|
278
|
+
) -> None:
|
|
251
279
|
"""Create the CloudWatch RUM app monitor"""
|
|
252
|
-
logger.info(
|
|
280
|
+
logger.info("Creating CloudWatch RUM app monitor")
|
|
281
|
+
|
|
282
|
+
def _resource_name(name: str) -> str:
|
|
283
|
+
"""Helper to generate resource names"""
|
|
284
|
+
return f"{self.rum_config.name}-{name}"
|
|
253
285
|
|
|
254
|
-
#
|
|
286
|
+
# Create app monitor configuration
|
|
255
287
|
app_monitor_config = rum.CfnAppMonitor.AppMonitorConfigurationProperty(
|
|
256
|
-
identity_pool_id=identity_pool_id,
|
|
257
|
-
guest_role_arn=guest_role_arn,
|
|
258
288
|
allow_cookies=self.rum_config.allow_cookies,
|
|
259
289
|
enable_x_ray=self.rum_config.enable_xray,
|
|
290
|
+
favorite_pages=self.rum_config.favorite_pages,
|
|
291
|
+
guest_role_arn=guest_role_arn,
|
|
292
|
+
identity_pool_id=identity_pool_id,
|
|
260
293
|
session_sample_rate=self.rum_config.session_sample_rate,
|
|
261
|
-
telemetries=self.rum_config.telemetries
|
|
294
|
+
telemetries=self.rum_config.telemetries,
|
|
262
295
|
)
|
|
263
296
|
|
|
264
|
-
# Add optional properties
|
|
265
|
-
if self.rum_config.excluded_pages:
|
|
266
|
-
app_monitor_config.excluded_pages = self.rum_config.excluded_pages
|
|
267
|
-
|
|
268
|
-
if self.rum_config.included_pages:
|
|
269
|
-
app_monitor_config.included_pages = self.rum_config.included_pages
|
|
270
|
-
|
|
271
|
-
if self.rum_config.favorite_pages:
|
|
272
|
-
app_monitor_config.favorite_pages = self.rum_config.favorite_pages
|
|
273
|
-
|
|
274
|
-
if self.rum_config.metric_destinations:
|
|
275
|
-
app_monitor_config.metric_destinations = [
|
|
276
|
-
rum.CfnAppMonitor.MetricDestinationProperty(**dest)
|
|
277
|
-
for dest in self.rum_config.metric_destinations
|
|
278
|
-
]
|
|
279
|
-
|
|
280
|
-
# Create custom events configuration if enabled
|
|
281
|
-
custom_events = None
|
|
282
|
-
if self.rum_config.custom_events_enabled:
|
|
283
|
-
custom_events = rum.CfnAppMonitor.CustomEventsProperty(
|
|
284
|
-
status="ENABLED"
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
# Create the app monitor
|
|
288
297
|
self.app_monitor = rum.CfnAppMonitor(
|
|
289
298
|
self,
|
|
290
|
-
id=
|
|
299
|
+
id=_resource_name("app-monitor"),
|
|
291
300
|
name=self.rum_config.name,
|
|
292
|
-
app_monitor_configuration=app_monitor_config,
|
|
293
301
|
domain=self.rum_config.domain,
|
|
294
|
-
|
|
302
|
+
app_monitor_configuration=app_monitor_config,
|
|
295
303
|
cw_log_enabled=self.rum_config.cw_log_enabled,
|
|
296
|
-
custom_events=custom_events
|
|
297
304
|
)
|
|
298
305
|
|
|
306
|
+
logger.info(f"Created CloudWatch RUM app monitor: {self.rum_config.name}")
|
|
307
|
+
|
|
308
|
+
# Create custom events configuration if enabled
|
|
309
|
+
custom_events = None
|
|
310
|
+
if self.rum_config.custom_events_enabled:
|
|
311
|
+
custom_events = rum.CfnAppMonitor.CustomEventsProperty(status="ENABLED")
|
|
312
|
+
|
|
313
|
+
# Update the app monitor with additional properties
|
|
314
|
+
# (Note: some properties like custom_events need to be set during creation)
|
|
315
|
+
|
|
299
316
|
# Add tags if specified
|
|
300
317
|
if self.rum_config.tags:
|
|
301
318
|
for key, value in self.rum_config.tags.items():
|
|
@@ -324,8 +341,8 @@ class RumStack(IStack, EnhancedSsmParameterMixin):
|
|
|
324
341
|
resource_values["user_pool_id"] = self.user_pool.user_pool_id
|
|
325
342
|
|
|
326
343
|
# Use enhanced SSM parameter export
|
|
327
|
-
exported_params = self.
|
|
328
|
-
|
|
344
|
+
exported_params = self.export_ssm_parameters(resource_values)
|
|
345
|
+
|
|
329
346
|
if exported_params:
|
|
330
347
|
logger.info(f"Exported {len(exported_params)} RUM parameters to SSM")
|
|
331
348
|
else:
|
|
@@ -11,6 +11,7 @@ from cdk_factory.configurations.resources.security_group_full_stack import (
|
|
|
11
11
|
SecurityGroupFullStackConfig,
|
|
12
12
|
)
|
|
13
13
|
from cdk_factory.interfaces.istack import IStack
|
|
14
|
+
from cdk_factory.interfaces.vpc_provider_mixin import VPCProviderMixin
|
|
14
15
|
from cdk_factory.stack.stack_module_registry import register_stack
|
|
15
16
|
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
16
17
|
|
|
@@ -19,7 +20,7 @@ logger = Logger(service="SecurityGroupFullStack")
|
|
|
19
20
|
|
|
20
21
|
@register_stack("security_group_full_stack_library_module")
|
|
21
22
|
@register_stack("security_group_full_stack")
|
|
22
|
-
class SecurityGroupsStack(IStack):
|
|
23
|
+
class SecurityGroupsStack(IStack, VPCProviderMixin):
|
|
23
24
|
|
|
24
25
|
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
|
|
25
26
|
super().__init__(scope, id, **kwargs)
|
|
@@ -193,37 +194,7 @@ class SecurityGroupsStack(IStack):
|
|
|
193
194
|
description="Uptime Robot",
|
|
194
195
|
)
|
|
195
196
|
|
|
196
|
-
|
|
197
|
-
# Outputs (exports)
|
|
198
|
-
# =========================================================
|
|
199
|
-
cdk.CfnOutput(
|
|
200
|
-
self,
|
|
201
|
-
"WebFleetAlbSecurityGroupOut",
|
|
202
|
-
value=alb_sg.ref,
|
|
203
|
-
description="Web Fleet Application Load Balancer Security Group",
|
|
204
|
-
export_name=f"{self.deployment.environment}-{self.workload.name}-WebFleetAlbSecurityGroup",
|
|
205
|
-
)
|
|
206
|
-
cdk.CfnOutput(
|
|
207
|
-
self,
|
|
208
|
-
"WebFleetInstancesSecurityGroupOut",
|
|
209
|
-
value=web_fleet_sg.ref,
|
|
210
|
-
description="Web Fleet Instances Security Group",
|
|
211
|
-
export_name=f"{self.deployment.environment}-{self.workload.name}-WebFleetInstancesSecurityGroup",
|
|
212
|
-
)
|
|
213
|
-
cdk.CfnOutput(
|
|
214
|
-
self,
|
|
215
|
-
"MySqlDbSecurityGroupOut",
|
|
216
|
-
value=mysql_sg.ref,
|
|
217
|
-
description="MySql Security Group",
|
|
218
|
-
export_name=f"{self.deployment.environment}-{self.workload.name}-MySqlDbSecurityGroup",
|
|
219
|
-
)
|
|
220
|
-
cdk.CfnOutput(
|
|
221
|
-
self,
|
|
222
|
-
"WebMonitoringSecurityGroupOut",
|
|
223
|
-
value=monitoring_sg.ref,
|
|
224
|
-
description="Web Fleet Application Load Balancer Security Group",
|
|
225
|
-
export_name=f"{self.deployment.environment}-{self.workload.name}-WebMonitoringSecurityGroup",
|
|
226
|
-
)
|
|
197
|
+
|
|
227
198
|
|
|
228
199
|
# =========================================================
|
|
229
200
|
# SSM Parameter Store Exports
|
|
@@ -274,30 +245,16 @@ class SecurityGroupsStack(IStack):
|
|
|
274
245
|
|
|
275
246
|
@property
|
|
276
247
|
def vpc(self) -> ec2.IVpc:
|
|
277
|
-
"""Get the VPC for the Security Group"""
|
|
248
|
+
"""Get the VPC for the Security Group using centralized VPC provider mixin."""
|
|
278
249
|
if self._vpc:
|
|
279
250
|
return self._vpc
|
|
280
251
|
|
|
281
|
-
#
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
"vpc_id": vpc_id,
|
|
288
|
-
"availability_zones": ["us-east-1a", "us-east-1b"]
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
# Use from_vpc_attributes() instead of from_lookup() because SSM imports return tokens
|
|
292
|
-
# from_lookup() requires concrete values and queries AWS during synthesis
|
|
293
|
-
self._vpc = ec2.Vpc.from_vpc_attributes(self, "VPC", **vpc_attrs)
|
|
294
|
-
elif self.sg_config.vpc_id:
|
|
295
|
-
self._vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=self.sg_config.vpc_id)
|
|
296
|
-
elif self.workload.vpc_id:
|
|
297
|
-
self._vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=self.workload.vpc_id)
|
|
298
|
-
else:
|
|
299
|
-
raise ValueError("VPC ID is not defined in the configuration or SSM imports.")
|
|
300
|
-
|
|
252
|
+
# Use the centralized VPC resolution from VPCProviderMixin
|
|
253
|
+
self._vpc = self.resolve_vpc(
|
|
254
|
+
config=self.sg_config,
|
|
255
|
+
deployment=self.deployment,
|
|
256
|
+
workload=self.workload
|
|
257
|
+
)
|
|
301
258
|
return self._vpc
|
|
302
259
|
|
|
303
260
|
def _export_ssm_parameters(self, security_groups_map: Dict[str, ec2.CfnSecurityGroup]) -> None:
|
|
@@ -15,7 +15,8 @@ from cdk_factory.configurations.deployment import DeploymentConfig
|
|
|
15
15
|
from cdk_factory.configurations.stack import StackConfig
|
|
16
16
|
from cdk_factory.configurations.resources.security_group import SecurityGroupConfig
|
|
17
17
|
from cdk_factory.interfaces.istack import IStack
|
|
18
|
-
from cdk_factory.interfaces.
|
|
18
|
+
from cdk_factory.interfaces.vpc_provider_mixin import VPCProviderMixin
|
|
19
|
+
from cdk_factory.interfaces.standardized_ssm_mixin import StandardizedSsmMixin
|
|
19
20
|
from cdk_factory.stack.stack_module_registry import register_stack
|
|
20
21
|
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
21
22
|
|
|
@@ -24,7 +25,7 @@ logger = Logger(service="SecurityGroupStack")
|
|
|
24
25
|
|
|
25
26
|
@register_stack("security_group_library_module")
|
|
26
27
|
@register_stack("security_group_stack")
|
|
27
|
-
class SecurityGroupStack(IStack,
|
|
28
|
+
class SecurityGroupStack(IStack, VPCProviderMixin, StandardizedSsmMixin):
|
|
28
29
|
"""
|
|
29
30
|
Reusable stack for AWS Security Groups.
|
|
30
31
|
Supports creating security groups with customizable rules.
|
|
@@ -82,17 +83,16 @@ class SecurityGroupStack(IStack, EnhancedSsmParameterMixin):
|
|
|
82
83
|
|
|
83
84
|
@property
|
|
84
85
|
def vpc(self) -> ec2.IVpc:
|
|
85
|
-
"""Get the VPC for the Security Group"""
|
|
86
|
+
"""Get the VPC for the Security Group using centralized VPC provider mixin."""
|
|
86
87
|
if self._vpc:
|
|
87
88
|
return self._vpc
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
self.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
89
|
+
|
|
90
|
+
# Use the centralized VPC resolution from VPCProviderMixin
|
|
91
|
+
self._vpc = self.resolve_vpc(
|
|
92
|
+
config=self.sg_config,
|
|
93
|
+
deployment=self.deployment,
|
|
94
|
+
workload=self.workload
|
|
95
|
+
)
|
|
96
96
|
return self._vpc
|
|
97
97
|
|
|
98
98
|
def _create_security_group(self, sg_name: str) -> ec2.SecurityGroup:
|
|
@@ -337,14 +337,7 @@ class SecurityGroupStack(IStack, EnhancedSsmParameterMixin):
|
|
|
337
337
|
|
|
338
338
|
def _export_cfn_outputs(self, sg_name: str) -> None:
|
|
339
339
|
"""Add CloudFormation outputs for the Security Group"""
|
|
340
|
-
|
|
341
|
-
# Security Group ID
|
|
342
|
-
cdk.CfnOutput(
|
|
343
|
-
self,
|
|
344
|
-
f"{sg_name}-id",
|
|
345
|
-
value=self.security_group.security_group_id,
|
|
346
|
-
export_name=f"{self.deployment.build_resource_name(sg_name)}-id",
|
|
347
|
-
)
|
|
340
|
+
return
|
|
348
341
|
|
|
349
342
|
def _export_ssm_parameters(self, sg_name: str) -> None:
|
|
350
343
|
"""Add SSM parameters for the Security Group"""
|
|
@@ -131,37 +131,4 @@ class SQSStack(IStack):
|
|
|
131
131
|
|
|
132
132
|
def _add_outputs(self) -> None:
|
|
133
133
|
"""Add CloudFormation outputs for the SQS queues"""
|
|
134
|
-
|
|
135
|
-
# Queue ARN
|
|
136
|
-
cdk.CfnOutput(
|
|
137
|
-
self,
|
|
138
|
-
f"{queue_name}-arn",
|
|
139
|
-
value=queue.queue_arn,
|
|
140
|
-
export_name=f"{self.deployment.build_resource_name(queue_name)}-arn"
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
# Queue URL
|
|
144
|
-
cdk.CfnOutput(
|
|
145
|
-
self,
|
|
146
|
-
f"{queue_name}-url",
|
|
147
|
-
value=queue.queue_url,
|
|
148
|
-
export_name=f"{self.deployment.build_resource_name(queue_name)}-url"
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
# Also add outputs for DLQs
|
|
152
|
-
for dlq_name, dlq in self.dead_letter_queues.items():
|
|
153
|
-
# DLQ ARN
|
|
154
|
-
cdk.CfnOutput(
|
|
155
|
-
self,
|
|
156
|
-
f"{dlq_name}-arn",
|
|
157
|
-
value=dlq.queue_arn,
|
|
158
|
-
export_name=f"{self.deployment.build_resource_name(dlq_name)}-arn"
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
# DLQ URL
|
|
162
|
-
cdk.CfnOutput(
|
|
163
|
-
self,
|
|
164
|
-
f"{dlq_name}-url",
|
|
165
|
-
value=dlq.queue_url,
|
|
166
|
-
export_name=f"{self.deployment.build_resource_name(dlq_name)}-url"
|
|
167
|
-
)
|
|
134
|
+
return
|
|
@@ -54,6 +54,11 @@ class StackStandards:
|
|
|
54
54
|
git_hash = GitUtilities.get_git_commit_hash()
|
|
55
55
|
if git_hash:
|
|
56
56
|
aws_cdk.Tags.of(scope).add("ApplicationGitHash", git_hash)
|
|
57
|
+
|
|
58
|
+
# Add CDK Factory version for tracking and debugging
|
|
59
|
+
from cdk_factory.version import __version__
|
|
60
|
+
aws_cdk.Tags.of(scope).add("CdkFactoryVersion", __version__)
|
|
61
|
+
|
|
57
62
|
aws_cdk.Tags.of(scope).add(
|
|
58
63
|
"DeploymentDateUTC", str(datetime.datetime.now(datetime.UTC))
|
|
59
64
|
)
|