Chapter 3: Manually Creating and Configuring Lambda Functions
9/1/25About 4 min
Chapter 3: Manually Creating and Configuring Lambda Functions
Learning Objectives
- Create a Lambda function through the AWS console
- Configure basic function parameters and environment variables
- Set up function permissions and execution roles
- Test and debug Lambda functions
Knowledge Points
Steps to Create a Lambda Function
The complete process of creating a Lambda function includes the following main steps:
Comparison of Function Creation Methods
Creation Method | Use Case | Advantages | Disadvantages |
---|---|---|---|
Author from scratch | Custom requirements | Full control | Requires manual configuration of everything |
Use a blueprint | Common patterns | Quick start | Limited templates |
Container image | Complex dependencies | Flexible deployment | Complex image management |
Import from browser | Existing code | Quick migration | Requires meeting AWS application requirements |
Example Operations
1. Basic Function Configuration
Create a basic Python Lambda function through the AWS console:
import json
import logging
# Configure logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
"""
A basic Lambda function example
Args:
event: Input event data
context: Lambda runtime context
Returns:
dict: HTTP response format
"""
# Log event information
logger.info(f"Received event: {json.dumps(event)}")
# Extract parameters from the event
name = event.get('name', 'World')
message = event.get('message', 'Hello')
# Construct the response
response = {
'statusCode': 200,
'headers': {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*'
},
'body': json.dumps({
'greeting': f"{message}, {name}!",
'timestamp': context.aws_request_id,
'function_name': context.function_name,
'remaining_time': context.get_remaining_time_in_millis()
})
}
logger.info(f"Returning response: {response}")
return response
2. Environment Variable Configuration Example
import os
import json
import boto3
from botocore.exceptions import ClientError
def lambda_handler(event, context):
"""
Lambda function example using environment variables
"""
# Get configuration from environment variables
region = os.environ.get('AWS_REGION', 'us-east-1')
table_name = os.environ.get('DYNAMODB_TABLE', 'default-table')
debug_mode = os.environ.get('DEBUG', 'false').lower() == 'true'
api_key = os.environ.get('API_KEY')
# Validate required environment variables
if not api_key:
return {
'statusCode': 500,
'body': json.dumps({
'error': 'API_KEY environment variable not set'
})
}
# Use environment variables
if debug_mode:
print(f"Debug mode enabled")
print(f"Region: {region}")
print(f"Table: {table_name}")
try:
# Use DynamoDB
dynamodb = boto3.resource('dynamodb', region_name=region)
table = dynamodb.Table(table_name)
# Example operation
response = table.scan(Limit=1)
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Configuration loaded successfully',
'region': region,
'table': table_name,
'debug': debug_mode,
'items_count': response.get('Count', 0)
})
}
except ClientError as e:
return {
'statusCode': 500,
'body': json.dumps({
'error': f"DynamoDB error: {str(e)}"
})
}
3. IAM Execution Role Configuration
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "lambda.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:PutItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Scan",
"dynamodb:Query"
],
"Resource": "arn:aws:dynamodb:*:*:table/MyTable"
},
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::my-bucket/*"
}
]
}
4. Test Event Configuration
# API Gateway test event
api_gateway_test_event = {
"httpMethod": "POST",
"path": "/hello",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer test-token"
},
"queryStringParameters": {
"name": "Alice"
},
"body": json.dumps({
"message": "Hello",
"timestamp": "2024-01-01T00:00:00Z"
}),
"requestContext": {
"requestId": "test-request-id",
"stage": "test",
"httpMethod": "POST",
"path": "/hello"
}
}
# S3 event test event
s3_test_event = {
"Records": [
{
"eventSource": "aws:s3",
"eventName": "ObjectCreated:Put",
"eventVersion": "2.1",
"eventTime": "2024-01-01T00:00:00.000Z",
"s3": {
"bucket": {
"name": "my-test-bucket",
"arn": "arn:aws:s3:::my-test-bucket"
},
"object": {
"key": "uploads/test-file.jpg",
"size": 1024,
"etag": "test-etag"
}
}
}
]
}
def lambda_handler(event, context):
"""
Lambda function that handles multiple event types
"""
# Determine the event type
if 'httpMethod' in event:
# API Gateway event
return handle_api_request(event, context)
elif 'Records' in event and event['Records']:
# S3 or other service event
return handle_record_event(event, context)
else:
# Custom event
return handle_custom_event(event, context)
def handle_api_request(event, context):
"""Handle an API Gateway request"""
method = event['httpMethod']
path = event['path']
return {
'statusCode': 200,
'body': json.dumps({
'message': f'Handled {method} request to {path}',
'requestId': context.aws_request_id
})
}
def handle_record_event(event, context):
"""Handle a Records event"""
processed_records = []
for record in event['Records']:
source = record.get('eventSource', 'unknown')
processed_records.append({
'source': source,
'eventName': record.get('eventName', 'unknown')
})
return {
'statusCode': 200,
'body': json.dumps({
'message': f'Processed {len(processed_records)} records',
'records': processed_records
})
}
def handle_custom_event(event, context):
"""Handle a custom event"""
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Handled custom event',
'event': event
})
}
Function Configuration Details
Basic Configuration Options
Memory and Performance Configuration
Memory (MB) | CPU Power | Use Case | Cost Impact |
---|---|---|---|
128-512 | Low | Simple APIs, text processing | Lowest cost |
512-1024 | Medium | Data processing, API calls | Balanced cost-performance |
1024-3008 | High | Image processing, complex computations | High-performance needs |
3008-10240 | Very High | Machine learning, big data | Highest cost |
Configuration Recommendations
- Memory Configuration: Adjust based on actual needs; too high wastes money, too low affects performance
- Timeout Setting: Recommended under 30 seconds for API functions, can be set longer for batch processing
- Environment Variables: Use KMS to encrypt sensitive information, avoid hard-coding
- Execution Role: Follow the principle of least privilege, grant only necessary permissions
Debugging and Monitoring
import json
import logging
import time
from datetime import datetime
# Configure structured logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def lambda_handler(event, context):
"""
Lambda function with detailed monitoring and debugging information
"""
start_time = time.time()
# Log the start of the request
logger.info({
'event': 'function_start',
'request_id': context.aws_request_id,
'function_name': context.function_name,
'memory_limit': context.memory_limit_in_mb,
'remaining_time': context.get_remaining_time_in_millis()
})
try:
# Process business logic
result = process_business_logic(event, context)
# Log success
processing_time = (time.time() - start_time) * 1000
logger.info({
'event': 'function_success',
'processing_time_ms': processing_time,
'request_id': context.aws_request_id
})
return result
except Exception as e:
# Log an error
processing_time = (time.time() - start_time) * 1000
logger.error({
'event': 'function_error',
'error_type': type(e).__name__,
'error_message': str(e),
'processing_time_ms': processing_time,
'request_id': context.aws_request_id
})
return {
'statusCode': 500,
'body': json.dumps({
'error': 'Internal server error',
'requestId': context.aws_request_id
})
}
def process_business_logic(event, context):
"""
Simulate business logic processing
"""
# Add business metrics
logger.info({
'event': 'business_logic_start',
'input_size': len(json.dumps(event))
})
# Simulate processing time
time.sleep(0.1)
return {
'statusCode': 200,
'body': json.dumps({
'message': 'Success',
'timestamp': datetime.utcnow().isoformat(),
'processed_at': context.aws_request_id
})
}
Common Issues
- Permission Errors: Ensure the execution role has permission to access the required resources
- Timeout Issues: Check the function execution time and adjust the timeout setting accordingly
- Insufficient Memory: Monitor memory usage and adjust the allocation as needed
- Dependency Issues: Ensure all dependency packages are correctly packaged and uploaded
Debugging Tips
- Use CloudWatch Logs to view detailed logs
- Use AWS X-Ray for distributed tracing
- Use SAM for local function testing
- Use test events to validate different scenarios