Skip to content

Instantly share code, notes, and snippets.

@natac13
Created July 23, 2020 13:04
Show Gist options
  • Save natac13/062a979b5133ecbcd3c513231661d970 to your computer and use it in GitHub Desktop.
Save natac13/062a979b5133ecbcd3c513231661d970 to your computer and use it in GitHub Desktop.
S3 301 redirect with headers set on metadata
AWSTemplateFormatVersion: "2010-09-09"
Description: "Static Website: server-side redirects with headers set on files found."
Metadata:
"AWS::CloudFormation::Interface":
ParameterGroups:
- Label:
default: "Required Parameters"
Parameters:
- DomainName
- Label:
default: "Operational Parameters"
Parameters:
- LogsRetentionInDays
Parameters:
DomainName:
Description: "The domain name of the website"
Type: String
LogsRetentionInDays:
Description: "Number of days to retain log events in the specified log group."
Type: Number
Default: 14
AllowedValues:
[
1,
3,
5,
7,
14,
30,
60,
90,
120,
150,
180,
365,
400,
545,
731,
1827,
3653,
]
Resources:
OriginResponseRole:
Type: "AWS::IAM::Role"
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
- Effect: Allow
Principal:
Service:
- "lambda.amazonaws.com"
- "edgelambda.amazonaws.com" # default @edge policies for lambda
Action: "sts:AssumeRole"
OriginResponseLambdaPolicy:
Type: "AWS::IAM::Policy"
Properties:
PolicyDocument:
Statement:
- Effect: Allow
Action:
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: !GetAtt "OriginResponseLogGroup.Arn"
PolicyName: lambda
Roles:
- !Ref OriginResponseRole
OriginResponseLambdaEdgePolicy:
Type: "AWS::IAM::Policy"
Properties:
PolicyDocument:
Statement:
- Effect: Allow
Action: "logs:CreateLogGroup"
Resource: !Sub "arn:${AWS::Partition}:logs:*:${AWS::AccountId}:log-group:/aws/lambda/us-east-1.${OriginResponseFunction}:log-stream:"
- Effect: Allow
Action:
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: !Sub "arn:${AWS::Partition}:logs:*:${AWS::AccountId}:log-group:/aws/lambda/us-east-1.${OriginResponseFunction}:log-stream:*"
PolicyName: "lambda-edge"
Roles:
- !Ref OriginResponseRole
OriginResponseFunction:
Type: "AWS::Lambda::Function"
Properties:
Code:
# If you change the ZipFile, rename the logical id OriginResponseVersionVX to trigger a new version creation!
ZipFile: !Sub |
const domainName = '${DomainName}'.toLowerCase();
exports.handler = async (event) => {
var response = event.Records[0].cf.response;
const headers = response.headers;
if (headers['x-amz-website-redirect-location']) {
let redirectURI = headers['x-amz-website-redirect-location'][0].value;
if (redirectURI.startsWith('/')) {
redirectURI = 'https://' + domainName + redirectURI;
}
response = {
status: '302',
statusDescription: 'Found',
headers: {
'location': [{
key: 'Location',
value: redirectURI,
}],
'cache-control': [{
key: 'Cache-Control',
value: 'public, max-age=300, s-maxage=3600'
}]
}
}
}
return response;
}
Handler: "index.handler"
MemorySize: 128
Role: !GetAtt "OriginResponseRole.Arn"
Runtime: "nodejs12.x"
Timeout: 5
OriginResponseVersionV4:
Type: "AWS::Lambda::Version"
Properties:
FunctionName: !Ref OriginResponseFunction
OriginResponseLogGroup:
Type: "AWS::Logs::LogGroup"
Properties:
LogGroupName: !Sub "/aws/lambda/${OriginResponseFunction}"
RetentionInDays: !Ref LogsRetentionInDays
Outputs:
StackName:
Description: "Stack name."
Value: !Sub "${AWS::StackName}"
OriginResponseLambdaEdgeFunctionVersionARN:
Description: "Version ARN of Lambda@Edge viewer request function."
Value: !Ref OriginResponseVersionV4
const domainName = '${DomainName}'.toLowerCase();
exports.handler = async (event) => {
var response = event.Records[0].cf.response;
const headers = response.headers;
if (headers['x-amz-website-redirect-location']) {
let redirectURI = headers['x-amz-website-redirect-location'][0].value;
if (redirectURI.startsWith('/')) {
redirectURI = 'https://' + domainName + redirectURI;
}
response = {
status: '302',
statusDescription: 'Found',
headers: {
'location': [{
key: 'Location',
value: redirectURI,
}],
'cache-control': [{
key: 'Cache-Control',
value: 'public, max-age=300, s-maxage=3600'
}]
}
}
}
return response;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment