Created
January 5, 2022 13:40
-
-
Save reinhrst/c4c726407c70a1c7a0c493b407428520 to your computer and use it in GitHub Desktop.
CloudFormation stack for website with react-routing and api-reverse-proxy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
AWSTemplateFormatVersion: 2010-09-09 | |
Description: Creates an https website | |
Metadata: {} | |
Parameters: | |
HostedZoneName: | |
Description: The HostedZoneName of the zone that you want to host the website on. This has to be in the same account, and has to be active (i.e. used as the DNS server for this domain). | |
Type: String | |
HostedZoneId: | |
Description: The ID for the HostedZoneName | |
Type: String | |
Hostname: | |
Description: The hostname to host the website on (in the HostedZoneId). This should not exist yet within the HostedZoneId. | |
Type: String | |
AllowedPattern: ^[a-z0-9][a-z0-9-]*$ | |
Default: www | |
PriceClass: | |
Type: String | |
Description: The CloudFront distribution price class | |
AllowedValues: | |
- 'PriceClass_100' | |
- 'PriceClass_200' | |
- 'PriceClass_All' | |
Mappings: {} | |
Conditions: {} | |
Resources: | |
Certificate: | |
Type: AWS::CertificateManager::Certificate | |
Properties: | |
DomainName: !Sub "${Hostname}.${HostedZoneName}" | |
DomainValidationOptions: | |
- DomainName: !Sub "${Hostname}.${HostedZoneName}" | |
HostedZoneId: !Ref HostedZoneId | |
ValidationMethod: DNS | |
Bucket: | |
Type: AWS::S3::Bucket | |
DeletionPolicy: Retain | |
Properties: | |
AccessControl: Private | |
BucketEncryption: | |
ServerSideEncryptionConfiguration: | |
- ServerSideEncryptionByDefault: | |
SSEAlgorithm: AES256 | |
BucketName: !Sub "${Hostname}.${HostedZoneName}" | |
PublicAccessBlockConfiguration: | |
BlockPublicAcls: true | |
BlockPublicPolicy: true | |
IgnorePublicAcls: true | |
RestrictPublicBuckets: true | |
VersioningConfiguration: | |
Status: Enabled | |
BucketPolicy: | |
Type: AWS::S3::BucketPolicy | |
Properties: | |
Bucket: !Ref Bucket | |
PolicyDocument: | |
Statement: | |
- Action: | |
- s3:GetObject | |
Effect: Allow | |
Resource: !Sub "arn:aws:s3:::${Bucket}/website/*" | |
Principal: | |
CanonicalUser: !GetAtt CloudFrontOriginAccessIdentity.S3CanonicalUserId | |
ApiSourceOriginRequestPolicy: | |
Type: AWS::CloudFront::OriginRequestPolicy | |
Properties: | |
OriginRequestPolicyConfig: | |
Name: ApiSourceOriginRequestPolicy | |
CookiesConfig: | |
CookieBehavior: none | |
QueryStringsConfig: | |
QueryStringBehavior: all | |
HeadersConfig: | |
HeaderBehavior: none | |
ApiSourceCachePolicy: | |
Type: AWS::CloudFront::CachePolicy | |
Properties: | |
CachePolicyConfig: | |
DefaultTTL: 0 | |
MinTTL: 0 | |
MaxTTL: 1 | |
Name: ApiSourceCachePolicy | |
ParametersInCacheKeyAndForwardedToOrigin: | |
EnableAcceptEncodingGzip: true | |
EnableAcceptEncodingBrotli: true | |
CookiesConfig: | |
CookieBehavior: none | |
QueryStringsConfig: | |
QueryStringBehavior: all | |
HeadersConfig: | |
HeaderBehavior: whitelist | |
Headers: | |
- Authorization | |
- Accept | |
- Content-Type | |
RoutingRedirectFunction: | |
Type: AWS::CloudFront::Function | |
Properties: | |
AutoPublish: true | |
FunctionCode: | | |
function handler(event) { | |
var request = event.request; | |
if (request.uri === "/OAuthResponse" | |
|| request.uri.startsWith("/division/")) { | |
request.uri = "/index.html" | |
} | |
return request; | |
} | |
FunctionConfig: | |
Comment: Redirects the paths used by the React Router | |
Runtime: cloudfront-js-1.0 | |
Name: RoutingRedirectFunction | |
CloudFrontDistribution: | |
Type: AWS::CloudFront::Distribution | |
Properties: | |
DistributionConfig: | |
Aliases: | |
- !Sub "${Hostname}.${HostedZoneName}" | |
DefaultCacheBehavior: | |
CachePolicyId: 4135ea2d-6df8-44a3-9df3-4b5a84be39ad # caching disabled | |
Compress: true | |
ForwardedValues: | |
QueryString: false | |
FunctionAssociations: | |
- EventType: viewer-request | |
FunctionARN: | |
!GetAtt RoutingRedirectFunction.FunctionMetadata.FunctionARN | |
TargetOriginId: !Sub "S3-${Hostname}.${HostedZoneName}" | |
ViewerProtocolPolicy: redirect-to-https | |
CacheBehaviors: | |
- AllowedMethods: [GET, HEAD, OPTIONS, PUT, PATCH, POST, DELETE] | |
CachePolicyId: !Ref ApiSourceCachePolicy | |
Compress: true | |
OriginRequestPolicyId: !Ref ApiSourceOriginRequestPolicy | |
PathPattern: /api/v1/* | |
TargetOriginId: apisource | |
ViewerProtocolPolicy: https-only | |
- AllowedMethods: [GET, HEAD, OPTIONS, PUT, PATCH, POST, DELETE] | |
CachePolicyId: !Ref ApiSourceCachePolicy | |
Compress: true | |
OriginRequestPolicyId: !Ref ApiSourceOriginRequestPolicy | |
PathPattern: /legacyApi/ | |
TargetOriginId: apisource | |
ViewerProtocolPolicy: https-only | |
- AllowedMethods: [GET, HEAD, OPTIONS, PUT, PATCH, POST, DELETE] | |
CachePolicyId: !Ref ApiSourceCachePolicy | |
Compress: true | |
OriginRequestPolicyId: !Ref ApiSourceOriginRequestPolicy | |
PathPattern: /legacyApi2/ | |
TargetOriginId: apisource | |
ViewerProtocolPolicy: https-only | |
DefaultRootObject: index.html | |
Enabled: true | |
HttpVersion: http2 | |
Origins: | |
- DomainName: !Sub "${Bucket}.s3.amazonaws.com" | |
OriginPath: /website | |
Id: !Sub "S3-${Hostname}.${HostedZoneName}" | |
S3OriginConfig: | |
OriginAccessIdentity: | |
!Sub "origin-access-identity/cloudfront/${CloudFrontOriginAccessIdentity}" | |
- DomainName: api.apisource.org | |
Id: apisource | |
OriginPath: "" | |
CustomOriginConfig: | |
OriginProtocolPolicy: match-viewer | |
Logging: | |
Bucket: !Sub "${Bucket}.s3.amazonaws.com" | |
IncludeCookies: False | |
Prefix: cloudfront-logs/ | |
PriceClass: !Ref PriceClass | |
ViewerCertificate: | |
AcmCertificateArn: !Ref Certificate | |
MinimumProtocolVersion: TLSv1 | |
SslSupportMethod: sni-only | |
Tags: | |
- Key: Domain | |
Value: !Sub "${Hostname}.${HostedZoneName}" | |
CloudFrontOriginAccessIdentity: | |
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity | |
Properties: | |
CloudFrontOriginAccessIdentityConfig: | |
Comment: !Sub 'CloudFront OAI for ${Hostname}.${HostedZoneName}' | |
DNSEntry: | |
Type: AWS::Route53::RecordSet | |
Properties: | |
Name: !Sub "${Hostname}.${HostedZoneName}." | |
Type: A | |
AliasTarget: | |
DNSName: !GetAtt CloudFrontDistribution.DomainName | |
HostedZoneId: Z2FDTNDATAQYW2 # hardcoded CloudFront zone id | |
HostedZoneName: !Sub "${HostedZoneName}." | |
Outputs: | |
{} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment