=============================================================================== Utilities =============================================================================== This section provides detailed API documentation for utility modules that simplify common AWS CDK operations. Deployment Utilities =============================================================================== The deployment utilities module provides programmatic control over CDK stack deployments, making it easy to deploy, manage, and clean up CDK stacks without requiring a full CDK project structure. Overview ------------------------------------------------------------------------------- The ``Deployer`` class handles CDK CLI operations, CloudFormation stack management, and lifecycle operations. It's particularly useful for: * **Functional Testing**: Deploy and test stacks programmatically * **CI/CD Pipelines**: Automate stack deployments with custom logic * **Dynamic Stack Management**: Create and destroy stacks on-demand * **Temporary Deployments**: Use context managers for automatic cleanup Key Features ------------------------------------------------------------------------------- * Automatic temporary directory management * Stack deployment tracking for cleanup * CloudFormation status monitoring * Stack output collection * Context manager support for automatic cleanup * Comprehensive error handling and logging * Timeout configuration for all operations API Reference ------------------------------------------------------------------------------- .. automodule:: core_aws_cdk.utils.deployment :members: :undoc-members: :show-inheritance: Basic Usage Example ------------------------------------------------------------------------------- Simple deployment with automatic cleanup: .. code-block:: python from aws_cdk import App from core_aws_cdk.utils.deployment import Deployer from core_aws_cdk.stacks.ecs.cluster.base import ECSClusterStack # Create deployer with context manager for auto-cleanup with Deployer(folder_name="test_deployment") as deployer: # Create CDK app with deployer's output directory app = App(outdir=str(deployer.cdk_out_dir)) # Define your stack stack = ECSClusterStack( app, "TestCluster", cluster_name="my-cluster", enable_fargate=True ) # Synthesize and deploy deployer.synthesize(app) result = deployer.deploy_stack("TestCluster") if result.success: print(f"Deployment successful in {result.duration_seconds:.2f}s") print(f"Stack outputs: {result.outputs}") else: print(f"Deployment failed: {result.error}") # Stack is automatically destroyed and temp dir cleaned up Advanced Usage Example ------------------------------------------------------------------------------- Manual deployment with status monitoring: .. code-block:: python from aws_cdk import App, Environment from core_aws_cdk.utils.deployment import Deployer from core_aws_cdk.stacks.ecs.cluster.base import ECSClusterStack # Initialize deployer deployer = Deployer( folder_name="ecs_deployment", auto_approve=True, region="us-east-1" ) try: # Create app app = App(outdir=str(deployer.cdk_out_dir)) # Create stack stack = ECSClusterStack( app, "ProductionCluster", cluster_name="prod-cluster", enable_fargate=True, enable_container_insights=True, env=Environment( account="123456789012", region="us-east-1" ) ) # Synthesize deployer.synthesize(app) # List available stacks stacks = deployer.list_stacks() print(f"Available stacks: {stacks}") # Show diff before deployment diff = deployer.diff_stack("ProductionCluster") print(f"Stack diff:\\n{diff}") # Deploy with custom timeout result = deployer.deploy_stack( stack_name="ProductionCluster", timeout_seconds=1200, # 20 minutes context={"env": "production"} ) if not result.success: raise RuntimeError(f"Deployment failed: {result.error}") # Wait for stack to be fully ready deployer.wait_for_stack( stack_name="ProductionCluster", target_status="CREATE_COMPLETE", max_wait_seconds=600 ) # Get stack status status = deployer.get_stack_status("ProductionCluster") print(f"Stack status: {status.status}") print(f"Resources: {status.resources_count}") print(f"Outputs: {status.outputs}") finally: # Manual cleanup deployer.cleanup_all() Functional Testing Example ------------------------------------------------------------------------------- Using the deployer in functional tests: .. code-block:: python import unittest from aws_cdk import App from core_aws_cdk.utils.deployment import Deployer from core_aws_cdk.stacks.ecs.cluster.base import ECSClusterStack class TestECSClusterDeployment(unittest.TestCase): """Functional tests that deploy real ECS clusters.""" def setUp(self) -> None: """Set up deployer before each test.""" self.deployer = Deployer( folder_name=f"test_{self._testMethodName}", auto_approve=True ) def tearDown(self) -> None: """Clean up after each test.""" self.deployer.cleanup_all() def test_fargate_cluster_deployment(self) -> None: """Test deploying a Fargate-only cluster.""" # Create app app = App(outdir=str(self.deployer.cdk_out_dir)) # Create stack stack = ECSClusterStack( app, "TestFargateCluster", cluster_name="test-fargate-cluster", enable_fargate=True, fargate_capacity_providers=["FARGATE", "FARGATE_SPOT"] ) # Synthesize and deploy self.deployer.synthesize(app) result = self.deployer.deploy_stack("TestFargateCluster") # Assertions self.assertTrue(result.success) self.assertIsNotNone(result.outputs) self.assertGreater(result.duration_seconds, 0) # Verify stack status status = self.deployer.get_stack_status("TestFargateCluster") self.assertEqual(status.status, "CREATE_COMPLETE") self.assertTrue(status.exists) if __name__ == "__main__": unittest.main() Multi-Stack Deployment Example ------------------------------------------------------------------------------- Deploying multiple dependent stacks: .. code-block:: python from aws_cdk import App, Environment from core_aws_cdk.utils.deployment import Deployer from core_aws_cdk.stacks.network.base import NetworkStack from core_aws_cdk.stacks.ecs.cluster.base import ECSClusterStack deployer = Deployer(folder_name="multi_stack") try: app = App(outdir=str(deployer.cdk_out_dir)) env = Environment(account="123456789012", region="us-east-1") # Create network stack network_stack = NetworkStack(app, "NetworkStack", env=env) vpc = network_stack.create_vpc( vpc_id="MainVPC", cidr="10.0.0.0/16", max_azs=2 ) # Create ECS cluster stack cluster_stack = ECSClusterStack( app, "ClusterStack", cluster_name="app-cluster", vpc=vpc, enable_fargate=True, env=env ) # Synthesize deployer.synthesize(app) # Deploy in order network_result = deployer.deploy_stack("NetworkStack") if not network_result.success: raise RuntimeError("Network stack failed") cluster_result = deployer.deploy_stack("ClusterStack") if not cluster_result.success: raise RuntimeError("Cluster stack failed") print("All stacks deployed successfully") except Exception as e: print(f"Deployment error: {e}") deployer.cleanup_all() Deployment Result Data Classes ------------------------------------------------------------------------------- DeploymentResult ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Returned by ``deploy_stack()`` with deployment information: .. code-block:: python @dataclass class DeploymentResult: stack_name: str # Name of the deployed stack success: bool # Whether deployment succeeded outputs: Dict[str, str] # CloudFormation outputs error: Optional[str] # Error message if failed duration_seconds: float # Deployment duration StackStatus ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Returned by ``get_stack_status()`` with current stack information: .. code-block:: python @dataclass class StackStatus: stack_name: str # Name of the stack status: str # CloudFormation status exists: bool # Whether stack exists resources_count: int # Number of resources outputs: Dict[str, str] # Stack outputs Common CloudFormation Status Values ------------------------------------------------------------------------------- When monitoring stack operations, you'll encounter these status values: **Creation Statuses:** * ``CREATE_IN_PROGRESS`` - Stack is being created * ``CREATE_COMPLETE`` - Stack created successfully * ``CREATE_FAILED`` - Stack creation failed **Update Statuses:** * ``UPDATE_IN_PROGRESS`` - Stack is being updated * ``UPDATE_COMPLETE`` - Stack updated successfully * ``UPDATE_FAILED`` - Stack update failed * ``UPDATE_ROLLBACK_IN_PROGRESS`` - Update failed, rolling back * ``UPDATE_ROLLBACK_COMPLETE`` - Rollback completed **Deletion Statuses:** * ``DELETE_IN_PROGRESS`` - Stack is being deleted * ``DELETE_COMPLETE`` - Stack deleted successfully * ``DELETE_FAILED`` - Stack deletion failed Best Practices ------------------------------------------------------------------------------- 1. **Use Context Managers**: Always use the ``with`` statement for automatic cleanup: .. code-block:: python with Deployer(folder_name="deployment") as deployer: # Your deployment code pass # Automatic cleanup happens here 2. **Set Appropriate Timeouts**: ECS clusters may take 10+ minutes to deploy: .. code-block:: python result = deployer.deploy_stack( "ECSStack", timeout_seconds=1200 # 20 minutes ) 3. **Monitor Stack Status**: Use ``wait_for_stack()`` for operations that need verification: .. code-block:: python deployer.wait_for_stack( "MyStack", "CREATE_COMPLETE", max_wait_seconds=600 ) 4. **Handle Errors Gracefully**: Always check deployment results: .. code-block:: python result = deployer.deploy_stack("MyStack") if not result.success: logger.error(f"Deployment failed: {result.error}") deployer.cleanup_all() return 5. **Use Explicit Regions**: Specify region to avoid relying on AWS profile: .. code-block:: python deployer = Deployer( folder_name="deployment", region="us-east-1" # Explicit region ) 6. **Clean Up Resources**: Always ensure cleanup happens, even on errors: .. code-block:: python deployer = Deployer(folder_name="test") try: # Your deployment code pass finally: deployer.cleanup_all() Troubleshooting ------------------------------------------------------------------------------- **CDK Synthesis Fails** If ``synthesize()`` fails, check: * CDK app is properly configured with ``outdir=str(deployer.cdk_out_dir)`` * All stack parameters are valid * Required AWS permissions are available **Deployment Times Out** If deployment exceeds timeout: * Increase ``timeout_seconds`` parameter (ECS clusters need 10-15 minutes) * Check AWS CloudFormation console for stack progress * Verify AWS service limits haven't been exceeded **Stack Not Found After Deployment** If ``get_stack_status()`` returns ``NOT_FOUND``: * Verify correct stack name (case-sensitive) * Check correct AWS region is configured * Confirm deployment actually succeeded **Cleanup Fails** If ``cleanup_all()`` has errors: * Check CloudFormation console for stack status * Verify stacks don't have resources that prevent deletion * Manually delete stacks via AWS console if needed See Also ------------------------------------------------------------------------------- * :doc:`testing` - Using the deployer in functional tests * :doc:`stacks` - Available CDK stacks * :doc:`examples` - Complete deployment examples