Live
Integrating Software Carbon Intensity into OpenTelemetry: Practical Implications for Cloud‑Native TeamsGitHub Push Email Notifications Discontinued – Impact on Automation and MonitoringZero‑Day File‑Upload Flaw in BeyondTrust Remote Support: Patch and Detection GuidanceAnthropic integrates Opaque’s confidential AI stack – what engineers need to knowGateway Forward Action Brings In‑Line Workers to Zero Trust Plans (Public Beta)Running a 74‑B Agent Model on a Laptop: Nvidia’s Bolt Quantization and Its ImpactGemini agent brings a unified, persistent AI coworker to startup engineering stacksGitHub Copilot adds multi‑repo queries and conversation tweaks for Slack and Microsoft TeamsIntegrating Software Carbon Intensity into OpenTelemetry: Practical Implications for Cloud‑Native TeamsGitHub Push Email Notifications Discontinued – Impact on Automation and MonitoringZero‑Day File‑Upload Flaw in BeyondTrust Remote Support: Patch and Detection GuidanceAnthropic integrates Opaque’s confidential AI stack – what engineers need to knowGateway Forward Action Brings In‑Line Workers to Zero Trust Plans (Public Beta)Running a 74‑B Agent Model on a Laptop: Nvidia’s Bolt Quantization and Its ImpactGemini agent brings a unified, persistent AI coworker to startup engineering stacksGitHub Copilot adds multi‑repo queries and conversation tweaks for Slack and Microsoft Teams
AWS

AWS Lambda Complete Guide: Functions, Triggers and Deployment

Overview

AWS Lambda is a serverless compute service that lets you run code without provisioning or managing servers. This tutorial covers function creation, event-driven architecture, and deployment patterns you need for the AWS Solutions Architect Associate (SAA-C03) exam.

Prerequisites:

  • AWS account with appropriate IAM permissions
  • Python 3.9+ installed locally
  • AWS CLI configured with credentials
  • Basic understanding of Python and JSON
  • Familiarity with AWS IAM and IAM roles

Why This Matters for SAA-C03: Lambda is central to serverless architecture design. The exam tests your ability to design scalable, cost-effective solutions using Lambda with various AWS services like S3, DynamoDB, API Gateway, and CloudWatch.

Getting Started

Step 1: Install AWS CLI and Configure Credentials

# Verify AWS CLI installation
aws --version

# Configure credentials (you'll be prompted for Access Key ID and Secret Access Key)
aws configure

# Test your configuration
aws sts get-caller-identity

Step 2: Create Your First Lambda Function

# Create a project directory
mkdir lambda-tutorial
cd lambda-tutorial

# Create the function code
cat > lambda_function.py << 'EOF'
import json
import logging

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context):
    """
    Simple Lambda handler that processes S3 events
    event: AWS Lambda event object
    context: AWS Lambda context object
    """
    try:
        logger.info(f"Received event: {json.dumps(event)}")
        
        # Extract bucket and key from S3 event
        bucket = event['Records'][0]['s3']['bucket']['name']
        key = event['Records'][0]['s3']['object']['key']
        
        response = {
            'statusCode': 200,
            'body': json.dumps({
                'message': f'Processed {key} from {bucket}',
                'bucket': bucket,
                'key': key
            })
        }
        
        return response
        
    except Exception as e:
        logger.error(f"Error processing event: {str(e)}")
        return {
            'statusCode': 500,
            'body': json.dumps({'error': str(e)})
        }
EOF

Step 3: Package and Deploy

# Create deployment package
zip lambda_deployment.zip lambda_function.py

# Create IAM role for Lambda
aws iam create-role \
  --role-name lambda-execution-role \
  --assume-role-policy-document '{
    "Version": "2012-10-17",
    "Statement": [{
      "Effect": "Allow",
      "Principal": {"Service": "lambda.amazonaws.com"},
      "Action": "sts:AssumeRole"
    }]
  }'

# Attach basic execution policy
aws iam attach-role-policy \
  --role-name lambda-execution-role \
  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

# Wait for role to be available (important!)
sleep 10

# Deploy the function
aws lambda create-function \
  --function-name my-first-lambda \
  --runtime python3.11 \
  --role arn:aws:iam::ACCOUNT_ID:role/lambda-execution-role \
  --handler lambda_function.lambda_handler \
  --zip-file fileb://lambda_deployment.zip

Lambda Functions and Event Handling

Understanding the Lambda Handler: The handler is the entry point for Lambda execution. It receives two parameters: event (contains data from the trigger) and context (provides runtime information).

# Advanced handler with multiple event types
import json
import boto3
from datetime import datetime

s3_client = boto3.client('s3')
dynamodb = boto3.resource('dynamodb')

def lambda_handler(event, context):
    """
    Handle multiple AWS event sources
    """
    
    # Extract source from context
    request_id = context.request_id
    function_name = context.function_name
    remaining_time = context.get_remaining_time_in_millis()
    
    print(f"Function: {function_name}, Request ID: {request_id}")
    print(f"Remaining time: {remaining_time}ms")
    
    # Determine event source
    if 'Records' in event:
        if 's3' in event['Records'][0]:
            return handle_s3_event(event)
        elif 'dynamodb' in event['Records'][0]:
            return handle_dynamodb_stream(event)
        elif 'sns' in event['Records'][0]:
            return handle_sns_event(event)
    elif 'requestContext' in event:
        return handle_api_gateway_event(event)
    elif 'source' in event and event['source'] == 'aws.events':
        return handle_scheduled_event(event)
    
    return {'statusCode': 400, 'body': 'Unknown event source'}

def handle_s3_event(event):
    """Process S3 bucket events"""
    results = []
    for record in event['Records']:
        bucket = record['s3']['bucket']['name']
        key = record['s3']['object']['key']
        results.append({'bucket': bucket, 'key': key})
    return {'statusCode': 200, 'body': json.dumps(results)}

def handle_dynamodb_stream(event):
    """Process DynamoDB stream records"""
    for record in event['Records']:
        if record['eventName'] == 'INSERT':
            new_image = record['dynamodb']['NewImage']
            print(f"New item: {new_image}")
        elif record['eventName'] == 'MODIFY':
            old_image = record['dynamodb']['OldImage']
            new_image = record['dynamodb']['NewImage']
            print(f"Modified from {old_image} to {new_image}")
    return {'statusCode': 200, 'body': 'Stream processed'}

def handle_sns_event(event):
    """Process SNS notifications"""
    for record in event['Records']:
        message = record['Sns']['Message']
        print(f"SNS Message: {message}")
    return {'statusCode': 200, 'body': 'SNS processed'}

def handle_api_gateway_event(event):
    """Handle API Gateway requests"""
    method = event['httpMethod']
    path = event['path']
    body = json.loads(event.get('body', '{}'))
    return {
        'statusCode': 200,
        'headers': {'Content-Type': 'application/json'},
        'body': json.dumps({
            'method': method,
            'path': path,
            'received': body
        })
    }

def handle_scheduled_event(event):
    """Handle CloudWatch scheduled events"""
    print(f"Scheduled event triggered at {datetime.now()}")
    # Perform periodic tasks
    return {'statusCode': 200, 'body': 'Scheduled task completed'}

Triggers, Configuration, and Best Practices

Configuring Lambda Triggers: Triggers automatically invoke your Lambda function when specific events occur in AWS services.

# Configure S3 trigger using AWS CLI
aws lambda add-permission \
  --function-name my-first-lambda \
  --statement-id AllowS3Invoke \
  --action lambda:InvokeFunction \
  --principal s3.amazonaws.com \
  --source-arn arn:aws:s3:::my-bucket

# Add S3 bucket notification configuration
aws s3api put-bucket-notification-configuration \
  --bucket my-bucket \
  --notification-configuration '{
    "LambdaFunctionConfigurations": [{
      "LambdaFunctionArn": "arn:aws:lambda:us-east-1:ACCOUNT_ID:function:my-first-lambda",
      "Events": ["s3:ObjectCreated:*"],
      "Filter": {
        "Key": {"FilterRules": [{"Name": "prefix", "Value": "uploads/"}]}
      }
    }]
  }'

# Configure API Gateway trigger
aws apigateway create-rest-api \
  --name lambda-api \
  --description "API Gateway for Lambda"

# Set up CloudWatch scheduled event
aws events put-rule \
  --name lambda-daily-task \
  --schedule-expression "cron(0 2 * * ? *)" \
  --state ENABLED

aws events put-targets \
  --rule lambda-daily-task \
  --targets "Id"="1","Arn"="arn:aws:lambda:us-east-1:ACCOUNT_ID:function:my-first-lambda"

Production Best Practices:

# Best practices template
import os
import json
import logging
from functools import lru_cache
import boto3
from botocore.exceptions import ClientError

# Configure logging
logger = logging.getLogger()
logger.setLevel(os.getenv('LOG_LEVEL', 'INFO'))

# Cache AWS client initialization outside handler for reuse
@lru_cache(maxsize=None)
def get_s3_client():
    return boto3.client('s3')

def lambda_handler(event, context):
    """
    Production-ready Lambda handler
    - Uses environment variables
    - Implements error handling and retries
    - Includes proper logging
    - Manages timeouts
    """
    try:
        # Get environment variables
        bucket = os.environ.get('BUCKET_NAME')
        max_retries = int(os.environ.get('MAX_RETRIES', 3))
        
        # Check remaining execution time
        remaining_ms = context.get_remaining_time_in_millis()
        if remaining_ms < 5000:  # Less than 5 seconds remaining
            logger.warning('Insufficient time remaining for execution')
            return {'statusCode': 429, 'body': 'Insufficient execution time'}
        
        # Process event
        logger.info(f"Processing event with remaining time: {remaining_ms}ms")
        result = process_with_retry(event, bucket, max_retries)
        
        return {
            'statusCode': 200,
            'body': json.dumps({'message': 'Success', 'result': result})
        }
        
    except ClientError as e:
        logger.error(f"AWS error: {e.response['Error']['Code']} - {e.response['Error']['Message']}")
        return {'statusCode': 500, 'body': json.dumps({'error': 'AWS service error'})}
    except Exception as e:
        logger.error(f"Unexpected error: {str(e)}", exc_info=True)
        return {'statusCode': 500, 'body': json.dumps({'error': 'Internal server error'})}

def process_with_retry(event, bucket, max_retries):
    """Implement retry logic"""
    for attempt in range(max_retries):
        try:
            return perform_operation(event, bucket)
        except ClientError as e:
            if attempt == max_retries - 1:
                raise
            logger.warning(f"Attempt {attempt + 1} failed, retrying...")

def perform_operation(event, bucket):
    """Actual business logic"""
    s3 = get_s3_client()
    # Implementation here
    return {'processed': True}

Exam Tips for AWS Solutions Architect Associate (SAA-C03)

Key Lambda Concepts for the Exam:

  • Concurrency limits: Default concurrent execution limit is 1,000 per account per region. Reserved concurrency guarantees capacity for critical functions
  • Cold starts: First invocation takes longer (initialization). Provisioned concurrency keeps instances warm
  • Timeout settings: Maximum execution time is 15 minutes. Functions must return before timeout or they fail
  • Memory allocation: RAM ranges from 128MB to 10,240MB. CPU allocation scales with memory. More memory = better performance = higher cost
  • Event sources: Synchronous (API Gateway, ALB, CloudFront) vs asynchronous (S3, SNS, SQS, DynamoDB Streams)
  • Dead-letter queues (DLQ): Capture failed async invocations for later analysis

Common Exam Scenarios:

  1. Scenario: "Build a real-time image processing pipeline for uploaded images." Answer: S3 → Lambda trigger → process image → store result in S3/DynamoDB
  2. Scenario: "Scale a processing system with unpredictable traffic." Answer: Lambda with SQS for decoupling + reserved concurrency for predictable workload
  3. Scenario: "Run scheduled daily reports." Answer: CloudWatch Events rule on cron schedule → Lambda function
  4. Scenario: "Minimize cold start latency for critical APIs." Answer: Use provisioned concurrency or increase allocated memory

Summary

Key Takeaways:

  • Lambda is serverless compute perfect for event-driven architectures
  • Master multiple event sources: S3, API Gateway, DynamoDB Streams, SNS, SQS, CloudWatch Events
  • Always implement proper error handling, logging, and retry logic in production
  • Understand concurrency, timeouts, and memory allocation for cost optimization
  • Use IAM roles with least-privilege permissions for security
  • Cache AWS SDK clients outside the handler for performance

Next Steps:

  • Practice deploying functions with AWS SAM (Serverless Application Model) for infrastructure as code
  • Explore Lambda layers for code reuse and dependencies
  • Study Lambda integration with API Gateway for REST API development
  • Review the official AWS Lambda Developer Guide and exam guide for SAA-C03

For comprehensive SAA-C03 preparation, visit our AWS Solutions Architect Associate Certification Guide.