AWS Lambda

ServerlessAWSFaaSEvent-drivenAuto-scalingMicroservices

Platform

AWS Lambda

Overview

AWS Lambda is the pioneering serverless computing service from Amazon that revolutionizes application development through event-driven code execution, automatic scaling, and pay-per-use pricing without server management. Since its 2014 launch, Lambda has maintained leadership in the serverless market, enabling complete serverless architecture construction through deep integration with API Gateway, DynamoDB, S3, EventBridge, and more. Supporting 15+ runtimes including Node.js, Python, Java, C#, Go, Ruby, and PowerShell, Lambda implements true usage-based billing with millisecond-precision charging, making it the gold standard for serverless computing platforms globally.

Details

AWS Lambda 2025 edition stands as an enterprise-grade serverless computing platform supporting billions of executions daily. The latest Arm Graviton3 processors deliver up to 34% performance improvements, while Provisioned Concurrency guarantees consistent response times. Advanced features include Lambda Layers for dependency management, Lambda Extensions for observability and security tool integration, and container image support for existing workload migration. Lambda SnapStart dramatically reduces Java application startup times by up to 90%, providing high-performance execution environments. With 250+ AWS service integrations and comprehensive enterprise features, Lambda continues to define the serverless computing paradigm.

Key Features

  • Event-driven Execution: Integration with 250+ AWS services
  • Auto-scaling: Automatic scaling from zero to 1000 concurrent executions
  • Multi-language Runtime: Support for 15+ programming languages
  • Pay-per-use: Billing in 100ms increments for actual execution time
  • High Availability: 99.95% SLA with multi-AZ redundancy
  • Security: VPC support, IAM integration, encryption

Pros and Cons

Pros

  • Most mature ecosystem as the serverless computing pioneer
  • Powerful event-driven architecture with 250+ native AWS service integrations
  • Consistent performance guarantees through Provisioned Concurrency
  • Significant cold start reduction with Lambda SnapStart
  • Comprehensive monitoring and logging (CloudWatch, X-Ray integration)
  • Enterprise-grade security and compliance capabilities

Cons

  • 15-minute execution time limit unsuitable for long-running processes
  • Memory limitations at 10GB and ephemeral storage constraints
  • Cold start latency for initial execution (except SnapStart-supported languages)
  • Vendor lock-in risk to AWS ecosystem
  • Complex permission management (IAM) with steep learning curve
  • Cost prediction difficulties with high concurrent execution volumes

Reference Pages

Code Examples

Setup and Function Creation

# AWS CLI installation and configuration
pip install awscli
aws configure

# AWS SAM CLI installation
pip install aws-sam-cli

# Create new Lambda function project
sam init --runtime nodejs18.x --name my-lambda-function
cd my-lambda-function

# Local execution and testing
sam local start-api --port 3000
sam local invoke HelloWorldFunction --event events/event.json
// Basic Node.js function structure
exports.handler = async (event, context) => {
    console.log('Event:', JSON.stringify(event, null, 2));
    console.log('Context:', JSON.stringify(context, null, 2));
    
    try {
        // Main processing logic
        const result = await processEvent(event);
        
        return {
            statusCode: 200,
            headers: {
                'Content-Type': 'application/json',
                'Access-Control-Allow-Origin': '*'
            },
            body: JSON.stringify({
                message: 'Function executed successfully',
                result: result,
                timestamp: new Date().toISOString()
            })
        };
    } catch (error) {
        console.error('Error:', error);
        
        return {
            statusCode: 500,
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                error: 'Internal server error',
                message: error.message
            })
        };
    }
};

async function processEvent(event) {
    // Business logic implementation
    return {
        eventType: event.Records ? 'S3/SQS Event' : 'API Gateway',
        eventSource: event.source || 'unknown',
        processed: true
    };
}

HTTP APIs and Request Handling

// API Gateway integrated Lambda function
exports.apiHandler = async (event, context) => {
    const httpMethod = event.httpMethod || event.requestContext?.http?.method;
    const path = event.path || event.rawPath;
    const pathParameters = event.pathParameters || {};
    const queryParameters = event.queryStringParameters || {};
    const headers = event.headers || {};
    const body = event.body ? JSON.parse(event.body) : null;
    
    console.log(`${httpMethod} ${path}`);
    console.log('Path Parameters:', pathParameters);
    console.log('Query Parameters:', queryParameters);
    
    try {
        let response;
        
        switch (httpMethod) {
            case 'GET':
                response = await handleGet(pathParameters, queryParameters);
                break;
            case 'POST':
                response = await handlePost(body, headers);
                break;
            case 'PUT':
                response = await handlePut(pathParameters.id, body);
                break;
            case 'DELETE':
                response = await handleDelete(pathParameters.id);
                break;
            default:
                throw new Error(`Unsupported method: ${httpMethod}`);
        }
        
        return createApiResponse(200, response);
    } catch (error) {
        console.error('API Error:', error);
        return createApiResponse(500, { error: error.message });
    }
};

function createApiResponse(statusCode, body, headers = {}) {
    return {
        statusCode,
        headers: {
            'Content-Type': 'application/json',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
            'Access-Control-Allow-Headers': 'Content-Type, Authorization',
            ...headers
        },
        body: JSON.stringify(body)
    };
}

async function handleGet(pathParams, queryParams) {
    if (pathParams.id) {
        return { message: `Getting item ${pathParams.id}` };
    }
    
    const limit = parseInt(queryParams.limit) || 10;
    const offset = parseInt(queryParams.offset) || 0;
    
    return {
        items: Array.from({ length: limit }, (_, i) => ({
            id: offset + i + 1,
            name: `Item ${offset + i + 1}`,
            created: new Date().toISOString()
        })),
        pagination: { limit, offset, total: 1000 }
    };
}

async function handlePost(body, headers) {
    const userAgent = headers['User-Agent'] || 'Unknown';
    const contentType = headers['Content-Type'] || 'application/json';
    
    return {
        message: 'Item created successfully',
        data: body,
        metadata: {
            userAgent,
            contentType,
            createdAt: new Date().toISOString()
        }
    };
}

Database Integration and Data Processing

// DynamoDB integrated Lambda function
const AWS = require('aws-sdk');
const dynamodb = new AWS.DynamoDB.DocumentClient();
const TABLE_NAME = process.env.TABLE_NAME || 'MyTable';

exports.databaseHandler = async (event, context) => {
    try {
        // Process S3 events
        if (event.Records && event.Records[0].eventSource === 'aws:s3') {
            return await processS3Event(event.Records);
        }
        
        // Process SQS messages
        if (event.Records && event.Records[0].eventSource === 'aws:sqs') {
            return await processSQSMessages(event.Records);
        }
        
        // Direct DynamoDB operations
        return await processDatabaseOperation(event);
        
    } catch (error) {
        console.error('Database error:', error);
        throw error;
    }
};

async function processS3Event(records) {
    const results = [];
    
    for (const record of records) {
        const bucket = record.s3.bucket.name;
        const key = decodeURIComponent(record.s3.object.key.replace(/\+/g, ' '));
        const eventName = record.eventName;
        
        console.log(`Processing S3 event: ${eventName} for ${bucket}/${key}`);
        
        const item = {
            id: `s3-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
            type: 'S3_EVENT',
            bucket: bucket,
            objectKey: key,
            eventName: eventName,
            timestamp: new Date().toISOString(),
            processed: true
        };
        
        // Record in DynamoDB
        await dynamodb.put({
            TableName: TABLE_NAME,
            Item: item
        }).promise();
        
        results.push(item);
    }
    
    return { processed: results.length, items: results };
}

async function processSQSMessages(records) {
    const batchResults = [];
    
    for (const record of records) {
        try {
            const messageBody = JSON.parse(record.body);
            const messageId = record.messageId;
            
            console.log(`Processing SQS message: ${messageId}`);
            
            // Process message and save to DynamoDB
            const processedItem = await processMessage(messageBody, messageId);
            batchResults.push(processedItem);
            
        } catch (error) {
            console.error(`Failed to process message ${record.messageId}:`, error);
            batchResults.push({ messageId: record.messageId, error: error.message });
        }
    }
    
    return { batchResults };
}

async function processMessage(messageBody, messageId) {
    const item = {
        id: messageId,
        type: 'SQS_MESSAGE',
        data: messageBody,
        processedAt: new Date().toISOString(),
        status: 'COMPLETED'
    };
    
    await dynamodb.put({
        TableName: TABLE_NAME,
        Item: item
    }).promise();
    
    return item;
}

async function processDatabaseOperation(event) {
    const operation = event.operation || 'query';
    
    switch (operation) {
        case 'query':
            return await queryItems(event.queryParams || {});
        case 'scan':
            return await scanTable(event.scanParams || {});
        case 'batchWrite':
            return await batchWriteItems(event.items || []);
        default:
            throw new Error(`Unsupported operation: ${operation}`);
    }
}

async function queryItems(params) {
    const queryParams = {
        TableName: TABLE_NAME,
        KeyConditionExpression: params.keyCondition || 'id = :id',
        ExpressionAttributeValues: params.attributeValues || { ':id': 'example' },
        Limit: params.limit || 10
    };
    
    const result = await dynamodb.query(queryParams).promise();
    return {
        items: result.Items,
        count: result.Count,
        lastEvaluatedKey: result.LastEvaluatedKey
    };
}

Authentication and Security

// Cognito JWT authentication and Lambda Authorizer
const jwt = require('jsonwebtoken');
const jwksClient = require('jwks-rsa');

const client = jwksClient({
    jwksUri: `https://cognito-idp.${process.env.AWS_REGION}.amazonaws.com/${process.env.USER_POOL_ID}/.well-known/jwks.json`
});

exports.authorizerHandler = async (event, context) => {
    try {
        const token = extractToken(event);
        const decodedToken = await verifyToken(token);
        const principalId = decodedToken.sub;
        
        // Authentication successful - generate IAM policy
        const policy = generatePolicy(principalId, 'Allow', event.methodArn, decodedToken);
        console.log('Authorization successful for user:', principalId);
        
        return policy;
    } catch (error) {
        console.error('Authorization failed:', error);
        throw new Error('Unauthorized');
    }
};

function extractToken(event) {
    const authorizationHeader = event.headers?.Authorization || event.headers?.authorization;
    
    if (!authorizationHeader) {
        throw new Error('Missing Authorization header');
    }
    
    const tokenMatch = authorizationHeader.match(/^Bearer\s+(.+)$/);
    if (!tokenMatch) {
        throw new Error('Invalid Authorization header format');
    }
    
    return tokenMatch[1];
}

async function verifyToken(token) {
    const decodedHeader = jwt.decode(token, { complete: true });
    if (!decodedHeader || !decodedHeader.header.kid) {
        throw new Error('Invalid token header');
    }
    
    const signingKey = await getSigningKey(decodedHeader.header.kid);
    
    return jwt.verify(token, signingKey, {
        audience: process.env.CLIENT_ID,
        issuer: `https://cognito-idp.${process.env.AWS_REGION}.amazonaws.com/${process.env.USER_POOL_ID}`,
        algorithms: ['RS256']
    });
}

function getSigningKey(kid) {
    return new Promise((resolve, reject) => {
        client.getSigningKey(kid, (err, key) => {
            if (err) {
                reject(err);
            } else {
                resolve(key.getPublicKey());
            }
        });
    });
}

function generatePolicy(principalId, effect, resource, decodedToken) {
    return {
        principalId,
        policyDocument: {
            Version: '2012-10-17',
            Statement: [
                {
                    Action: 'execute-api:Invoke',
                    Effect: effect,
                    Resource: resource
                }
            ]
        },
        context: {
            userId: principalId,
            email: decodedToken.email,
            groups: JSON.stringify(decodedToken['cognito:groups'] || []),
            tokenExpiry: decodedToken.exp.toString()
        }
    };
}

// Secure Lambda function implementation
exports.secureHandler = async (event, context) => {
    // Get context from API Gateway Authorizer
    const userId = event.requestContext?.authorizer?.userId;
    const userEmail = event.requestContext?.authorizer?.email;
    const userGroups = JSON.parse(event.requestContext?.authorizer?.groups || '[]');
    
    if (!userId) {
        return createApiResponse(401, { error: 'Unauthorized' });
    }
    
    try {
        // Request encryption verification
        const encryptedData = event.body;
        const decryptedData = await decryptRequestData(encryptedData);
        
        // User permission verification
        if (!hasRequiredPermissions(userGroups, 'READ_DATA')) {
            return createApiResponse(403, { error: 'Insufficient permissions' });
        }
        
        // Secure data processing
        const result = await processSecureData(decryptedData, userId);
        
        // Response encryption
        const encryptedResponse = await encryptResponseData(result);
        
        return createApiResponse(200, { data: encryptedResponse });
        
    } catch (error) {
        console.error('Security error:', error);
        return createApiResponse(500, { error: 'Security validation failed' });
    }
};

async function decryptRequestData(encryptedData) {
    const AWS = require('aws-sdk');
    const kms = new AWS.KMS();
    
    const decryptParams = {
        CiphertextBlob: Buffer.from(encryptedData, 'base64')
    };
    
    const result = await kms.decrypt(decryptParams).promise();
    return JSON.parse(result.Plaintext.toString());
}

function hasRequiredPermissions(userGroups, requiredPermission) {
    const permissionMap = {
        'admin': ['READ_DATA', 'WRITE_DATA', 'DELETE_DATA'],
        'editor': ['READ_DATA', 'WRITE_DATA'],
        'viewer': ['READ_DATA']
    };
    
    return userGroups.some(group => 
        permissionMap[group]?.includes(requiredPermission)
    );
}

Event-Driven Architecture

// EventBridge integrated event processing
const AWS = require('aws-sdk');
const eventbridge = new AWS.EventBridge();
const sns = new AWS.SNS();

exports.eventDrivenHandler = async (event, context) => {
    try {
        // Process custom EventBridge events
        if (event.source && event['detail-type']) {
            return await processCustomEvent(event);
        }
        
        // CloudWatch Events scheduled execution
        if (event.source === 'aws.events') {
            return await processScheduledEvent(event);
        }
        
        // Step Functions state change events
        if (event.source === 'aws.states') {
            return await processStepFunctionEvent(event);
        }
        
        return { message: 'Event processed successfully' };
        
    } catch (error) {
        console.error('Event processing error:', error);
        
        // Send error notification
        await sendErrorNotification(error, event);
        throw error;
    }
};

async function processCustomEvent(event) {
    console.log('Processing custom event:', event['detail-type']);
    console.log('Event source:', event.source);
    console.log('Event detail:', JSON.stringify(event.detail, null, 2));
    
    const eventType = event['detail-type'];
    const eventData = event.detail;
    
    switch (eventType) {
        case 'User Registration':
            return await handleUserRegistration(eventData);
        case 'Order Placed':
            return await handleOrderPlaced(eventData);
        case 'Payment Processed':
            return await handlePaymentProcessed(eventData);
        default:
            console.log(`Unhandled event type: ${eventType}`);
            return { processed: false, reason: 'Unknown event type' };
    }
}

async function handleUserRegistration(userData) {
    console.log('New user registration:', userData.userId);
    
    // Publish welcome email event
    await publishEvent('user.welcome-email', {
        userId: userData.userId,
        email: userData.email,
        registrationTimestamp: new Date().toISOString()
    });
    
    // Publish user profile setup event
    await publishEvent('user.profile-setup', {
        userId: userData.userId,
        defaultSettings: {
            notifications: true,
            newsletter: false
        }
    });
    
    return { processed: true, eventType: 'User Registration' };
}

async function handleOrderPlaced(orderData) {
    console.log('New order placed:', orderData.orderId);
    
    // Publish inventory check event
    await publishEvent('inventory.check', {
        orderId: orderData.orderId,
        items: orderData.items,
        requestedBy: orderData.customerId
    });
    
    // Publish payment processing event
    await publishEvent('payment.process', {
        orderId: orderData.orderId,
        amount: orderData.totalAmount,
        customerId: orderData.customerId,
        paymentMethod: orderData.paymentMethod
    });
    
    return { processed: true, eventType: 'Order Placed' };
}

async function publishEvent(eventType, eventData) {
    const params = {
        Entries: [
            {
                Source: 'my-application',
                DetailType: eventType,
                Detail: JSON.stringify(eventData),
                EventBusName: process.env.EVENT_BUS_NAME || 'default'
            }
        ]
    };
    
    const result = await eventbridge.putEvents(params).promise();
    console.log('Event published:', eventType, result.Entries[0].EventId);
}

async function processScheduledEvent(event) {
    console.log('Processing scheduled event');
    
    const ruleName = event.resources[0].split('/').pop();
    console.log('Triggered by rule:', ruleName);
    
    switch (ruleName) {
        case 'daily-backup':
            return await performDailyBackup();
        case 'weekly-report':
            return await generateWeeklyReport();
        case 'monthly-cleanup':
            return await performMonthlyCleanup();
        default:
            console.log(`Unknown scheduled rule: ${ruleName}`);
            return { processed: false };
    }
}

async function performDailyBackup() {
    console.log('Performing daily backup...');
    
    // Execute database backup
    const backupResult = await createDatabaseBackup();
    
    // Backup completion notification
    await publishEvent('backup.completed', {
        backupId: backupResult.backupId,
        timestamp: new Date().toISOString(),
        status: 'success'
    });
    
    return { 
        processed: true, 
        action: 'daily-backup',
        backupId: backupResult.backupId
    };
}

async function createDatabaseBackup() {
    // Implement actual backup logic
    const backupId = `backup-${Date.now()}`;
    console.log('Creating backup:', backupId);
    
    // Simulate backup process
    return { backupId, status: 'completed' };
}

async function sendErrorNotification(error, originalEvent) {
    const message = {
        error: error.message,
        stack: error.stack,
        originalEvent: originalEvent,
        timestamp: new Date().toISOString(),
        functionName: process.env.AWS_LAMBDA_FUNCTION_NAME
    };
    
    const params = {
        TopicArn: process.env.ERROR_NOTIFICATION_TOPIC_ARN,
        Subject: 'Lambda Function Error Alert',
        Message: JSON.stringify(message, null, 2)
    };
    
    if (process.env.ERROR_NOTIFICATION_TOPIC_ARN) {
        await sns.publish(params).promise();
        console.log('Error notification sent');
    }
}

Monitoring and Performance Optimization

// CloudWatch Metrics & X-Ray integrated monitoring
const AWS = require('aws-sdk');
const AWSXRay = require('aws-xray-sdk-core');
const aws = AWSXRay.captureAWS(AWS);

const cloudwatch = new aws.CloudWatch();

exports.monitoringHandler = async (event, context) => {
    const segment = AWSXRay.getSegment();
    const subsegment = segment.addNewSubsegment('business-logic');
    
    try {
        // Record custom metrics
        await recordCustomMetrics('FunctionInvocation', 1);
        
        // Start performance measurement
        const startTime = Date.now();
        
        // Execute main processing
        const result = await performBusinessLogic(event);
        
        // Record execution time
        const executionTime = Date.now() - startTime;
        await recordCustomMetrics('ExecutionTime', executionTime, 'Milliseconds');
        
        // Record success metrics
        await recordCustomMetrics('SuccessfulExecution', 1);
        
        // Add X-Ray annotations
        subsegment.addAnnotation('executionTime', executionTime);
        subsegment.addAnnotation('resultCount', result.items?.length || 0);
        subsegment.addMetadata('result', result);
        
        subsegment.close();
        
        return {
            statusCode: 200,
            body: JSON.stringify({
                result,
                metrics: {
                    executionTime,
                    timestamp: new Date().toISOString()
                }
            })
        };
        
    } catch (error) {
        // Record error metrics
        await recordCustomMetrics('ErrorCount', 1);
        await recordCustomMetrics('ErrorRate', 1);
        
        // Add X-Ray error information
        subsegment.addError(error);
        subsegment.close(error);
        
        console.error('Function error:', error);
        throw error;
    }
};

async function recordCustomMetrics(metricName, value, unit = 'Count') {
    const params = {
        Namespace: 'MyApplication/Lambda',
        MetricData: [
            {
                MetricName: metricName,
                Value: value,
                Unit: unit,
                Timestamp: new Date(),
                Dimensions: [
                    {
                        Name: 'FunctionName',
                        Value: process.env.AWS_LAMBDA_FUNCTION_NAME
                    },
                    {
                        Name: 'Environment',
                        Value: process.env.ENVIRONMENT || 'production'
                    }
                ]
            }
        ]
    };
    
    try {
        await cloudwatch.putMetricData(params).promise();
    } catch (error) {
        console.error('Failed to record metric:', error);
    }
}

async function performBusinessLogic(event) {
    // Detailed tracing with X-Ray subsegments
    const subsegment = AWSXRay.getSegment().addNewSubsegment('data-processing');
    
    try {
        // Database access tracing
        const dbSubsegment = subsegment.addNewSubsegment('database-query');
        const dbResults = await queryDatabase(event.query);
        dbSubsegment.addMetadata('queryResult', { count: dbResults.length });
        dbSubsegment.close();
        
        // External API call tracing
        const apiSubsegment = subsegment.addNewSubsegment('external-api');
        const apiResults = await callExternalAPI(event.apiParams);
        apiSubsegment.addMetadata('apiResponse', apiResults);
        apiSubsegment.close();
        
        // Data processing tracing
        const processSubsegment = subsegment.addNewSubsegment('data-transformation');
        const processedData = await processData(dbResults, apiResults);
        processSubsegment.addMetadata('processedItems', processedData.length);
        processSubsegment.close();
        
        subsegment.close();
        
        return {
            items: processedData,
            summary: {
                dbResultCount: dbResults.length,
                apiResultCount: apiResults.length,
                processedCount: processedData.length
            }
        };
        
    } catch (error) {
        subsegment.addError(error);
        subsegment.close(error);
        throw error;
    }
}

// Performance optimization implementation
exports.optimizedHandler = async (event, context) => {
    // Consistency with Provisioned Concurrency
    console.log('Function version:', context.functionVersion);
    console.log('Allocated memory:', context.memoryLimitInMB);
    
    // Dependency usage from Lambda Layers
    const sharedUtils = require('/opt/nodejs/shared-utils');
    
    // Connection pool reuse (during container reuse)
    if (!global.dbConnectionPool) {
        global.dbConnectionPool = await createDatabasePool();
        console.log('Database connection pool created');
    }
    
    // Environment variable cache utilization
    const config = {
        tableName: process.env.TABLE_NAME,
        region: process.env.AWS_REGION,
        maxRetries: parseInt(process.env.MAX_RETRIES) || 3
    };
    
    try {
        // Parallel execution optimization for async processing
        const [userData, configData, metricsData] = await Promise.all([
            fetchUserData(event.userId),
            fetchConfiguration(config.tableName),
            fetchMetrics(event.timeRange)
        ]);
        
        // CPU-bound processing optimization
        const processedResult = await optimizedDataProcessing(userData, configData);
        
        // Memory usage monitoring
        const memoryUsage = process.memoryUsage();
        console.log('Memory usage:', {
            heapUsed: Math.round(memoryUsage.heapUsed / 1024 / 1024) + ' MB',
            heapTotal: Math.round(memoryUsage.heapTotal / 1024 / 1024) + ' MB'
        });
        
        return {
            statusCode: 200,
            body: JSON.stringify({
                result: processedResult,
                performance: {
                    memoryUsage: memoryUsage,
                    timestamp: new Date().toISOString()
                }
            })
        };
        
    } catch (error) {
        console.error('Optimized handler error:', error);
        throw error;
    }
};

async function createDatabasePool() {
    // Database connection pool creation (container-level reuse)
    const pool = {
        connections: new Map(),
        maxConnections: 10,
        created: new Date().toISOString()
    };
    
    console.log('Database pool initialized');
    return pool;
}

async function optimizedDataProcessing(userData, configData) {
    // Efficient large data processing with streaming
    const results = [];
    const batchSize = 100;
    
    for (let i = 0; i < userData.length; i += batchSize) {
        const batch = userData.slice(i, i + batchSize);
        const batchResults = await processBatch(batch, configData);
        results.push(...batchResults);
        
        // Promote garbage collection
        if (i % 500 === 0) {
            global.gc && global.gc();
        }
    }
    
    return results;
}

async function processBatch(batch, config) {
    return batch.map(item => ({
        id: item.id,
        processed: true,
        timestamp: new Date().toISOString(),
        config: config.version
    }));
}

Deployment and Production Operations

# SAM Template (template.yaml)
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: 'AWS Lambda Serverless Application'

Globals:
  Function:
    Timeout: 30
    MemorySize: 1024
    Runtime: nodejs18.x
    Environment:
      Variables:
        ENVIRONMENT: !Ref Environment
        LOG_LEVEL: !Ref LogLevel

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues: [dev, staging, prod]
  LogLevel:
    Type: String
    Default: INFO
    AllowedValues: [DEBUG, INFO, WARN, ERROR]

Resources:
  # Lambda Function Definition
  MyLambdaFunction:
    Type: AWS::Serverless::Function
    Properties:
      FunctionName: !Sub 'my-lambda-${Environment}'
      CodeUri: src/
      Handler: index.handler
      Runtime: nodejs18.x
      MemorySize: 1024
      Timeout: 30
      ReservedConcurrencyLimit: 100
      ProvisionedConcurrencyConfig:
        ProvisionedConcurrencyScaling:
          ProvisionedConcurrencyManagement: Manual
          ProvisionedConcurrencyCount: 10
      Environment:
        Variables:
          TABLE_NAME: !Ref DynamoDBTable
          BUCKET_NAME: !Ref S3Bucket
      Events:
        ApiEvent:
          Type: Api
          Properties:
            Path: /api/{proxy+}
            Method: any
            RestApiId: !Ref MyApi
        ScheduleEvent:
          Type: Schedule
          Properties:
            Schedule: 'rate(5 minutes)'
            Input: '{"source": "scheduled"}'
      Policies:
        - DynamoDBCrudPolicy:
            TableName: !Ref DynamoDBTable
        - S3ReadPolicy:
            BucketName: !Ref S3Bucket
        - CloudWatchPutMetricPolicy: {}

  # API Gateway
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      Name: !Sub 'my-api-${Environment}'
      StageName: !Ref Environment
      TracingEnabled: true
      Cors:
        AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
        AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
        AllowOrigin: "'*'"
      Auth:
        DefaultAuthorizer: CognitoAuthorizer
        Authorizers:
          CognitoAuthorizer:
            UserPoolArn: !GetAtt CognitoUserPool.Arn

  # DynamoDB Table
  DynamoDBTable:
    Type: AWS::DynamoDB::Table
    Properties:
      TableName: !Sub 'my-table-${Environment}'
      BillingMode: PAY_PER_REQUEST
      AttributeDefinitions:
        - AttributeName: id
          AttributeType: S
      KeySchema:
        - AttributeName: id
          KeyType: HASH
      StreamSpecification:
        StreamViewType: NEW_AND_OLD_IMAGES
      PointInTimeRecoverySpecification:
        PointInTimeRecoveryEnabled: true

  # S3 Bucket
  S3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Sub 'my-bucket-${Environment}-${AWS::AccountId}'
      VersioningConfiguration:
        Status: Enabled
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        BlockPublicPolicy: true
        IgnorePublicAcls: true
        RestrictPublicBuckets: true

  # Cognito User Pool
  CognitoUserPool:
    Type: AWS::Cognito::UserPool
    Properties:
      UserPoolName: !Sub 'my-pool-${Environment}'
      AutoVerifiedAttributes:
        - email
      Policies:
        PasswordPolicy:
          MinimumLength: 8
          RequireUppercase: true
          RequireLowercase: true
          RequireNumbers: true
          RequireSymbols: true

Outputs:
  ApiEndpoint:
    Description: 'API Gateway endpoint URL'
    Value: !Sub 'https://${MyApi}.execute-api.${AWS::Region}.amazonaws.com/${Environment}'
  FunctionName:
    Description: 'Lambda Function Name'
    Value: !Ref MyLambdaFunction
  TableName:
    Description: 'DynamoDB Table Name'
    Value: !Ref DynamoDBTable
#!/bin/bash
# deploy.sh - Deployment script

set -e

ENVIRONMENT=${1:-dev}
REGION=${2:-us-east-1}
STACK_NAME="my-lambda-app-${ENVIRONMENT}"

echo "Deploying to environment: ${ENVIRONMENT}"
echo "Region: ${REGION}"
echo "Stack name: ${STACK_NAME}"

# SAM build
echo "Building SAM application..."
sam build --use-container

# SAM deploy
echo "Deploying SAM application..."
sam deploy \
    --stack-name ${STACK_NAME} \
    --region ${REGION} \
    --capabilities CAPABILITY_IAM \
    --parameter-overrides \
        Environment=${ENVIRONMENT} \
        LogLevel=INFO \
    --confirm-changeset \
    --resolve-s3

# Get CloudFormation stack outputs
echo "Getting stack outputs..."
aws cloudformation describe-stacks \
    --stack-name ${STACK_NAME} \
    --region ${REGION} \
    --query 'Stacks[0].Outputs'

# Test deployed function
echo "Testing deployed function..."
FUNCTION_NAME=$(aws cloudformation describe-stacks \
    --stack-name ${STACK_NAME} \
    --region ${REGION} \
    --query 'Stacks[0].Outputs[?OutputKey==`FunctionName`].OutputValue' \
    --output text)

aws lambda invoke \
    --function-name ${FUNCTION_NAME} \
    --region ${REGION} \
    --payload '{"test": true}' \
    response.json

echo "Deployment completed successfully!"
echo "Function response:"
cat response.json
# monitoring.sh - Monitoring and log verification
#!/bin/bash

FUNCTION_NAME=${1:-my-lambda-function}
ENVIRONMENT=${2:-dev}

echo "Monitoring Lambda function: ${FUNCTION_NAME}"

# Check CloudWatch Logs
echo "Fetching recent logs..."
aws logs describe-log-groups \
    --log-group-name-prefix "/aws/lambda/${FUNCTION_NAME}" \
    --query 'logGroups[0].logGroupName' \
    --output text | \
xargs -I {} aws logs tail {} --follow

# Check CloudWatch Metrics
echo "Fetching metrics..."
aws cloudwatch get-metric-statistics \
    --namespace AWS/Lambda \
    --metric-name Duration \
    --dimensions Name=FunctionName,Value=${FUNCTION_NAME} \
    --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
    --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
    --period 300 \
    --statistics Average,Maximum

# Check function configuration
echo "Function configuration:"
aws lambda get-function-configuration \
    --function-name ${FUNCTION_NAME} \
    --query '{
        Runtime: Runtime,
        MemorySize: MemorySize,
        Timeout: Timeout,
        LastModified: LastModified,
        Version: Version
    }'

echo "Monitoring complete!"