S3, Lambda & IAM Patterns
S3 — Key Operations (AWS CLI)
# Create / manage buckets
aws s3 mb s3://my-bucket
aws s3 rb s3://my-bucket --force
# Copy / sync
aws s3 cp ./dist s3://my-bucket/dist/ --recursive
aws s3 cp s3://my-bucket/file.txt ./local/
aws s3 sync ./dist s3://my-bucket/ --delete # delete files not in source
aws s3 sync s3://src-bucket s3://dst-bucket # bucket-to-bucket
# List / delete
aws s3 ls s3://my-bucket/
aws s3 rm s3://my-bucket/old-file.txt
aws s3 rm s3://my-bucket/logs/ --recursive
# Presigned URL (temporary access)
aws s3 presign s3://my-bucket/private-file.pdf --expires-in 3600
# Set public static website hosting
aws s3 website s3://my-bucket/ --index-document index.html --error-document error.html
# S3 bucket policy (public read)
{
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow", "Principal": "*", "Action": "s3:GetObject", "Resource": "arn:aws:s3:::my-bucket/*"}]
}Lambda
// Lambda handler (Node.js)
export const handler = async (event, context) => {
console.log('Event:', JSON.stringify(event, null, 2));
// API Gateway event
const { httpMethod, path, queryStringParameters, body } = event;
const data = body ? JSON.parse(body) : null;
// S3 event
const bucket = event.Records[0].s3.bucket.name;
const key = decodeURIComponent(event.Records[0].s3.object.key);
// SQS event
for (const record of event.Records) {
const message = JSON.parse(record.body);
await processMessage(message);
}
return {
statusCode: 200,
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message: 'Success' }),
};
};
// Environment variables
const db = process.env.DATABASE_URL;
// AWS SDK v3
import { S3Client, GetObjectCommand } from '@aws-sdk/client-s3';
const s3 = new S3Client({ region: 'us-east-1' });
const obj = await s3.send(new GetObjectCommand({ Bucket: 'my-bucket', Key: 'file.txt' }));IAM — Roles & Policies
// IAM Policy — allow Lambda to read S3 and write CloudWatch Logs
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
}
]
}
// Trust policy — who can assume this role
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": { "Service": "lambda.amazonaws.com" },
"Action": "sts:AssumeRole"
}]
}Cost Optimization Tips
Use Reserved Instances or Savings Plans for predictable workloads (up to 72% off On-Demand)
Use Spot Instances for fault-tolerant batch workloads (up to 90% off)
S3 lifecycle policies — move old data to S3-IA or Glacier
Enable S3 Intelligent-Tiering for unpredictable access patterns
CloudFront reduces S3 data transfer costs (CloudFront egress is cheaper)
Right-size EC2 instances using AWS Compute Optimizer recommendations
Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free