cdk-factory 0.16.8__tar.gz → 0.16.10__tar.gz

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.
Files changed (164) hide show
  1. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/PKG-INFO +1 -1
  2. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/pyproject.toml +1 -1
  3. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/interfaces/vpc_provider_mixin.py +34 -9
  4. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +71 -64
  5. cdk_factory-0.16.10/src/cdk_factory/version.py +1 -0
  6. cdk_factory-0.16.8/src/cdk_factory/version.py +0 -1
  7. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/.gitignore +0 -0
  8. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/.windsurfrules +0 -0
  9. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/LICENSE +0 -0
  10. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/README.md +0 -0
  11. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/REFACTORING_PLAN.md +0 -0
  12. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/archive/README.md +0 -0
  13. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/archive/migrate_to_enhanced_ssm.py +0 -0
  14. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/examples/json-imports/README.md +0 -0
  15. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/examples/separate-api-gateway/README.md +0 -0
  16. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/examples/separate-api-gateway/api-gateway-stack.json +0 -0
  17. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/examples/separate-api-gateway/config.json +0 -0
  18. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/examples/separate-api-gateway/lambda-stack.json +0 -0
  19. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/mypy.ini +0 -0
  20. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/publish_to_pypi.py +0 -0
  21. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/publish_to_pypi.sh +0 -0
  22. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/pysetup.py +0 -0
  23. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/pysetup.sh +0 -0
  24. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/requirements.dev.txt +0 -0
  25. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/requirements.tests.txt +0 -0
  26. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/requirements.txt +0 -0
  27. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/run-checks.sh +0 -0
  28. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/run-tests-clean-venv.sh +0 -0
  29. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/run-tests.sh +0 -0
  30. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/scripts/cloudfront-cleanup.sh +0 -0
  31. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/__init__.py +0 -0
  32. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/app.py +0 -0
  33. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/builds/README.md +0 -0
  34. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/cdk.json +0 -0
  35. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/cli.py +0 -0
  36. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/commands/command_loader.py +0 -0
  37. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/base_config.py +0 -0
  38. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/cdk_config.py +0 -0
  39. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/deployment.py +0 -0
  40. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/deployment_wave.py +0 -0
  41. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/devops.py +0 -0
  42. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/enhanced_base_config.py +0 -0
  43. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/enhanced_ssm_config.py +0 -0
  44. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/management.py +0 -0
  45. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/pipeline.py +0 -0
  46. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/pipeline_stage.py +0 -0
  47. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/_resources.py +0 -0
  48. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/acm.py +0 -0
  49. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/api_gateway.py +0 -0
  50. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/apigateway_route_config.py +0 -0
  51. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/auto_scaling.py +0 -0
  52. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/cloudfront.py +0 -0
  53. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/cloudwatch_widget.py +0 -0
  54. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/code_artifact.py +0 -0
  55. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/code_artifact_login.py +0 -0
  56. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/code_repository.py +0 -0
  57. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/cognito.py +0 -0
  58. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/docker.py +0 -0
  59. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/dynamodb.py +0 -0
  60. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/ecr.py +0 -0
  61. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/ecs_service.py +0 -0
  62. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/exisiting.py +0 -0
  63. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/lambda_edge.py +0 -0
  64. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/lambda_function.py +0 -0
  65. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/lambda_layers.py +0 -0
  66. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/lambda_triggers.py +0 -0
  67. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/load_balancer.py +0 -0
  68. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/monitoring.py +0 -0
  69. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/rds.py +0 -0
  70. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/resource_mapping.py +0 -0
  71. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/resource_naming.py +0 -0
  72. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/resource_types.py +0 -0
  73. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/route53.py +0 -0
  74. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/route53_hosted_zone.py +0 -0
  75. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/rum.py +0 -0
  76. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/s3.py +0 -0
  77. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/security_group.py +0 -0
  78. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/security_group_full_stack.py +0 -0
  79. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/sqs.py +0 -0
  80. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/resources/vpc.py +0 -0
  81. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/stack.py +0 -0
  82. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/configurations/workload.py +0 -0
  83. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py +0 -0
  84. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/ecr/ecr_construct.py +0 -0
  85. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/lambdas/lambda_function_construct.py +0 -0
  86. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/lambdas/lambda_function_docker_construct.py +0 -0
  87. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/lambdas/lambda_function_role_construct.py +0 -0
  88. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/lambdas/policies/policy_docs.py +0 -0
  89. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/lambdas/policies/policy_statements.py +0 -0
  90. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/s3_buckets/s3_bucket_construct.py +0 -0
  91. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_destination_construct.py +0 -0
  92. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_source_construct.py +0 -0
  93. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/constructs/sqs/policies/sqs_policies.py +0 -0
  94. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +0 -0
  95. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/interfaces/istack.py +0 -0
  96. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/interfaces/live_ssm_resolver.py +0 -0
  97. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/interfaces/networked_stack_mixin.py +0 -0
  98. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/interfaces/ssm_parameter_mixin.py +0 -0
  99. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/lambdas/edge/ip_gate/handler.py +0 -0
  100. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/lambdas/health_handler.py +0 -0
  101. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/pipeline/path_utils.py +0 -0
  102. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/pipeline/pipeline_factory.py +0 -0
  103. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/pipeline/security/policies.py +0 -0
  104. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/pipeline/security/roles.py +0 -0
  105. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/pipeline/stage.py +0 -0
  106. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack/istack.py +0 -0
  107. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack/stack_factory.py +0 -0
  108. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack/stack_module_loader.py +0 -0
  109. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack/stack_module_registry.py +0 -0
  110. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack/stack_modules.py +0 -0
  111. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/__init__.py +0 -0
  112. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/acm/__init__.py +0 -0
  113. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/acm/acm_stack.py +0 -0
  114. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/api_gateway/api_gateway_stack.py +0 -0
  115. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/auto_scaling/__init__.py +0 -0
  116. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/aws_lambdas/lambda_stack.py +0 -0
  117. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/buckets/README.md +0 -0
  118. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/buckets/bucket_stack.py +0 -0
  119. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/cloudfront/__init__.py +0 -0
  120. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/cloudfront/cloudfront_stack.py +0 -0
  121. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/code_artifact/code_artifact_stack.py +0 -0
  122. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/cognito/cognito_stack.py +0 -0
  123. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/dynamodb/dynamodb_stack.py +0 -0
  124. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/ecr/README.md +0 -0
  125. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/ecr/ecr_stack.py +0 -0
  126. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/ecs/__init__.py +0 -0
  127. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/ecs/ecs_service_stack.py +0 -0
  128. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/lambda_edge/__init__.py +0 -0
  129. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +0 -0
  130. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/load_balancer/__init__.py +0 -0
  131. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/load_balancer/load_balancer_stack.py +0 -0
  132. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/monitoring/__init__.py +0 -0
  133. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/monitoring/monitoring_stack.py +0 -0
  134. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/rds/__init__.py +0 -0
  135. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/rds/rds_stack.py +0 -0
  136. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/route53/__init__.py +0 -0
  137. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/route53/route53_stack.py +0 -0
  138. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/rum/__init__.py +0 -0
  139. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/rum/rum_stack.py +0 -0
  140. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/security_group/__init__.py +0 -0
  141. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/security_group/security_group_full_stack.py +0 -0
  142. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/security_group/security_group_stack.py +0 -0
  143. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/simple_queue_service/sqs_stack.py +0 -0
  144. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/stack_base.py +0 -0
  145. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/vpc/__init__.py +0 -0
  146. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/vpc/vpc_stack.py +0 -0
  147. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stack_library/websites/static_website_stack.py +0 -0
  148. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/stages/websites/static_website_stage.py +0 -0
  149. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/templates/README.md +0 -0
  150. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/templates/app.py.template +0 -0
  151. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/templates/cdk.json.template +0 -0
  152. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/api_gateway_integration_utility.py +0 -0
  153. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/commandline_args.py +0 -0
  154. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/configuration_loader.py +0 -0
  155. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/docker_utilities.py +0 -0
  156. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/environment_services.py +0 -0
  157. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/file_operations.py +0 -0
  158. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/git_utilities.py +0 -0
  159. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/json_loading_utility.py +0 -0
  160. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/lambda_function_utilities.py +0 -0
  161. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utilities/os_execute.py +0 -0
  162. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/utils/api_gateway_utilities.py +0 -0
  163. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/cdk_factory/workload/workload_factory.py +0 -0
  164. {cdk_factory-0.16.8 → cdk_factory-0.16.10}/src/handlers/test/handler.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdk_factory
3
- Version: 0.16.8
3
+ Version: 0.16.10
4
4
  Summary: CDK Factory. A QuickStarter and best practices setup for CDK projects
5
5
  Author-email: Eric Wilson <eric.wilson@geekcafe.com>
6
6
  License: MIT License
@@ -33,7 +33,7 @@ markers = [
33
33
  [project]
34
34
 
35
35
  name = "cdk_factory"
36
- version = "0.16.8"
36
+ version = "0.16.10"
37
37
  authors = [
38
38
  { name="Eric Wilson", email="eric.wilson@geekcafe.com" }
39
39
  ]
@@ -71,15 +71,29 @@ class VPCProviderMixin:
71
71
  # This works with the enhanced SsmParameterMixin
72
72
  if hasattr(self, '_ssm_imported_values') and "vpc_id" in self._ssm_imported_values:
73
73
  vpc_id = self._ssm_imported_values["vpc_id"]
74
+
75
+ # Get subnet IDs first to determine AZ count
76
+ subnet_ids = []
77
+ if hasattr(self, '_ssm_imported_values') and "subnet_ids" in self._ssm_imported_values:
78
+ imported_subnets = self._ssm_imported_values["subnet_ids"]
79
+ if isinstance(imported_subnets, str):
80
+ subnet_ids = [s.strip() for s in imported_subnets.split(",") if s.strip()]
81
+ elif isinstance(imported_subnets, list):
82
+ subnet_ids = imported_subnets
83
+
84
+ # Adjust availability zones to match subnet count
85
+ if subnet_ids and availability_zones:
86
+ availability_zones = [f"us-east-1{chr(97+i)}" for i in range(len(subnet_ids))]
87
+
74
88
  return self._create_vpc_from_ssm(vpc_id, availability_zones)
75
89
 
76
90
  # Check config-level VPC ID
77
91
  if hasattr(config, 'vpc_id') and config.vpc_id:
78
- return ec2.Vpc.from_lookup(self, "VPC", vpc_id=config.vpc_id)
92
+ return ec2.Vpc.from_lookup(self, f"{self.stack_name}-VPC", vpc_id=config.vpc_id)
79
93
 
80
94
  # Check workload-level VPC ID
81
95
  if hasattr(workload, 'vpc_id') and workload.vpc_id:
82
- return ec2.Vpc.from_lookup(self, "VPC", vpc_id=workload.vpc_id)
96
+ return ec2.Vpc.from_lookup(self, f"{self.stack_name}-VPC", vpc_id=workload.vpc_id)
83
97
 
84
98
  # No VPC found - raise descriptive error
85
99
  raise self._create_vpc_not_found_error(config, workload)
@@ -105,15 +119,26 @@ class VPCProviderMixin:
105
119
  "availability_zones": availability_zones,
106
120
  }
107
121
 
108
- # If we have subnet_ids from SSM, provide dummy subnets
109
- # The actual subnets will be set via CloudFormation escape hatch
122
+ # If we have subnet_ids from SSM, use the actual subnet IDs
110
123
  if hasattr(self, '_ssm_imported_values') and "subnet_ids" in self._ssm_imported_values:
111
- # Provide dummy subnet IDs - these will be overridden by the escape hatch
112
- # We need at least one dummy subnet per AZ to satisfy CDK's validation
113
- vpc_attrs["public_subnet_ids"] = ["subnet-dummy1", "subnet-dummy2"]
124
+ imported_subnets = self._ssm_imported_values["subnet_ids"]
125
+ if isinstance(imported_subnets, str):
126
+ # Split comma-separated subnet IDs
127
+ subnet_ids = [s.strip() for s in imported_subnets.split(",") if s.strip()]
128
+ elif isinstance(imported_subnets, list):
129
+ subnet_ids = imported_subnets
130
+ else:
131
+ subnet_ids = []
132
+
133
+ # Use the actual subnet IDs from SSM
134
+ if subnet_ids:
135
+ vpc_attrs["public_subnet_ids"] = subnet_ids
136
+ else:
137
+ # Fallback to dummy subnets if no valid subnet IDs
138
+ vpc_attrs["public_subnet_ids"] = ["subnet-dummy1", "subnet-dummy2"]
114
139
 
115
- # Use from_vpc_attributes() for SSM tokens
116
- self._vpc = ec2.Vpc.from_vpc_attributes(self, "VPC", **vpc_attrs)
140
+ # Use from_vpc_attributes() for SSM tokens with unique construct name
141
+ self._vpc = ec2.Vpc.from_vpc_attributes(self, f"{self.stack_name}-VPC", **vpc_attrs)
117
142
  return self._vpc
118
143
 
119
144
  def _create_vpc_not_found_error(self, config: Any, workload: Any) -> ValueError:
@@ -21,6 +21,7 @@ from cdk_factory.configurations.deployment import DeploymentConfig
21
21
  from cdk_factory.configurations.stack import StackConfig
22
22
  from cdk_factory.configurations.resources.auto_scaling import AutoScalingConfig
23
23
  from cdk_factory.interfaces.istack import IStack
24
+ from cdk_factory.interfaces.vpc_provider_mixin import VPCProviderMixin
24
25
  from cdk_factory.stack.stack_module_registry import register_stack
25
26
  from cdk_factory.workload.workload_factory import WorkloadConfig
26
27
 
@@ -29,7 +30,7 @@ logger = Logger(service="AutoScalingStack")
29
30
 
30
31
  @register_stack("auto_scaling_library_module")
31
32
  @register_stack("auto_scaling_stack")
32
- class AutoScalingStack(IStack):
33
+ class AutoScalingStack(IStack, VPCProviderMixin):
33
34
  """
34
35
  Reusable stack for AWS Auto Scaling Groups.
35
36
  Supports creating EC2 Auto Scaling Groups with customizable configurations.
@@ -41,6 +42,9 @@ class AutoScalingStack(IStack):
41
42
  # Initialize parent class properly - IStack inherits from enhanced SsmParameterMixin
42
43
  super().__init__(scope, id, **kwargs)
43
44
 
45
+ # Initialize VPC cache from mixin
46
+ self._initialize_vpc_cache()
47
+
44
48
  self.asg_config = None
45
49
  self.stack_config = None
46
50
  self.deployment = None
@@ -50,10 +54,11 @@ class AutoScalingStack(IStack):
50
54
  self.launch_template = None
51
55
  self.instance_role = None
52
56
  self.user_data = None
57
+ self.user_data_commands = [] # Store raw commands for ECS cluster detection
53
58
  self.ecs_cluster = None
54
- self._vpc = None
55
59
 
56
60
  # SSM imports storage is now handled by the enhanced SsmParameterMixin via IStack
61
+ # VPC caching is now handled by VPCProviderMixin
57
62
 
58
63
  def build(
59
64
  self,
@@ -92,12 +97,13 @@ class AutoScalingStack(IStack):
92
97
  # Create user data
93
98
  self.user_data = self._create_user_data()
94
99
 
95
- # Create launch template
96
- self.launch_template = self._create_launch_template(asg_name)
97
-
98
100
  # Create ECS cluster if ECS configuration is detected
101
+ # This must happen before launch template creation so user data can be updated
99
102
  self._create_ecs_cluster_if_needed(asg_name)
100
103
 
104
+ # Create launch template
105
+ self.launch_template = self._create_launch_template(asg_name)
106
+
101
107
  # Create Auto Scaling Group
102
108
  self.auto_scaling_group = self._create_auto_scaling_group(asg_name)
103
109
 
@@ -112,57 +118,16 @@ class AutoScalingStack(IStack):
112
118
 
113
119
  @property
114
120
  def vpc(self) -> ec2.IVpc:
115
- """Get the VPC for the Auto Scaling Group using enhanced SsmParameterMixin"""
121
+ """Get the VPC for the Auto Scaling Group using VPCProviderMixin"""
116
122
  if not self.asg_config:
117
123
  raise AttributeError("AutoScalingStack not properly initialized. Call build() first.")
118
124
 
119
- # Return cached VPC if already created
120
- if self._vpc:
121
- return self._vpc
122
-
123
- # Check SSM imported values first using enhanced mixin
124
- if self.has_ssm_import("vpc_id"):
125
- vpc_id = self.get_ssm_imported_value("vpc_id")
126
-
127
- # Get subnet IDs first to determine AZ count
128
- subnet_ids = []
129
- if self.has_ssm_import("subnet_ids"):
130
- imported_subnets = self.get_ssm_imported_value("subnet_ids", [])
131
- if isinstance(imported_subnets, str):
132
- # Split comma-separated subnet IDs
133
- subnet_ids = [s.strip() for s in imported_subnets.split(",") if s.strip()]
134
- elif isinstance(imported_subnets, list):
135
- subnet_ids = imported_subnets
136
-
137
- # Build VPC attributes with matching AZ count
138
- vpc_attrs = {
139
- "vpc_id": vpc_id,
140
- "availability_zones": [f"us-east-1{chr(97+i)}" for i in range(len(subnet_ids))] if subnet_ids else ["us-east-1a", "us-east-1b"],
141
- }
142
-
143
- # Use the actual subnet IDs from SSM
144
- if subnet_ids:
145
- vpc_attrs["public_subnet_ids"] = subnet_ids
146
- else:
147
- # Fallback to dummy subnets if no valid subnet IDs
148
- vpc_attrs["public_subnet_ids"] = ["subnet-dummy1", "subnet-dummy2"]
149
-
150
- # Use from_vpc_attributes() for SSM tokens
151
- self._vpc = ec2.Vpc.from_vpc_attributes(self, f"{self.stack_name}-VPC", **vpc_attrs)
152
- return self._vpc
153
- elif self.asg_config.vpc_id:
154
- self._vpc = ec2.Vpc.from_lookup(self, f"{self.stack_name}-VPC", vpc_id=self.asg_config.vpc_id)
155
- return self._vpc
156
- elif self.workload.vpc_id:
157
- self._vpc = ec2.Vpc.from_lookup(self, f"{self.stack_name}-VPC", vpc_id=self.workload.vpc_id)
158
- return self._vpc
159
- else:
160
- # Use default VPC if not provided
161
- raise ValueError(
162
- "VPC is not defined in the configuration. "
163
- "You can provide it a the auto_scaling.vpc_id in the configuration "
164
- "or a top level workload.vpc_id in the workload configuration."
165
- )
125
+ # Use VPCProviderMixin to resolve VPC with proper subnet handling
126
+ return self.resolve_vpc(
127
+ config=self.asg_config,
128
+ deployment=self.deployment,
129
+ workload=self.workload
130
+ )
166
131
 
167
132
  def _get_target_group_arns(self) -> List[str]:
168
133
  """Get target group ARNs from SSM imports using enhanced SsmParameterMixin"""
@@ -277,12 +242,16 @@ class AutoScalingStack(IStack):
277
242
  """Create user data for EC2 instances"""
278
243
  user_data = ec2.UserData.for_linux()
279
244
 
245
+ # Store raw commands for ECS cluster detection
246
+ self.user_data_commands = ["set -euxo pipefail"]
247
+
280
248
  # Add base commands
281
249
  user_data.add_commands("set -euxo pipefail")
282
250
 
283
251
  # Add custom commands from config
284
252
  for command in self.asg_config.user_data_commands:
285
253
  user_data.add_commands(command)
254
+ self.user_data_commands.append(command)
286
255
 
287
256
  # Add user data scripts from files (with variable substitution)
288
257
  if self.asg_config.user_data_scripts:
@@ -622,8 +591,6 @@ class AutoScalingStack(IStack):
622
591
  """Create ECS cluster if ECS configuration is detected"""
623
592
  # Check if this is an ECS configuration by looking for ECS-related patterns
624
593
  is_ecs_config = (
625
- # Check if ECS cluster name is in user data
626
- (self.user_data and "ECS_CLUSTER=" in str(self.user_data)) or
627
594
  # Check if ECS managed policy is attached
628
595
  any("AmazonEC2ContainerServiceforEC2Role" in policy for policy in self.asg_config.managed_policies) or
629
596
  # Check for explicit ECS configuration
@@ -634,17 +601,9 @@ class AutoScalingStack(IStack):
634
601
  logger.debug("No ECS configuration detected, skipping cluster creation")
635
602
  return
636
603
 
637
- # Extract cluster name from user data or use default
604
+ # Generate cluster name from stack configuration
638
605
  cluster_name = f"{self.deployment.build_resource_name('cluster')}"
639
606
 
640
- # Try to extract cluster name from user data if available
641
- if self.user_data:
642
- user_data_str = str(self.user_data)
643
- for line in user_data_str.split('\n'):
644
- if 'ECS_CLUSTER=' in line:
645
- cluster_name = line.split('ECS_CLUSTER=')[1].strip()
646
- break
647
-
648
607
  logger.info(f"Creating ECS cluster: {cluster_name}")
649
608
 
650
609
  # Create ECS cluster
@@ -656,6 +615,10 @@ class AutoScalingStack(IStack):
656
615
  container_insights=True
657
616
  )
658
617
 
618
+ # Inject the cluster name into user data if user data exists
619
+ if self.user_data and self.user_data_commands:
620
+ self._inject_cluster_name_into_user_data(cluster_name)
621
+
659
622
  # Export cluster name
660
623
  cdk.CfnOutput(
661
624
  self,
@@ -672,6 +635,50 @@ class AutoScalingStack(IStack):
672
635
  export_name=f"{self.deployment.build_resource_name(cluster_name)}-arn",
673
636
  )
674
637
 
638
+ def _inject_cluster_name_into_user_data(self, cluster_name: str) -> None:
639
+ """Inject the ECS cluster name into user data commands"""
640
+ injected_commands = []
641
+ cluster_name_injected = False
642
+
643
+ for command in self.user_data_commands:
644
+ # If this command already sets ECS_CLUSTER, replace it
645
+ if 'ECS_CLUSTER=' in command:
646
+ # Replace existing ECS_CLUSTER setting with our cluster name
647
+ parts = command.split('ECS_CLUSTER=')
648
+ if len(parts) > 1:
649
+ # Keep everything before ECS_CLUSTER=, add our cluster name, then add the rest
650
+ before = parts[0]
651
+ after_parts = parts[1].split(None, 1) # Split on first whitespace
652
+ after = after_parts[1] if len(after_parts) > 1 else ''
653
+ new_command = f"{before}ECS_CLUSTER={cluster_name} {after}".strip()
654
+ injected_commands.append(new_command)
655
+ cluster_name_injected = True
656
+ else:
657
+ injected_commands.append(f"{command}ECS_CLUSTER={cluster_name}")
658
+ cluster_name_injected = True
659
+ else:
660
+ injected_commands.append(command)
661
+
662
+ # If no ECS_CLUSTER was found in existing commands, add it
663
+ if not cluster_name_injected:
664
+ injected_commands.append(f"echo ECS_CLUSTER={cluster_name} >> /etc/ecs/ecs.config")
665
+
666
+ # Update the user data with the injected commands
667
+ self.user_data_commands = injected_commands
668
+
669
+ # If user data object exists, we need to recreate it with the updated commands
670
+ if hasattr(self, 'user_data') and self.user_data:
671
+ self.user_data = self._recreate_user_data_with_commands(injected_commands)
672
+
673
+ def _recreate_user_data_with_commands(self, commands: List[str]) -> ec2.UserData:
674
+ """Recreate user data with updated commands"""
675
+ user_data = ec2.UserData.for_linux()
676
+
677
+ for command in commands:
678
+ user_data.add_commands(command)
679
+
680
+ return user_data
681
+
675
682
  def _export_resources(self, asg_name: str) -> None:
676
683
  """Export stack resources to SSM and CloudFormation outputs"""
677
684
  # Export ASG name
@@ -0,0 +1 @@
1
+ __version__ = "0.16.10"
@@ -1 +0,0 @@
1
- __version__ = "0.16.8"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes