cdk-factory 0.9.11__tar.gz → 0.10.0__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 (158) hide show
  1. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/PKG-INFO +1 -1
  2. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/pyproject.toml +1 -1
  3. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/run-tests.sh +10 -6
  4. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/app.py +39 -8
  5. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/auto_scaling.py +27 -0
  6. cdk_factory-0.10.0/src/cdk_factory/configurations/resources/cloudfront.py +124 -0
  7. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/ecs_service.py +12 -0
  8. cdk_factory-0.10.0/src/cdk_factory/configurations/resources/lambda_edge.py +92 -0
  9. cdk_factory-0.10.0/src/cdk_factory/configurations/resources/monitoring.py +74 -0
  10. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py +51 -1
  11. cdk_factory-0.10.0/src/cdk_factory/lambdas/edge/ip_gate/handler.py +104 -0
  12. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/pipeline/pipeline_factory.py +1 -0
  13. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +99 -0
  14. cdk_factory-0.10.0/src/cdk_factory/stack_library/cloudfront/__init__.py +6 -0
  15. cdk_factory-0.10.0/src/cdk_factory/stack_library/cloudfront/cloudfront_stack.py +627 -0
  16. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/ecs/ecs_service_stack.py +90 -0
  17. cdk_factory-0.10.0/src/cdk_factory/stack_library/lambda_edge/__init__.py +6 -0
  18. cdk_factory-0.10.0/src/cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +217 -0
  19. cdk_factory-0.10.0/src/cdk_factory/stack_library/monitoring/__init__.py +6 -0
  20. cdk_factory-0.10.0/src/cdk_factory/stack_library/monitoring/monitoring_stack.py +492 -0
  21. cdk_factory-0.10.0/src/cdk_factory/version.py +1 -0
  22. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/workload/workload_factory.py +2 -0
  23. cdk_factory-0.9.11/src/cdk_factory/configurations/resources/cloudfront.py +0 -34
  24. cdk_factory-0.9.11/src/cdk_factory/version.py +0 -1
  25. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/.gitignore +0 -0
  26. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/.windsurfrules +0 -0
  27. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/LICENSE +0 -0
  28. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/README.md +0 -0
  29. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/archive/README.md +0 -0
  30. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/archive/migrate_to_enhanced_ssm.py +0 -0
  31. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/examples/json-imports/README.md +0 -0
  32. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/examples/separate-api-gateway/README.md +0 -0
  33. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/examples/separate-api-gateway/api-gateway-stack.json +0 -0
  34. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/examples/separate-api-gateway/config.json +0 -0
  35. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/examples/separate-api-gateway/lambda-stack.json +0 -0
  36. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/mypy.ini +0 -0
  37. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/publish_to_pypi.py +0 -0
  38. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/publish_to_pypi.sh +0 -0
  39. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/pysetup.py +0 -0
  40. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/pysetup.sh +0 -0
  41. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/requirements.dev.txt +0 -0
  42. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/requirements.tests.txt +0 -0
  43. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/requirements.txt +0 -0
  44. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/run-checks.sh +0 -0
  45. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/run-tests-clean-venv.sh +0 -0
  46. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/__init__.py +0 -0
  47. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/builds/README.md +0 -0
  48. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/cdk.json +0 -0
  49. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/cli.py +0 -0
  50. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/commands/command_loader.py +0 -0
  51. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/base_config.py +0 -0
  52. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/cdk_config.py +0 -0
  53. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/deployment.py +0 -0
  54. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/deployment_wave.py +0 -0
  55. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/devops.py +0 -0
  56. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/enhanced_base_config.py +0 -0
  57. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/enhanced_ssm_config.py +0 -0
  58. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/management.py +0 -0
  59. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/pipeline.py +0 -0
  60. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/pipeline_stage.py +0 -0
  61. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/_resources.py +0 -0
  62. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/api_gateway.py +0 -0
  63. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/apigateway_route_config.py +0 -0
  64. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/cloudwatch_widget.py +0 -0
  65. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/code_artifact.py +0 -0
  66. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/code_artifact_login.py +0 -0
  67. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/code_repository.py +0 -0
  68. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/cognito.py +0 -0
  69. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/docker.py +0 -0
  70. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/dynamodb.py +0 -0
  71. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/ecr.py +0 -0
  72. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/exisiting.py +0 -0
  73. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/lambda_function.py +0 -0
  74. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/lambda_layers.py +0 -0
  75. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/lambda_triggers.py +0 -0
  76. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/load_balancer.py +0 -0
  77. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/rds.py +0 -0
  78. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/resource_mapping.py +0 -0
  79. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/resource_naming.py +0 -0
  80. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/resource_types.py +0 -0
  81. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/route53.py +0 -0
  82. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/route53_hosted_zone.py +0 -0
  83. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/rum.py +0 -0
  84. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/s3.py +0 -0
  85. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/security_group.py +0 -0
  86. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/security_group_full_stack.py +0 -0
  87. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/sqs.py +0 -0
  88. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/resources/vpc.py +0 -0
  89. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/stack.py +0 -0
  90. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/configurations/workload.py +0 -0
  91. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/ecr/ecr_construct.py +0 -0
  92. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/lambdas/lambda_function_construct.py +0 -0
  93. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/lambdas/lambda_function_docker_construct.py +0 -0
  94. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/lambdas/lambda_function_role_construct.py +0 -0
  95. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/lambdas/policies/policy_docs.py +0 -0
  96. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/lambdas/policies/policy_statements.py +0 -0
  97. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/s3_buckets/s3_bucket_construct.py +0 -0
  98. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_destination_construct.py +0 -0
  99. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_source_construct.py +0 -0
  100. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/constructs/sqs/policies/sqs_policies.py +0 -0
  101. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +0 -0
  102. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/interfaces/istack.py +0 -0
  103. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/interfaces/live_ssm_resolver.py +0 -0
  104. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/interfaces/ssm_parameter_mixin.py +0 -0
  105. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/lambdas/health_handler.py +0 -0
  106. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/pipeline/path_utils.py +0 -0
  107. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/pipeline/security/policies.py +0 -0
  108. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/pipeline/security/roles.py +0 -0
  109. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/pipeline/stage.py +0 -0
  110. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack/istack.py +0 -0
  111. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack/stack_factory.py +0 -0
  112. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack/stack_module_loader.py +0 -0
  113. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack/stack_module_registry.py +0 -0
  114. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack/stack_modules.py +0 -0
  115. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/__init__.py +0 -0
  116. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/api_gateway/api_gateway_stack.py +0 -0
  117. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/auto_scaling/__init__.py +0 -0
  118. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/aws_lambdas/lambda_stack.py +0 -0
  119. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/buckets/README.md +0 -0
  120. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/buckets/bucket_stack.py +0 -0
  121. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/code_artifact/code_artifact_stack.py +0 -0
  122. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/cognito/cognito_stack.py +0 -0
  123. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/dynamodb/dynamodb_stack.py +0 -0
  124. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/ecr/README.md +0 -0
  125. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/ecr/ecr_stack.py +0 -0
  126. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/ecs/__init__.py +0 -0
  127. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/load_balancer/__init__.py +0 -0
  128. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/load_balancer/load_balancer_stack.py +0 -0
  129. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/rds/__init__.py +0 -0
  130. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/rds/rds_stack.py +0 -0
  131. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/route53/__init__.py +0 -0
  132. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/route53/route53_stack.py +0 -0
  133. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/rum/__init__.py +0 -0
  134. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/rum/rum_stack.py +0 -0
  135. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/security_group/__init__.py +0 -0
  136. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/security_group/security_group_full_stack.py +0 -0
  137. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/security_group/security_group_stack.py +0 -0
  138. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/simple_queue_service/sqs_stack.py +0 -0
  139. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/stack_base.py +0 -0
  140. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/vpc/__init__.py +0 -0
  141. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/vpc/vpc_stack.py +0 -0
  142. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stack_library/websites/static_website_stack.py +0 -0
  143. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/stages/websites/static_website_stage.py +0 -0
  144. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/templates/README.md +0 -0
  145. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/templates/app.py.template +0 -0
  146. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/templates/cdk.json.template +0 -0
  147. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/api_gateway_integration_utility.py +0 -0
  148. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/commandline_args.py +0 -0
  149. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/configuration_loader.py +0 -0
  150. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/docker_utilities.py +0 -0
  151. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/environment_services.py +0 -0
  152. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/file_operations.py +0 -0
  153. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/git_utilities.py +0 -0
  154. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/json_loading_utility.py +0 -0
  155. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/lambda_function_utilities.py +0 -0
  156. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utilities/os_execute.py +0 -0
  157. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/src/cdk_factory/utils/api_gateway_utilities.py +0 -0
  158. {cdk_factory-0.9.11 → cdk_factory-0.10.0}/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.9.11
3
+ Version: 0.10.0
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.9.11"
36
+ version = "0.10.0"
37
37
  authors = [
38
38
  { name="Eric Wilson", email="eric.wilson@geekcafe.com" }
39
39
  ]
@@ -24,15 +24,19 @@ echo "=================================="
24
24
  if [ ! -d ".venv" ]; then
25
25
  echo -e "${YELLOW}Creating virtual environment...${NC}"
26
26
  python3 -m venv .venv
27
+ # Install dependencies
28
+ echo -e "${YELLOW}Installing dependencies...${NC}"
29
+ pip install -q -r requirements.dev.txt
30
+ pip install -q -r requirements.tests.txt
31
+ fi
32
+
33
+ # see if it's activated
34
+ if [ ! -f ".venv/bin/activate" ]; then
35
+ echo -e "${YELLOW}Activating virtual environment...${NC}"
36
+ source ./.venv/bin/activate
27
37
  fi
28
38
 
29
- echo -e "${YELLOW}Activating virtual environment...${NC}"
30
- source ./.venv/bin/activate
31
39
 
32
- # Install dependencies
33
- echo -e "${YELLOW}Installing dependencies...${NC}"
34
- pip install -q -r requirements.dev.txt
35
- pip install -q -r requirements.tests.txt
36
40
 
37
41
  # Check if pytest is installed in the virtual environment
38
42
  if ! command -v pytest &> /dev/null; then
@@ -32,15 +32,12 @@ class CdkAppFactory:
32
32
  config_path: str | None = None,
33
33
  outdir: str | None = None,
34
34
  add_env_context: bool = True,
35
- auto_detect_project_root: bool = True,
36
- is_pipeline: bool = False,
37
35
  ) -> None:
38
36
 
39
37
  self.args = args or CommandlineArgs()
40
38
  self.runtime_directory = runtime_directory
41
39
  self.config_path: str | None = config_path
42
40
  self.add_env_context = add_env_context
43
- self._is_pipeline = is_pipeline
44
41
 
45
42
  # Auto-detect runtime_directory if not provided
46
43
  if not self.runtime_directory:
@@ -50,21 +47,26 @@ class CdkAppFactory:
50
47
  # 1. Explicit outdir parameter (highest priority)
51
48
  # 2. CDK_OUTDIR environment variable
52
49
  # 3. Default: {runtime_directory}/cdk.out
53
-
50
+
54
51
  supplied_outdir = outdir or (
55
52
  self.args.outdir if hasattr(self.args, "outdir") else None
56
53
  )
57
-
54
+
58
55
  if supplied_outdir:
59
- # Explicit outdir: convert to absolute path
60
- self.outdir = os.path.abspath(supplied_outdir)
56
+ # Explicit outdir: if relative, resolve against runtime_directory
57
+ # If absolute, use as-is
58
+ if os.path.isabs(supplied_outdir):
59
+ self.outdir = supplied_outdir
60
+ else:
61
+ # Relative path: resolve against runtime_directory, not cwd
62
+ self.outdir = os.path.join(self.runtime_directory, supplied_outdir)
61
63
  elif os.getenv("CDK_OUTDIR"):
62
64
  # Environment variable override
63
65
  self.outdir = os.path.abspath(os.getenv("CDK_OUTDIR"))
64
66
  else:
65
67
  # Default: cdk.out in runtime_directory
66
68
  # This resolves correctly in both local and CodeBuild environments
67
- self.outdir = str(Path(self.runtime_directory).resolve() / "cdk.out")
69
+ self.outdir = os.path.join(self.runtime_directory, "cdk.out")
68
70
 
69
71
  # Clean and recreate directory for fresh synthesis
70
72
  if os.path.exists(self.outdir):
@@ -126,6 +128,8 @@ class CdkAppFactory:
126
128
  # Validate that the assembly directory exists and has files
127
129
  self._validate_synth_output(assembly)
128
130
 
131
+ self._copy_cdk_out_to_project_root()
132
+
129
133
  return assembly
130
134
 
131
135
  def _validate_synth_output(self, assembly: CloudAssembly) -> None:
@@ -244,6 +248,33 @@ class CdkAppFactory:
244
248
  # Priority 4: Fallback to runtime_directory
245
249
  return str(current)
246
250
 
251
+ def _copy_cdk_out_to_project_root(self):
252
+ # Copy the cdk.out directory to the project root so it can be picked up by CodeBuild
253
+ # Source: the actual CDK output directory from the synthesis (e.g., /tmp/cdk-factory/cdk.out)
254
+ cdk_out_source = self.outdir
255
+
256
+ # raise Exception(f"cdk_out_source: {cdk_out_source}")
257
+
258
+ # Destination: project root (two directories up from devops/cdk-iac where this file lives)
259
+ project_root = os.getenv("CODEBUILD_SRC_DIR")
260
+ if not project_root:
261
+ return
262
+
263
+ cdk_out_dest = os.path.join(project_root, "cdk.out")
264
+
265
+ print(f"👉 Project root: {project_root}")
266
+ print(f"👉 CDK output source: {cdk_out_source}")
267
+ print(f"👉 CDK output destination: {cdk_out_dest}")
268
+
269
+ if os.path.exists(cdk_out_dest):
270
+ print("❌ CDK output directory already exists, skipping copy")
271
+ return
272
+ else:
273
+ print("✅ CDK output directory does not exist, copying")
274
+
275
+ shutil.copytree(cdk_out_source, cdk_out_dest)
276
+ print(f"✅ Copied CDK output to {cdk_out_dest}")
277
+
247
278
 
248
279
  if __name__ == "__main__":
249
280
  # deploy_test()
@@ -148,3 +148,30 @@ class AutoScalingConfig(EnhancedBaseConfig):
148
148
  def target_group_arns(self) -> List[str]:
149
149
  """Target group ARNs for the Auto Scaling Group"""
150
150
  return self.__config.get("target_group_arns", [])
151
+
152
+ @property
153
+ def user_data_scripts(self) -> List[Dict[str, Any]]:
154
+ """
155
+ User data scripts to inject from files.
156
+ Each script should have:
157
+ - type: 'file' or 'inline'
158
+ - path: path to script file (if type is 'file')
159
+ - content: script content (if type is 'inline')
160
+ - variables: dict of variables for substitution
161
+ """
162
+ return self.__config.get("user_data_scripts", [])
163
+
164
+ @property
165
+ def iam_inline_policies(self) -> List[Dict[str, Any]]:
166
+ """
167
+ IAM inline policies to attach to the instance role.
168
+ Each policy should have:
169
+ - name: policy name
170
+ - statements: list of IAM policy statements
171
+ """
172
+ return self.__config.get("iam_inline_policies", [])
173
+
174
+ @property
175
+ def key_name(self) -> Optional[str]:
176
+ """EC2 key pair name for SSH access"""
177
+ return self.__config.get("key_name")
@@ -0,0 +1,124 @@
1
+ """
2
+ Geek Cafe, LLC
3
+ Maintainers: Eric Wilson
4
+ MIT License. See Project Root for the license information.
5
+ """
6
+ from typing import Dict, List, Any, Optional
7
+ from cdk_factory.configurations.enhanced_base_config import EnhancedBaseConfig
8
+
9
+
10
+ class CloudFrontConfig(EnhancedBaseConfig):
11
+ """
12
+ CloudFront Distribution Configuration
13
+ Supports both S3 origins (static sites) and custom origins (ALB, API Gateway, etc.)
14
+ """
15
+
16
+ def __init__(self, config: dict = None, deployment=None) -> None:
17
+ super().__init__(
18
+ config or {},
19
+ resource_type="cloudfront",
20
+ resource_name=config.get("name", "cloudfront") if config else "cloudfront"
21
+ )
22
+ self._config = config or {}
23
+ self._deployment = deployment
24
+
25
+ @property
26
+ def name(self) -> str:
27
+ """Distribution name"""
28
+ return self._config.get("name", "cloudfront")
29
+
30
+ @property
31
+ def description(self) -> str:
32
+ """Distribution description"""
33
+ return self._config.get("description", "CloudFront Distribution")
34
+
35
+ @property
36
+ def comment(self) -> str:
37
+ """Distribution comment"""
38
+ return self._config.get("comment", "")
39
+
40
+ @property
41
+ def enabled(self) -> bool:
42
+ """Whether distribution is enabled"""
43
+ return self._config.get("enabled", True)
44
+
45
+ @property
46
+ def aliases(self) -> List[str]:
47
+ """Alternate domain names (CNAMEs)"""
48
+ return self._config.get("aliases", [])
49
+
50
+ @property
51
+ def price_class(self) -> str:
52
+ """Price class for edge locations"""
53
+ return self._config.get("price_class", "PriceClass_100")
54
+
55
+ @property
56
+ def http_version(self) -> str:
57
+ """HTTP version (http2, http2_and_3)"""
58
+ return self._config.get("http_version", "http2_and_3")
59
+
60
+ @property
61
+ def certificate(self) -> Optional[Dict[str, Any]]:
62
+ """ACM certificate configuration"""
63
+ return self._config.get("certificate")
64
+
65
+ @property
66
+ def origins(self) -> List[Dict[str, Any]]:
67
+ """Origin configurations"""
68
+ return self._config.get("origins", [])
69
+
70
+ @property
71
+ def default_cache_behavior(self) -> Dict[str, Any]:
72
+ """Default cache behavior"""
73
+ return self._config.get("default_cache_behavior", {})
74
+
75
+ @property
76
+ def cache_behaviors(self) -> List[Dict[str, Any]]:
77
+ """Additional cache behaviors"""
78
+ return self._config.get("cache_behaviors", [])
79
+
80
+ @property
81
+ def custom_error_responses(self) -> List[Dict[str, Any]]:
82
+ """Custom error responses"""
83
+ return self._config.get("custom_error_responses", [])
84
+
85
+ @property
86
+ def logging(self) -> Optional[Dict[str, Any]]:
87
+ """Logging configuration"""
88
+ return self._config.get("logging")
89
+
90
+ @property
91
+ def waf_web_acl_id(self) -> Optional[str]:
92
+ """WAF Web ACL ID"""
93
+ return self._config.get("waf_web_acl_id")
94
+
95
+ @property
96
+ def default_root_object(self) -> str:
97
+ """Default root object"""
98
+ return self._config.get("default_root_object", "index.html")
99
+
100
+ @property
101
+ def tags(self) -> Dict[str, str]:
102
+ """Resource tags"""
103
+ return self._config.get("tags", {})
104
+
105
+ @property
106
+ def ssm_exports(self) -> Dict[str, str]:
107
+ """SSM parameter exports"""
108
+ return self._config.get("ssm_exports", {})
109
+
110
+ @property
111
+ def ssm_imports(self) -> Dict[str, str]:
112
+ """SSM parameter imports"""
113
+ return self._config.get("ssm_imports", {})
114
+
115
+ @property
116
+ def hosted_zone_id(self) -> str:
117
+ """
118
+ Returns the hosted_zone_id for cloudfront
119
+ Use this when making dns changes when you want your custom domain
120
+ to be route through cloudfront.
121
+
122
+ As far as I know this Id is static and used for all of cloudfront
123
+ """
124
+ return self._config.get("hosted_zone_id", "Z2FDTNDATAQYW2")
@@ -142,3 +142,15 @@ class EcsServiceConfig:
142
142
  def is_maintenance_mode(self) -> bool:
143
143
  """Whether this is a maintenance mode deployment"""
144
144
  return self.deployment_type == "maintenance"
145
+
146
+ @property
147
+ def volumes(self) -> List[Dict[str, Any]]:
148
+ """
149
+ Volume definitions for the task.
150
+ Supports host volumes for EC2 launch type and EFS volumes.
151
+ Each volume should have:
152
+ - name: volume name
153
+ - host: {source_path: "/path/on/host"} for bind mounts
154
+ - efs: {...} for EFS volumes
155
+ """
156
+ return self.task_definition.get("volumes", [])
@@ -0,0 +1,92 @@
1
+ """
2
+ Lambda@Edge Configuration for CDK-Factory
3
+ Geek Cafe, LLC
4
+ Maintainers: Eric Wilson
5
+ MIT License. See Project Root for the license information.
6
+ """
7
+ from typing import Dict, Optional
8
+ from cdk_factory.configurations.enhanced_base_config import EnhancedBaseConfig
9
+
10
+
11
+ class LambdaEdgeConfig(EnhancedBaseConfig):
12
+ """
13
+ Configuration class for Lambda@Edge functions.
14
+ Lambda@Edge has specific constraints:
15
+ - Must be deployed in us-east-1
16
+ - Max timeout: 5 seconds for origin-request/response, 30s for viewer-request/response
17
+ - Max memory: 10GB (but typically use 128-512MB for edge functions)
18
+ - Must use versioned functions (not $LATEST)
19
+ """
20
+
21
+ def __init__(self, config: dict = None, deployment=None) -> None:
22
+ super().__init__(
23
+ config or {},
24
+ resource_type="lambda_edge",
25
+ resource_name=config.get("name", "lambda-edge") if config else "lambda-edge"
26
+ )
27
+ self._config = config or {}
28
+ self._deployment = deployment
29
+
30
+ @property
31
+ def name(self) -> str:
32
+ """Function name"""
33
+ return self._config.get("name", "lambda-edge")
34
+
35
+ @property
36
+ def handler(self) -> str:
37
+ """Handler function (e.g., 'handler.lambda_handler')"""
38
+ return self._config.get("handler", "handler.lambda_handler")
39
+
40
+ @property
41
+ def runtime(self) -> str:
42
+ """Lambda runtime (e.g., 'python3.11')"""
43
+ return self._config.get("runtime", "python3.11")
44
+
45
+ @property
46
+ def memory_size(self) -> int:
47
+ """Memory size in MB (128-10240)"""
48
+ return int(self._config.get("memory_size", 128))
49
+
50
+ @property
51
+ def timeout(self) -> int:
52
+ """Timeout in seconds (max 5 for origin-request)"""
53
+ timeout = int(self._config.get("timeout", 5))
54
+ if timeout > 5:
55
+ raise ValueError("Lambda@Edge origin-request timeout cannot exceed 5 seconds")
56
+ return timeout
57
+
58
+ @property
59
+ def code_path(self) -> str:
60
+ """Path to Lambda function code directory"""
61
+ return self._config.get("code_path", "./lambdas/edge/ip_gate")
62
+
63
+ @property
64
+ def environment(self) -> Dict[str, str]:
65
+ """Environment variables for the Lambda function"""
66
+ return self._config.get("environment", {})
67
+
68
+ @property
69
+ def description(self) -> str:
70
+ """Function description"""
71
+ return self._config.get("description", "Lambda@Edge function")
72
+
73
+ @property
74
+ def event_type(self) -> str:
75
+ """
76
+ Lambda@Edge event type:
77
+ - viewer-request: Executes when CloudFront receives a request from viewer
78
+ - origin-request: Executes before CloudFront forwards request to origin
79
+ - origin-response: Executes after CloudFront receives response from origin
80
+ - viewer-response: Executes before CloudFront returns response to viewer
81
+ """
82
+ return self._config.get("event_type", "origin-request")
83
+
84
+ @property
85
+ def publish_version(self) -> bool:
86
+ """Whether to publish a new version (required for Lambda@Edge)"""
87
+ return self._config.get("publish_version", True)
88
+
89
+ @property
90
+ def include_body(self) -> bool:
91
+ """Whether to include request body in origin-request events"""
92
+ return self._config.get("include_body", False)
@@ -0,0 +1,74 @@
1
+ """
2
+ Monitoring Configuration
3
+ Geek Cafe, LLC
4
+ Maintainers: Eric Wilson
5
+ MIT License. See Project Root for the license information.
6
+ """
7
+
8
+ from typing import Dict, List, Any, Optional
9
+ from cdk_factory.configurations.enhanced_base_config import EnhancedBaseConfig
10
+
11
+
12
+ class MonitoringConfig(EnhancedBaseConfig):
13
+ """
14
+ Monitoring Configuration for CloudWatch Alarms and Dashboards
15
+ """
16
+
17
+ def __init__(self, config: dict = None, deployment=None) -> None:
18
+ super().__init__(
19
+ config or {},
20
+ resource_type="monitoring",
21
+ resource_name=config.get("name", "monitoring") if config else "monitoring"
22
+ )
23
+ self._config = config or {}
24
+ self._deployment = deployment
25
+
26
+ @property
27
+ def name(self) -> str:
28
+ """Monitoring stack name"""
29
+ return self._config.get("name", "monitoring")
30
+
31
+ @property
32
+ def sns_topics(self) -> List[Dict[str, Any]]:
33
+ """SNS topics for alarm notifications"""
34
+ return self._config.get("sns_topics", [])
35
+
36
+ @property
37
+ def alarms(self) -> List[Dict[str, Any]]:
38
+ """CloudWatch alarms configuration"""
39
+ return self._config.get("alarms", [])
40
+
41
+ @property
42
+ def dashboards(self) -> List[Dict[str, Any]]:
43
+ """CloudWatch dashboards configuration"""
44
+ return self._config.get("dashboards", [])
45
+
46
+ @property
47
+ def composite_alarms(self) -> List[Dict[str, Any]]:
48
+ """Composite alarms (combine multiple alarms)"""
49
+ return self._config.get("composite_alarms", [])
50
+
51
+ @property
52
+ def log_metric_filters(self) -> List[Dict[str, Any]]:
53
+ """CloudWatch Logs metric filters"""
54
+ return self._config.get("log_metric_filters", [])
55
+
56
+ @property
57
+ def enable_anomaly_detection(self) -> bool:
58
+ """Enable CloudWatch anomaly detection"""
59
+ return self._config.get("enable_anomaly_detection", False)
60
+
61
+ @property
62
+ def tags(self) -> Dict[str, str]:
63
+ """Resource tags"""
64
+ return self._config.get("tags", {})
65
+
66
+ @property
67
+ def ssm_exports(self) -> Dict[str, str]:
68
+ """SSM parameter exports"""
69
+ return self._config.get("ssm_exports", {})
70
+
71
+ @property
72
+ def ssm_imports(self) -> Dict[str, str]:
73
+ """SSM parameter imports for resource ARNs"""
74
+ return self._config.get("ssm_imports", {})
@@ -1,10 +1,11 @@
1
- from typing import Any, List, Mapping
1
+ from typing import Any, List, Mapping, Optional
2
2
 
3
3
  from aws_cdk import Duration
4
4
  from aws_cdk import aws_certificatemanager as acm
5
5
  from aws_cdk import aws_cloudfront as cloudfront
6
6
  from aws_cdk import aws_cloudfront_origins as origins
7
7
  from aws_cdk import aws_iam as iam
8
+ from aws_cdk import aws_lambda as _lambda
8
9
  from aws_cdk import aws_s3 as s3
9
10
  from constructs import Construct
10
11
  from cdk_factory.configurations.stack import StackConfig
@@ -123,6 +124,7 @@ class CloudFrontDistributionConstruct(Construct):
123
124
  origin=origin,
124
125
  viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
125
126
  function_associations=self.__get_function_associations(),
127
+ edge_lambdas=self.__get_lambda_edge_associations(),
126
128
  ),
127
129
  default_root_object="index.html",
128
130
  error_responses=self._error_responses(),
@@ -218,6 +220,54 @@ class CloudFrontDistributionConstruct(Construct):
218
220
 
219
221
  return function_associations
220
222
 
223
+ def __get_lambda_edge_associations(self) -> Optional[List[cloudfront.EdgeLambda]]:
224
+ """
225
+ Get the Lambda@Edge associations for the distribution from config.
226
+
227
+ Returns:
228
+ List[cloudfront.EdgeLambda] or None: list of Lambda@Edge associations
229
+ """
230
+ edge_lambdas = []
231
+
232
+ if self.stack_config and isinstance(self.stack_config, StackConfig):
233
+ cloudfront_config = self.stack_config.dictionary.get("cloudfront", {})
234
+ lambda_edge_associations = cloudfront_config.get("lambda_edge_associations", [])
235
+
236
+ for association in lambda_edge_associations:
237
+ event_type_str = association.get("event_type", "origin-request")
238
+ lambda_arn = association.get("lambda_arn")
239
+ include_body = association.get("include_body", False)
240
+
241
+ if not lambda_arn:
242
+ continue # Skip if no ARN provided
243
+
244
+ # Map event type string to CloudFront enum
245
+ event_type_map = {
246
+ "viewer-request": cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
247
+ "origin-request": cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
248
+ "origin-response": cloudfront.LambdaEdgeEventType.ORIGIN_RESPONSE,
249
+ "viewer-response": cloudfront.LambdaEdgeEventType.VIEWER_RESPONSE,
250
+ }
251
+
252
+ event_type = event_type_map.get(event_type_str, cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST)
253
+
254
+ # Import the Lambda function version by ARN
255
+ lambda_version = _lambda.Version.from_version_arn(
256
+ self,
257
+ f"LambdaEdge-{event_type_str}",
258
+ version_arn=lambda_arn
259
+ )
260
+
261
+ edge_lambdas.append(
262
+ cloudfront.EdgeLambda(
263
+ function_version=lambda_version,
264
+ event_type=event_type,
265
+ include_body=include_body
266
+ )
267
+ )
268
+
269
+ return edge_lambdas if edge_lambdas else None
270
+
221
271
  def __get_combined_function(self, hosts: List[str]) -> cloudfront.Function:
222
272
  """
223
273
  Creates a combined CloudFront function that does both URL rewriting and host restrictions.
@@ -0,0 +1,104 @@
1
+ """
2
+ Lambda@Edge Origin-Request Handler for IP-based Access Gating
3
+ Geek Cafe, LLC
4
+ Maintainers: Eric Wilson
5
+ """
6
+
7
+ import ipaddress
8
+ import json
9
+ import os
10
+
11
+
12
+ def lambda_handler(event, context):
13
+ """
14
+ Lambda@Edge origin-request handler that implements IP-based gating
15
+ with maintenance site fallback.
16
+
17
+ Features:
18
+ - Inject X-Viewer-IP header for origin visibility
19
+ - Check viewer IP against allowlist when gate is enabled
20
+ - Rewrite blocked IPs to maintenance CloudFront distribution, and serve up maintenance site
21
+ - Toggle via GATE_ENABLED environment variable
22
+ """
23
+
24
+ # Extract request from CloudFront event
25
+ request = event['Records'][0]['cf']['request']
26
+ client_ip = request['clientIp']
27
+
28
+ # Configuration from environment variables
29
+ gate_enabled = os.environ.get('GATE_ENABLED', 'false').lower() == 'true'
30
+ allow_cidrs_str = os.environ.get('ALLOW_CIDRS', '')
31
+ maint_cf_host = os.environ.get('MAINT_CF_HOST', '')
32
+
33
+ # Parse allowed CIDRs
34
+ allow_cidrs = [cidr.strip() for cidr in allow_cidrs_str.split(',') if cidr.strip()]
35
+
36
+ # Always inject viewer IP header
37
+ if 'headers' not in request:
38
+ request['headers'] = {}
39
+
40
+ request['headers']['x-viewer-ip'] = [{
41
+ 'key': 'X-Viewer-IP',
42
+ 'value': client_ip
43
+ }]
44
+
45
+ # If gate is disabled, pass through to origin
46
+ if not gate_enabled:
47
+ return request
48
+
49
+ # Check if IP is in allowlist
50
+ ip_allowed = False
51
+ try:
52
+ client_ip_obj = ipaddress.ip_address(client_ip)
53
+ for cidr in allow_cidrs:
54
+ try:
55
+ network = ipaddress.ip_network(cidr, strict=False)
56
+ if client_ip_obj in network:
57
+ ip_allowed = True
58
+ break
59
+ except (ValueError, ipaddress.AddressValueError):
60
+ # Invalid CIDR, skip
61
+ continue
62
+ except (ValueError, ipaddress.AddressValueError):
63
+ # Invalid client IP, block by default
64
+ ip_allowed = False
65
+
66
+ # If IP is allowed, pass through to origin
67
+ if ip_allowed:
68
+ return request
69
+
70
+ # IP not allowed - redirect to maintenance site
71
+ if not maint_cf_host:
72
+ # Safety: if maintenance host not configured, pass through with warning
73
+ # In production, you might want to return a fixed error response instead
74
+ return request
75
+
76
+ # Rewrite origin to maintenance CloudFront distribution
77
+ request['origin'] = {
78
+ 'custom': {
79
+ 'domainName': maint_cf_host,
80
+ 'port': 443,
81
+ 'protocol': 'https',
82
+ 'path': '',
83
+ 'sslProtocols': ['TLSv1.2'],
84
+ 'readTimeout': 30,
85
+ 'keepaliveTimeout': 5,
86
+ 'customHeaders': {}
87
+ }
88
+ }
89
+
90
+ # Update Host header to match new origin
91
+ request['headers']['host'] = [{
92
+ 'key': 'Host',
93
+ 'value': maint_cf_host
94
+ }]
95
+
96
+ # Normalize URI - redirect directory requests to index.html
97
+ uri = request.get('uri', '/')
98
+ if uri.endswith('/'):
99
+ request['uri'] = uri + 'index.html'
100
+ elif '.' not in uri.split('/')[-1]:
101
+ # No file extension, likely a directory
102
+ request['uri'] = uri + '/index.html'
103
+
104
+ return request
@@ -403,6 +403,7 @@ class PipelineFactoryStack(IStack):
403
403
  relative_path = os.path.relpath(abs_output, abs_cwd)
404
404
  return relative_path
405
405
  except ValueError:
406
+ print(f"Failed to compute relative path from {abs_output} to {abs_cwd}")
406
407
  # Different drives on Windows or other edge case
407
408
  # Fall back to basename approach (just the directory name)
408
409
  return "cdk.out"