cdk-factory 0.16.15__py3-none-any.whl → 0.17.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.
- 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 +53 -29
- 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 +102 -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.15.dist-info → cdk_factory-0.17.0.dist-info}/METADATA +1 -1
- {cdk_factory-0.16.15.dist-info → cdk_factory-0.17.0.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 -721
- 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.15.dist-info → cdk_factory-0.17.0.dist-info}/WHEEL +0 -0
- {cdk_factory-0.16.15.dist-info → cdk_factory-0.17.0.dist-info}/entry_points.txt +0 -0
- {cdk_factory-0.16.15.dist-info → cdk_factory-0.17.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,232 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
ECS Cluster Stack Module
|
|
3
|
-
|
|
4
|
-
Provides a dedicated stack for creating and configuring ECS clusters
|
|
5
|
-
with proper configurability and explicit resource management.
|
|
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_iam as iam,
|
|
14
|
-
CfnOutput,
|
|
15
|
-
)
|
|
16
|
-
from constructs import Construct
|
|
17
|
-
|
|
18
|
-
from cdk_factory.configurations.stack import StackConfig
|
|
19
|
-
from cdk_factory.configurations.deployment import DeploymentConfig
|
|
20
|
-
from cdk_factory.configurations.workload import WorkloadConfig
|
|
21
|
-
from cdk_factory.interfaces.vpc_provider_mixin import VPCProviderMixin
|
|
22
|
-
from cdk_factory.configurations.resources.ecs_cluster import EcsClusterConfig
|
|
23
|
-
from cdk_factory.stack.stack_module_registry import register_stack
|
|
24
|
-
from cdk_factory.interfaces.istack import IStack
|
|
25
|
-
|
|
26
|
-
logger = logging.getLogger(__name__)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@register_stack("ecs_cluster_stack")
|
|
30
|
-
class EcsClusterStack(IStack, VPCProviderMixin):
|
|
31
|
-
"""
|
|
32
|
-
A dedicated stack for creating and managing ECS clusters.
|
|
33
|
-
|
|
34
|
-
This stack provides explicit configuration of ECS clusters including:
|
|
35
|
-
- Cluster naming
|
|
36
|
-
- Container insights
|
|
37
|
-
- Cluster settings
|
|
38
|
-
- SSM parameter exports
|
|
39
|
-
- IAM role configurations
|
|
40
|
-
"""
|
|
41
|
-
|
|
42
|
-
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
|
|
43
|
-
"""
|
|
44
|
-
Initialize the ECS Cluster stack.
|
|
45
|
-
|
|
46
|
-
Args:
|
|
47
|
-
scope: The CDK construct scope
|
|
48
|
-
id: The construct ID
|
|
49
|
-
"""
|
|
50
|
-
super().__init__(scope, id, **kwargs)
|
|
51
|
-
|
|
52
|
-
self._initialize_vpc_cache()
|
|
53
|
-
|
|
54
|
-
self.ecs_config: Optional[EcsClusterConfig] = None
|
|
55
|
-
self.stack_config: Optional[StackConfig] = None
|
|
56
|
-
self.deployment: Optional[DeploymentConfig] = None
|
|
57
|
-
self.workload: Optional[WorkloadConfig] = None
|
|
58
|
-
self.ecs_cluster: Optional[ecs.Cluster] = None
|
|
59
|
-
self.instance_role: Optional[iam.Role] = None
|
|
60
|
-
self.instance_profile: Optional[iam.CfnInstanceProfile] = None
|
|
61
|
-
|
|
62
|
-
# SSM imported values
|
|
63
|
-
self.ssm_imported_values: Dict[str, Any] = {}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def build(
|
|
68
|
-
self,
|
|
69
|
-
stack_config: StackConfig,
|
|
70
|
-
deployment: DeploymentConfig,
|
|
71
|
-
workload: WorkloadConfig,
|
|
72
|
-
) -> None:
|
|
73
|
-
"""Build the ECS Cluster stack"""
|
|
74
|
-
self._build(stack_config, deployment, workload)
|
|
75
|
-
|
|
76
|
-
def _build(
|
|
77
|
-
self,
|
|
78
|
-
stack_config: StackConfig,
|
|
79
|
-
deployment: DeploymentConfig,
|
|
80
|
-
workload: WorkloadConfig,
|
|
81
|
-
) -> None:
|
|
82
|
-
"""Internal build method for the ECS Cluster stack"""
|
|
83
|
-
self.stack_config = stack_config
|
|
84
|
-
self.deployment = deployment
|
|
85
|
-
self.workload = workload
|
|
86
|
-
|
|
87
|
-
# Initialize VPC cache from mixin
|
|
88
|
-
self._initialize_vpc_cache()
|
|
89
|
-
|
|
90
|
-
# Load ECS cluster configuration
|
|
91
|
-
self.ecs_config: EcsClusterConfig = EcsClusterConfig(
|
|
92
|
-
stack_config.dictionary.get("ecs_cluster", {})
|
|
93
|
-
)
|
|
94
|
-
|
|
95
|
-
logger.info(f"Creating ECS Cluster stack: {self.stack_name}")
|
|
96
|
-
|
|
97
|
-
# Process SSM imports first
|
|
98
|
-
self.process_ssm_imports(self.ecs_config, deployment, "ECS Cluster")
|
|
99
|
-
|
|
100
|
-
# Create the ECS cluster
|
|
101
|
-
self._create_ecs_cluster()
|
|
102
|
-
|
|
103
|
-
# Create IAM roles if needed
|
|
104
|
-
self._create_iam_roles()
|
|
105
|
-
|
|
106
|
-
# Export cluster information
|
|
107
|
-
self._export_cluster_info()
|
|
108
|
-
|
|
109
|
-
logger.info(f"ECS Cluster stack created: {self.stack_name}")
|
|
110
|
-
|
|
111
|
-
def _create_ecs_cluster(self):
|
|
112
|
-
"""Create the ECS cluster with explicit configuration."""
|
|
113
|
-
logger.info(f"Creating ECS cluster: {self.ecs_config.name}")
|
|
114
|
-
|
|
115
|
-
# Build cluster settings
|
|
116
|
-
cluster_settings = []
|
|
117
|
-
|
|
118
|
-
# Add container insights if enabled
|
|
119
|
-
if self.ecs_config.container_insights:
|
|
120
|
-
cluster_settings.append({"name": "containerInsights", "value": "enabled"})
|
|
121
|
-
|
|
122
|
-
# Add custom cluster settings
|
|
123
|
-
if self.ecs_config.cluster_settings:
|
|
124
|
-
cluster_settings.extend(self.ecs_config.cluster_settings)
|
|
125
|
-
|
|
126
|
-
# Create the ECS cluster
|
|
127
|
-
self.vpc = self.resolve_vpc(
|
|
128
|
-
config=self.ecs_config,
|
|
129
|
-
deployment=self.deployment,
|
|
130
|
-
workload=self.workload
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
self.ecs_cluster = ecs.Cluster(
|
|
134
|
-
self,
|
|
135
|
-
"ECSCluster",
|
|
136
|
-
cluster_name=self.ecs_config.name,
|
|
137
|
-
vpc=self.vpc,
|
|
138
|
-
container_insights=self.ecs_config.container_insights,
|
|
139
|
-
default_cloud_map_namespace=(
|
|
140
|
-
self.ecs_config.cloud_map_namespace
|
|
141
|
-
if self.ecs_config.cloud_map_namespace
|
|
142
|
-
else None
|
|
143
|
-
),
|
|
144
|
-
execute_command_configuration=(
|
|
145
|
-
self.ecs_config.execute_command_configuration
|
|
146
|
-
if self.ecs_config.execute_command_configuration
|
|
147
|
-
else None
|
|
148
|
-
),
|
|
149
|
-
)
|
|
150
|
-
|
|
151
|
-
logger.info(f"Created ECS cluster: {self.ecs_config.name}")
|
|
152
|
-
|
|
153
|
-
def _create_iam_roles(self):
|
|
154
|
-
"""Create IAM roles for the ECS cluster if configured."""
|
|
155
|
-
if not self.ecs_config.create_instance_role:
|
|
156
|
-
return
|
|
157
|
-
|
|
158
|
-
logger.info("Creating ECS instance role")
|
|
159
|
-
|
|
160
|
-
# Create the instance role
|
|
161
|
-
self.instance_role = iam.Role(
|
|
162
|
-
self,
|
|
163
|
-
"ECSInstanceRole",
|
|
164
|
-
assumed_by=iam.ServicePrincipal("ec2.amazonaws.com"),
|
|
165
|
-
role_name=self.ecs_config.instance_role_name
|
|
166
|
-
or f"{self.ecs_config.name}-instance-role",
|
|
167
|
-
)
|
|
168
|
-
|
|
169
|
-
# Add managed policies
|
|
170
|
-
for policy in self.ecs_config.managed_policies:
|
|
171
|
-
self.instance_role.add_managed_policy(
|
|
172
|
-
iam.ManagedPolicy.from_aws_managed_policy_name(policy)
|
|
173
|
-
)
|
|
174
|
-
|
|
175
|
-
# Add inline policies if provided
|
|
176
|
-
if self.ecs_config.inline_policies:
|
|
177
|
-
for policy_name, policy_document in self.ecs_config.inline_policies.items():
|
|
178
|
-
self.instance_role.add_to_policy(
|
|
179
|
-
iam.PolicyStatement.from_json(policy_document)
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
# Create instance profile
|
|
183
|
-
self.instance_profile = iam.CfnInstanceProfile(
|
|
184
|
-
self,
|
|
185
|
-
"ECSInstanceProfile",
|
|
186
|
-
roles=[self.instance_role.role_name],
|
|
187
|
-
instance_profile_name=self.ecs_config.instance_profile_name
|
|
188
|
-
or f"{self.ecs_config.name}-instance-profile",
|
|
189
|
-
)
|
|
190
|
-
|
|
191
|
-
logger.info("Created ECS instance role and profile")
|
|
192
|
-
|
|
193
|
-
def _export_cluster_info(self):
|
|
194
|
-
"""Export cluster information via SSM parameters and CloudFormation outputs."""
|
|
195
|
-
logger.info("Exporting ECS cluster information")
|
|
196
|
-
|
|
197
|
-
ssm_exports = self.ecs_config.ssm_exports
|
|
198
|
-
|
|
199
|
-
if not ssm_exports:
|
|
200
|
-
logger.info("No SSM exports configured for ECS Cluster")
|
|
201
|
-
return
|
|
202
|
-
|
|
203
|
-
logger.info(f"Processing {len(ssm_exports)} SSM exports for ECS Cluster")
|
|
204
|
-
|
|
205
|
-
if "cluster_name" in ssm_exports:
|
|
206
|
-
self.export_ssm_parameter(
|
|
207
|
-
scope=self,
|
|
208
|
-
id="ClusterNameParam",
|
|
209
|
-
value=self.ecs_config.name,
|
|
210
|
-
parameter_name=ssm_exports["cluster_name"],
|
|
211
|
-
description=f"ECS Cluster Name: {self.ecs_config.name}",
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
if "cluster_arn" in ssm_exports:
|
|
215
|
-
self.export_ssm_parameter(
|
|
216
|
-
scope=self,
|
|
217
|
-
id="ClusterArnParam",
|
|
218
|
-
value=self.ecs_cluster.cluster_arn,
|
|
219
|
-
parameter_name=ssm_exports["cluster_arn"],
|
|
220
|
-
description=f"ECS Cluster ARN: {self.ecs_cluster.cluster_arn}",
|
|
221
|
-
)
|
|
222
|
-
|
|
223
|
-
if "instance_role_arn" in ssm_exports:
|
|
224
|
-
self.export_ssm_parameter(
|
|
225
|
-
scope=self,
|
|
226
|
-
id="InstanceRoleArnParam",
|
|
227
|
-
value=self.instance_role.role_arn,
|
|
228
|
-
parameter_name=ssm_exports["instance_role_arn"],
|
|
229
|
-
description=f"ECS Instance Role ARN: {self.instance_role.role_arn}",
|
|
230
|
-
)
|
|
231
|
-
|
|
232
|
-
|
|
@@ -1,298 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
VPC Stack Pattern for CDK-Factory
|
|
3
|
-
Maintainers: Eric Wilson
|
|
4
|
-
MIT License. See Project Root for the license information.
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
from typing import Dict, Any, List, Optional
|
|
8
|
-
|
|
9
|
-
import aws_cdk as cdk
|
|
10
|
-
from aws_cdk import aws_ec2 as ec2
|
|
11
|
-
from aws_lambda_powertools import Logger
|
|
12
|
-
from constructs import Construct
|
|
13
|
-
|
|
14
|
-
from cdk_factory.configurations.deployment import DeploymentConfig
|
|
15
|
-
from cdk_factory.configurations.stack import StackConfig
|
|
16
|
-
from cdk_factory.configurations.resources.vpc import VpcConfig
|
|
17
|
-
from cdk_factory.interfaces.istack import IStack
|
|
18
|
-
from cdk_factory.interfaces.enhanced_ssm_parameter_mixin import EnhancedSsmParameterMixin
|
|
19
|
-
from cdk_factory.stack.stack_module_registry import register_stack
|
|
20
|
-
from cdk_factory.workload.workload_factory import WorkloadConfig
|
|
21
|
-
|
|
22
|
-
logger = Logger(service="VpcStack")
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
@register_stack("vpc_library_module")
|
|
26
|
-
@register_stack("vpc_stack")
|
|
27
|
-
class VpcStack(IStack, EnhancedSsmParameterMixin):
|
|
28
|
-
"""
|
|
29
|
-
Reusable stack for AWS VPC.
|
|
30
|
-
Supports creating VPCs with customizable CIDR blocks, subnets, and networking components.
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
def __init__(self, scope: Construct, id: str, **kwargs) -> None:
|
|
34
|
-
super().__init__(scope, id, **kwargs)
|
|
35
|
-
self.vpc_config = None
|
|
36
|
-
self.stack_config = None
|
|
37
|
-
self.deployment = None
|
|
38
|
-
self.workload = None
|
|
39
|
-
self.vpc = None
|
|
40
|
-
|
|
41
|
-
def build(
|
|
42
|
-
self,
|
|
43
|
-
stack_config: StackConfig,
|
|
44
|
-
deployment: DeploymentConfig,
|
|
45
|
-
workload: WorkloadConfig,
|
|
46
|
-
) -> None:
|
|
47
|
-
"""Build the VPC stack"""
|
|
48
|
-
self._build(stack_config, deployment, workload)
|
|
49
|
-
|
|
50
|
-
def _build(
|
|
51
|
-
self,
|
|
52
|
-
stack_config: StackConfig,
|
|
53
|
-
deployment: DeploymentConfig,
|
|
54
|
-
workload: WorkloadConfig,
|
|
55
|
-
) -> None:
|
|
56
|
-
"""Internal build method for the VPC stack"""
|
|
57
|
-
self.stack_config = stack_config
|
|
58
|
-
self.deployment = deployment
|
|
59
|
-
self.workload = workload
|
|
60
|
-
|
|
61
|
-
self.vpc_config = VpcConfig(stack_config.dictionary.get("vpc", {}), deployment)
|
|
62
|
-
vpc_name = deployment.build_resource_name(self.vpc_config.name)
|
|
63
|
-
|
|
64
|
-
# Setup enhanced SSM integration
|
|
65
|
-
self.setup_enhanced_ssm_integration(self, self.vpc_config)
|
|
66
|
-
|
|
67
|
-
# Import any required resources from SSM
|
|
68
|
-
imported_resources = self.auto_import_resources({
|
|
69
|
-
"deployment_name": deployment.name,
|
|
70
|
-
"environment": deployment.environment,
|
|
71
|
-
"workload_name": workload.name
|
|
72
|
-
})
|
|
73
|
-
|
|
74
|
-
if imported_resources:
|
|
75
|
-
logger.info(f"Imported resources from SSM: {list(imported_resources.keys())}")
|
|
76
|
-
|
|
77
|
-
# Create the VPC
|
|
78
|
-
self.vpc = self._create_vpc(vpc_name)
|
|
79
|
-
|
|
80
|
-
# Add outputs
|
|
81
|
-
self._add_outputs(vpc_name)
|
|
82
|
-
|
|
83
|
-
def _create_vpc(self, vpc_name: str) -> ec2.Vpc:
|
|
84
|
-
"""Create a VPC with the specified configuration"""
|
|
85
|
-
# Configure subnet configuration
|
|
86
|
-
subnet_configuration = self._get_subnet_configuration()
|
|
87
|
-
|
|
88
|
-
# Configure NAT gateways
|
|
89
|
-
nat_gateway_count = self.vpc_config.nat_gateways.get("count", 1)
|
|
90
|
-
|
|
91
|
-
# Get explicit availability zones to avoid dummy AZs in pipeline synthesis
|
|
92
|
-
# When CDK synthesizes in a pipeline context, it doesn't have access to real AZs
|
|
93
|
-
# So we explicitly specify them based on the deployment region
|
|
94
|
-
availability_zones = None
|
|
95
|
-
if self.deployment:
|
|
96
|
-
region = self.deployment.region or "us-east-1"
|
|
97
|
-
# Explicitly list AZs for the region to avoid dummy values
|
|
98
|
-
max_azs = self.vpc_config.max_azs or 2
|
|
99
|
-
if region == "us-east-1":
|
|
100
|
-
availability_zones = [f"us-east-1{chr(97+i)}" for i in range(max_azs)] # us-east-1a, us-east-1b, etc.
|
|
101
|
-
elif region == "us-east-2":
|
|
102
|
-
availability_zones = [f"us-east-2{chr(97+i)}" for i in range(max_azs)]
|
|
103
|
-
elif region == "us-west-1":
|
|
104
|
-
availability_zones = [f"us-west-1{chr(97+i)}" for i in range(max_azs)]
|
|
105
|
-
elif region == "us-west-2":
|
|
106
|
-
availability_zones = [f"us-west-2{chr(97+i)}" for i in range(max_azs)]
|
|
107
|
-
|
|
108
|
-
# Build VPC properties
|
|
109
|
-
# Note: CDK doesn't allow both 'availability_zones' and 'max_azs' - use one or the other
|
|
110
|
-
vpc_props = {
|
|
111
|
-
"vpc_name": vpc_name,
|
|
112
|
-
"cidr": self.vpc_config.cidr,
|
|
113
|
-
"nat_gateways": nat_gateway_count,
|
|
114
|
-
"subnet_configuration": subnet_configuration,
|
|
115
|
-
"enable_dns_hostnames": self.vpc_config.enable_dns_hostnames,
|
|
116
|
-
"enable_dns_support": self.vpc_config.enable_dns_support,
|
|
117
|
-
"gateway_endpoints": (
|
|
118
|
-
{
|
|
119
|
-
"S3": ec2.GatewayVpcEndpointOptions(
|
|
120
|
-
service=ec2.GatewayVpcEndpointAwsService.S3
|
|
121
|
-
)
|
|
122
|
-
}
|
|
123
|
-
if self.vpc_config.enable_s3_endpoint
|
|
124
|
-
else None
|
|
125
|
-
),
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
# Use either availability_zones or max_azs, not both
|
|
129
|
-
if availability_zones:
|
|
130
|
-
vpc_props["availability_zones"] = availability_zones
|
|
131
|
-
else:
|
|
132
|
-
vpc_props["max_azs"] = self.vpc_config.max_azs
|
|
133
|
-
|
|
134
|
-
# Create the VPC
|
|
135
|
-
vpc = ec2.Vpc(self, vpc_name, **vpc_props)
|
|
136
|
-
|
|
137
|
-
# Add interface endpoints if specified
|
|
138
|
-
if self.vpc_config.enable_interface_endpoints:
|
|
139
|
-
self._add_interface_endpoints(vpc, self.vpc_config.interface_endpoints)
|
|
140
|
-
|
|
141
|
-
# Add tags if specified
|
|
142
|
-
for key, value in self.vpc_config.tags.items():
|
|
143
|
-
cdk.Tags.of(vpc).add(key, value)
|
|
144
|
-
|
|
145
|
-
return vpc
|
|
146
|
-
|
|
147
|
-
def _get_subnet_configuration(self) -> List[ec2.SubnetConfiguration]:
|
|
148
|
-
"""Configure the subnets for the VPC"""
|
|
149
|
-
subnet_configs = []
|
|
150
|
-
|
|
151
|
-
# Public subnets
|
|
152
|
-
if self.vpc_config.public_subnets:
|
|
153
|
-
subnet_configs.append(
|
|
154
|
-
ec2.SubnetConfiguration(
|
|
155
|
-
name=self.vpc_config.public_subnet_name,
|
|
156
|
-
subnet_type=ec2.SubnetType.PUBLIC,
|
|
157
|
-
cidr_mask=self.vpc_config.public_subnet_mask,
|
|
158
|
-
)
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
# Private subnets
|
|
162
|
-
if self.vpc_config.private_subnets:
|
|
163
|
-
subnet_configs.append(
|
|
164
|
-
ec2.SubnetConfiguration(
|
|
165
|
-
name=self.vpc_config.private_subnet_name,
|
|
166
|
-
subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS,
|
|
167
|
-
cidr_mask=self.vpc_config.private_subnet_mask,
|
|
168
|
-
)
|
|
169
|
-
)
|
|
170
|
-
|
|
171
|
-
# Isolated subnets
|
|
172
|
-
if self.vpc_config.isolated_subnets:
|
|
173
|
-
subnet_configs.append(
|
|
174
|
-
ec2.SubnetConfiguration(
|
|
175
|
-
name=self.vpc_config.isolated_subnet_name,
|
|
176
|
-
subnet_type=ec2.SubnetType.PRIVATE_ISOLATED,
|
|
177
|
-
cidr_mask=self.vpc_config.isolated_subnet_mask,
|
|
178
|
-
)
|
|
179
|
-
)
|
|
180
|
-
|
|
181
|
-
return subnet_configs
|
|
182
|
-
|
|
183
|
-
def _get_nat_gateway_configuration(self) -> Dict[str, Any]:
|
|
184
|
-
"""Configure NAT gateways for the VPC"""
|
|
185
|
-
return self.vpc_config.nat_gateways
|
|
186
|
-
|
|
187
|
-
def _add_interface_endpoints(self, vpc: ec2.Vpc, endpoints: List[str]) -> None:
|
|
188
|
-
"""Add interface endpoints to the VPC"""
|
|
189
|
-
# Common interface endpoints
|
|
190
|
-
endpoint_services = {
|
|
191
|
-
"ecr.api": ec2.InterfaceVpcEndpointAwsService.ECR,
|
|
192
|
-
"ecr.dkr": ec2.InterfaceVpcEndpointAwsService.ECR_DOCKER,
|
|
193
|
-
"logs": ec2.InterfaceVpcEndpointAwsService.CLOUDWATCH_LOGS,
|
|
194
|
-
"ssm": ec2.InterfaceVpcEndpointAwsService.SSM,
|
|
195
|
-
"secretsmanager": ec2.InterfaceVpcEndpointAwsService.SECRETS_MANAGER,
|
|
196
|
-
"lambda": ec2.InterfaceVpcEndpointAwsService.LAMBDA_,
|
|
197
|
-
"sts": ec2.InterfaceVpcEndpointAwsService.STS,
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
# Add specified endpoints
|
|
201
|
-
for endpoint in endpoints:
|
|
202
|
-
if endpoint in endpoint_services:
|
|
203
|
-
vpc.add_interface_endpoint(
|
|
204
|
-
f"{endpoint}-endpoint", service=endpoint_services[endpoint]
|
|
205
|
-
)
|
|
206
|
-
else:
|
|
207
|
-
logger.warning(f"Unsupported interface endpoint: {endpoint}")
|
|
208
|
-
|
|
209
|
-
def _add_outputs(self, vpc_name: str) -> None:
|
|
210
|
-
"""Add CloudFormation outputs for the VPC"""
|
|
211
|
-
if self.vpc:
|
|
212
|
-
cdk.CfnOutput(
|
|
213
|
-
self,
|
|
214
|
-
f"{vpc_name}-id",
|
|
215
|
-
value=self.vpc.vpc_id,
|
|
216
|
-
export_name=f"{self.deployment.build_resource_name(vpc_name)}-id",
|
|
217
|
-
)
|
|
218
|
-
|
|
219
|
-
cdk.CfnOutput(
|
|
220
|
-
self,
|
|
221
|
-
f"{vpc_name}-public-subnets",
|
|
222
|
-
value=",".join(
|
|
223
|
-
[subnet.subnet_id for subnet in self.vpc.public_subnets]
|
|
224
|
-
),
|
|
225
|
-
export_name=f"{self.deployment.build_resource_name(vpc_name)}-public-subnets",
|
|
226
|
-
)
|
|
227
|
-
|
|
228
|
-
if self.vpc.private_subnets:
|
|
229
|
-
cdk.CfnOutput(
|
|
230
|
-
self,
|
|
231
|
-
f"{vpc_name}-private-subnets",
|
|
232
|
-
value=",".join(
|
|
233
|
-
[subnet.subnet_id for subnet in self.vpc.private_subnets]
|
|
234
|
-
),
|
|
235
|
-
export_name=f"{self.deployment.build_resource_name(vpc_name)}-private-subnets",
|
|
236
|
-
)
|
|
237
|
-
|
|
238
|
-
if hasattr(self.vpc, "isolated_subnets") and self.vpc.isolated_subnets:
|
|
239
|
-
cdk.CfnOutput(
|
|
240
|
-
self,
|
|
241
|
-
f"{vpc_name}-isolated-subnets",
|
|
242
|
-
value=",".join(
|
|
243
|
-
[subnet.subnet_id for subnet in self.vpc.isolated_subnets]
|
|
244
|
-
),
|
|
245
|
-
export_name=f"{self.deployment.build_resource_name(vpc_name)}-isolated-subnets",
|
|
246
|
-
)
|
|
247
|
-
|
|
248
|
-
# Export SSM parameters if configured
|
|
249
|
-
self._export_ssm_parameters(vpc_name)
|
|
250
|
-
|
|
251
|
-
def _export_ssm_parameters(self, vpc_name: str) -> None:
|
|
252
|
-
"""Export VPC resources to SSM Parameter Store using enhanced auto-export"""
|
|
253
|
-
if not self.vpc:
|
|
254
|
-
return
|
|
255
|
-
|
|
256
|
-
# Create a dictionary of VPC resources to export
|
|
257
|
-
vpc_resources = {
|
|
258
|
-
"vpc_id": self.vpc.vpc_id,
|
|
259
|
-
"vpc_cidr": self.vpc.vpc_cidr_block,
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
# Add subnet IDs as comma-separated lists
|
|
263
|
-
if self.vpc.public_subnets:
|
|
264
|
-
vpc_resources["public_subnet_ids"] = ",".join(
|
|
265
|
-
[subnet.subnet_id for subnet in self.vpc.public_subnets]
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
if self.vpc.private_subnets:
|
|
269
|
-
vpc_resources["private_subnet_ids"] = ",".join(
|
|
270
|
-
[subnet.subnet_id for subnet in self.vpc.private_subnets]
|
|
271
|
-
)
|
|
272
|
-
|
|
273
|
-
if hasattr(self.vpc, "isolated_subnets") and self.vpc.isolated_subnets:
|
|
274
|
-
vpc_resources["isolated_subnet_ids"] = ",".join(
|
|
275
|
-
[subnet.subnet_id for subnet in self.vpc.isolated_subnets]
|
|
276
|
-
)
|
|
277
|
-
|
|
278
|
-
# Use enhanced auto-export with context
|
|
279
|
-
context = {
|
|
280
|
-
"deployment_name": self.deployment.name,
|
|
281
|
-
"environment": self.deployment.environment,
|
|
282
|
-
"workload_name": self.workload.name
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
exported_params = self.auto_export_resources(vpc_resources, context)
|
|
286
|
-
|
|
287
|
-
if exported_params:
|
|
288
|
-
logger.info(f"Auto-exported VPC resources to SSM: {list(exported_params.keys())}")
|
|
289
|
-
else:
|
|
290
|
-
# Fall back to legacy method for backward compatibility
|
|
291
|
-
self.export_resource_to_ssm(
|
|
292
|
-
scope=self,
|
|
293
|
-
resource_values=vpc_resources,
|
|
294
|
-
config=self.vpc_config,
|
|
295
|
-
resource_name=vpc_name,
|
|
296
|
-
resource_type="vpc",
|
|
297
|
-
context=context
|
|
298
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|