cdk-factory 0.15.10__py3-none-any.whl → 0.18.9__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 +6 -4
- cdk_factory/configurations/deployment.py +12 -0
- cdk_factory/configurations/devops.py +1 -1
- cdk_factory/configurations/pipeline_stage.py +29 -5
- cdk_factory/configurations/resources/acm.py +85 -0
- 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 +108 -0
- cdk_factory/configurations/resources/ecs_service.py +17 -2
- cdk_factory/configurations/resources/load_balancer.py +17 -4
- cdk_factory/configurations/resources/monitoring.py +8 -3
- cdk_factory/configurations/resources/rds.py +305 -19
- 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 +6 -3
- cdk_factory/interfaces/networked_stack_mixin.py +75 -0
- cdk_factory/interfaces/standardized_ssm_mixin.py +657 -0
- cdk_factory/interfaces/vpc_provider_mixin.py +210 -0
- cdk_factory/lambdas/edge/ip_gate/handler.py +42 -40
- cdk_factory/pipeline/pipeline_factory.py +222 -27
- cdk_factory/stack/stack_factory.py +34 -0
- cdk_factory/stack_library/__init__.py +3 -2
- cdk_factory/stack_library/acm/__init__.py +6 -0
- cdk_factory/stack_library/acm/acm_stack.py +169 -0
- cdk_factory/stack_library/api_gateway/api_gateway_stack.py +84 -59
- cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +366 -408
- 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 +12 -0
- cdk_factory/stack_library/ecs/ecs_cluster_stack.py +316 -0
- cdk_factory/stack_library/ecs/ecs_service_stack.py +20 -39
- cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +2 -2
- cdk_factory/stack_library/load_balancer/load_balancer_stack.py +151 -118
- cdk_factory/stack_library/rds/rds_stack.py +85 -74
- cdk_factory/stack_library/route53/route53_stack.py +8 -3
- 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/stack_base.py +5 -0
- cdk_factory/stack_library/vpc/vpc_stack.py +272 -124
- cdk_factory/stack_library/websites/static_website_stack.py +1 -1
- 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 +12 -3
- cdk_factory/validation/config_validator.py +483 -0
- cdk_factory/version.py +1 -1
- cdk_factory/workload/workload_factory.py +1 -0
- {cdk_factory-0.15.10.dist-info → cdk_factory-0.18.9.dist-info}/METADATA +1 -1
- {cdk_factory-0.15.10.dist-info → cdk_factory-0.18.9.dist-info}/RECORD +61 -54
- cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +0 -321
- cdk_factory/interfaces/ssm_parameter_mixin.py +0 -329
- {cdk_factory-0.15.10.dist-info → cdk_factory-0.18.9.dist-info}/WHEEL +0 -0
- {cdk_factory-0.15.10.dist-info → cdk_factory-0.18.9.dist-info}/entry_points.txt +0 -0
- {cdk_factory-0.15.10.dist-info → cdk_factory-0.18.9.dist-info}/licenses/LICENSE +0 -0
|
@@ -17,14 +17,19 @@ class BaseConfig:
|
|
|
17
17
|
SSM parameter paths can be customized with prefixes and templates at different levels:
|
|
18
18
|
1. Global level: In the workload or deployment config
|
|
19
19
|
2. Stack level: In the stack config
|
|
20
|
-
3. Resource level: In the resource config (
|
|
20
|
+
3. Resource level: In the resource config (ssm.exports/ssm.imports)
|
|
21
21
|
|
|
22
22
|
Example configurations:
|
|
23
23
|
```json
|
|
24
24
|
{
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
"
|
|
25
|
+
"ssm": {
|
|
26
|
+
"prefix_template": "/{environment}/{resource_type}/{attribute}",
|
|
27
|
+
"exports": {
|
|
28
|
+
"vpc_id": "my-vpc-id"
|
|
29
|
+
},
|
|
30
|
+
"imports": {
|
|
31
|
+
"security_group_id": "/my-app/security-group/id"
|
|
32
|
+
}
|
|
28
33
|
}
|
|
29
34
|
}
|
|
30
35
|
```
|
|
@@ -57,6 +62,16 @@ class BaseConfig:
|
|
|
57
62
|
"""
|
|
58
63
|
return self.__config
|
|
59
64
|
|
|
65
|
+
@property
|
|
66
|
+
def ssm(self) -> Dict[str, Any]:
|
|
67
|
+
"""
|
|
68
|
+
Get the SSM configuration for this resource.
|
|
69
|
+
|
|
70
|
+
Returns:
|
|
71
|
+
Dictionary containing SSM configuration with imports/exports
|
|
72
|
+
"""
|
|
73
|
+
return self.__config.get("ssm", {})
|
|
74
|
+
|
|
60
75
|
@property
|
|
61
76
|
def ssm_prefix_template(self) -> str:
|
|
62
77
|
"""
|
|
@@ -68,7 +83,7 @@ class BaseConfig:
|
|
|
68
83
|
Returns:
|
|
69
84
|
The SSM parameter prefix template string
|
|
70
85
|
"""
|
|
71
|
-
return self.
|
|
86
|
+
return self.ssm.get("prefix_template", "/{deployment_name}/{resource_type}/{attribute}")
|
|
72
87
|
|
|
73
88
|
@property
|
|
74
89
|
def ssm_exports(self) -> Dict[str, str]:
|
|
@@ -87,7 +102,7 @@ class BaseConfig:
|
|
|
87
102
|
Returns:
|
|
88
103
|
Dictionary mapping attribute names to SSM parameter paths for export
|
|
89
104
|
"""
|
|
90
|
-
return self.
|
|
105
|
+
return self.ssm.get("exports", {})
|
|
91
106
|
|
|
92
107
|
@property
|
|
93
108
|
def ssm_imports(self) -> Dict[str, str]:
|
|
@@ -106,25 +121,9 @@ class BaseConfig:
|
|
|
106
121
|
Returns:
|
|
107
122
|
Dictionary mapping attribute names to SSM parameter paths for import
|
|
108
123
|
"""
|
|
109
|
-
return self.
|
|
110
|
-
|
|
111
|
-
@property
|
|
112
|
-
def ssm_parameters(self) -> Dict[str, str]:
|
|
113
|
-
"""
|
|
114
|
-
Get all SSM parameter path mappings (both exports and imports).
|
|
115
|
-
|
|
116
|
-
This is provided for backward compatibility.
|
|
117
|
-
New code should use ssm_exports and ssm_imports instead.
|
|
118
|
-
|
|
119
|
-
Returns:
|
|
120
|
-
Dictionary mapping attribute names to SSM parameter paths
|
|
121
|
-
"""
|
|
122
|
-
# Merge exports and imports, with exports taking precedence
|
|
123
|
-
combined = {**self.ssm_imports, **self.ssm_exports}
|
|
124
|
-
# Also include any parameters directly under ssm_parameters for backward compatibility
|
|
125
|
-
combined.update(self.__config.get("ssm_parameters", {}))
|
|
126
|
-
return combined
|
|
124
|
+
return self.ssm.get("imports", {})
|
|
127
125
|
|
|
126
|
+
|
|
128
127
|
def get(self, key: str, default: Any = None) -> Any:
|
|
129
128
|
"""
|
|
130
129
|
Get a configuration value by key.
|
|
@@ -183,11 +183,13 @@ class CdkConfig:
|
|
|
183
183
|
if self._resolved_config_file_path is None:
|
|
184
184
|
raise ValueError("Config file path is not set")
|
|
185
185
|
|
|
186
|
-
file_name =
|
|
186
|
+
file_name = os.path.join(".dynamic", os.path.basename(self._resolved_config_file_path))
|
|
187
187
|
path = os.path.join(Path(self._resolved_config_file_path).parent, file_name)
|
|
188
|
-
|
|
188
|
+
|
|
189
|
+
if not os.path.exists(Path(path).parent):
|
|
190
|
+
os.makedirs(Path(path).parent)
|
|
189
191
|
cdk = config.get("cdk", {})
|
|
190
|
-
if replacements
|
|
192
|
+
if replacements:
|
|
191
193
|
config = JsonLoadingUtility.recursive_replace(config, replacements)
|
|
192
194
|
print(f"📀 Saving config to {path}")
|
|
193
195
|
# add the original cdk back
|
|
@@ -214,7 +216,7 @@ class CdkConfig:
|
|
|
214
216
|
value = static_value
|
|
215
217
|
elif environment_variable_name is not None and not value:
|
|
216
218
|
value = os.environ.get(environment_variable_name, None)
|
|
217
|
-
if value is None and required:
|
|
219
|
+
if (value is None or str(value).strip() == "") and required:
|
|
218
220
|
raise ValueError(
|
|
219
221
|
f"Failed to get value for environment variable {environment_variable_name}"
|
|
220
222
|
)
|
|
@@ -28,6 +28,18 @@ class DeploymentConfig:
|
|
|
28
28
|
self.__load()
|
|
29
29
|
|
|
30
30
|
def __load(self):
|
|
31
|
+
# Validate environment consistency
|
|
32
|
+
deployment_env = self.__deployment.get("environment")
|
|
33
|
+
workload_env = self.__workload.get("environment")
|
|
34
|
+
|
|
35
|
+
if deployment_env and workload_env and deployment_env != workload_env:
|
|
36
|
+
from aws_lambda_powertools import Logger
|
|
37
|
+
logger = Logger()
|
|
38
|
+
logger.warning(
|
|
39
|
+
f"Environment mismatch: deployment.environment='{deployment_env}' != workload.environment='{workload_env}'. "
|
|
40
|
+
f"Using workload.environment for consistency."
|
|
41
|
+
)
|
|
42
|
+
|
|
31
43
|
self.__load_pipeline()
|
|
32
44
|
self.__load_stacks()
|
|
33
45
|
|
|
@@ -117,8 +117,32 @@ class PipelineStageConfig:
|
|
|
117
117
|
@property
|
|
118
118
|
def builds(self) -> List[Dict[str, Any]]:
|
|
119
119
|
"""
|
|
120
|
-
Returns the
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
return
|
|
120
|
+
Returns the builds configured for this stage.
|
|
121
|
+
|
|
122
|
+
If the stage has a "builds" array of strings, resolve them to the
|
|
123
|
+
corresponding build objects defined at workload["builds"].
|
|
124
|
+
Otherwise, return an empty list.
|
|
125
|
+
"""
|
|
126
|
+
stage_build_refs = self.dictionary.get("builds", [])
|
|
127
|
+
if not stage_build_refs:
|
|
128
|
+
return []
|
|
129
|
+
|
|
130
|
+
workload_builds: List[Dict[str, Any]] = self.workload.get("builds", [])
|
|
131
|
+
by_name: Dict[str, Dict[str, Any]] = {}
|
|
132
|
+
for b in workload_builds:
|
|
133
|
+
name = b.get("name") or b.get("id")
|
|
134
|
+
if name:
|
|
135
|
+
by_name[name] = b
|
|
136
|
+
|
|
137
|
+
resolved: List[Dict[str, Any]] = []
|
|
138
|
+
for ref in stage_build_refs:
|
|
139
|
+
if isinstance(ref, str):
|
|
140
|
+
if ref in by_name:
|
|
141
|
+
resolved.append(by_name[ref])
|
|
142
|
+
else:
|
|
143
|
+
raise ValueError(f"Build '{ref}' referenced by stage '{self.name}' not found in workload.builds")
|
|
144
|
+
elif isinstance(ref, dict):
|
|
145
|
+
# Allow inline build definitions at the stage level as a fallback
|
|
146
|
+
resolved.append(ref)
|
|
147
|
+
|
|
148
|
+
return resolved
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
AcmConfig - supports ACM (AWS Certificate Manager) settings for AWS CDK.
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for license information.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Any, Dict, List, Optional
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class AcmConfig:
|
|
11
|
+
"""
|
|
12
|
+
ACM Configuration - supports AWS Certificate Manager settings.
|
|
13
|
+
Each property reads from the config dict and provides a sensible default if not set.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, config: dict = None, deployment=None) -> None:
|
|
17
|
+
self.__config = config or {}
|
|
18
|
+
self.__deployment = deployment
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def name(self) -> str:
|
|
22
|
+
"""Certificate configuration name"""
|
|
23
|
+
return self.__config.get("name", "certificate")
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def domain_name(self) -> str:
|
|
27
|
+
"""Primary domain name for the certificate"""
|
|
28
|
+
domain = self.__config.get("domain_name")
|
|
29
|
+
if not domain:
|
|
30
|
+
raise ValueError("domain_name is required for ACM certificate")
|
|
31
|
+
return domain
|
|
32
|
+
|
|
33
|
+
@property
|
|
34
|
+
def subject_alternative_names(self) -> List[str]:
|
|
35
|
+
"""Subject alternative names (SANs) for the certificate"""
|
|
36
|
+
sans = self.__config.get("subject_alternative_names", [])
|
|
37
|
+
# Also check for alternate_names for backward compatibility
|
|
38
|
+
if not sans:
|
|
39
|
+
sans = self.__config.get("alternate_names", [])
|
|
40
|
+
return sans
|
|
41
|
+
|
|
42
|
+
@property
|
|
43
|
+
def hosted_zone_id(self) -> Optional[str]:
|
|
44
|
+
"""Route53 hosted zone ID for DNS validation"""
|
|
45
|
+
return self.__config.get("hosted_zone_id")
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def hosted_zone_name(self) -> Optional[str]:
|
|
49
|
+
"""Route53 hosted zone name (used for looking up zone)"""
|
|
50
|
+
return self.__config.get("hosted_zone_name")
|
|
51
|
+
|
|
52
|
+
@property
|
|
53
|
+
def validation_method(self) -> str:
|
|
54
|
+
"""Certificate validation method (DNS or EMAIL)"""
|
|
55
|
+
return self.__config.get("validation_method", "DNS")
|
|
56
|
+
|
|
57
|
+
@property
|
|
58
|
+
def certificate_transparency_logging_preference(self) -> Optional[str]:
|
|
59
|
+
"""Certificate transparency logging preference (ENABLED or DISABLED)"""
|
|
60
|
+
return self.__config.get("certificate_transparency_logging_preference")
|
|
61
|
+
|
|
62
|
+
@property
|
|
63
|
+
def ssm(self) -> Dict[str, Any]:
|
|
64
|
+
"""SSM configuration for importing/exporting resources"""
|
|
65
|
+
return self.__config.get("ssm", {})
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def ssm_exports(self) -> Dict[str, str]:
|
|
69
|
+
"""SSM parameter paths to export certificate details"""
|
|
70
|
+
exports = self.ssm.get("exports", {})
|
|
71
|
+
|
|
72
|
+
# Provide default SSM export path if not specified
|
|
73
|
+
if not exports and self.__deployment:
|
|
74
|
+
workload_env = self.__deployment.workload.get("environment", self.__deployment.environment)
|
|
75
|
+
workload_name = self.__deployment.workload.get("name", self.__deployment.workload_name)
|
|
76
|
+
exports = {
|
|
77
|
+
"certificate_arn": f"/{workload_env}/{workload_name}/certificate/arn"
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
return exports
|
|
81
|
+
|
|
82
|
+
@property
|
|
83
|
+
def tags(self) -> Dict[str, str]:
|
|
84
|
+
"""Tags to apply to the certificate"""
|
|
85
|
+
return self.__config.get("tags", {})
|
|
@@ -70,12 +70,9 @@ class AutoScalingConfig(EnhancedBaseConfig):
|
|
|
70
70
|
return self.__config.get("termination_policies", ["DEFAULT"])
|
|
71
71
|
|
|
72
72
|
@property
|
|
73
|
-
def update_policy(self) -> Dict[str, Any]:
|
|
73
|
+
def update_policy(self) -> Optional[Dict[str, Any]]:
|
|
74
74
|
"""Update policy configuration"""
|
|
75
|
-
return self.__config.get(
|
|
76
|
-
"update_policy",
|
|
77
|
-
{"min_instances_in_service": 1, "max_batch_size": 1, "pause_time": 300},
|
|
78
|
-
)
|
|
75
|
+
return self.__config.get("update_policy")
|
|
79
76
|
|
|
80
77
|
@property
|
|
81
78
|
def user_data_commands(self) -> List[str]:
|
|
@@ -175,3 +172,8 @@ class AutoScalingConfig(EnhancedBaseConfig):
|
|
|
175
172
|
def key_name(self) -> Optional[str]:
|
|
176
173
|
"""EC2 key pair name for SSH access"""
|
|
177
174
|
return self.__config.get("key_name")
|
|
175
|
+
|
|
176
|
+
@property
|
|
177
|
+
def ssm_imports(self) -> Dict[str, Any]:
|
|
178
|
+
"""SSM imports for the Auto Scaling Group"""
|
|
179
|
+
return self.__config.get("ssm", {}).get("imports", {})
|
|
@@ -102,15 +102,20 @@ class CloudFrontConfig(EnhancedBaseConfig):
|
|
|
102
102
|
"""Resource tags"""
|
|
103
103
|
return self._config.get("tags", {})
|
|
104
104
|
|
|
105
|
+
@property
|
|
106
|
+
def ssm(self) -> Dict[str, Any]:
|
|
107
|
+
"""SSM configuration"""
|
|
108
|
+
return self._config.get("ssm", {})
|
|
109
|
+
|
|
105
110
|
@property
|
|
106
111
|
def ssm_exports(self) -> Dict[str, str]:
|
|
107
112
|
"""SSM parameter exports"""
|
|
108
|
-
return self.
|
|
113
|
+
return self.ssm.get("exports", {})
|
|
109
114
|
|
|
110
115
|
@property
|
|
111
116
|
def ssm_imports(self) -> Dict[str, str]:
|
|
112
117
|
"""SSM parameter imports"""
|
|
113
|
-
return self.
|
|
118
|
+
return self.ssm.get("imports", {})
|
|
114
119
|
|
|
115
120
|
@property
|
|
116
121
|
def hosted_zone_id(self) -> str:
|
|
@@ -128,7 +128,7 @@ class ECRConfig(EnhancedBaseConfig):
|
|
|
128
128
|
Example:
|
|
129
129
|
{
|
|
130
130
|
"enabled": true,
|
|
131
|
-
"accounts": ["
|
|
131
|
+
"accounts": [os.environ.get("ECR_ALLOWED_ACCOUNT_1"), os.environ.get("ECR_ALLOWED_ACCOUNT_2")],
|
|
132
132
|
"services": [
|
|
133
133
|
{
|
|
134
134
|
"name": "lambda",
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ECS Cluster Configuration
|
|
3
|
+
|
|
4
|
+
Defines the configuration schema for ECS cluster stacks.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Optional, Dict, Any, List
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class EcsClusterConfig:
|
|
11
|
+
"""
|
|
12
|
+
Configuration for an ECS cluster.
|
|
13
|
+
|
|
14
|
+
This class defines all the configurable parameters for an ECS cluster,
|
|
15
|
+
providing explicit control over cluster creation and settings.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
def __init__(self, config: Dict[str, Any]) -> None:
|
|
19
|
+
self._config = config or {}
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def dictionary(self) -> Dict[str, Any]:
|
|
23
|
+
"""Access to the underlying configuration dictionary (for compatibility with SSM mixin)"""
|
|
24
|
+
return self._config
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def name(self) -> str:
|
|
28
|
+
"""Name of the ECS cluster. Supports template variables like {{WORKLOAD_NAME}}-{{ENVIRONMENT}}-cluster"""
|
|
29
|
+
return self._config.get("name", "cluster")
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def container_insights(self) -> bool:
|
|
33
|
+
"""Enable container insights for the cluster"""
|
|
34
|
+
return self._config.get("container_insights", True)
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def cluster_settings(self) -> Optional[List[Dict[str, str]]]:
|
|
38
|
+
"""Additional cluster settings as name-value pairs"""
|
|
39
|
+
return self._config.get("cluster_settings")
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def cloud_map_namespace(self) -> Optional[Dict[str, Any]]:
|
|
43
|
+
"""Cloud Map namespace configuration for service discovery"""
|
|
44
|
+
return self._config.get("cloud_map_namespace")
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def execute_command_configuration(self) -> Optional[Dict[str, Any]]:
|
|
48
|
+
"""Execute command configuration for ECS"""
|
|
49
|
+
return self._config.get("execute_command_configuration")
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def vpc_id(self) -> Optional[str]:
|
|
53
|
+
"""VPC ID where the cluster should be created"""
|
|
54
|
+
return self._config.get("vpc_id")
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def ssm_vpc_id(self) -> Optional[str]:
|
|
58
|
+
"""SSM parameter path to import VPC ID"""
|
|
59
|
+
return self._config.get("ssm_vpc_id")
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def create_instance_role(self) -> bool:
|
|
63
|
+
"""Whether to create an ECS instance role"""
|
|
64
|
+
return self._config.get("create_instance_role", True)
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def instance_role_name(self) -> Optional[str]:
|
|
68
|
+
"""Custom name for the ECS instance role"""
|
|
69
|
+
return self._config.get("instance_role_name")
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def instance_profile_name(self) -> Optional[str]:
|
|
73
|
+
"""Custom name for the ECS instance profile"""
|
|
74
|
+
return self._config.get("instance_profile_name")
|
|
75
|
+
|
|
76
|
+
@property
|
|
77
|
+
def managed_policies(self) -> List[str]:
|
|
78
|
+
"""List of AWS managed policies to attach to the instance role"""
|
|
79
|
+
return self._config.get("managed_policies", [
|
|
80
|
+
"service-role/AmazonEC2ContainerServiceforEC2Role",
|
|
81
|
+
"AmazonSSMManagedInstanceCore"
|
|
82
|
+
])
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def inline_policies(self) -> Optional[Dict[str, Dict[str, Any]]]:
|
|
86
|
+
"""Inline IAM policies to attach to the instance role"""
|
|
87
|
+
return self._config.get("inline_policies")
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def export_ssm_parameters(self) -> bool:
|
|
91
|
+
"""Whether to export cluster information to SSM parameters"""
|
|
92
|
+
return self._config.get("export_ssm_parameters", True)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def ssm(self) -> Dict[str, Any]:
|
|
97
|
+
"""SSM configuration"""
|
|
98
|
+
return self._config.get("ssm", {})
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def ssm_exports(self) -> Dict[str, str]:
|
|
102
|
+
"""SSM parameter exports"""
|
|
103
|
+
return self.ssm.get("exports", {})
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def ssm_imports(self) -> Dict[str, Any]:
|
|
107
|
+
"""SSM parameter imports"""
|
|
108
|
+
return self.ssm.get("imports", {})
|
|
@@ -123,10 +123,15 @@ class EcsServiceConfig:
|
|
|
123
123
|
"""Resource tags"""
|
|
124
124
|
return self._config.get("tags", {})
|
|
125
125
|
|
|
126
|
+
@property
|
|
127
|
+
def ssm(self) -> Dict[str, Any]:
|
|
128
|
+
"""SSM configuration"""
|
|
129
|
+
return self._config.get("ssm", {})
|
|
130
|
+
|
|
126
131
|
@property
|
|
127
132
|
def ssm_exports(self) -> Dict[str, str]:
|
|
128
133
|
"""SSM parameter exports"""
|
|
129
|
-
return self.
|
|
134
|
+
return self.ssm.get("exports", {})
|
|
130
135
|
|
|
131
136
|
@property
|
|
132
137
|
def ssm_imports(self) -> Dict[str, Any]:
|
|
@@ -134,13 +139,23 @@ class EcsServiceConfig:
|
|
|
134
139
|
# Check both nested and flat structures for backwards compatibility
|
|
135
140
|
if "ssm" in self._config and "imports" in self._config["ssm"]:
|
|
136
141
|
return self._config["ssm"]["imports"]
|
|
137
|
-
return self.
|
|
142
|
+
return self.ssm.get("imports", {})
|
|
138
143
|
|
|
139
144
|
@property
|
|
140
145
|
def deployment_type(self) -> str:
|
|
141
146
|
"""Deployment type: production, maintenance, or blue-green"""
|
|
142
147
|
return self._config.get("deployment_type", "production")
|
|
143
148
|
|
|
149
|
+
@property
|
|
150
|
+
def deployment_circuit_breaker(self) -> Dict[str, Any]:
|
|
151
|
+
"""Deployment circuit breaker configuration"""
|
|
152
|
+
return self._config.get("deployment_circuit_breaker", {})
|
|
153
|
+
|
|
154
|
+
@property
|
|
155
|
+
def deployment_configuration(self) -> Dict[str, Any]:
|
|
156
|
+
"""Deployment configuration (maximum_percent, minimum_healthy_percent)"""
|
|
157
|
+
return self._config.get("deployment_configuration", {})
|
|
158
|
+
|
|
144
159
|
@property
|
|
145
160
|
def is_maintenance_mode(self) -> bool:
|
|
146
161
|
"""Whether this is a maintenance mode deployment"""
|
|
@@ -144,10 +144,23 @@ class LoadBalancerConfig(EnhancedBaseConfig):
|
|
|
144
144
|
"block_response", default_response
|
|
145
145
|
)
|
|
146
146
|
|
|
147
|
+
@property
|
|
148
|
+
def ssm(self) -> Dict[str, Any]:
|
|
149
|
+
"""SSM configuration"""
|
|
150
|
+
return self.__config.get("ssm", {})
|
|
151
|
+
|
|
147
152
|
@property
|
|
148
153
|
def ssm_imports(self) -> Dict[str, Any]:
|
|
149
154
|
"""SSM parameter imports for the Load Balancer"""
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
155
|
+
return self.ssm.get("imports", {})
|
|
156
|
+
|
|
157
|
+
@property
|
|
158
|
+
def ssm_exports(self) -> Dict[str, Any]:
|
|
159
|
+
"""SSM parameter exports for the Load Balancer"""
|
|
160
|
+
return self.ssm.get("exports", {})
|
|
161
|
+
|
|
162
|
+
@property
|
|
163
|
+
def ssm_parameters(self) -> Dict[str, Any]:
|
|
164
|
+
"""SSM parameters for the Load Balancer (only exports, not imports)"""
|
|
165
|
+
# For LoadBalancer, only return exports to prevent trying to export imported values
|
|
166
|
+
return self.ssm_exports
|
|
@@ -18,7 +18,7 @@ class MonitoringConfig(EnhancedBaseConfig):
|
|
|
18
18
|
super().__init__(
|
|
19
19
|
config or {},
|
|
20
20
|
resource_type="monitoring",
|
|
21
|
-
resource_name=config.get("name", "monitoring") if config else "monitoring"
|
|
21
|
+
resource_name=config.get("name", "monitoring") if config else "monitoring",
|
|
22
22
|
)
|
|
23
23
|
self._config = config or {}
|
|
24
24
|
self._deployment = deployment
|
|
@@ -63,12 +63,17 @@ class MonitoringConfig(EnhancedBaseConfig):
|
|
|
63
63
|
"""Resource tags"""
|
|
64
64
|
return self._config.get("tags", {})
|
|
65
65
|
|
|
66
|
+
@property
|
|
67
|
+
def ssm(self) -> Dict[str, Any]:
|
|
68
|
+
"""SSM configuration"""
|
|
69
|
+
return self._config.get("ssm", {})
|
|
70
|
+
|
|
66
71
|
@property
|
|
67
72
|
def ssm_exports(self) -> Dict[str, str]:
|
|
68
73
|
"""SSM parameter exports"""
|
|
69
|
-
return self.
|
|
74
|
+
return self.ssm.get("exports", {})
|
|
70
75
|
|
|
71
76
|
@property
|
|
72
77
|
def ssm_imports(self) -> Dict[str, str]:
|
|
73
78
|
"""SSM parameter imports for resource ARNs"""
|
|
74
|
-
return self.
|
|
79
|
+
return self.ssm.get("imports", {})
|