-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathreact-cors-spa-stack.yaml
176 lines (164 loc) · 5.77 KB
/
react-cors-spa-stack.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
AWSTemplateFormatVersion: '2010-09-09'
Description: >
Creates the infrastructure to host and expose a Single Page Application:
- An Amazon S3 bucket for hosting the application
- An Amazon CloudFront distribution to expose the application
- An Amazon S3 bucket for hosting bucket and cloudfront access logs
- A public API to be used by the application to demonstrate CORS configuration
Parameters: {}
Resources:
# Our simple CORS compliant REST API
SimpleAPI:
Type: 'AWS::ApiGateway::RestApi'
Properties:
Description: A simple CORS compliant API
Name: SimpleAPI
EndpointConfiguration:
Types:
- REGIONAL
# The Resource (/hello) of our API
SimpleAPIResource:
Type: 'AWS::ApiGateway::Resource'
Properties:
ParentId: !GetAtt
- SimpleAPI
- RootResourceId
PathPart: hello
RestApiId: !Ref SimpleAPI
# The method to call (GET) for our API
HelloAPIGETMethod:
Type: 'AWS::ApiGateway::Method'
#checkov:skip=CKV_AWS_59: "This API does not expose backend service"
Properties:
ApiKeyRequired: false
AuthorizationType: NONE
HttpMethod: GET
Integration:
Type: MOCK
PassthroughBehavior: WHEN_NO_MATCH
RequestTemplates:
application/json: "{\n \"statusCode\": 200\n}"
IntegrationResponses:
- StatusCode: 200
SelectionPattern: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: '''*'''
ResponseTemplates:
application/json: "{\"message\": \"Hello World!\"}"
MethodResponses:
- StatusCode: 200
ResponseParameters:
method.response.header.Access-Control-Allow-Origin: true
ResponseModels:
application/json: Empty
RestApiId: !Ref SimpleAPI
ResourceId: !Ref SimpleAPIResource
# A deployment resource for deploying our API
Deployment:
Type: 'AWS::ApiGateway::Deployment'
DependsOn:
- HelloAPIGETMethod
Properties:
RestApiId: !Ref SimpleAPI
StageName: v1
# The Amazon S3 bucket into which our Single Page Application build files must be deployed
S3Bucket:
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Sub 'react-cors-spa-${SimpleAPI}'
PublicAccessBlockConfiguration:
BlockPublicAcls : true
BlockPublicPolicy : true
IgnorePublicAcls : true
RestrictPublicBuckets : true
LoggingConfiguration:
DestinationBucketName: !Ref LoggingBucket
LogFilePrefix: s3-access-logs
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: 'AES256'
# The Amazon S3 bucket policy for securing the bucket hosting the application
BucketPolicy:
Type: 'AWS::S3::BucketPolicy'
Properties:
PolicyDocument:
Id: MyPolicy
Version: 2012-10-17
Statement:
- Sid: PolicyForCloudFrontPrivateContent
Effect: Allow
Principal:
CanonicalUser: !GetAtt CFOriginAccessIdentity.S3CanonicalUserId
Action: 's3:GetObject*'
Resource: !Join
- ''
- - 'arn:aws:s3:::'
- !Ref S3Bucket
- /*
Bucket: !Ref S3Bucket
# The Amazon S3 bucket into which access logs from S3 (for the application) and CloudFront will be put
LoggingBucket:
#checkov:skip=CKV_AWS_18: "This bucket is private and only for storing logs"
Type: 'AWS::S3::Bucket'
Properties:
BucketName: !Sub 'react-cors-spa-${SimpleAPI}-logs'
PublicAccessBlockConfiguration:
BlockPublicAcls : true
BlockPublicPolicy : true
IgnorePublicAcls : true
RestrictPublicBuckets : true
AccessControl: LogDeliveryWrite
VersioningConfiguration:
Status: Enabled
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: 'AES256'
DeletionPolicy: Delete
# The Amazon CloudFront distribution exposing our Single Page Application
CFDistribution:
#checkov:skip=CKV_AWS_68: "For demo purposes and to reduce cost, no WAF is configured"
Type: 'AWS::CloudFront::Distribution'
DependsOn:
- CFOriginAccessIdentity
Properties:
DistributionConfig:
Origins:
- DomainName: !GetAtt S3Bucket.RegionalDomainName
Id: myS3Origin
S3OriginConfig:
OriginAccessIdentity: !Sub "origin-access-identity/cloudfront/${CFOriginAccessIdentity}"
Enabled: 'true'
DefaultRootObject: index.html
DefaultCacheBehavior:
AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: myS3Origin
CachePolicyId: 658327ea-f89d-4fab-a63d-7e88639e58f6 # CachingOptimized
OriginRequestPolicyId: 88a5eaf4-2fd4-4709-b370-b4c650ea3fcf # CORS-S3Origin
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_All
Logging:
Bucket: !GetAtt LoggingBucket.RegionalDomainName
Prefix: 'cloudfront-access-logs'
ViewerCertificate:
CloudFrontDefaultCertificate: true
MinimumProtocolVersion: 'TLSv1.2_2021'
# The Amazon CloudFront origin access identity
CFOriginAccessIdentity:
Type: 'AWS::CloudFront::CloudFrontOriginAccessIdentity'
DependsOn:
- S3Bucket
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: !Sub 'access-identity-react-cors-spa-${SimpleAPI}'
Outputs:
APIEndpoint:
Value: !Sub "https://${SimpleAPI}.execute-api.${AWS::Region}.amazonaws.com/v1/hello"
BucketName:
Value: !Sub "react-cors-spa-${CFOriginAccessIdentity}"