CloudFront Edge Auth (Functions vs Lambda@Edge)
AWS architecture template · CloudFront Functions cost 1/6th of Lambda@Edge for simple header manipulation, URL rewrites, and JWT validation at the edge. Lambda@Edge reserved for heavy compute.
CloudFront Edge Auth (Functions vs Lambda@Edge) is a free AWS architecture template built with CloudFront, IAM, Lambda, S3 and WAF. Open it in TheArchitect to edit the diagram, estimate monthly cost, and export the CloudFormation or Terraform that deploys it.
AWS services in this template
- CloudFront
- IAM
- Lambda
- S3
- WAF
Deployment notes
Needs input
- CloudFront Functions: free tier 2M invocations/month, then $0.10/million. Lambda@Edge: $0.60/million + compute.
- Use CloudFront Functions for: URL rewrites, header injection, simple JWT validation, A/B routing by cookie.
- Use Lambda@Edge only when you need: full Node.js runtime, external HTTP calls, >10ms compute, or response body manipulation.
- WAF association requires deploying WAF WebACL in us-east-1 regardless of distribution region.
Generated CloudFormation — 5 resources
| Logical ID | Resource type |
|---|---|
| WAFCLOUDFRONTwaf | AWS::WAFv2::WebACL |
| CloudFrontFunctionscloudfront | AWS::CloudFront::Distribution |
| LambdaEdgecomplexonlylambda | AWS::Lambda::Function |
| S3Origins3 | AWS::S3::Bucket |
| OriginAccessRoleiam | AWS::IAM::Role |
View the full CloudFormation template
{
"AWSTemplateFormatVersion": "2010-09-09",
"Description": "Generated by TheArchitect — https://www.thecloudarchitect.dev",
"Metadata": {
"TheArchitect": {
"Edges": [
{
"From": "WAFCLOUDFRONTwaf",
"To": "CloudFrontFunctionscloudfront",
"Label": "protect"
},
{
"From": "CloudFrontFunctionscloudfront",
"To": "S3Origins3",
"Label": "origin fetch"
},
{
"From": "OriginAccessRoleiam",
"To": "S3Origins3",
"Label": "OAC policy"
}
]
}
},
"Resources": {
"WAFCLOUDFRONTwaf": {
"Type": "AWS::WAFv2::WebACL",
"Properties": {
"Name": "cost-edge-waf",
"Scope": "CLOUDFRONT",
"DefaultAction": {
"Allow": {}
},
"VisibilityConfig": {
"CloudWatchMetricsEnabled": true,
"MetricName": "cost-edge-waf",
"SampledRequestsEnabled": true
},
"Description": "Edge WAF — IP rate limiting, geo blocking, SQLi/XSS managed rules"
}
},
"CloudFrontFunctionscloudfront": {
"Type": "AWS::CloudFront::Distribution",
"Properties": {
"DistributionConfig": {
"Enabled": true,
"Comment": "CloudFront with Functions for edge logic. Associate WAF WebACL for DDoS/bot protection.",
"DefaultRootObject": "index.html",
"PriceClass": "PriceClass_100",
"HttpVersion": "http2and3",
"DefaultCacheBehavior": {
"TargetOriginId": "S3Origin",
"ViewerProtocolPolicy": "redirect-to-https",
"CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6"
},
"ViewerCertificate": {
"CloudFrontDefaultCertificate": true
},
"Origins": [
{
"DomainName": {
"Fn::GetAtt": [
"S3Origins3",
"RegionalDomainName"
]
},
"Id": "S3Origin",
"S3OriginConfig": {
"OriginAccessIdentity": ""
}
}
]
}
}
},
"LambdaEdgecomplexonlylambda": {
"Type": "AWS::Lambda::Function",
"Properties": {
"FunctionName": "cost-edge-auth-complex",
"Runtime": "nodejs20.x",
"Handler": "index.handler",
"MemorySize": 128,
"Architectures": [
"arm64"
],
"Timeout": 5,
"Description": "Lambda@Edge — reserved for complex auth flows requiring external IdP calls or response body rewriting.",
"Environment": {
"Variables": {
"APP_ENV": "demo",
"LOG_LEVEL": "info"
}
},
"TracingConfig": {
"Mode": "Active"
},
"Code": {
"ZipFile": "exports.handler = async (event) => ({ statusCode: 200, body: JSON.stringify({ ok: true, requestId: event.requestContext?.requestId || 'demo' }) });"
}
}
},
"S3Origins3": {
"Type": "AWS::S3::Bucket",
"DependsOn": [
"OriginAccessRoleiam"
],
"Properties": {
"BucketName": "cost-edge-origin",
"OwnershipControls": {
"Rules": [
{
"ObjectOwnership": "BucketOwnerEnforced"
}
]
},
"BucketEncryption": {
"ServerSideEncryptionConfiguration": [
{
"ServerSideEncryptionByDefault": {
"SSEAlgorithm": "AES256"
}
}
]
},
"PublicAccessBlockConfiguration": {
"BlockPublicAcls": true,
"BlockPublicPolicy": true,
"IgnorePublicAcls": true,
"RestrictPublicBuckets": true
}
}
},
"OriginAccessRoleiam": {
"Type": "AWS::IAM::Role",
"Properties": {
"RoleName": "cost-edge-oac-role",
"Description": "OAC role — grants CloudFront s3:GetObject on origin bucket"
}
}
}
}Generated by TheArchitect from the diagram above. Review values such as names, CIDR ranges and instance sizes before deploying to your account.
Related templates
- Twitter/X Scale TestCloudFront behavior split, API Gateway VPC Link, public/internal ALBs, private app/data subnets, queues, media, and data stores
- Static Website (S3 + CloudFront + Route53)SAA-C03: S3 origin → CloudFront CDN → Route53 DNS alias. WAF edge protection, OAC enforces private bucket.
- Media Transcode PipelineS3 upload triggers a Lambda dispatcher that enqueues SQS jobs consumed by auto-scaled Fargate workers. Renditions are served via CloudFront.