cdk-factory 0.16.16__py3-none-any.whl → 0.17.1__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/devops.py +1 -1
- cdk_factory/configurations/resources/cloudfront.py +7 -2
- cdk_factory/configurations/resources/ecr.py +1 -1
- cdk_factory/configurations/resources/ecs_cluster.py +7 -5
- cdk_factory/configurations/resources/ecs_service.py +7 -2
- cdk_factory/configurations/resources/load_balancer.py +8 -9
- cdk_factory/configurations/resources/monitoring.py +8 -3
- cdk_factory/configurations/resources/rds.py +7 -8
- cdk_factory/configurations/resources/rum.py +7 -2
- cdk_factory/configurations/resources/s3.py +1 -1
- 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/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 +612 -0
- cdk_factory/interfaces/vpc_provider_mixin.py +66 -32
- 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 +2 -2
- cdk_factory/stack_library/api_gateway/api_gateway_stack.py +84 -59
- cdk_factory/stack_library/auto_scaling/auto_scaling_stack_standardized.py +530 -0
- cdk_factory/stack_library/code_artifact/code_artifact_stack.py +2 -2
- 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 -1
- cdk_factory/stack_library/ecs/ecs_cluster_stack_standardized.py +305 -0
- cdk_factory/stack_library/ecs/ecs_service_stack.py +10 -26
- cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +2 -2
- cdk_factory/stack_library/load_balancer/load_balancer_stack.py +11 -35
- cdk_factory/stack_library/rds/rds_stack.py +10 -27
- cdk_factory/stack_library/route53/route53_stack.py +2 -2
- cdk_factory/stack_library/rum/rum_stack.py +108 -91
- cdk_factory/stack_library/security_group/security_group_full_stack.py +9 -22
- cdk_factory/stack_library/security_group/security_group_stack.py +11 -11
- cdk_factory/stack_library/vpc/vpc_stack_standardized.py +411 -0
- cdk_factory/utilities/api_gateway_integration_utility.py +24 -16
- cdk_factory/utilities/environment_services.py +3 -3
- 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.16.dist-info → cdk_factory-0.17.1.dist-info}/METADATA +1 -1
- {cdk_factory-0.16.16.dist-info → cdk_factory-0.17.1.dist-info}/RECORD +52 -52
- cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +0 -321
- cdk_factory/interfaces/ssm_parameter_mixin.py +0 -454
- cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +0 -748
- cdk_factory/stack_library/ecs/ecs_cluster_stack.py +0 -232
- cdk_factory/stack_library/vpc/vpc_stack.py +0 -298
- {cdk_factory-0.16.16.dist-info → cdk_factory-0.17.1.dist-info}/WHEEL +0 -0
- {cdk_factory-0.16.16.dist-info → cdk_factory-0.17.1.dist-info}/entry_points.txt +0 -0
- {cdk_factory-0.16.16.dist-info → cdk_factory-0.17.1.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ECS Cluster Stack Module (Standardized SSM Version)
|
|
3
|
+
|
|
4
|
+
Provides a dedicated stack for creating and configuring ECS clusters
|
|
5
|
+
with proper configurability, explicit resource management, and standardized SSM integration.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import logging
|
|
9
|
+
from typing import Optional, Dict, Any
|
|
10
|
+
|
|
11
|
+
from aws_cdk import (
|
|
12
|
+
aws_ecs as ecs,
|
|
13
|
+
aws_ec2 as ec2,
|
|
14
|
+
aws_iam as iam,
|
|
15
|
+
CfnOutput,
|
|
16
|
+
)
|
|
17
|
+
from constructs import Construct
|
|
18
|
+
|
|
19
|
+
from cdk_factory.configurations.stack import StackConfig
|
|
20
|
+
from cdk_factory.configurations.deployment import DeploymentConfig
|
|
21
|
+
from cdk_factory.configurations.workload import WorkloadConfig
|
|
22
|
+
from cdk_factory.interfaces.vpc_provider_mixin import VPCProviderMixin
|
|
23
|
+
from cdk_factory.interfaces.standardized_ssm_mixin import StandardizedSsmMixin
|
|
24
|
+
from cdk_factory.configurations.resources.ecs_cluster import EcsClusterConfig
|
|
25
|
+
from cdk_factory.stack.stack_module_registry import register_stack
|
|
26
|
+
from cdk_factory.interfaces.istack import IStack
|
|
27
|
+
|
|
28
|
+
logger = logging.getLogger(__name__)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@register_stack("ecs_cluster_stack")
|
|
32
|
+
class EcsClusterStack(IStack, VPCProviderMixin, StandardizedSsmMixin):
|
|
33
|
+
"""
|
|
34
|
+
A dedicated stack for creating and managing ECS clusters with standardized SSM integration.
|
|
35
|
+
|
|
36
|
+
This stack provides explicit configuration of ECS clusters including:
|
|
37
|
+
- Cluster naming
|
|
38
|
+
- Container insights
|
|
39
|
+
- Cluster settings
|
|
40
|
+
- Standardized SSM parameter exports
|
|
41
|
+
- IAM role configurations
|
|
42
|
+
- Template variable resolution
|
|
43
|
+
- Comprehensive validation
|
|
44
|
+
"""
|
|
45
|
+
|
|
46
|
+
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
|
|
47
|
+
"""
|
|
48
|
+
Initialize the ECS Cluster stack.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
scope: The CDK construct scope
|
|
52
|
+
id: The construct ID
|
|
53
|
+
"""
|
|
54
|
+
super().__init__(scope, id, **kwargs)
|
|
55
|
+
|
|
56
|
+
self._initialize_vpc_cache()
|
|
57
|
+
|
|
58
|
+
self.ecs_config: Optional[EcsClusterConfig] = None
|
|
59
|
+
self.stack_config: Optional[StackConfig] = None
|
|
60
|
+
self.deployment: Optional[DeploymentConfig] = None
|
|
61
|
+
self.workload: Optional[WorkloadConfig] = None
|
|
62
|
+
self.ecs_cluster: Optional[ecs.Cluster] = None
|
|
63
|
+
self.instance_role: Optional[iam.Role] = None
|
|
64
|
+
self.instance_profile: Optional[iam.CfnInstanceProfile] = None
|
|
65
|
+
|
|
66
|
+
def build(
|
|
67
|
+
self,
|
|
68
|
+
stack_config: StackConfig,
|
|
69
|
+
deployment: DeploymentConfig,
|
|
70
|
+
workload: WorkloadConfig,
|
|
71
|
+
) -> None:
|
|
72
|
+
"""Build the ECS Cluster stack"""
|
|
73
|
+
self._build(stack_config, deployment, workload)
|
|
74
|
+
|
|
75
|
+
def _build(
|
|
76
|
+
self,
|
|
77
|
+
stack_config: StackConfig,
|
|
78
|
+
deployment: DeploymentConfig,
|
|
79
|
+
workload: WorkloadConfig,
|
|
80
|
+
) -> None:
|
|
81
|
+
"""Internal build method for the ECS Cluster stack"""
|
|
82
|
+
self.stack_config = stack_config
|
|
83
|
+
self.deployment = deployment
|
|
84
|
+
self.workload = workload
|
|
85
|
+
|
|
86
|
+
# Initialize VPC cache from mixin
|
|
87
|
+
self._initialize_vpc_cache()
|
|
88
|
+
|
|
89
|
+
# Load ECS cluster configuration
|
|
90
|
+
self.ecs_config: EcsClusterConfig = EcsClusterConfig(
|
|
91
|
+
stack_config.dictionary.get("ecs_cluster", {})
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
cluster_name = deployment.build_resource_name(self.ecs_config.name)
|
|
95
|
+
|
|
96
|
+
logger.info(f"Creating ECS Cluster stack: {cluster_name}")
|
|
97
|
+
|
|
98
|
+
# Setup standardized SSM integration
|
|
99
|
+
self.setup_standardized_ssm_integration(
|
|
100
|
+
scope=self,
|
|
101
|
+
config=self.ecs_config,
|
|
102
|
+
resource_type="ecs_cluster",
|
|
103
|
+
resource_name=cluster_name,
|
|
104
|
+
deployment=deployment,
|
|
105
|
+
workload=workload
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
# Process SSM imports using standardized method
|
|
109
|
+
self.process_standardized_ssm_imports()
|
|
110
|
+
|
|
111
|
+
# Create the ECS cluster
|
|
112
|
+
self._create_ecs_cluster()
|
|
113
|
+
|
|
114
|
+
# Create IAM roles if needed
|
|
115
|
+
self._create_iam_roles()
|
|
116
|
+
|
|
117
|
+
# Export cluster information
|
|
118
|
+
self._export_cluster_info()
|
|
119
|
+
|
|
120
|
+
# Export SSM parameters
|
|
121
|
+
self._export_ssm_parameters()
|
|
122
|
+
|
|
123
|
+
logger.info(f"ECS Cluster stack created: {cluster_name}")
|
|
124
|
+
|
|
125
|
+
def _create_ecs_cluster(self):
|
|
126
|
+
"""Create the ECS cluster with explicit configuration."""
|
|
127
|
+
logger.info(f"Creating ECS cluster: {self.ecs_config.name}")
|
|
128
|
+
|
|
129
|
+
# Build cluster settings
|
|
130
|
+
cluster_settings = []
|
|
131
|
+
|
|
132
|
+
# Add container insights if enabled
|
|
133
|
+
if self.ecs_config.container_insights:
|
|
134
|
+
cluster_settings.append({"name": "containerInsights", "value": "enabled"})
|
|
135
|
+
|
|
136
|
+
# Add custom cluster settings
|
|
137
|
+
if self.ecs_config.cluster_settings:
|
|
138
|
+
cluster_settings.extend(self.ecs_config.cluster_settings)
|
|
139
|
+
|
|
140
|
+
# Get VPC using standardized approach
|
|
141
|
+
self.vpc = self._get_vpc()
|
|
142
|
+
|
|
143
|
+
# Create the ECS cluster
|
|
144
|
+
self.ecs_cluster = ecs.Cluster(
|
|
145
|
+
self,
|
|
146
|
+
"ECSCluster",
|
|
147
|
+
cluster_name=self.ecs_config.name,
|
|
148
|
+
vpc=self.vpc,
|
|
149
|
+
container_insights=self.ecs_config.container_insights,
|
|
150
|
+
default_cloud_map_namespace=(
|
|
151
|
+
self.ecs_config.cloud_map_namespace
|
|
152
|
+
if self.ecs_config.cloud_map_namespace
|
|
153
|
+
else None
|
|
154
|
+
),
|
|
155
|
+
execute_command_configuration=(
|
|
156
|
+
self.ecs_config.execute_command_configuration
|
|
157
|
+
if self.ecs_config.execute_command_configuration
|
|
158
|
+
else None
|
|
159
|
+
),
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
logger.info(f"ECS cluster created: {self.ecs_config.name}")
|
|
163
|
+
|
|
164
|
+
def _get_vpc(self):
|
|
165
|
+
"""
|
|
166
|
+
Get VPC using the centralized VPC provider mixin.
|
|
167
|
+
"""
|
|
168
|
+
# Use the centralized VPC resolution from VPCProviderMixin
|
|
169
|
+
return self.resolve_vpc(
|
|
170
|
+
config=self.ecs_config,
|
|
171
|
+
deployment=self.deployment,
|
|
172
|
+
workload=self.workload
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
def _create_iam_roles(self):
|
|
176
|
+
"""Create IAM roles for the ECS cluster if configured."""
|
|
177
|
+
if not self.ecs_config.create_instance_role:
|
|
178
|
+
logger.info("Skipping instance role creation (disabled in config)")
|
|
179
|
+
return
|
|
180
|
+
|
|
181
|
+
logger.info("Creating ECS instance role")
|
|
182
|
+
|
|
183
|
+
# Create the instance role
|
|
184
|
+
self.instance_role = iam.Role(
|
|
185
|
+
self,
|
|
186
|
+
"ECSInstanceRole",
|
|
187
|
+
assumed_by=iam.ServicePrincipal("ec2.amazonaws.com"),
|
|
188
|
+
managed_policies=[
|
|
189
|
+
iam.ManagedPolicy.from_aws_managed_policy_name("AmazonECSWorkerNodePolicy"),
|
|
190
|
+
iam.ManagedPolicy.from_aws_managed_policy_name("AmazonEC2ContainerRegistryReadOnly"),
|
|
191
|
+
iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSSMManagedInstanceCore"),
|
|
192
|
+
],
|
|
193
|
+
role_name=f"{self.ecs_config.name}-ecs-instance-role",
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
# Create instance profile
|
|
197
|
+
self.instance_profile = iam.CfnInstanceProfile(
|
|
198
|
+
self,
|
|
199
|
+
"ECSInstanceProfile",
|
|
200
|
+
roles=[self.instance_role.role_name],
|
|
201
|
+
instance_profile_name=f"{self.ecs_config.name}-ecs-instance-profile",
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
logger.info("ECS instance role and profile created")
|
|
205
|
+
|
|
206
|
+
def _export_cluster_info(self):
|
|
207
|
+
"""Export cluster information as CloudFormation outputs."""
|
|
208
|
+
if not self.ecs_cluster:
|
|
209
|
+
return
|
|
210
|
+
|
|
211
|
+
cluster_name = self.deployment.build_resource_name(self.ecs_config.name)
|
|
212
|
+
|
|
213
|
+
# Export cluster name
|
|
214
|
+
CfnOutput(
|
|
215
|
+
self,
|
|
216
|
+
f"{cluster_name}-ClusterName",
|
|
217
|
+
value=self.ecs_cluster.cluster_name,
|
|
218
|
+
description=f"ECS Cluster Name for {cluster_name}",
|
|
219
|
+
export_name=f"{self.deployment.workload_name}-{self.deployment.environment}-ecs-cluster-name",
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# Export cluster ARN
|
|
223
|
+
CfnOutput(
|
|
224
|
+
self,
|
|
225
|
+
f"{cluster_name}-ClusterArn",
|
|
226
|
+
value=self.ecs_cluster.cluster_arn,
|
|
227
|
+
description=f"ECS Cluster ARN for {cluster_name}",
|
|
228
|
+
export_name=f"{self.deployment.workload_name}-{self.deployment.environment}-ecs-cluster-arn",
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Export security group if available
|
|
232
|
+
if hasattr(self.ecs_cluster, 'connections') and self.ecs_cluster.connections:
|
|
233
|
+
security_groups = self.ecs_cluster.connections.security_groups
|
|
234
|
+
if security_groups:
|
|
235
|
+
CfnOutput(
|
|
236
|
+
self,
|
|
237
|
+
f"{cluster_name}-SecurityGroupId",
|
|
238
|
+
value=security_groups[0].security_group_id,
|
|
239
|
+
description=f"ECS Cluster Security Group ID for {cluster_name}",
|
|
240
|
+
export_name=f"{self.deployment.workload_name}-{self.deployment.environment}-ecs-cluster-sg-id",
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# Export instance profile if created
|
|
244
|
+
if self.instance_profile:
|
|
245
|
+
CfnOutput(
|
|
246
|
+
self,
|
|
247
|
+
f"{cluster_name}-InstanceProfileArn",
|
|
248
|
+
value=self.instance_profile.attr_arn,
|
|
249
|
+
description=f"ECS Instance Profile ARN for {cluster_name}",
|
|
250
|
+
export_name=f"{self.deployment.workload_name}-{self.deployment.environment}-ecs-instance-profile-arn",
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
logger.info("ECS cluster information exported as outputs")
|
|
254
|
+
|
|
255
|
+
def _export_ssm_parameters(self) -> None:
|
|
256
|
+
"""Export SSM parameters using standardized approach"""
|
|
257
|
+
if not self.ecs_cluster:
|
|
258
|
+
logger.warning("No ECS cluster to export")
|
|
259
|
+
return
|
|
260
|
+
|
|
261
|
+
# Prepare resource values for export
|
|
262
|
+
resource_values = {
|
|
263
|
+
"ecs_cluster_name": self.ecs_cluster.cluster_name,
|
|
264
|
+
"ecs_cluster_arn": self.ecs_cluster.cluster_arn,
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
# Add security group ID if available
|
|
268
|
+
if hasattr(self.ecs_cluster, 'connections') and self.ecs_cluster.connections:
|
|
269
|
+
security_groups = self.ecs_cluster.connections.security_groups
|
|
270
|
+
if security_groups:
|
|
271
|
+
resource_values["ecs_cluster_security_group_id"] = security_groups[0].security_group_id
|
|
272
|
+
|
|
273
|
+
# Add instance profile ARN if created
|
|
274
|
+
if self.instance_profile:
|
|
275
|
+
resource_values["ecs_instance_profile_arn"] = self.instance_profile.attr_arn
|
|
276
|
+
|
|
277
|
+
# Export using standardized SSM mixin
|
|
278
|
+
exported_params = self.export_standardized_ssm_parameters(resource_values)
|
|
279
|
+
|
|
280
|
+
logger.info(f"Exported SSM parameters: {exported_params}")
|
|
281
|
+
|
|
282
|
+
# Backward compatibility methods
|
|
283
|
+
def process_ssm_imports(self, config: Any, deployment: DeploymentConfig, resource_type: str = "resource") -> None:
|
|
284
|
+
"""Backward compatibility method for existing modules."""
|
|
285
|
+
# Extract SSM configuration from old format
|
|
286
|
+
if hasattr(config, 'ssm_imports'):
|
|
287
|
+
# Convert old ssm_imports format to new format
|
|
288
|
+
old_imports = config.ssm_imports
|
|
289
|
+
new_imports = {}
|
|
290
|
+
|
|
291
|
+
for key, value in old_imports.items():
|
|
292
|
+
# Resolve template variables using old method
|
|
293
|
+
if isinstance(value, str) and not value.startswith('/'):
|
|
294
|
+
value = f"/{deployment.environment}/{deployment.workload_name}/{value}"
|
|
295
|
+
new_imports[key] = value
|
|
296
|
+
|
|
297
|
+
# Update SSM config
|
|
298
|
+
self.ssm_config = {"imports": new_imports}
|
|
299
|
+
|
|
300
|
+
# Process imports using standardized method
|
|
301
|
+
self.process_standardized_ssm_imports()
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
# Backward compatibility alias
|
|
305
|
+
EcsClusterStackStandardized = EcsClusterStack
|
|
@@ -23,7 +23,8 @@ from cdk_factory.configurations.deployment import DeploymentConfig
|
|
|
23
23
|
from cdk_factory.configurations.stack import StackConfig
|
|
24
24
|
from cdk_factory.configurations.resources.ecs_service import EcsServiceConfig
|
|
25
25
|
from cdk_factory.interfaces.istack import IStack
|
|
26
|
-
from cdk_factory.interfaces.
|
|
26
|
+
from cdk_factory.interfaces.vpc_provider_mixin import VPCProviderMixin
|
|
27
|
+
from cdk_factory.interfaces.standardized_ssm_mixin import StandardizedSsmMixin
|
|
27
28
|
from cdk_factory.stack.stack_module_registry import register_stack
|
|
28
29
|
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
29
30
|
|
|
@@ -33,7 +34,7 @@ logger = Logger(service="EcsServiceStack")
|
|
|
33
34
|
@register_stack("ecs_service_library_module")
|
|
34
35
|
@register_stack("ecs_service_stack")
|
|
35
36
|
@register_stack("fargate_service_stack")
|
|
36
|
-
class EcsServiceStack(IStack,
|
|
37
|
+
class EcsServiceStack(IStack, VPCProviderMixin, StandardizedSsmMixin):
|
|
37
38
|
"""
|
|
38
39
|
Reusable stack for ECS/Fargate services with Docker container support.
|
|
39
40
|
Supports blue-green deployments, maintenance mode, and auto-scaling.
|
|
@@ -102,30 +103,13 @@ class EcsServiceStack(IStack, EnhancedSsmParameterMixin):
|
|
|
102
103
|
self._add_outputs(service_name)
|
|
103
104
|
|
|
104
105
|
def _load_vpc(self) -> None:
|
|
105
|
-
"""Load VPC
|
|
106
|
-
#
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"vpc_id": vpc_id,
|
|
113
|
-
"availability_zones": ["us-east-1a", "us-east-1b"]
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
# Use from_vpc_attributes() for SSM tokens
|
|
117
|
-
self._vpc = ec2.Vpc.from_vpc_attributes(self, "VPC", **vpc_attrs)
|
|
118
|
-
else:
|
|
119
|
-
vpc_id = self.ecs_config.vpc_id or self.workload.vpc_id
|
|
120
|
-
|
|
121
|
-
if not vpc_id:
|
|
122
|
-
raise ValueError("VPC ID is required for ECS service")
|
|
123
|
-
|
|
124
|
-
self._vpc = ec2.Vpc.from_lookup(
|
|
125
|
-
self,
|
|
126
|
-
"VPC",
|
|
127
|
-
vpc_id=vpc_id
|
|
128
|
-
)
|
|
106
|
+
"""Load VPC using the centralized VPC provider mixin."""
|
|
107
|
+
# Use the centralized VPC resolution from VPCProviderMixin
|
|
108
|
+
self._vpc = self.resolve_vpc(
|
|
109
|
+
config=self.ecs_config,
|
|
110
|
+
deployment=self.deployment,
|
|
111
|
+
workload=self.workload
|
|
112
|
+
)
|
|
129
113
|
|
|
130
114
|
def _process_ssm_imports(self) -> None:
|
|
131
115
|
"""
|
|
@@ -25,7 +25,7 @@ from cdk_factory.configurations.deployment import DeploymentConfig
|
|
|
25
25
|
from cdk_factory.configurations.stack import StackConfig
|
|
26
26
|
from cdk_factory.configurations.resources.lambda_edge import LambdaEdgeConfig
|
|
27
27
|
from cdk_factory.interfaces.istack import IStack
|
|
28
|
-
from cdk_factory.interfaces.
|
|
28
|
+
from cdk_factory.interfaces.standardized_ssm_mixin import StandardizedSsmMixin
|
|
29
29
|
from cdk_factory.stack.stack_module_registry import register_stack
|
|
30
30
|
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
31
31
|
|
|
@@ -34,7 +34,7 @@ logger = Logger(service="LambdaEdgeStack")
|
|
|
34
34
|
|
|
35
35
|
@register_stack("lambda_edge_library_module")
|
|
36
36
|
@register_stack("lambda_edge_stack")
|
|
37
|
-
class LambdaEdgeStack(IStack,
|
|
37
|
+
class LambdaEdgeStack(IStack, StandardizedSsmMixin):
|
|
38
38
|
"""
|
|
39
39
|
Reusable stack for Lambda@Edge functions.
|
|
40
40
|
|
|
@@ -19,7 +19,8 @@ from cdk_factory.configurations.deployment import DeploymentConfig
|
|
|
19
19
|
from cdk_factory.configurations.stack import StackConfig
|
|
20
20
|
from cdk_factory.configurations.resources.load_balancer import LoadBalancerConfig
|
|
21
21
|
from cdk_factory.interfaces.istack import IStack
|
|
22
|
-
from cdk_factory.interfaces.
|
|
22
|
+
from cdk_factory.interfaces.vpc_provider_mixin import VPCProviderMixin
|
|
23
|
+
from cdk_factory.interfaces.standardized_ssm_mixin import StandardizedSsmMixin
|
|
23
24
|
from cdk_factory.stack.stack_module_registry import register_stack
|
|
24
25
|
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
25
26
|
|
|
@@ -30,7 +31,7 @@ logger = Logger(service="LoadBalancerStack")
|
|
|
30
31
|
@register_stack("alb_stack")
|
|
31
32
|
@register_stack("load_balancer_library_module")
|
|
32
33
|
@register_stack("load_balancer_stack")
|
|
33
|
-
class LoadBalancerStack(IStack,
|
|
34
|
+
class LoadBalancerStack(IStack, VPCProviderMixin, StandardizedSsmMixin):
|
|
34
35
|
"""
|
|
35
36
|
Reusable stack for AWS Load Balancers.
|
|
36
37
|
Supports creating Application and Network Load Balancers with customizable configurations.
|
|
@@ -174,41 +175,16 @@ class LoadBalancerStack(IStack, EnhancedSsmParameterMixin):
|
|
|
174
175
|
|
|
175
176
|
@property
|
|
176
177
|
def vpc(self) -> ec2.IVpc:
|
|
177
|
-
"""Get the VPC for the Load Balancer"""
|
|
178
|
+
"""Get the VPC for the Load Balancer using centralized VPC provider mixin."""
|
|
178
179
|
if self._vpc:
|
|
179
180
|
return self._vpc
|
|
180
|
-
|
|
181
|
-
#
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
"vpc_id": vpc_id,
|
|
188
|
-
"availability_zones": ["us-east-1a", "us-east-1b"],
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
# If we have subnet_ids from SSM, provide dummy public subnets
|
|
192
|
-
# The actual subnets will be set via CloudFormation escape hatch
|
|
193
|
-
if "subnet_ids" in self.ssm_imported_values:
|
|
194
|
-
# Provide dummy subnet IDs - these will be overridden by the escape hatch
|
|
195
|
-
# We need at least one dummy subnet per AZ to satisfy CDK's validation
|
|
196
|
-
vpc_attrs["public_subnet_ids"] = ["subnet-dummy1", "subnet-dummy2"]
|
|
197
|
-
|
|
198
|
-
# Use from_vpc_attributes() instead of from_lookup() because SSM imports return tokens
|
|
199
|
-
self._vpc = ec2.Vpc.from_vpc_attributes(self, "VPC", **vpc_attrs)
|
|
200
|
-
elif self.lb_config.vpc_id:
|
|
201
|
-
self._vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=self.lb_config.vpc_id)
|
|
202
|
-
elif self.workload.vpc_id:
|
|
203
|
-
self._vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=self.workload.vpc_id)
|
|
204
|
-
else:
|
|
205
|
-
# Use default VPC if not provided
|
|
206
|
-
raise ValueError(
|
|
207
|
-
"VPC is not defined in the configuration. "
|
|
208
|
-
"You can provide it a the load_balancer.vpc_id in the configuration "
|
|
209
|
-
"or a top level workload.vpc_id in the workload configuration."
|
|
210
|
-
)
|
|
211
|
-
|
|
181
|
+
|
|
182
|
+
# Use the centralized VPC resolution from VPCProviderMixin
|
|
183
|
+
self._vpc = self.resolve_vpc(
|
|
184
|
+
config=self.lb_config,
|
|
185
|
+
deployment=self.deployment,
|
|
186
|
+
workload=self.workload
|
|
187
|
+
)
|
|
212
188
|
return self._vpc
|
|
213
189
|
|
|
214
190
|
def _process_ssm_imports(self) -> None:
|
|
@@ -18,7 +18,8 @@ from cdk_factory.configurations.deployment import DeploymentConfig
|
|
|
18
18
|
from cdk_factory.configurations.stack import StackConfig
|
|
19
19
|
from cdk_factory.configurations.resources.rds import RdsConfig
|
|
20
20
|
from cdk_factory.interfaces.istack import IStack
|
|
21
|
-
from cdk_factory.interfaces.
|
|
21
|
+
from cdk_factory.interfaces.vpc_provider_mixin import VPCProviderMixin
|
|
22
|
+
from cdk_factory.interfaces.standardized_ssm_mixin import StandardizedSsmMixin
|
|
22
23
|
from cdk_factory.stack.stack_module_registry import register_stack
|
|
23
24
|
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
24
25
|
|
|
@@ -27,7 +28,7 @@ logger = Logger(service="RdsStack")
|
|
|
27
28
|
|
|
28
29
|
@register_stack("rds_library_module")
|
|
29
30
|
@register_stack("rds_stack")
|
|
30
|
-
class RdsStack(IStack,
|
|
31
|
+
class RdsStack(IStack, VPCProviderMixin, StandardizedSsmMixin):
|
|
31
32
|
"""
|
|
32
33
|
Reusable stack for AWS RDS.
|
|
33
34
|
Supports creating RDS instances with customizable configurations.
|
|
@@ -115,34 +116,16 @@ class RdsStack(IStack, EnhancedSsmParameterMixin):
|
|
|
115
116
|
|
|
116
117
|
@property
|
|
117
118
|
def vpc(self) -> ec2.IVpc:
|
|
118
|
-
"""Get the VPC for the RDS instance"""
|
|
119
|
+
"""Get the VPC for the RDS instance using centralized VPC provider mixin."""
|
|
119
120
|
if self._vpc:
|
|
120
121
|
return self._vpc
|
|
121
122
|
|
|
122
|
-
#
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# We'll create a DB subnet group separately instead
|
|
129
|
-
vpc_attrs = {
|
|
130
|
-
"vpc_id": vpc_id,
|
|
131
|
-
"availability_zones": ["us-east-1a", "us-east-1b"]
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
# Use from_vpc_attributes() for SSM tokens
|
|
135
|
-
self._vpc = ec2.Vpc.from_vpc_attributes(self, "VPC", **vpc_attrs)
|
|
136
|
-
elif self.rds_config.vpc_id:
|
|
137
|
-
self._vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=self.rds_config.vpc_id)
|
|
138
|
-
elif self.workload.vpc_id:
|
|
139
|
-
self._vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=self.workload.vpc_id)
|
|
140
|
-
else:
|
|
141
|
-
raise ValueError(
|
|
142
|
-
"VPC is not defined in the configuration. "
|
|
143
|
-
"You can provide it a the rds.vpc_id in the configuration "
|
|
144
|
-
"or a top level workload.vpc_id in the workload configuration."
|
|
145
|
-
)
|
|
123
|
+
# Use the centralized VPC resolution from VPCProviderMixin
|
|
124
|
+
self._vpc = self.resolve_vpc(
|
|
125
|
+
config=self.rds_config,
|
|
126
|
+
deployment=self.deployment,
|
|
127
|
+
workload=self.workload
|
|
128
|
+
)
|
|
146
129
|
return self._vpc
|
|
147
130
|
|
|
148
131
|
def _get_security_groups(self) -> List[ec2.ISecurityGroup]:
|
|
@@ -18,7 +18,7 @@ from cdk_factory.configurations.deployment import DeploymentConfig
|
|
|
18
18
|
from cdk_factory.configurations.stack import StackConfig
|
|
19
19
|
from cdk_factory.configurations.resources.route53 import Route53Config
|
|
20
20
|
from cdk_factory.interfaces.istack import IStack
|
|
21
|
-
from cdk_factory.interfaces.
|
|
21
|
+
from cdk_factory.interfaces.standardized_ssm_mixin import StandardizedSsmMixin
|
|
22
22
|
from cdk_factory.stack.stack_module_registry import register_stack
|
|
23
23
|
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
24
24
|
|
|
@@ -27,7 +27,7 @@ logger = Logger(service="Route53Stack")
|
|
|
27
27
|
|
|
28
28
|
@register_stack("route53_library_module")
|
|
29
29
|
@register_stack("route53_stack")
|
|
30
|
-
class Route53Stack(IStack,
|
|
30
|
+
class Route53Stack(IStack, StandardizedSsmMixin):
|
|
31
31
|
"""
|
|
32
32
|
Reusable stack for AWS Route53.
|
|
33
33
|
Supports creating hosted zones, DNS records, and certificate validation.
|