Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
525 changes: 525 additions & 0 deletions docs/build_recipes/build-tools.md

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions docs/build_recipes/getting-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ Each build tool has its strengths and is optimized for different use cases. Cons

| Tool | Best for | Considerations |
| --------------------- | --------------------------------- | ------------------------------------------- |
| **[pip](build-with-pip.md)** | Simple projects, CI/CD | Lightweight, universal |
| **[poetry](build-with-poetry.md)** | Modern Python projects | Excellent dependency management, lock files |
| **[uv](build-with-uv.md)** | Fast builds, performance-critical | Extremely fast, Rust-based |
| **[pants](build-with-pants.md)** | Monorepos, complex projects | Advanced build system, incremental builds |
| **[SAM](build-with-sam.md)** | AWS-native deployments | Integrated with AWS, local testing |
| **[CDK](build-with-cdk.md)** | Infrastructure as code | Programmatic infrastructure, type safety |
| **[pip](build-tools.md#pip)** | Simple projects, CI/CD | Lightweight, universal |
| **[uv](build-tools.md#uv)** | Fast builds, performance-critical | Extremely fast, Rust-based |
| **[poetry](bbuild-tools.md#poetry)** | Modern Python projects | Excellent dependency management, lock files |
| **[SAM](build-tools.md#sam)** | AWS-native deployments | Integrated with AWS, local testing |
| **[CDK](build-tools.md#cdk)** | Infrastructure as code | Programmatic infrastructure, type safety |
| **[pants](build-tools.md#pants)** | Monorepos, complex projects | Advanced build system, incremental builds |

???+ tip
All examples in this guide are available in the [project repository](https://github.com/aws-powertools/powertools-lambda-python/tree/develop/examples/build_recipes){target="_blank"}.
14 changes: 7 additions & 7 deletions docs/build_recipes/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,16 +39,16 @@ This guide is organized into focused sections to help you find exactly what you
### 📚 Fundamentals

* **[Getting started](getting-started.md)** - Prerequisites, tool selection, and basic setup
* **[Cross-platform builds](cross-platform.md)** - Handle architecture differences and compiled dependencies
* **[Cross-platform builds](cross-integration.md)** - Handle architecture differences and compiled dependencies

### 🔧 Build tools

* **[Build with pip](build-with-pip.md)** - Simple, universal package management
* **[Build with Poetry](build-with-poetry.md)** - Modern dependency management with lock files
* **[Build with uv](build-with-uv.md)** - Extremely fast Rust-based package manager
* **[Build with SAM](build-with-sam.md)** - AWS Serverless Application Model integration
* **[Build with CDK](build-with-cdk.md)** - Infrastructure as code with type safety
* **[Build with Pants](build-with-pants.md)** - Advanced build system for monorepos
* **[Build with pip](build-tools.md#pip)** - Simple, universal package management
* **[Build with uv](build-tools.md#uv)** - Extremely fast Rust-based package manager
* **[Build with Poetry](build-tools.md#poetry)** - Modern dependency management with lock files
* **[Build with SAM](build-tools.md#sam)** - AWS Serverless Application Model integration
* **[Build with CDK](build-tools.md#cdk)** - Infrastructure as code with type safety
* **[Build with Pants](build-tools.md#pants)** - Advanced build system for monorepos

### ⚡ Advanced topics

Expand Down
74 changes: 74 additions & 0 deletions examples/build_recipes/cdk/basic/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
import aws_cdk as cdk
from aws_cdk import (
Duration,
Stack,
)
from aws_cdk import (
aws_apigateway as apigateway,
)
from aws_cdk import (
aws_lambda as _lambda,
)
from aws_cdk import (
aws_logs as logs,
)
from constructs import Construct


class PowertoolsLambdaStack(Stack):
def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)

# Use public Powertools layer
powertools_layer = _lambda.LayerVersion.from_layer_version_arn(
self,
"PowertoolsLayer",
layer_version_arn="arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:1",
)

# Lambda Function
api_function = _lambda.Function(
self,
"ApiFunction",
runtime=_lambda.Runtime.PYTHON_3_13,
handler="lambda_function.lambda_handler",
code=_lambda.Code.from_asset("src"),
layers=[powertools_layer],
timeout=Duration.seconds(30),
memory_size=512,
environment={
"POWERTOOLS_SERVICE_NAME": "api-service",
"POWERTOOLS_METRICS_NAMESPACE": "MyApp",
"POWERTOOLS_LOG_LEVEL": "INFO",
},
log_retention=logs.RetentionDays.ONE_WEEK,
)

# API Gateway
api = apigateway.RestApi(
self,
"ApiGateway",
rest_api_name="Powertools API",
description="API powered by Lambda with Powertools",
)

# API Integration
integration = apigateway.LambdaIntegration(api_function)
api.root.add_proxy(
default_integration=integration,
any_method=True,
)

# Outputs
cdk.CfnOutput(
self,
"ApiUrl",
value=api.url,
description="API Gateway URL",
)


app = cdk.App()
PowertoolsLambdaStack(app, "PowertoolsLambdaStack")
app.synth()
14 changes: 14 additions & 0 deletions examples/build_recipes/cdk/basic/build-cdk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

echo "🏗️ Building CDK application..."

# Install CDK dependencies
pip install -r requirements.txt

# Bootstrap CDK (first time only)
# cdk bootstrap

# Deploy stack
cdk deploy --require-approval never

echo "✅ CDK application deployed successfully"
21 changes: 21 additions & 0 deletions examples/build_recipes/cdk/basic/cdk-commands.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/bash
# Install Python dependencies
pip install -r requirements.txt

# Synthesize CloudFormation template
cdk synth

# Deploy stack
cdk deploy

# Deploy specific stack
cdk deploy MyLambdaStack

# Destroy stack
cdk destroy

# List all stacks
cdk list

# Compare deployed stack with current state
cdk diff
37 changes: 37 additions & 0 deletions examples/build_recipes/cdk/basic/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"app": "python app.py",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"requirements*.txt",
"source.bat",
"**/__pycache__",
"**/.venv"
]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": ["aws", "aws-cn"],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
"@aws-cdk/aws-route53-patters:useCertificate": true,
"@aws-cdk/customresources:installLatestAwsSdkDefault": false
}
}
9 changes: 9 additions & 0 deletions examples/build_recipes/cdk/basic/setup-cdk.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash
# Install AWS CDK CLI
npm install -g aws-cdk

# Verify installation
cdk --version

# Bootstrap CDK in your AWS account (one-time setup)
cdk bootstrap aws://ACCOUNT-ID/REGION
27 changes: 27 additions & 0 deletions examples/build_recipes/cdk/basic/src/lambda_function.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from aws_lambda_powertools import Logger, Metrics, Tracer
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.metrics import MetricUnit

logger = Logger()
tracer = Tracer()
metrics = Metrics()
app = APIGatewayRestResolver()


@app.get("/health")
def health_check():
return {"status": "healthy", "service": "powertools-cdk"}


@app.get("/metrics")
def get_metrics():
metrics.add_metric(name="MetricsEndpointCalled", unit=MetricUnit.Count, value=1)
return {"message": "Metrics recorded"}


@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
@tracer.capture_lambda_handler
@metrics.log_metrics(capture_cold_start_metric=True)
def lambda_handler(event, context):
return app.resolve(event, context)
21 changes: 21 additions & 0 deletions examples/build_recipes/cdk/multi-stack/app_multi_stack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/usr/bin/env python3
import aws_cdk as cdk
from stacks.powertools_cdk_stack import PowertoolsStack

app = cdk.App()

# Get environment from context or default to dev
environment = app.node.try_get_context("environment") or "dev"

# Create stack for the specified environment
PowertoolsStack(
app,
f"PowertoolsStack-{environment}",
environment=environment,
env=cdk.Environment(
account=app.node.try_get_context("account"),
region=app.node.try_get_context("region") or "us-east-1",
),
)

app.synth()
37 changes: 37 additions & 0 deletions examples/build_recipes/cdk/multi-stack/cdk.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"app": "python app_multi_stack.py",
"watch": {
"include": [
"**"
],
"exclude": [
"README.md",
"cdk*.json",
"requirements*.txt",
"source.bat",
"**/__pycache__",
"**/.venv"
]
},
"context": {
"@aws-cdk/aws-lambda:recognizeLayerVersion": true,
"@aws-cdk/core:checkSecretUsage": true,
"@aws-cdk/core:target-partitions": ["aws", "aws-cn"],
"@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true,
"@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true,
"@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true,
"@aws-cdk/aws-s3:createDefaultLoggingPolicy": true,
"@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true,
"@aws-cdk/aws-apigateway:disableCloudWatchRole": true,
"@aws-cdk/core:enablePartitionLiterals": true,
"@aws-cdk/aws-events:eventsTargetQueueSameAccount": true,
"@aws-cdk/aws-iam:minimizePolicies": true,
"@aws-cdk/core:validateSnapshotRemovalPolicy": true,
"@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true,
"@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true,
"@aws-cdk/aws-route53-patters:useCertificate": true,
"@aws-cdk/customresources:installLatestAwsSdkDefault": false
}
}
14 changes: 14 additions & 0 deletions examples/build_recipes/cdk/multi-stack/deploy-environments.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash

# Deploy to different environments
environments=("dev" "staging" "prod")

for env in "${environments[@]}"; do
echo "🚀 Deploying to $env environment..."

cdk deploy PowertoolsStack-$env \
--context environment=$env \
--require-approval never

echo "✅ $env deployment completed"
done
49 changes: 49 additions & 0 deletions examples/build_recipes/cdk/multi-stack/src/app/api.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import os

import boto3

from aws_lambda_powertools import Logger, Metrics, Tracer
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
from aws_lambda_powertools.logging import correlation_paths
from aws_lambda_powertools.metrics import MetricUnit

logger = Logger()
tracer = Tracer()
metrics = Metrics()
app = APIGatewayRestResolver()

# Initialize AWS clients
dynamodb = boto3.resource("dynamodb")
sqs = boto3.client("sqs")

table = dynamodb.Table(os.environ["TABLE_NAME"])
queue_url = os.environ["QUEUE_URL"]


@app.get("/health")
def health_check():
return {"status": "healthy", "service": "powertools-cdk-api"}


@app.post("/tasks")
@tracer.capture_method
def create_task():
task_data = app.current_event.json_body

# Store in DynamoDB
table.put_item(Item={"pk": task_data["task_id"], "task_type": task_data["task_type"], "status": "pending"})

# Send to SQS for processing
sqs.send_message(QueueUrl=queue_url, MessageBody=app.current_event.body)

metrics.add_metric(name="TaskCreated", unit=MetricUnit.Count, value=1)
logger.info("Task created", extra={"task_id": task_data["task_id"]})

return {"message": "Task created successfully", "task_id": task_data["task_id"]}


@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_REST)
@tracer.capture_lambda_handler
@metrics.log_metrics(capture_cold_start_metric=True)
def lambda_handler(event, context):
return app.resolve(event, context)
Empty file.
Loading