Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pdehlke/2f1710c300b0cc0e8e66c8f02db47e55 to your computer and use it in GitHub Desktop.
Save pdehlke/2f1710c300b0cc0e8e66c8f02db47e55 to your computer and use it in GitHub Desktop.
AWSTemplateFormatVersion: '2010-09-09'
Description: <Your description>
Parameters:
Domain:
Type: String
Default: <default domain URI>
AllowedValues:
- <list of allowed domain URIs>
Description: <description>
Mappings:
DomainProperties:
aptible.com:
RoleComponent: production
BaseReportUri: <report URI>
aptible-staging-uri.com:
RoleComponent: staging
BaseReportUri: <report URI>
Resources:
CloudFrontDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
DefaultCacheBehavior:
LambdaFunctionAssociations:
- EventType: viewer-response
LambdaFunctionARN:
!Ref SecureHeadersLambdaFunctionWithVersion
SecureHeadersSourceCode:
Type: AWS::CloudFormation::CustomResource
Properties:
ServiceToken: !GetAtt LambdaIdentity.Arn
Code: !Sub
- |
'use strict';
exports.handler = (event, context, callback) => {
const response = event.Records[0].cf.response;
const headers = response.headers;
headers['strict-transport-security'] = [{
key: 'Strict-Transport-Security',
value: 'max-age=31536000'
}];
headers['x-frame-options'] = [{
key: 'X-Frame-Options',
value: 'DENY'
}];
headers['x-xss-protection'] = [{
key: 'X-XSS-Protection',
value: '1; report-uri=${BaseReportUri}/xss/enforce'
}];
headers['x-content-type-options'] = [{
key: 'X-Content-Type-Options',
value: 'nosniff'
}];
headers['referrer-policy'] = [{
key: 'Referrer-Policy',
value: 'strict-origin'
}];
headers['expect-ct'] = [{
key: 'Expect-CT',
value: 'max-age=3600; report-uri=${BaseReportUri}/ct/reportOnly'
}];
callback(null, response);
};
- BaseReportUri: !FindInMap
- DomainProperties
- !Ref Domain
- BaseReportUri
SecureHeadersLambdaFunction:
Type: AWS::Lambda::Function
Properties:
Handler: index.handler
Role: !GetAtt LambdaExecutionRole.Arn
Code:
ZipFile: !GetAtt SecureHeadersSourceCode.Code
Runtime: nodejs6.10
LambdaExecutionRole:
Type: AWS::IAM::Role
Properties:
Path: /service-role/
RoleName: !Join
- "-"
- - !Ref Subdomain
- !FindInMap
- DomainProperties
- !Ref Domain
- RoleComponent
- SecureHeadersExecutionRole
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- edgelambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
SecureHeadersLambdaFunctionWithVersion:
Type: AWS::CloudFormation::CustomResource
Properties:
ServiceToken: !GetAtt LambdaVersioner.Arn
FunctionName:
!Ref SecureHeadersLambdaFunction
Code:
!GetAtt SecureHeadersSourceCode.Code
DependsOn: SecureHeadersLambdaFunction
LambdaVersioner:
Type: AWS::Lambda::Function
Properties:
Role: !GetAtt LambdaVersionerExecutionRole.Arn
Code:
ZipFile: !Sub |
var AWS = require('aws-sdk');
var response = require('cfn-response');
exports.handler = (event, context) => {
console.log("Request received:\n", JSON.stringify(event));
if (event.RequestType == 'Delete') {
return response.send(event, context, response.SUCCESS);
}
var lambda = new AWS.Lambda();
lambda.publishVersion({ FunctionName: event.ResourceProperties.FunctionName }).promise().then((data) => {
return response.send(event, context, response.SUCCESS, { Version: data.Version }, data.FunctionArn);
}).catch((e) => {
return response.send(event, context, response.FAILED, e);
});
};
Handler: index.handler
Runtime: nodejs6.10
Timeout: 30
LambdaVersionerExecutionRole:
Type: AWS::IAM::Role
Properties:
Path: /
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: PublishVersion
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ['lambda:PublishVersion']
Resource: '*'
LambdaIdentity:
Type: AWS::Lambda::Function
Properties:
Role: !GetAtt LambdaIdentityExecutionRole.Arn
Code:
ZipFile: >
var r = require('cfn-response');
exports.handler = function(ev, ctx) {
r.send(ev, ctx, r.SUCCESS, ev.ResourceProperties);
};
Handler: index.handler
Runtime: nodejs6.10
Timeout: 30
LambdaIdentityExecutionRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment