@webiny/pulumi-aws 0.0.0-ee-vpcs.549378cf03

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +328 -0
  3. package/apps/admin/createAdminPulumiApp.d.ts +24 -0
  4. package/apps/admin/createAdminPulumiApp.js +21 -0
  5. package/apps/admin/createAdminPulumiApp.js.map +1 -0
  6. package/apps/admin/index.d.ts +1 -0
  7. package/apps/admin/index.js +18 -0
  8. package/apps/admin/index.js.map +1 -0
  9. package/apps/api/ApiApwScheduler.d.ts +20 -0
  10. package/apps/api/ApiApwScheduler.js +246 -0
  11. package/apps/api/ApiApwScheduler.js.map +1 -0
  12. package/apps/api/ApiCloudfront.d.ts +3 -0
  13. package/apps/api/ApiCloudfront.js +101 -0
  14. package/apps/api/ApiCloudfront.js.map +1 -0
  15. package/apps/api/ApiFileManager.d.ts +10 -0
  16. package/apps/api/ApiFileManager.js +166 -0
  17. package/apps/api/ApiFileManager.js.map +1 -0
  18. package/apps/api/ApiGateway.d.ts +18 -0
  19. package/apps/api/ApiGateway.js +88 -0
  20. package/apps/api/ApiGateway.js.map +1 -0
  21. package/apps/api/ApiGraphql.d.ts +26 -0
  22. package/apps/api/ApiGraphql.js +167 -0
  23. package/apps/api/ApiGraphql.js.map +1 -0
  24. package/apps/api/ApiHeadlessCMS.d.ts +13 -0
  25. package/apps/api/ApiHeadlessCMS.js +94 -0
  26. package/apps/api/ApiHeadlessCMS.js.map +1 -0
  27. package/apps/api/ApiOutput.d.ts +15 -0
  28. package/apps/api/ApiOutput.js +43 -0
  29. package/apps/api/ApiOutput.js.map +1 -0
  30. package/apps/api/ApiPageBuilder.d.ts +24 -0
  31. package/apps/api/ApiPageBuilder.js +248 -0
  32. package/apps/api/ApiPageBuilder.js.map +1 -0
  33. package/apps/api/createApiPulumiApp.d.ts +71 -0
  34. package/apps/api/createApiPulumiApp.js +188 -0
  35. package/apps/api/createApiPulumiApp.js.map +1 -0
  36. package/apps/api/index.d.ts +9 -0
  37. package/apps/api/index.js +122 -0
  38. package/apps/api/index.js.map +1 -0
  39. package/apps/awsUtils.d.ts +3 -0
  40. package/apps/awsUtils.js +23 -0
  41. package/apps/awsUtils.js.map +1 -0
  42. package/apps/common/CoreOutput.d.ts +21 -0
  43. package/apps/common/CoreOutput.js +50 -0
  44. package/apps/common/CoreOutput.js.map +1 -0
  45. package/apps/common/VpcConfig.d.ts +8 -0
  46. package/apps/common/VpcConfig.js +37 -0
  47. package/apps/common/VpcConfig.js.map +1 -0
  48. package/apps/common/index.d.ts +2 -0
  49. package/apps/common/index.js +31 -0
  50. package/apps/common/index.js.map +1 -0
  51. package/apps/core/CoreCognito.d.ts +10 -0
  52. package/apps/core/CoreCognito.js +100 -0
  53. package/apps/core/CoreCognito.js.map +1 -0
  54. package/apps/core/CoreDynamo.d.ts +5 -0
  55. package/apps/core/CoreDynamo.js +51 -0
  56. package/apps/core/CoreDynamo.js.map +1 -0
  57. package/apps/core/CoreElasticSearch.d.ts +16 -0
  58. package/apps/core/CoreElasticSearch.js +286 -0
  59. package/apps/core/CoreElasticSearch.js.map +1 -0
  60. package/apps/core/CoreEventBus.d.ts +1 -0
  61. package/apps/core/CoreEventBus.js +25 -0
  62. package/apps/core/CoreEventBus.js.map +1 -0
  63. package/apps/core/CoreFileManager.d.ts +8 -0
  64. package/apps/core/CoreFileManager.js +55 -0
  65. package/apps/core/CoreFileManager.js.map +1 -0
  66. package/apps/core/CoreVpc.d.ts +13 -0
  67. package/apps/core/CoreVpc.js +148 -0
  68. package/apps/core/CoreVpc.js.map +1 -0
  69. package/apps/core/createCorePulumiApp.d.ts +64 -0
  70. package/apps/core/createCorePulumiApp.js +104 -0
  71. package/apps/core/createCorePulumiApp.js.map +1 -0
  72. package/apps/core/index.d.ts +6 -0
  73. package/apps/core/index.js +83 -0
  74. package/apps/core/index.js.map +1 -0
  75. package/apps/createAppBucket.d.ts +13 -0
  76. package/apps/createAppBucket.js +106 -0
  77. package/apps/createAppBucket.js.map +1 -0
  78. package/apps/customDomain.d.ts +9 -0
  79. package/apps/customDomain.js +14 -0
  80. package/apps/customDomain.js.map +1 -0
  81. package/apps/index.d.ts +7 -0
  82. package/apps/index.js +100 -0
  83. package/apps/index.js.map +1 -0
  84. package/apps/lambdaUtils.d.ts +10 -0
  85. package/apps/lambdaUtils.js +82 -0
  86. package/apps/lambdaUtils.js.map +1 -0
  87. package/apps/react/createReactPulumiApp.d.ts +33 -0
  88. package/apps/react/createReactPulumiApp.js +144 -0
  89. package/apps/react/createReactPulumiApp.js.map +1 -0
  90. package/apps/react/index.d.ts +1 -0
  91. package/apps/react/index.js +18 -0
  92. package/apps/react/index.js.map +1 -0
  93. package/apps/tenantRouter.d.ts +3 -0
  94. package/apps/tenantRouter.js +115 -0
  95. package/apps/tenantRouter.js.map +1 -0
  96. package/apps/website/WebsitePrerendering.d.ts +39 -0
  97. package/apps/website/WebsitePrerendering.js +300 -0
  98. package/apps/website/WebsitePrerendering.js.map +1 -0
  99. package/apps/website/createWebsitePulumiApp.d.ts +74 -0
  100. package/apps/website/createWebsitePulumiApp.js +246 -0
  101. package/apps/website/createWebsitePulumiApp.js.map +1 -0
  102. package/apps/website/deliveryViewerRequest.d.ts +2 -0
  103. package/apps/website/deliveryViewerRequest.js +32 -0
  104. package/apps/website/deliveryViewerRequest.js.map +1 -0
  105. package/apps/website/index.d.ts +1 -0
  106. package/apps/website/index.js +18 -0
  107. package/apps/website/index.js.map +1 -0
  108. package/components/tenantRouter/WebsiteTenantRouter.d.ts +11 -0
  109. package/components/tenantRouter/WebsiteTenantRouter.js +98 -0
  110. package/components/tenantRouter/WebsiteTenantRouter.js.map +1 -0
  111. package/components/tenantRouter/functions/origin/request.d.ts +1 -0
  112. package/components/tenantRouter/functions/origin/request.js +129 -0
  113. package/components/tenantRouter/functions/origin/request.js.map +1 -0
  114. package/enterprise/createAdminPulumiApp.d.ts +1 -0
  115. package/enterprise/createAdminPulumiApp.js +25 -0
  116. package/enterprise/createAdminPulumiApp.js.map +1 -0
  117. package/enterprise/createApiPulumiApp.d.ts +61 -0
  118. package/enterprise/createApiPulumiApp.js +68 -0
  119. package/enterprise/createApiPulumiApp.js.map +1 -0
  120. package/enterprise/createCorePulumiApp.d.ts +42 -0
  121. package/enterprise/createCorePulumiApp.js +137 -0
  122. package/enterprise/createCorePulumiApp.js.map +1 -0
  123. package/enterprise/createWebsitePulumiApp.d.ts +56 -0
  124. package/enterprise/createWebsitePulumiApp.js +68 -0
  125. package/enterprise/createWebsitePulumiApp.js.map +1 -0
  126. package/enterprise/index.d.ts +4 -0
  127. package/enterprise/index.js +57 -0
  128. package/enterprise/index.js.map +1 -0
  129. package/index.d.ts +3 -0
  130. package/index.js +44 -0
  131. package/index.js.map +1 -0
  132. package/package.json +53 -0
  133. package/utils/crawlDirectory.d.ts +1 -0
  134. package/utils/crawlDirectory.js +33 -0
  135. package/utils/crawlDirectory.js.map +1 -0
  136. package/utils/getPresignedPost.d.ts +11 -0
  137. package/utils/getPresignedPost.js +46 -0
  138. package/utils/getPresignedPost.js.map +1 -0
  139. package/utils/index.d.ts +3 -0
  140. package/utils/index.js +51 -0
  141. package/utils/index.js.map +1 -0
  142. package/utils/lambdaEnvVariables.d.ts +20 -0
  143. package/utils/lambdaEnvVariables.js +78 -0
  144. package/utils/lambdaEnvVariables.js.map +1 -0
  145. package/utils/storageMigrate.d.ts +0 -0
  146. package/utils/storageMigrate.js +292 -0
  147. package/utils/storageMigrate.js.map +1 -0
  148. package/utils/tagResources.d.ts +5 -0
  149. package/utils/tagResources.js +43 -0
  150. package/utils/tagResources.js.map +1 -0
  151. package/utils/uploadFolderToS3.d.ts +26 -0
  152. package/utils/uploadFolderToS3.js +188 -0
  153. package/utils/uploadFolderToS3.js.map +1 -0
@@ -0,0 +1,300 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+
5
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports.createPrerenderingService = createPrerenderingService;
11
+
12
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
13
+
14
+ var path = _interopRequireWildcard(require("path"));
15
+
16
+ var pulumi = _interopRequireWildcard(require("@pulumi/pulumi"));
17
+
18
+ var aws = _interopRequireWildcard(require("@pulumi/aws"));
19
+
20
+ var _dynamodb = require("aws-sdk/clients/dynamodb");
21
+
22
+ var _awsLayers = require("@webiny/aws-layers");
23
+
24
+ var _lambdaUtils = require("../lambdaUtils");
25
+
26
+ var _common = require("../common");
27
+
28
+ var _awsUtils = require("../awsUtils");
29
+
30
+ // @ts-ignore
31
+ function createPrerenderingService(app, params) {
32
+ const queue = app.addResource(aws.sqs.Queue, {
33
+ name: "ps-render-queue",
34
+ config: {
35
+ visibilityTimeoutSeconds: 300,
36
+ fifoQueue: true
37
+ }
38
+ });
39
+ const policy = createLambdaPolicy(app, queue.output, params);
40
+ const renderer = createRenderer(app, queue.output, policy.output, params);
41
+ const subscriber = createRenderSubscriber(app, policy.output, params);
42
+ const flush = createFlushService(app, policy.output, params);
43
+ const settings = createPrerenderingSettingsDbItem(app, queue.output, params);
44
+ return {
45
+ subscriber,
46
+ renderer,
47
+ flush,
48
+ settings
49
+ };
50
+ }
51
+
52
+ function createPrerenderingSettingsDbItem(app, queue, params) {
53
+ /**
54
+ * To handle everything related to prerendering, we need the following information:
55
+ * - appUrl - SPA URL used to prerender HTML
56
+ * - bucket - name of the S3 bucket used for storage of HTML snapshots
57
+ * - cloudfrontId - for cache invalidation
58
+ * - sqsQueueUrl - an SQS queue for prerendering tasks (messages)
59
+ */
60
+ const tableItem = app.addResource(aws.dynamodb.TableItem, {
61
+ name: "psSettings",
62
+ config: {
63
+ tableName: params.dbTableName,
64
+ hashKey: params.dbTableHashKey,
65
+ rangeKey: params.dbTableRangeKey,
66
+ item: pulumi.interpolate`{
67
+ "PK": "PS#SETTINGS",
68
+ "SK": "${app.params.run.variant || "default"}",
69
+ "data": {
70
+ "appUrl": "${params.appUrl}",
71
+ "deliveryUrl": "${params.deliveryUrl}",
72
+ "bucket": "${params.bucket}",
73
+ "cloudfrontId": "${params.cloudfrontId}",
74
+ "sqsQueueUrl": "${queue.url}"
75
+ }
76
+ }` // We're using the native DynamoDB converter to avoid building those nested objects ourselves.
77
+ .apply(v => JSON.stringify(_dynamodb.Converter.marshall(JSON.parse(v))))
78
+ }
79
+ });
80
+ return {
81
+ tableItem
82
+ };
83
+ }
84
+
85
+ function createRenderSubscriber(app, policy, params) {
86
+ const core = app.getModule(_common.CoreOutput);
87
+ const role = (0, _lambdaUtils.createLambdaRole)(app, {
88
+ name: "ps-render-subscriber-role",
89
+ policy: policy
90
+ });
91
+ const lambda = app.addResource(aws.lambda.Function, {
92
+ name: "ps-render-subscriber-lambda",
93
+ config: {
94
+ role: role.output.arn,
95
+ runtime: "nodejs14.x",
96
+ handler: "handler.handler",
97
+ timeout: 30,
98
+ memorySize: 512,
99
+ environment: {
100
+ variables: (0, _lambdaUtils.getCommonLambdaEnvVariables)().apply(value => (0, _objectSpread2.default)((0, _objectSpread2.default)({}, value), {}, {
101
+ DB_TABLE: params.dbTableName
102
+ }))
103
+ },
104
+ description: "Subscribes to render events on event bus",
105
+ code: new pulumi.asset.AssetArchive({
106
+ ".": new pulumi.asset.FileArchive(path.join(app.paths.workspace, "prerendering/subscribe/build"))
107
+ }),
108
+ vpcConfig: app.getModule(_common.VpcConfig).functionVpcConfig
109
+ }
110
+ });
111
+ /**
112
+ * TODO: when we get to staged rollouts and variants, maybe we can create per-variant event rules,
113
+ * to avoid invocation of all variant lambdas just to do a `detail-type` check and exit early.
114
+ * That way, we would be publishing events scoped to a variant, like "RenderPages-{variant}".
115
+ */
116
+
117
+ const eventRule = app.addResource(aws.cloudwatch.EventRule, {
118
+ name: "ps-render-subscriber-event-rule",
119
+ config: {
120
+ eventBusName: core.eventBusArn,
121
+ eventPattern: JSON.stringify({
122
+ "detail-type": ["RenderPages"]
123
+ })
124
+ }
125
+ });
126
+ const eventPermission = app.addResource(aws.lambda.Permission, {
127
+ name: "ps-render-subscriber-event-permission",
128
+ config: {
129
+ action: "lambda:InvokeFunction",
130
+ function: lambda.output.arn,
131
+ principal: "events.amazonaws.com",
132
+ sourceArn: eventRule.output.arn
133
+ }
134
+ });
135
+ const eventTarget = app.addResource(aws.cloudwatch.EventTarget, {
136
+ name: "ps-render-subscriber-event-target",
137
+ config: {
138
+ rule: eventRule.output.name,
139
+ eventBusName: core.eventBusArn,
140
+ arn: lambda.output.arn
141
+ }
142
+ });
143
+ return {
144
+ policy,
145
+ role,
146
+ lambda,
147
+ eventRule,
148
+ eventPermission,
149
+ eventTarget
150
+ };
151
+ }
152
+
153
+ function createRenderer(app, queue, policy, params) {
154
+ const role = (0, _lambdaUtils.createLambdaRole)(app, {
155
+ name: "ps-render-lambda-role",
156
+ policy: policy,
157
+ executionRole: aws.iam.ManagedPolicy.AWSLambdaSQSQueueExecutionRole
158
+ });
159
+ const lambda = app.addResource(aws.lambda.Function, {
160
+ name: "ps-render-lambda",
161
+ config: {
162
+ role: role.output.arn,
163
+ runtime: "nodejs14.x",
164
+ handler: "handler.handler",
165
+ timeout: 300,
166
+ memorySize: 2048,
167
+ layers: [(0, _awsLayers.getLayerArn)("shelf-io-chrome-aws-lambda-layer")],
168
+ environment: {
169
+ variables: (0, _lambdaUtils.getCommonLambdaEnvVariables)().apply(value => (0, _objectSpread2.default)((0, _objectSpread2.default)({}, value), {}, {
170
+ DB_TABLE: params.dbTableName
171
+ }))
172
+ },
173
+ description: "Renders pages and stores output in an S3 bucket of choice.",
174
+ code: new pulumi.asset.AssetArchive({
175
+ ".": new pulumi.asset.FileArchive(path.join(app.paths.workspace, "prerendering/render/build"))
176
+ }),
177
+ vpcConfig: app.getModule(_common.VpcConfig).functionVpcConfig
178
+ }
179
+ });
180
+ const eventSourceMapping = app.addResource(aws.lambda.EventSourceMapping, {
181
+ name: "ps-render-event-source-mapping",
182
+ config: {
183
+ functionName: lambda.output.arn,
184
+ eventSourceArn: queue.arn,
185
+ batchSize: 1
186
+ }
187
+ });
188
+ return {
189
+ policy,
190
+ role,
191
+ lambda,
192
+ eventSourceMapping
193
+ };
194
+ }
195
+
196
+ function createFlushService(app, policy, params) {
197
+ const core = app.getModule(_common.CoreOutput);
198
+ const role = (0, _lambdaUtils.createLambdaRole)(app, {
199
+ name: "ps-flush-lambda-role",
200
+ policy: policy
201
+ });
202
+ const lambda = app.addResource(aws.lambda.Function, {
203
+ name: "ps-flush-lambda",
204
+ config: {
205
+ role: role.output.arn,
206
+ runtime: "nodejs14.x",
207
+ handler: "handler.handler",
208
+ timeout: 30,
209
+ memorySize: 512,
210
+ environment: {
211
+ variables: (0, _lambdaUtils.getCommonLambdaEnvVariables)().apply(value => (0, _objectSpread2.default)((0, _objectSpread2.default)({}, value), {}, {
212
+ DB_TABLE: params.dbTableName
213
+ }))
214
+ },
215
+ description: "Subscribes to flush events on event bus",
216
+ code: new pulumi.asset.AssetArchive({
217
+ ".": new pulumi.asset.FileArchive(path.join(app.paths.workspace, "prerendering/flush/build"))
218
+ }),
219
+ vpcConfig: app.getModule(_common.VpcConfig).functionVpcConfig
220
+ }
221
+ });
222
+ const eventRule = app.addResource(aws.cloudwatch.EventRule, {
223
+ name: "ps-flush-event-rule",
224
+ config: {
225
+ eventBusName: core.eventBusArn,
226
+ eventPattern: JSON.stringify({
227
+ "detail-type": ["FlushPages"]
228
+ })
229
+ }
230
+ });
231
+ const eventPermission = app.addResource(aws.lambda.Permission, {
232
+ name: "ps-flush-event-permission",
233
+ config: {
234
+ action: "lambda:InvokeFunction",
235
+ function: lambda.output.arn,
236
+ principal: "events.amazonaws.com",
237
+ sourceArn: eventRule.output.arn
238
+ }
239
+ });
240
+ const eventTarget = app.addResource(aws.cloudwatch.EventTarget, {
241
+ name: "ps-flush-event-target",
242
+ config: {
243
+ rule: eventRule.output.name,
244
+ eventBusName: core.eventBusArn,
245
+ arn: lambda.output.arn
246
+ }
247
+ });
248
+ return {
249
+ policy,
250
+ role,
251
+ lambda,
252
+ eventRule,
253
+ eventPermission,
254
+ eventTarget
255
+ };
256
+ }
257
+
258
+ function createLambdaPolicy(app, queue, params) {
259
+ const core = app.getModule(_common.CoreOutput);
260
+ const awsAccountId = (0, _awsUtils.getAwsAccountId)(app);
261
+ return app.addResource(aws.iam.Policy, {
262
+ name: "ps-lambda-policy",
263
+ config: {
264
+ description: "This policy enables access to Lambda, S3, Cloudfront, SQS and Dynamodb",
265
+ policy: {
266
+ Version: "2012-10-17",
267
+ Statement: [{
268
+ Sid: "PermissionForDynamodb",
269
+ Effect: "Allow",
270
+ Action: ["dynamodb:BatchGetItem", "dynamodb:BatchWriteItem", "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem"],
271
+ Resource: core.apply(s => {
272
+ // Add permissions to DynamoDB table
273
+ const resources = [`${s.primaryDynamodbTableArn}`, `${s.primaryDynamodbTableArn}/*`]; // Attach permissions for elastic search dynamo as well (if ES is enabled).
274
+
275
+ if (s.elasticsearchDynamodbTableArn) {
276
+ resources.push(`${s.elasticsearchDynamodbTableArn}`, `${s.elasticsearchDynamodbTableArn}/*`);
277
+ }
278
+
279
+ return resources;
280
+ })
281
+ }, {
282
+ Sid: "PermissionForS3",
283
+ Effect: "Allow",
284
+ Action: ["s3:DeleteObject", "s3:GetObject", "s3:PutObject"],
285
+ Resource: [pulumi.interpolate`arn:aws:s3:::${params.bucket}/*`]
286
+ }, {
287
+ Sid: "PermissionForCloudfront",
288
+ Effect: "Allow",
289
+ Action: "cloudfront:CreateInvalidation",
290
+ Resource: pulumi.interpolate`arn:aws:cloudfront::${awsAccountId}:distribution/*`
291
+ }, {
292
+ Sid: "PermissionForSQS",
293
+ Effect: "Allow",
294
+ Action: ["sqs:SendMessage", "sqs:SendMessageBatch"],
295
+ Resource: queue.arn
296
+ }]
297
+ }
298
+ }
299
+ });
300
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"names":["createPrerenderingService","app","params","queue","addResource","aws","sqs","Queue","name","config","visibilityTimeoutSeconds","fifoQueue","policy","createLambdaPolicy","output","renderer","createRenderer","subscriber","createRenderSubscriber","flush","createFlushService","settings","createPrerenderingSettingsDbItem","tableItem","dynamodb","TableItem","tableName","dbTableName","hashKey","dbTableHashKey","rangeKey","dbTableRangeKey","item","pulumi","interpolate","run","variant","appUrl","deliveryUrl","bucket","cloudfrontId","url","apply","v","JSON","stringify","Converter","marshall","parse","core","getModule","CoreOutput","role","createLambdaRole","lambda","Function","arn","runtime","handler","timeout","memorySize","environment","variables","getCommonLambdaEnvVariables","value","DB_TABLE","description","code","asset","AssetArchive","FileArchive","path","join","paths","workspace","vpcConfig","VpcConfig","functionVpcConfig","eventRule","cloudwatch","EventRule","eventBusName","eventBusArn","eventPattern","eventPermission","Permission","action","function","principal","sourceArn","eventTarget","EventTarget","rule","executionRole","iam","ManagedPolicy","AWSLambdaSQSQueueExecutionRole","layers","getLayerArn","eventSourceMapping","EventSourceMapping","functionName","eventSourceArn","batchSize","awsAccountId","getAwsAccountId","Policy","Version","Statement","Sid","Effect","Action","Resource","s","resources","primaryDynamodbTableArn","elasticsearchDynamodbTableArn","push"],"sources":["WebsitePrerendering.ts"],"sourcesContent":["import * as path from \"path\";\nimport * as pulumi from \"@pulumi/pulumi\";\nimport * as aws from \"@pulumi/aws\";\nimport { Converter } from \"aws-sdk/clients/dynamodb\";\n\nimport { PulumiApp } from \"@webiny/pulumi\";\n// @ts-ignore\nimport { getLayerArn } from \"@webiny/aws-layers\";\n\nimport { createLambdaRole, getCommonLambdaEnvVariables } from \"../lambdaUtils\";\nimport { CoreOutput, VpcConfig } from \"../common\";\nimport { getAwsAccountId } from \"../awsUtils\";\n\ninterface PreRenderingServiceParams {\n dbTableName: pulumi.Output<string>;\n dbTableHashKey: pulumi.Output<string>;\n dbTableRangeKey: pulumi.Output<string>;\n appUrl: pulumi.Output<string>;\n deliveryUrl: pulumi.Output<string>;\n bucket: pulumi.Output<string>;\n cloudfrontId: pulumi.Output<string>;\n}\n\nexport function createPrerenderingService(app: PulumiApp, params: PreRenderingServiceParams) {\n const queue = app.addResource(aws.sqs.Queue, {\n name: \"ps-render-queue\",\n config: {\n visibilityTimeoutSeconds: 300,\n fifoQueue: true\n }\n });\n\n const policy = createLambdaPolicy(app, queue.output, params);\n const renderer = createRenderer(app, queue.output, policy.output, params);\n const subscriber = createRenderSubscriber(app, policy.output, params);\n const flush = createFlushService(app, policy.output, params);\n const settings = createPrerenderingSettingsDbItem(app, queue.output, params);\n\n return {\n subscriber,\n renderer,\n flush,\n settings\n };\n}\n\nfunction createPrerenderingSettingsDbItem(\n app: PulumiApp,\n queue: pulumi.Output<aws.sqs.Queue>,\n params: PreRenderingServiceParams\n) {\n /**\n * To handle everything related to prerendering, we need the following information:\n * - appUrl - SPA URL used to prerender HTML\n * - bucket - name of the S3 bucket used for storage of HTML snapshots\n * - cloudfrontId - for cache invalidation\n * - sqsQueueUrl - an SQS queue for prerendering tasks (messages)\n */\n const tableItem = app.addResource(aws.dynamodb.TableItem, {\n name: \"psSettings\",\n config: {\n tableName: params.dbTableName,\n hashKey: params.dbTableHashKey,\n rangeKey: params.dbTableRangeKey,\n item: pulumi.interpolate`{\n \"PK\": \"PS#SETTINGS\",\n \"SK\": \"${app.params.run.variant || \"default\"}\",\n \"data\": {\n \"appUrl\": \"${params.appUrl}\",\n \"deliveryUrl\": \"${params.deliveryUrl}\",\n \"bucket\": \"${params.bucket}\",\n \"cloudfrontId\": \"${params.cloudfrontId}\",\n \"sqsQueueUrl\": \"${queue.url}\"\n }\n }`\n // We're using the native DynamoDB converter to avoid building those nested objects ourselves.\n .apply(v => JSON.stringify(Converter.marshall(JSON.parse(v))))\n }\n });\n\n return { tableItem };\n}\n\nfunction createRenderSubscriber(\n app: PulumiApp,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const core = app.getModule(CoreOutput);\n\n const role = createLambdaRole(app, {\n name: \"ps-render-subscriber-role\",\n policy: policy\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-render-subscriber-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 30,\n memorySize: 512,\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Subscribes to render events on event bus\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/subscribe/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n /**\n * TODO: when we get to staged rollouts and variants, maybe we can create per-variant event rules,\n * to avoid invocation of all variant lambdas just to do a `detail-type` check and exit early.\n * That way, we would be publishing events scoped to a variant, like \"RenderPages-{variant}\".\n */\n\n const eventRule = app.addResource(aws.cloudwatch.EventRule, {\n name: \"ps-render-subscriber-event-rule\",\n config: {\n eventBusName: core.eventBusArn,\n eventPattern: JSON.stringify({\n \"detail-type\": [\"RenderPages\"]\n })\n }\n });\n\n const eventPermission = app.addResource(aws.lambda.Permission, {\n name: \"ps-render-subscriber-event-permission\",\n config: {\n action: \"lambda:InvokeFunction\",\n function: lambda.output.arn,\n principal: \"events.amazonaws.com\",\n sourceArn: eventRule.output.arn\n }\n });\n\n const eventTarget = app.addResource(aws.cloudwatch.EventTarget, {\n name: \"ps-render-subscriber-event-target\",\n config: {\n rule: eventRule.output.name,\n eventBusName: core.eventBusArn,\n arn: lambda.output.arn\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventRule,\n eventPermission,\n eventTarget\n };\n}\n\nfunction createRenderer(\n app: PulumiApp,\n queue: pulumi.Output<aws.sqs.Queue>,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const role = createLambdaRole(app, {\n name: \"ps-render-lambda-role\",\n policy: policy,\n executionRole: aws.iam.ManagedPolicy.AWSLambdaSQSQueueExecutionRole\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-render-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 300,\n memorySize: 2048,\n layers: [getLayerArn(\"shelf-io-chrome-aws-lambda-layer\")],\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Renders pages and stores output in an S3 bucket of choice.\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/render/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n const eventSourceMapping = app.addResource(aws.lambda.EventSourceMapping, {\n name: \"ps-render-event-source-mapping\",\n config: {\n functionName: lambda.output.arn,\n eventSourceArn: queue.arn,\n batchSize: 1\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventSourceMapping\n };\n}\n\nfunction createFlushService(\n app: PulumiApp,\n policy: pulumi.Output<aws.iam.Policy>,\n params: PreRenderingServiceParams\n) {\n const core = app.getModule(CoreOutput);\n\n const role = createLambdaRole(app, {\n name: \"ps-flush-lambda-role\",\n policy: policy\n });\n\n const lambda = app.addResource(aws.lambda.Function, {\n name: \"ps-flush-lambda\",\n config: {\n role: role.output.arn,\n runtime: \"nodejs14.x\",\n handler: \"handler.handler\",\n timeout: 30,\n memorySize: 512,\n environment: {\n variables: getCommonLambdaEnvVariables().apply(value => ({\n ...value,\n DB_TABLE: params.dbTableName\n }))\n },\n description: \"Subscribes to flush events on event bus\",\n code: new pulumi.asset.AssetArchive({\n \".\": new pulumi.asset.FileArchive(\n path.join(app.paths.workspace, \"prerendering/flush/build\")\n )\n }),\n vpcConfig: app.getModule(VpcConfig).functionVpcConfig\n }\n });\n\n const eventRule = app.addResource(aws.cloudwatch.EventRule, {\n name: \"ps-flush-event-rule\",\n config: {\n eventBusName: core.eventBusArn,\n eventPattern: JSON.stringify({\n \"detail-type\": [\"FlushPages\"]\n })\n }\n });\n\n const eventPermission = app.addResource(aws.lambda.Permission, {\n name: \"ps-flush-event-permission\",\n config: {\n action: \"lambda:InvokeFunction\",\n function: lambda.output.arn,\n principal: \"events.amazonaws.com\",\n sourceArn: eventRule.output.arn\n }\n });\n\n const eventTarget = app.addResource(aws.cloudwatch.EventTarget, {\n name: \"ps-flush-event-target\",\n config: {\n rule: eventRule.output.name,\n eventBusName: core.eventBusArn,\n arn: lambda.output.arn\n }\n });\n\n return {\n policy,\n role,\n lambda,\n eventRule,\n eventPermission,\n eventTarget\n };\n}\n\nfunction createLambdaPolicy(\n app: PulumiApp,\n queue: pulumi.Output<aws.sqs.Queue>,\n params: PreRenderingServiceParams\n) {\n const core = app.getModule(CoreOutput);\n const awsAccountId = getAwsAccountId(app);\n\n return app.addResource(aws.iam.Policy, {\n name: \"ps-lambda-policy\",\n config: {\n description: \"This policy enables access to Lambda, S3, Cloudfront, SQS and Dynamodb\",\n policy: {\n Version: \"2012-10-17\",\n Statement: [\n {\n Sid: \"PermissionForDynamodb\",\n Effect: \"Allow\",\n Action: [\n \"dynamodb:BatchGetItem\",\n \"dynamodb:BatchWriteItem\",\n \"dynamodb:DeleteItem\",\n \"dynamodb:GetItem\",\n \"dynamodb:PutItem\",\n \"dynamodb:Query\",\n \"dynamodb:Scan\",\n \"dynamodb:UpdateItem\"\n ],\n Resource: core.apply(s => {\n // Add permissions to DynamoDB table\n const resources = [\n `${s.primaryDynamodbTableArn}`,\n `${s.primaryDynamodbTableArn}/*`\n ];\n\n // Attach permissions for elastic search dynamo as well (if ES is enabled).\n if (s.elasticsearchDynamodbTableArn) {\n resources.push(\n `${s.elasticsearchDynamodbTableArn}`,\n `${s.elasticsearchDynamodbTableArn}/*`\n );\n }\n\n return resources;\n })\n },\n {\n Sid: \"PermissionForS3\",\n Effect: \"Allow\",\n Action: [\"s3:DeleteObject\", \"s3:GetObject\", \"s3:PutObject\"],\n Resource: [pulumi.interpolate`arn:aws:s3:::${params.bucket}/*`]\n },\n {\n Sid: \"PermissionForCloudfront\",\n Effect: \"Allow\",\n Action: \"cloudfront:CreateInvalidation\",\n Resource: pulumi.interpolate`arn:aws:cloudfront::${awsAccountId}:distribution/*`\n },\n {\n Sid: \"PermissionForSQS\",\n Effect: \"Allow\",\n Action: [\"sqs:SendMessage\", \"sqs:SendMessageBatch\"],\n Resource: queue.arn\n }\n ]\n }\n }\n });\n}\n"],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import * as pulumi from "@pulumi/pulumi";
2
+ import * as aws from "@pulumi/aws";
3
+ import { PulumiAppParamCallback, PulumiAppParam } from "@webiny/pulumi";
4
+ import { CustomDomainParams } from "../customDomain";
5
+ export declare type WebsitePulumiApp = ReturnType<typeof createWebsitePulumiApp>;
6
+ export interface CreateWebsitePulumiAppParams {
7
+ /**
8
+ * Custom domain(s) configuration.
9
+ */
10
+ domains?: PulumiAppParamCallback<CustomDomainParams>;
11
+ /**
12
+ * Custom preview domain(s) configuration.
13
+ */
14
+ previewDomains?: PulumiAppParamCallback<CustomDomainParams>;
15
+ /**
16
+ * Enables or disables VPC for the API.
17
+ * For VPC to work you also have to enable it in the `core` application.
18
+ */
19
+ vpc?: PulumiAppParam<boolean | undefined>;
20
+ /**
21
+ * Provides a way to adjust existing Pulumi code (cloud infrastructure resources)
22
+ * or add additional ones into the mix.
23
+ */
24
+ pulumi?: (app: WebsitePulumiApp) => void | Promise<void>;
25
+ /**
26
+ * Prefixes names of all Pulumi cloud infrastructure resource with given prefix.
27
+ */
28
+ pulumiResourceNamePrefix?: PulumiAppParam<string>;
29
+ }
30
+ export declare const createWebsitePulumiApp: (projectAppParams?: CreateWebsitePulumiAppParams) => import("@webiny/pulumi").PulumiApp<{
31
+ prerendering: {
32
+ subscriber: {
33
+ policy: pulumi.Output<import("@pulumi/aws/iam/policy").Policy>;
34
+ role: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/iam/role").Role>;
35
+ lambda: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/lambda/function").Function>;
36
+ eventRule: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/cloudwatch/eventRule").EventRule>;
37
+ eventPermission: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/lambda/permission").Permission>;
38
+ eventTarget: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/cloudwatch/eventTarget").EventTarget>;
39
+ };
40
+ renderer: {
41
+ policy: pulumi.Output<import("@pulumi/aws/iam/policy").Policy>;
42
+ role: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/iam/role").Role>;
43
+ lambda: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/lambda/function").Function>;
44
+ eventSourceMapping: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/lambda/eventSourceMapping").EventSourceMapping>;
45
+ };
46
+ flush: {
47
+ policy: pulumi.Output<import("@pulumi/aws/iam/policy").Policy>;
48
+ role: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/iam/role").Role>;
49
+ lambda: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/lambda/function").Function>;
50
+ eventRule: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/cloudwatch/eventRule").EventRule>;
51
+ eventPermission: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/lambda/permission").Permission>;
52
+ eventTarget: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/cloudwatch/eventTarget").EventTarget>;
53
+ };
54
+ settings: {
55
+ tableItem: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/dynamodb/tableItem").TableItem>;
56
+ };
57
+ };
58
+ app: {
59
+ cloudfront: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/cloudfront/distribution").Distribution>;
60
+ bucket: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/s3/bucket").Bucket>;
61
+ originIdentity: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/cloudfront/originAccessIdentity").OriginAccessIdentity>;
62
+ origin: aws.types.input.cloudfront.DistributionOrigin;
63
+ bucketPublicAccessBlock: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/s3/bucketPublicAccessBlock").BucketPublicAccessBlock>;
64
+ bucketPolicy: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/s3/bucketPolicy").BucketPolicy>;
65
+ };
66
+ delivery: {
67
+ cloudfront: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/cloudfront/distribution").Distribution>;
68
+ bucket: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/s3/bucket").Bucket>;
69
+ originIdentity: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/cloudfront/originAccessIdentity").OriginAccessIdentity>;
70
+ origin: aws.types.input.cloudfront.DistributionOrigin;
71
+ bucketPublicAccessBlock: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/s3/bucketPublicAccessBlock").BucketPublicAccessBlock>;
72
+ bucketPolicy: import("@webiny/pulumi").PulumiAppResource<typeof import("@pulumi/aws/s3/bucketPolicy").BucketPolicy>;
73
+ };
74
+ }> & import("../lambdaUtils").WithCommonLambdaEnvVariables;
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+
3
+ var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
4
+
5
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
6
+
7
+ Object.defineProperty(exports, "__esModule", {
8
+ value: true
9
+ });
10
+ exports.createWebsitePulumiApp = void 0;
11
+
12
+ var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
13
+
14
+ var pulumi = _interopRequireWildcard(require("@pulumi/pulumi"));
15
+
16
+ var aws = _interopRequireWildcard(require("@pulumi/aws"));
17
+
18
+ var _fs = _interopRequireDefault(require("fs"));
19
+
20
+ var _pulumi2 = require("@webiny/pulumi");
21
+
22
+ var _createAppBucket = require("../createAppBucket");
23
+
24
+ var _customDomain = require("../customDomain");
25
+
26
+ var _WebsitePrerendering = require("./WebsitePrerendering");
27
+
28
+ var _ = require("./..");
29
+
30
+ var _utils = require("../../utils");
31
+
32
+ var _tenantRouter = require("../tenantRouter");
33
+
34
+ const createWebsitePulumiApp = (projectAppParams = {}) => {
35
+ const app = (0, _pulumi2.createPulumiApp)({
36
+ name: "website",
37
+ path: "apps/website",
38
+ config: projectAppParams,
39
+ program: async app => {
40
+ const pulumiResourceNamePrefix = app.getParam(projectAppParams.pulumiResourceNamePrefix);
41
+
42
+ if (pulumiResourceNamePrefix) {
43
+ app.onResource(resource => {
44
+ if (!resource.name.startsWith(pulumiResourceNamePrefix)) {
45
+ resource.name = `${pulumiResourceNamePrefix}${resource.name}`;
46
+ }
47
+ });
48
+ } // Overrides must be applied via a handler, registered at the very start of the program.
49
+ // By doing this, we're ensuring user's adjustments are not applied to late.
50
+
51
+
52
+ if (projectAppParams.pulumi) {
53
+ app.addHandler(() => {
54
+ return projectAppParams.pulumi(app);
55
+ });
56
+ }
57
+
58
+ const prod = app.params.run.env === "prod"; // Register core output as a module available for all other modules
59
+
60
+ const core = app.addModule(_.CoreOutput); // Register VPC config module to be available to other modules.
61
+
62
+ const vpcEnabled = app.getParam(projectAppParams === null || projectAppParams === void 0 ? void 0 : projectAppParams.vpc) ?? prod;
63
+ app.addModule(_.VpcConfig, {
64
+ enabled: vpcEnabled
65
+ });
66
+ const appBucket = (0, _createAppBucket.createPrivateAppBucket)(app, "app");
67
+ const appCloudfront = app.addResource(aws.cloudfront.Distribution, {
68
+ name: "app",
69
+ config: {
70
+ enabled: true,
71
+ waitForDeployment: true,
72
+ origins: [appBucket.origin],
73
+ defaultRootObject: "index.html",
74
+ defaultCacheBehavior: {
75
+ compress: true,
76
+ targetOriginId: appBucket.origin.originId,
77
+ viewerProtocolPolicy: "redirect-to-https",
78
+ allowedMethods: ["GET", "HEAD", "OPTIONS"],
79
+ cachedMethods: ["GET", "HEAD", "OPTIONS"],
80
+ forwardedValues: {
81
+ cookies: {
82
+ forward: "none"
83
+ },
84
+ queryString: false
85
+ },
86
+ // MinTTL <= DefaultTTL <= MaxTTL
87
+ minTtl: 0,
88
+ defaultTtl: 0,
89
+ maxTtl: 0
90
+ },
91
+ priceClass: "PriceClass_100",
92
+ customErrorResponses: [{
93
+ errorCode: 404,
94
+ responseCode: 404,
95
+ responsePagePath: "/index.html"
96
+ }],
97
+ restrictions: {
98
+ geoRestriction: {
99
+ restrictionType: "none"
100
+ }
101
+ },
102
+ viewerCertificate: {
103
+ cloudfrontDefaultCertificate: true
104
+ }
105
+ }
106
+ });
107
+ const deliveryBucket = (0, _createAppBucket.createPrivateAppBucket)(app, "delivery");
108
+ /**
109
+ * We need to have a Cloudfront Function to perform a simple request rewrite, so the request always includes
110
+ * an "/index.html". This is necessary because our buckets are not "website" buckets, and we need to
111
+ * have an exact object key when requesting page paths.
112
+ */
113
+
114
+ const viewerRequest = app.addResource(aws.cloudfront.Function, {
115
+ name: "cfViewerRequest",
116
+ config: {
117
+ runtime: "cloudfront-js-1.0",
118
+ publish: true,
119
+ code: _fs.default.readFileSync(__dirname + `/deliveryViewerRequest.js`, "utf8")
120
+ }
121
+ });
122
+ const deliveryCloudfront = app.addResource(aws.cloudfront.Distribution, {
123
+ name: "delivery",
124
+ config: {
125
+ enabled: true,
126
+ waitForDeployment: true,
127
+ origins: [deliveryBucket.origin, appBucket.origin],
128
+ defaultRootObject: "index.html",
129
+ defaultCacheBehavior: {
130
+ compress: true,
131
+ targetOriginId: deliveryBucket.origin.originId,
132
+ viewerProtocolPolicy: "redirect-to-https",
133
+ allowedMethods: ["GET", "HEAD", "OPTIONS"],
134
+ cachedMethods: ["GET", "HEAD", "OPTIONS"],
135
+ originRequestPolicyId: "",
136
+ forwardedValues: {
137
+ cookies: {
138
+ forward: "none"
139
+ },
140
+ queryString: true
141
+ },
142
+ // MinTTL <= DefaultTTL <= MaxTTL
143
+ minTtl: 0,
144
+ defaultTtl: 30,
145
+ maxTtl: 30,
146
+ functionAssociations: [{
147
+ functionArn: viewerRequest.output.arn,
148
+ eventType: "viewer-request"
149
+ }]
150
+ },
151
+ orderedCacheBehaviors: [{
152
+ compress: true,
153
+ allowedMethods: ["GET", "HEAD", "OPTIONS"],
154
+ cachedMethods: ["GET", "HEAD", "OPTIONS"],
155
+ forwardedValues: {
156
+ cookies: {
157
+ forward: "none"
158
+ },
159
+ headers: [],
160
+ queryString: false
161
+ },
162
+ pathPattern: "/static/*",
163
+ viewerProtocolPolicy: "allow-all",
164
+ targetOriginId: appBucket.origin.originId,
165
+ // MinTTL <= DefaultTTL <= MaxTTL
166
+ minTtl: 0,
167
+ defaultTtl: 2592000,
168
+ // 30 days
169
+ maxTtl: 2592000
170
+ }],
171
+ customErrorResponses: [{
172
+ errorCode: 404,
173
+ responseCode: 404,
174
+ responsePagePath: "/_NOT_FOUND_PAGE_/index.html"
175
+ }],
176
+ priceClass: "PriceClass_100",
177
+ restrictions: {
178
+ geoRestriction: {
179
+ restrictionType: "none"
180
+ }
181
+ },
182
+ viewerCertificate: {
183
+ cloudfrontDefaultCertificate: true
184
+ }
185
+ }
186
+ });
187
+ const prerendering = (0, _WebsitePrerendering.createPrerenderingService)(app, {
188
+ dbTableName: core.primaryDynamodbTableName,
189
+ dbTableHashKey: core.primaryDynamodbTableHashKey,
190
+ dbTableRangeKey: core.primaryDynamodbTableRangeKey,
191
+ appUrl: pulumi.interpolate`https://${appCloudfront.output.domainName}`,
192
+ deliveryUrl: pulumi.interpolate`https://${deliveryCloudfront.output.domainName}`,
193
+ bucket: deliveryBucket.bucket.output.bucket,
194
+ cloudfrontId: deliveryCloudfront.output.id
195
+ });
196
+ const domains = app.getParam(projectAppParams.domains);
197
+
198
+ if (domains) {
199
+ (0, _customDomain.applyCustomDomain)(deliveryCloudfront, domains);
200
+ }
201
+
202
+ const previewDomains = app.getParam(projectAppParams.previewDomains);
203
+
204
+ if (previewDomains) {
205
+ (0, _customDomain.applyCustomDomain)(appCloudfront, previewDomains);
206
+ }
207
+
208
+ if (process.env.WCP_PROJECT_ENVIRONMENT || process.env.WEBINY_MULTI_TENANCY === "true") {
209
+ (0, _tenantRouter.applyTenantRouter)(app, deliveryCloudfront);
210
+ }
211
+
212
+ app.addOutputs({
213
+ // Cloudfront and S3 bucket used to host the single-page application (SPA). The URL of the distribution is mainly
214
+ // utilized by the Page Builder app's prerendering engine. Using this URL, it accesses the SPA and creates HTML snapshots.
215
+ // The files that are generated in that process are stored in the `deliveryStorage` S3 bucket further below.
216
+ appId: appCloudfront.output.id,
217
+ appStorage: appBucket.bucket.output.id,
218
+ appUrl: appCloudfront.output.domainName.apply(value => `https://${value}`),
219
+ appDomain: appCloudfront.output.domainName,
220
+ // These are the Cloudfront and S3 bucket that will deliver static pages to the actual website visitors.
221
+ // The static HTML snapshots delivered from them still rely on the app's S3 bucket
222
+ // defined above, for serving static assets (JS, CSS, images).
223
+ deliveryId: deliveryCloudfront.output.id,
224
+ deliveryStorage: deliveryBucket.bucket.output.id,
225
+ deliveryDomain: deliveryCloudfront.output.domainName,
226
+ deliveryUrl: deliveryCloudfront.output.domainName.apply(value => `https://${value}`)
227
+ });
228
+ (0, _utils.tagResources)({
229
+ WbyProjectName: String(process.env["WEBINY_PROJECT_NAME"]),
230
+ WbyEnvironment: String(process.env["WEBINY_ENV"])
231
+ });
232
+ return {
233
+ prerendering,
234
+ app: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, appBucket), {}, {
235
+ cloudfront: appCloudfront
236
+ }),
237
+ delivery: (0, _objectSpread2.default)((0, _objectSpread2.default)({}, deliveryBucket), {}, {
238
+ cloudfront: deliveryCloudfront
239
+ })
240
+ };
241
+ }
242
+ });
243
+ return (0, _utils.withCommonLambdaEnvVariables)(app);
244
+ };
245
+
246
+ exports.createWebsitePulumiApp = createWebsitePulumiApp;