Applications
Overview
The Application class provides the foundation for building AWS cloud-native applications with minimal boilerplate. It manages infrastructure deployment using AWS CDK with built-in best practices, while providing core operational features like configuration management, error tracking, and service communication.
Key capabilities:
Infrastructure deployment and management through AWS CDK
Multi-environment deployments (dev, staging, prod) in a single account
Built-in operational features (configuration, error handling, pub/sub)
Docker-based Lambda deployments with automatic dependency management
Core Features
Global Settings
Global Settings is a shared configuration table that provides plain-text values accessible by any part of the application. It acts as a central source for application-wide variables.
enable_global_settings=True # Default
How it Works
All settings are stored in a single DynamoDB table with unrestricted access across the application. Any Lambda function or component can read any setting. Note: Values are currently stored as plain text.
Key Benefits
Single source for application-wide variables
Changes take effect without redeployment
Accessible from any application component
Simple key-value storage pattern
Framework-managed infrastructure
Use When
Defining shared variables across components
Managing feature flags or toggles
Configuring framework behavior
Exception Trap
The Exception Trap is a centralized error capturing system for Lambda functions. It automatically stores errors with their full context for later analysis.
How it Works
When a Lambda function throws an error, the Exception Trap:
Captures the full error context (stack trace, event data, metadata)
Stores it in a central database
Retains errors for 48 hours by default
Key Benefits
Complete error context in one place
Automatic cleanup of old errors
No impact on application behavior
Simple debugging of production issues
Error tracking across distributed functions
Use When
Debugging errors
Analyzing patterns in application failures
Tracing issues across multiple functions
Error monitoring needs structure
Event Bus
The Event Bus enables Lambda functions to communicate using events. Any function can publish an event, and any function can subscribe to receive specific event types.
enable_event_bus=False # Default
How it Works
Functions publish events with a type and payload. The Event Bus handles delivery to all functions that subscribe to that event type. Subscribers process events independently - if one fails, others continue normally.
All events and their processing results are stored in DynamoDB tables, creating a complete audit trail. This includes the original event, when it was published, which subscribers received it, processing status, and any responses. Event data is stored in a structured format that can be queried programmatically.
Key Benefits
Complete audit trail of all events and processing results
Query event history programmatically via DynamoDB
Track which functions processed which events
Identify processing failures and successes
Add new functions without changing existing code
Multiple functions can handle the same event
Function failures stay isolated
No direct dependencies between functions
Use When
Functions need to trigger other functions
Multiple actions needed for one event
Adding features to existing processes
Building independent processing steps
Decoupling application components
Audit trail of event processing required
Need to query event history programmatically
Deployment Configuration
The Application combines app_name and deployment_id to create unique resource identifiers, enabling:
Multiple application deployments in one AWS account
Clear resource ownership
Simple development environments
app = Application(
app_name='customer-portal',
deployment_id='dev-team1'
) # Resources will be prefixed with 'customer-portal-dev-team1'
Infrastructure Components
The Application automatically configures required infrastructure based on enabled features. This includes:
Core stacks and dependencies
Docker image management
Resource permissions
Cross-stack references
Docker Management
The Application handles container image builds for Lambda functions:
Library Base Image: Contains framework code and dependencies
Application Image: Contains application code
# Use library base image (recommended)
app = Application(
app_name='myapp',
deployment_id='dev',
app_entry='./src',
app_image_use_lib_base=True # Builds on top of Da Vinci base image
)
# Custom application image
app = Application(
app_name='myapp',
deployment_id='dev',
app_entry='./src',
app_image_use_lib_base=False # Uses your Dockerfile from app_entry
)
Application Dockerfile Requirements
When using a custom Dockerfile in your application’s app_entry directory, you must install uv to respect custom package index configurations in your pyproject.toml.
Why uv is Required
If your pyproject.toml specifies a custom package index:
[[tool.uv.index]]
url = "https://packages.example.com/simple/"
Then pip will not respect this configuration. The Dockerfile must use uv pip install to properly read the index configuration from pyproject.toml.
Required Dockerfile Pattern
# Image is passed as a build arg by the framework
ARG IMAGE
FROM $IMAGE
# Install uv to respect pyproject.toml index configuration
RUN pip install uv
ADD . ${LAMBDA_TASK_ROOT}/myapp
RUN rm -rf /var/task/myapp/.venv
# Use uv pip install to respect custom package indexes
RUN cd ${LAMBDA_TASK_ROOT}/myapp && uv pip install --system .
Key Points
pip install uvinstalls uv in the Lambda base imageuv pip install --systemreads[[tool.uv.index]]frompyproject.toml--systemflag installs packages globally (no virtual environment)This pattern works with both PyPI and custom package repositories
Stack Management
The Application manages AWS CloudFormation stacks and their dependencies:
# Framework handles dependencies
app.add_uninitialized_stack(MyCustomStack)
# Enable core features
app = Application(
app_name='myapp',
deployment_id='dev',
enable_event_bus=True,
enable_exception_trap=True
)
Sidecar Applications
Overview
A sidecar application is a separate CDK application that deploys alongside and connects to an existing da_vinci Application. Sidecars share the parent’s operational infrastructure (global settings, event bus, exception trap) but maintain their own stack deployments.
When to Use
Use a sidecar application when you need:
Auxiliary services that support the main application
Services with different deployment lifecycles
Additional infrastructure that shouldn’t be in the main app
Services managed by different teams using the same resources
Example use cases:
Monitoring dashboards that read from main app’s exception trap
Admin tools that modify global settings
Background processing services triggered by main app events
Integration services connecting to external systems
How It Works
Resource Organization:
Sidecar has its own CDK app and CloudFormation stacks
Shares parent’s
deployment_idfor consistent resource namingGets unique resource names via
sidecar_app_nameprefixConnects to parent’s infrastructure via resource discovery
Deployment Requirements:
Parent application must be deployed first
Sidecar reads parent’s configuration from global settings table
Sidecar automatically discovers shared resources
Sidecar can add its own stacks and Lambda functions
Request Flow Differences:
Regular Application Service:
Request → API Gateway → Lambda (in Application stack)
↓
Shared Resources
Sidecar Service:
Request → API Gateway → Lambda (in SidecarApplication stack)
↓
Shared Resources ← Discovered via resource registry
Example
from da_vinci_cdk import Application, SideCarApplication, Stack
# Main application (deploy first)
app = Application(
app_name='customer-portal',
deployment_id='prod',
enable_event_bus=True,
enable_exception_trap=True
)
# Sidecar application for admin tools (deploy separately)
admin_app = SideCarApplication(
app_name='customer-portal', # Same as parent
deployment_id='prod', # Same as parent
sidecar_app_name='admin-tools', # Unique identifier
app_entry='./admin_src'
)
# Add stacks to sidecar
admin_app.add_uninitialized_stack(AdminDashboardStack)
# Sidecar functions can access parent's:
# - Global settings table
# - Event bus (if enabled)
# - Exception trap (if enabled)
# - Resource registry
Limitations
Parent application must exist and be deployed
Cannot modify parent application’s stacks
Shares parent’s global settings (read/write access)
Must use same AWS account and region as parent
Best Practices
Resource Organization
Group related resources in purpose-specific stacks
Store shared configuration in global settings
Use event bus for component communication
Use exception trap for error tracking
Use sidecars for auxiliary services with separate lifecycles
Environment Isolation
Use different deployment_id values for different environments:
# Development
app_dev = Application(app_name='myapp', deployment_id='dev')
# Staging
app_staging = Application(app_name='myapp', deployment_id='staging')
# Production
app_prod = Application(app_name='myapp', deployment_id='prod')
Feature Flags
Enable only the features you need:
app = Application(
app_name='myapp',
deployment_id='dev',
enable_global_settings=True, # Almost always needed
enable_exception_trap=True, # Recommended for production
enable_event_bus=False, # Only if using events
)