Full-stack implementation of a dynamic global serverless API hosted on AWS Lambda.
Check it out at https://headers.owen.dev
- Cloudformation code defining:
- Code for the Lambda Function
Our cloudfront distribution defines one cache behavior:
- It accepts GET and HEAD requests
- Requests are cached based on the values of these headers:
- CloudFront-Viewer-City
- CloudFront-Viewer-Country
- CloudFront-Viewer-Country-Name
- CloudFront-Viewer-Country-Region
- CloudFront-Viewer-Country-Region-Name
- CloudFront-Viewer-Latitude
- CloudFront-Viewer-Longitude
- CloudFront-Viewer-Metro-Code
- CloudFront-Viewer-Postal-Code
- CloudFront-Viewer-Time-Zone
- Responses are cached for up to 1 day.
- All of the above headers are also forwarded to the origin.
Distro:
Type: AWS::CloudFront::Distribution
Properties:
...
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
TargetOriginId: 1
ViewerProtocolPolicy: redirect-to-https
MinTTL: 0
MaxTTL: 86400
DefaultTTL: 86400
ForwardedValues:
Headers:
- CloudFront-Viewer-City
- CloudFront-Viewer-Country
- CloudFront-Viewer-Country-Name
- CloudFront-Viewer-Country-Region
- CloudFront-Viewer-Country-Region-Name
- CloudFront-Viewer-Latitude
- CloudFront-Viewer-Longitude
- CloudFront-Viewer-Metro-Code
- CloudFront-Viewer-Postal-Code
- CloudFront-Viewer-Time-Zone
QueryString: False
We define one Origin that points to our APIGateway resource.
Distro:
Type: AWS::CloudFront::Distribution
Properties:
...
Origins:
-
CustomOriginConfig:
HTTPSPort: 443
OriginKeepaliveTimeout: 1
OriginProtocolPolicy: https-only
OriginSSLProtocols:
- TLSv1.2
DomainName: !Sub
- '${APIResourceID}.execute-api.${AWS::Region}.amazonaws.com'
-
APIResourceID: !GetAtt API.RootResourceId
Id: 1
OriginPath: /Prod
PriceClass: PriceClass_100
The Lambda and APIGateway is pretty straightforward. You can find reference material to these Serverless resources here.
ReturnHeadersFunction:
Type: AWS::Serverless::Function
Properties:
FunctionName: list-headers
CodeUri: dist/
Handler: handler.handler
Runtime: python3.8
Timeout: 29
AutoPublishAlias: live
DeploymentPreference:
#Change to Canary10Percent5Minutes after developemnt
Type: AllAtOnce
MemorySize: 128
Events:
APIGateway:
Type: Api
Properties:
Path: /
Method: GET
RestApiId: !Ref API
API:
Type: AWS::Serverless::Api
Properties:
Cors: "'headers.owen.dev'"
StageName: Prod
You'll want to update references to headers.owen.dev
to point to your own domain, or just not use a custom domain at all.
You'll also need to remove references to my personal site in the Lambda source code.
Update the deployment code to remove references to the S3 Bucket in my account.
This project can be enhanced by:
- Use the new Cloudformation cache support, which does not have cloudformation support at this time.
- Add DNS support for APIGateway, update the deployment code to allow for deploying to each AWS region.