Skills powertools-lambda
install
source · Clone the upstream repo
git clone https://github.com/TerminalSkills/skills
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/TerminalSkills/skills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/powertools-lambda" ~/.claude/skills/terminalskills-skills-powertools-lambda && rm -rf "$T"
manifest:
skills/powertools-lambda/SKILL.mdsafety · automated scan (low risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
- pip install
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content
AWS Lambda Powertools — Serverless Best Practices
You are an expert in AWS Lambda Powertools, the developer toolkit for implementing serverless best practices. You help developers add structured logging, distributed tracing (X-Ray), custom metrics (CloudWatch EMF), idempotency, feature flags, parameter management, and event parsing to Lambda functions — with zero boilerplate using decorators and middleware.
Core Capabilities
TypeScript
// handler.ts — Lambda with Powertools middleware import { Logger } from "@aws-lambda-powertools/logger"; import { Tracer } from "@aws-lambda-powertools/tracer"; import { Metrics, MetricUnit } from "@aws-lambda-powertools/metrics"; import { injectLambdaContext } from "@aws-lambda-powertools/logger/middleware"; import { captureLambdaHandler } from "@aws-lambda-powertools/tracer/middleware"; import { logMetrics } from "@aws-lambda-powertools/metrics/middleware"; import middy from "@middy/core"; const logger = new Logger({ serviceName: "payment-service" }); const tracer = new Tracer({ serviceName: "payment-service" }); const metrics = new Metrics({ namespace: "PaymentService", serviceName: "payment-service" }); const lambdaHandler = async (event: APIGatewayProxyEvent) => { // Structured logging with correlation IDs logger.appendKeys({ orderId: event.pathParameters?.id }); logger.info("Processing payment", { amount: 29.99, currency: "USD" }); // Custom metrics (published to CloudWatch automatically) metrics.addMetric("PaymentProcessed", MetricUnit.Count, 1); metrics.addMetric("PaymentAmount", MetricUnit.None, 29.99); metrics.addDimension("PaymentMethod", "card"); // Tracing (X-Ray subsegments) const subsegment = tracer.getSegment()?.addNewSubsegment("stripe-charge"); try { const charge = await processStripePayment(event); subsegment?.addAnnotation("chargeId", charge.id); tracer.addResponseAsMetadata(charge); return { statusCode: 200, body: JSON.stringify(charge) }; } catch (error) { subsegment?.addError(error as Error); logger.error("Payment failed", error as Error); metrics.addMetric("PaymentFailed", MetricUnit.Count, 1); throw error; } finally { subsegment?.close(); } }; // Middy middleware stack export const handler = middy(lambdaHandler) .use(injectLambdaContext(logger, { logEvent: true })) .use(captureLambdaHandler(tracer)) .use(logMetrics(metrics));
Idempotency
import { makeIdempotent, IdempotencyConfig } from "@aws-lambda-powertools/idempotency"; import { DynamoDBPersistenceLayer } from "@aws-lambda-powertools/idempotency/dynamodb"; const persistenceStore = new DynamoDBPersistenceLayer({ tableName: "idempotency-table", }); const config = new IdempotencyConfig({ eventKeyJmesPath: "body.orderId", // Dedup key from event expiresAfterSeconds: 3600, // 1 hour TTL }); const processPayment = async (event: any) => { const body = JSON.parse(event.body); // This function runs EXACTLY ONCE per orderId, even on retries const result = await chargeCard(body.orderId, body.amount); return { statusCode: 200, body: JSON.stringify(result) }; }; export const handler = makeIdempotent(processPayment, { persistenceStore, config, });
Python
from aws_lambda_powertools import Logger, Tracer, Metrics from aws_lambda_powertools.event_handler import APIGatewayRestResolver from aws_lambda_powertools.utilities.typing import LambdaContext from aws_lambda_powertools.logging import correlation_paths logger = Logger(service="user-service") tracer = Tracer(service="user-service") metrics = Metrics(namespace="UserService") app = APIGatewayRestResolver() @app.get("/users/<user_id>") @tracer.capture_method def get_user(user_id: str): logger.info("Fetching user", extra={"user_id": user_id}) user = db.get_user(user_id) metrics.add_metric(name="UserFetched", unit="Count", value=1) return {"user": user} @app.post("/users") @tracer.capture_method def create_user(): body = app.current_event.json_body user = db.create_user(body) metrics.add_metric(name="UserCreated", unit="Count", value=1) return {"user": user}, 201 @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: dict, context: LambdaContext) -> dict: return app.resolve(event, context)
Installation
# TypeScript npm install @aws-lambda-powertools/logger @aws-lambda-powertools/tracer @aws-lambda-powertools/metrics # Python pip install aws-lambda-powertools
Best Practices
- Structured logging — Use Logger for JSON logs with correlation IDs; enables CloudWatch Insights queries
- Distributed tracing — Use Tracer with X-Ray; trace requests across Lambda → DynamoDB → SQS → Lambda chains
- Custom metrics — Use Metrics with EMF format; CloudWatch picks up without API calls, zero cost overhead
- Idempotency — Use for payment/order handlers; prevents duplicate processing on Lambda retries
- Event parsing — Use event handler resolvers for API Gateway, SQS, S3 events; type-safe with validation
- Cold start metric — Enable
; track and optimize cold starts per functioncapture_cold_start_metric - Correlation IDs — Inject automatically from API Gateway, ALB, or custom headers; trace requests end-to-end
- Middy middleware — Stack Powertools as middy middleware in TypeScript; clean separation of concerns