@stacksjs/cloud 0.66.0 → 0.67.0

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.
@@ -1,71 +0,0 @@
1
- import type { aws_cloudfront as cloudfront, aws_s3 as s3 } from 'aws-cdk-lib'
2
- import type { Construct } from 'constructs'
3
- import type { NestedCloudProps } from '../types'
4
- import { config } from '@stacksjs/config'
5
- import { path as p } from '@stacksjs/path'
6
- import { hasFiles } from '@stacksjs/storage'
7
- import { docsSourceHash, websiteSourceHash } from '@stacksjs/utils'
8
- import { AssetHashType, aws_s3_deployment as s3deploy } from 'aws-cdk-lib'
9
-
10
- export interface DeploymentStackProps extends NestedCloudProps {
11
- publicBucket: s3.Bucket
12
- docsBucket?: s3.Bucket
13
- privateBucket: s3.Bucket
14
- mainDistribution: cloudfront.Distribution
15
- docsDistribution?: cloudfront.Distribution
16
- }
17
-
18
- export class DeploymentStack {
19
- privateSource: string
20
- docsSource: string
21
- publicSource: string
22
-
23
- constructor(scope: Construct, props: DeploymentStackProps) {
24
- // following paths are relative to where the command is run from
25
- this.privateSource = '../../private'
26
- this.docsSource = '../docs/dist/'
27
- this.publicSource = config.app.docMode === true ? this.docsSource : '../views/web/dist/'
28
- const mainBucket = config.app.docMode === true ? props.docsBucket : props.publicBucket
29
-
30
- new s3deploy.BucketDeployment(scope, 'Website', {
31
- sources: [
32
- s3deploy.Source.asset(this.publicSource, {
33
- assetHash: websiteSourceHash(),
34
- assetHashType: AssetHashType.CUSTOM,
35
- }),
36
- ],
37
- destinationBucket: mainBucket as s3.Bucket,
38
- distribution: props.mainDistribution,
39
- // distributionPaths: ['/*'],
40
- })
41
-
42
- if (this.shouldDeployDocs()) {
43
- // if docs should be deployed, add it to the deployment
44
- new s3deploy.BucketDeployment(scope, 'Docs', {
45
- sources: [
46
- s3deploy.Source.asset(this.docsSource, {
47
- assetHash: docsSourceHash(),
48
- assetHashType: AssetHashType.CUSTOM,
49
- }),
50
- ],
51
- destinationBucket: props.docsBucket as s3.Bucket,
52
- distribution: props.docsDistribution,
53
- // distributionPaths: ['/*'],
54
- })
55
- }
56
-
57
- if (hasFiles(this.privateSource)) {
58
- new s3deploy.BucketDeployment(scope, 'PrivateFiles', {
59
- sources: [s3deploy.Source.asset(this.privateSource)],
60
- destinationBucket: props.privateBucket,
61
- })
62
- }
63
- else {
64
- console.error(`The path ${this.privateSource} does not have any files`)
65
- }
66
- }
67
-
68
- shouldDeployDocs(): boolean {
69
- return hasFiles(p.projectPath('docs')) && !config.app.docMode
70
- }
71
- }
package/src/cloud/dns.ts DELETED
@@ -1,41 +0,0 @@
1
- import type { Construct } from 'constructs'
2
- import type { NestedCloudProps } from '../types'
3
- import { RemovalPolicy, aws_route53 as route53, aws_s3 as s3, aws_route53_targets as targets } from 'aws-cdk-lib'
4
-
5
- export class DnsStack {
6
- zone: route53.IHostedZone
7
-
8
- constructor(scope: Construct, props: NestedCloudProps) {
9
- // lets see if the zone already exists because Buddy should have created it already
10
- this.zone = route53.PublicHostedZone.fromLookup(scope, 'AppUrlHostedZone', {
11
- domainName: props.domain,
12
- })
13
-
14
- // setup the www redirect
15
- // Create a bucket for www.yourdomain.com and configure it to redirect to yourdomain.com
16
- const wwwBucket = new s3.Bucket(scope, 'WwwBucket', {
17
- bucketName: `www.${props.domain}`,
18
- websiteRedirect: {
19
- hostName: props.domain,
20
- protocol: s3.RedirectProtocol.HTTPS,
21
- },
22
- removalPolicy: RemovalPolicy.DESTROY,
23
- autoDeleteObjects: true,
24
- })
25
-
26
- // Create a Route53 record for www.yourdomain.com
27
- new route53.ARecord(scope, 'WwwAliasRecord', {
28
- recordName: `www.${props.domain}`,
29
- zone: this.zone,
30
- target: route53.RecordTarget.fromAlias(new targets.BucketWebsiteTarget(wwwBucket)),
31
- })
32
-
33
- // TODO: this only needs to be created if Lemon Squeezy is being used
34
- // Create a Route53 record for www.yourdomain.com
35
- new route53.ARecord(scope, 'StoreAliasRecord', {
36
- recordName: `store.${props.domain}`,
37
- zone: this.zone,
38
- target: route53.RecordTarget.fromIpAddresses('137.66.37.136'),
39
- })
40
- }
41
- }
package/src/cloud/docs.ts DELETED
@@ -1,50 +0,0 @@
1
- import type { CfnResource } from 'aws-cdk-lib'
2
- import type { Construct } from 'constructs'
3
- import type { NestedCloudProps } from '../types'
4
- import { config } from '@stacksjs/config'
5
- import { path as p } from '@stacksjs/path'
6
- import { storage } from '@stacksjs/storage'
7
- import { originRequestFunctionHash } from '@stacksjs/utils'
8
- import { AssetHashType, aws_lambda as lambda, CfnOutput as Output, RemovalPolicy } from 'aws-cdk-lib'
9
-
10
- export interface DocsStackProps extends NestedCloudProps {
11
- //
12
- }
13
-
14
- export class DocsStack {
15
- originRequestFunction: lambda.Function
16
-
17
- constructor(scope: Construct, props: DocsStackProps) {
18
- // if docsPrefix is not set, then we know we are in docsMode and the documentation lives at the root of the domain
19
- const docsPrefix = 'docs'
20
-
21
- // this edge function ensures pretty docs urls
22
- // soon to be reused for our Meema features
23
- this.originRequestFunction = new lambda.Function(scope, 'OriginRequestFunction', {
24
- // this needs to have timestamp to ensure uniqueness. Since Origin Request (Lambda@Edge) functions are replicated functions, the
25
- // deletion process takes a "long time". This way, the function is always unique in cases of quick recreations.
26
- functionName: `${props.slug}-${props.appEnv}-origin-request-${props.timestamp}`,
27
- description: 'The Stacks Origin Request function that prettifies URLs by removing the .html extension',
28
- runtime: lambda.Runtime.NODEJS_20_X,
29
- handler: 'dist/origin-request.handler',
30
- code: lambda.Code.fromAsset(p.cloudPath('dist.zip'), {
31
- assetHash: originRequestFunctionHash(),
32
- assetHashType: AssetHashType.CUSTOM,
33
- }),
34
- })
35
-
36
- // applying this is a workaround for failing deployments due to the following DELETE_FAILED error:
37
- // > Resource handler returned message: "Lambda was unable to delete arn:aws:lambda:us-east-1:92330274019:function:stacks-cloud-production-OriginRequestFunction4FA39-XQadJcSWY8Lz:1 because it is a replicated function. Please see our documentation for Deleting Lambda@Edge Functions and Replicas. (Service: Lambda, Status Code: 400, Request ID: 83bd3112-aaa4-4980-bfcf-3ee2052a0435)" (RequestToken: c91aed31-1a62-9425-c25d-4fc0fccfa45f, HandlerErrorCode: InvalidRequest)
38
- // if we do not delete this resource, then it circumvents trying to delete the function and the deployment succeeds
39
- // buddy cloud:cleanup is what will be suggested running after user ensured no more sensitive data is in the buckets
40
- const cfnOriginRequestFunction = this.originRequestFunction.node.defaultChild as CfnResource
41
- cfnOriginRequestFunction.applyRemovalPolicy(RemovalPolicy.RETAIN)
42
-
43
- if (!config.app.docMode && storage.hasFiles(p.projectPath('docs'))) {
44
- new Output(scope, 'DocsUrl', {
45
- value: `https://${docsPrefix}.${props.domain}`,
46
- description: 'The URL of the deployed documentation',
47
- })
48
- }
49
- }
50
- }
@@ -1,356 +0,0 @@
1
- import type { Construct } from 'constructs'
2
- import type { NestedCloudProps } from '../types'
3
- import { config } from '@stacksjs/config'
4
- import {
5
- Duration,
6
- aws_iam as iam,
7
- aws_lambda as lambda,
8
- RemovalPolicy,
9
- aws_route53 as route53,
10
- aws_s3 as s3,
11
- aws_s3_notifications as s3n,
12
- aws_ses as ses,
13
- Stack,
14
- Tags,
15
- } from 'aws-cdk-lib'
16
-
17
- export interface EmailStackProps extends NestedCloudProps {
18
- zone: route53.IHostedZone
19
- }
20
-
21
- export class EmailStack {
22
- emailBucket: s3.Bucket
23
-
24
- constructor(scope: Construct, props: EmailStackProps) {
25
- const bucketPrefix = `${props.slug}-${props.appEnv}`
26
- this.emailBucket = new s3.Bucket(scope, 'EmailBucket', {
27
- bucketName: `${bucketPrefix}-email-${props.timestamp}`,
28
- versioned: true,
29
- removalPolicy: RemovalPolicy.DESTROY,
30
- autoDeleteObjects: true,
31
- // encryptionKey: this.encryptionKey,
32
- encryption: s3.BucketEncryption.S3_MANAGED,
33
- lifecycleRules: [
34
- {
35
- id: '24h',
36
- enabled: true,
37
- expiration: Duration.days(1),
38
- noncurrentVersionExpiration: Duration.days(1),
39
- prefix: 'today/',
40
- },
41
- {
42
- id: 'Intelligent transition for Inbox',
43
- enabled: true,
44
- prefix: 'inbox/',
45
- transitions: [
46
- {
47
- storageClass: s3.StorageClass.INTELLIGENT_TIERING,
48
- transitionAfter: Duration.days(0),
49
- },
50
- ],
51
- },
52
- {
53
- id: 'Intelligent transition for Sent',
54
- enabled: true,
55
- prefix: 'sent/',
56
- transitions: [
57
- {
58
- storageClass: s3.StorageClass.INTELLIGENT_TIERING,
59
- transitionAfter: Duration.days(0),
60
- },
61
- ],
62
- },
63
- ],
64
- })
65
-
66
- Tags.of(this.emailBucket).add('daily-backup', 'true')
67
-
68
- const sesPrincipal = new iam.ServicePrincipal('ses.amazonaws.com')
69
- const ruleSetName = `${props.slug}-${props.appEnv}-email-receipt-rule-set`
70
- const receiptRuleName = `${props.slug}-${props.appEnv}-email-receipt-rule`
71
-
72
- const ruleSet = new ses.CfnReceiptRuleSet(scope, 'SESReceiptRuleSet', {
73
- ruleSetName,
74
- })
75
-
76
- this.emailBucket.addToResourcePolicy(
77
- new iam.PolicyStatement({
78
- sid: 'AllowSESPuts',
79
- effect: iam.Effect.ALLOW,
80
- principals: [sesPrincipal],
81
- actions: ['s3:PutObject'],
82
- resources: [`${this.emailBucket.bucketArn}/*`],
83
- conditions: {
84
- StringEquals: {
85
- 'aws:SourceAccount': Stack.of(scope).account,
86
- },
87
- ArnLike: {
88
- 'aws:SourceArn': `arn:aws:ses:${Stack.of(scope).region}:${
89
- Stack.of(scope).account
90
- }:receipt-rule-set/${ruleSetName}:receipt-rule/${receiptRuleName}`,
91
- },
92
- },
93
- }),
94
- )
95
-
96
- const receiptRule = new ses.CfnReceiptRule(scope, 'SESReceiptRule', {
97
- ruleSetName: ruleSet.ref,
98
- rule: {
99
- name: receiptRuleName,
100
- enabled: true,
101
- actions: [
102
- {
103
- s3Action: {
104
- bucketName: this.emailBucket.bucketName,
105
- objectKeyPrefix: 'tmp/email_in/',
106
- },
107
- },
108
- ],
109
- recipients: config.email.mailboxes || [],
110
- scanEnabled: config.email.server?.scan || true,
111
- tlsPolicy: 'Require',
112
- },
113
- })
114
-
115
- // this line is important to make sure the bucket is created before the receipt rule
116
- // do not remove it, unless you want a hell of a time debugging randomness
117
- receiptRule.node.addDependency(this.emailBucket)
118
-
119
- const iamGroup = new iam.Group(scope, 'IAMGroup', {
120
- groupName: `${props.slug}-${props.appEnv}-email-management-s3-group`,
121
- })
122
-
123
- const listBucketsPolicyStatement = new iam.PolicyStatement({
124
- effect: iam.Effect.ALLOW,
125
- actions: ['s3:ListAllMyBuckets'],
126
- resources: ['*'],
127
- })
128
-
129
- const policyStatement = new iam.PolicyStatement({
130
- effect: iam.Effect.ALLOW,
131
- actions: [
132
- 's3:ListBucket',
133
- 's3:GetObject',
134
- 's3:PutObject',
135
- 's3:DeleteObject',
136
- 's3:GetObjectAcl',
137
- 's3:GetObjectVersionAcl',
138
- 's3:PutObjectAcl',
139
- 's3:PutObjectVersionAcl',
140
- ],
141
- resources: [this.emailBucket.bucketArn, `${this.emailBucket.bucketArn}/*`],
142
- })
143
-
144
- const policy = new iam.Policy(scope, 'EmailAccessPolicy', {
145
- policyName: `${props.slug}-${props.appEnv}-email-management-s3-policy`,
146
- statements: [policyStatement, listBucketsPolicyStatement],
147
- })
148
-
149
- iamGroup.attachInlinePolicy(policy)
150
-
151
- // Create a SES domain identity
152
- const sesIdentity = new ses.CfnEmailIdentity(scope, 'DomainIdentity', {
153
- emailIdentity: props.domain,
154
-
155
- dkimSigningAttributes: {
156
- nextSigningKeyLength: 'RSA_2048_BIT',
157
- },
158
-
159
- dkimAttributes: {
160
- signingEnabled: true,
161
- },
162
-
163
- mailFromAttributes: {
164
- behaviorOnMxFailure: 'USE_DEFAULT_VALUE',
165
- mailFromDomain: `mail.${props.domain}`,
166
- },
167
-
168
- feedbackAttributes: {
169
- emailForwardingEnabled: true,
170
- },
171
- })
172
-
173
- // Create a Route53 records for the SES domain identity
174
- // https://github.com/aws/aws-cdk/issues/21306
175
- new route53.CfnRecordSet(scope, 'DkimRecord1', {
176
- hostedZoneName: `${props.zone.zoneName}.`,
177
- name: sesIdentity.attrDkimDnsTokenName1,
178
- type: 'CNAME',
179
- resourceRecords: [sesIdentity.attrDkimDnsTokenValue1],
180
- ttl: '1800',
181
- })
182
-
183
- new route53.CfnRecordSet(scope, 'DkimRecord2', {
184
- hostedZoneName: `${props.zone.zoneName}.`,
185
- name: sesIdentity.attrDkimDnsTokenName2,
186
- type: 'CNAME',
187
- resourceRecords: [sesIdentity.attrDkimDnsTokenValue2],
188
- ttl: '1800',
189
- })
190
-
191
- new route53.CfnRecordSet(scope, 'DkimRecord3', {
192
- hostedZoneName: `${props.zone.zoneName}.`,
193
- name: sesIdentity.attrDkimDnsTokenName3,
194
- type: 'CNAME',
195
- resourceRecords: [sesIdentity.attrDkimDnsTokenValue3],
196
- ttl: '1800',
197
- })
198
-
199
- new route53.MxRecord(scope, 'MxRecord', {
200
- zone: props.zone,
201
- recordName: 'mail',
202
- values: [
203
- {
204
- priority: 10,
205
- hostName: 'feedback-smtp.us-east-1.amazonses.com',
206
- },
207
- ],
208
- })
209
-
210
- new route53.TxtRecord(scope, 'TxtSpfRecord', {
211
- zone: props.zone,
212
- recordName: 'mail',
213
- values: ['v=spf1 include:amazonses.com ~all'],
214
- })
215
-
216
- new route53.TxtRecord(scope, 'TxtDmarcRecord', {
217
- zone: props.zone,
218
- recordName: '_dmarc',
219
- values: [`v=DMARC1;p=quarantine;pct=25;rua=mailto:dmarcreports@${props.domain}`],
220
- })
221
-
222
- const lambdaEmailOutboundRole = new iam.Role(scope, 'LambdaEmailOutboundRole', {
223
- roleName: `${props.slug}-${props.appEnv}-email-outbound`,
224
- assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
225
- managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')],
226
- })
227
-
228
- const lambdaEmailOutbound = new lambda.Function(scope, 'LambdaEmailOutbound', {
229
- functionName: `${props.slug}-${props.appEnv}-email-outbound`,
230
- description: 'Take the JSON and convert it in to an raw email.',
231
- code: lambda.Code.fromInline('exports.handler = async (event) => {return true;};'), // this needs to be updated with the real lambda code
232
- handler: 'index.handler',
233
- memorySize: 256,
234
- runtime: lambda.Runtime.NODEJS_18_X,
235
- timeout: Duration.seconds(60),
236
- environment: {
237
- BUCKET: this.emailBucket.bucketName,
238
- },
239
- role: lambdaEmailOutboundRole,
240
- })
241
-
242
- lambdaEmailOutboundRole.addToPolicy(policyStatement)
243
-
244
- const sesPolicyStatement = new iam.PolicyStatement({
245
- effect: iam.Effect.ALLOW,
246
- actions: ['ses:SendRawEmail'],
247
- resources: ['*'],
248
- })
249
-
250
- lambdaEmailOutboundRole.addToPolicy(sesPolicyStatement)
251
-
252
- const lambdaEmailInboundRole = new iam.Role(scope, 'LambdaEmailInboundRole', {
253
- roleName: `${props.slug}-${props.appEnv}-email-inbound`,
254
- assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
255
- managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')],
256
- })
257
-
258
- const lambdaEmailInbound = new lambda.Function(scope, 'LambdaEmailInbound', {
259
- functionName: `${props.slug}-${props.appEnv}-email-inbound`,
260
- description: 'This Lambda organizes all the incoming emails based on the From and To field.',
261
- code: lambda.Code.fromInline('exports.handler = async (event) => {return true;};'), // this needs to be updated with the real lambda code
262
- handler: 'index.handler',
263
- memorySize: 256,
264
- role: lambdaEmailInboundRole,
265
- runtime: lambda.Runtime.NODEJS_18_X,
266
- timeout: Duration.seconds(60),
267
- environment: {
268
- BUCKET: this.emailBucket.bucketName,
269
- },
270
- })
271
-
272
- new lambda.CfnPermission(scope, 'S3InboundPermission', {
273
- action: 'lambda:InvokeFunction',
274
- functionName: lambdaEmailInbound.functionName,
275
- principal: 's3.amazonaws.com',
276
- })
277
-
278
- const inboundS3PolicyStatement = new iam.PolicyStatement({
279
- effect: iam.Effect.ALLOW,
280
- actions: ['s3:*'],
281
- resources: [this.emailBucket.bucketArn, `${this.emailBucket.bucketArn}/*`],
282
- })
283
-
284
- lambdaEmailInboundRole.addToPolicy(inboundS3PolicyStatement)
285
-
286
- const sesInboundPolicyStatement = new iam.PolicyStatement({
287
- effect: iam.Effect.ALLOW,
288
- actions: ['ses:ListIdentities'],
289
- resources: ['*'],
290
- })
291
-
292
- lambdaEmailInboundRole.addToPolicy(sesInboundPolicyStatement)
293
-
294
- const lambdaEmailConverterRole = new iam.Role(scope, 'LambdaEmailConverterRole', {
295
- roleName: `${props.slug}-${props.appEnv}-email-converter`,
296
- assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
297
- managedPolicies: [iam.ManagedPolicy.fromAwsManagedPolicyName('service-role/AWSLambdaBasicExecutionRole')],
298
- })
299
-
300
- const lambdaEmailConverter = new lambda.Function(scope, 'LambdaEmailConverter', {
301
- functionName: `${props.slug}-${props.appEnv}-email-converter`,
302
- description: 'This Lambda converts raw emails files in to HTML and text.',
303
- code: lambda.Code.fromInline(
304
- 'exports.handler = async (event) => {console.log("hello world email converter");return true;};',
305
- ), // this needs to be updated with the real lambda code
306
- handler: 'index.handler',
307
- memorySize: 256,
308
- role: lambdaEmailConverterRole,
309
- runtime: lambda.Runtime.NODEJS_18_X,
310
- timeout: Duration.seconds(60),
311
- environment: {
312
- BUCKET: this.emailBucket.bucketName,
313
- },
314
- })
315
-
316
- const converterS3PolicyStatement = new iam.PolicyStatement({
317
- effect: iam.Effect.ALLOW,
318
- actions: ['s3:*'],
319
- resources: [this.emailBucket.bucketArn, `${this.emailBucket.bucketArn}/*`],
320
- })
321
-
322
- new lambda.CfnPermission(scope, 'S3ConverterPermission', {
323
- action: 'lambda:InvokeFunction',
324
- functionName: lambdaEmailConverter.functionName,
325
- principal: 's3.amazonaws.com',
326
- })
327
-
328
- lambdaEmailConverterRole.addToPolicy(converterS3PolicyStatement)
329
-
330
- this.emailBucket.addEventNotification(
331
- s3.EventType.OBJECT_CREATED_PUT,
332
- new s3n.LambdaDestination(lambdaEmailInbound),
333
- { prefix: 'tmp/email_in/' },
334
- )
335
- this.emailBucket.addEventNotification(
336
- s3.EventType.OBJECT_CREATED_PUT,
337
- new s3n.LambdaDestination(lambdaEmailOutbound),
338
- { prefix: 'tmp/email_out/json/' },
339
- )
340
- this.emailBucket.addEventNotification(
341
- s3.EventType.OBJECT_CREATED_COPY,
342
- new s3n.LambdaDestination(lambdaEmailConverter),
343
- { prefix: 'sent/' },
344
- )
345
- this.emailBucket.addEventNotification(
346
- s3.EventType.OBJECT_CREATED_COPY,
347
- new s3n.LambdaDestination(lambdaEmailConverter),
348
- { prefix: 'inbox/' },
349
- )
350
- this.emailBucket.addEventNotification(
351
- s3.EventType.OBJECT_CREATED_COPY,
352
- new s3n.LambdaDestination(lambdaEmailConverter),
353
- { prefix: 'today/' },
354
- )
355
- }
356
- }
@@ -1,35 +0,0 @@
1
- import type { aws_ec2 as ec2 } from 'aws-cdk-lib'
2
- import type { Construct } from 'constructs'
3
- import type { NestedCloudProps } from '../types'
4
- import { aws_efs as efs, RemovalPolicy } from 'aws-cdk-lib'
5
-
6
- export interface FileSystemStackProps extends NestedCloudProps {
7
- vpc: ec2.Vpc
8
- }
9
-
10
- export class FileSystemStack {
11
- fileSystem: efs.FileSystem
12
- accessPoint: efs.AccessPoint
13
-
14
- constructor(scope: Construct, props: FileSystemStackProps) {
15
- this.fileSystem = new efs.FileSystem(scope, 'FileSystem', {
16
- fileSystemName: `${props.slug}-${props.appEnv}-efs`,
17
- vpc: props.vpc,
18
- removalPolicy: RemovalPolicy.DESTROY,
19
- lifecyclePolicy: efs.LifecyclePolicy.AFTER_7_DAYS,
20
- performanceMode: efs.PerformanceMode.GENERAL_PURPOSE,
21
- throughputMode: efs.ThroughputMode.BURSTING,
22
- enableAutomaticBackups: true, // TODO: ensure this is documented
23
- encrypted: true,
24
- })
25
-
26
- this.accessPoint = new efs.AccessPoint(scope, 'FileSystemAccessPoint', {
27
- fileSystem: this.fileSystem,
28
- path: '/',
29
- posixUser: {
30
- uid: '1000',
31
- gid: '1000',
32
- },
33
- })
34
- }
35
- }
@@ -1,141 +0,0 @@
1
- import type { Construct } from 'constructs'
2
- import type { CloudOptions } from '../types'
3
- import { config } from '@stacksjs/config'
4
- import { Stack } from 'aws-cdk-lib'
5
- import { AiStack } from './ai'
6
- import { CdnStack } from './cdn'
7
- import { CliStack } from './cli'
8
- import { ComputeStack } from './compute'
9
- import { DeploymentStack } from './deployment'
10
- import { DnsStack } from './dns'
11
- import { DocsStack } from './docs'
12
- import { EmailStack } from './email'
13
- import { FileSystemStack } from './file-system'
14
- import { JumpBoxStack } from './jump-box'
15
- import { NetworkStack } from './network'
16
- import { PermissionsStack } from './permissions'
17
- import { QueueStack } from './queue'
18
- import { RedirectsStack } from './redirects'
19
- import { SecurityStack } from './security'
20
- import { StorageStack } from './storage'
21
-
22
- // import { DashboardStack } from './dashboard'
23
-
24
- export class Cloud extends Stack {
25
- dns: DnsStack
26
- security: SecurityStack
27
- storage: StorageStack
28
- network: NetworkStack
29
- fileSystem: FileSystemStack
30
- jumpBox: JumpBoxStack
31
- docs: DocsStack
32
- email: EmailStack
33
- redirects: RedirectsStack
34
- permissions: PermissionsStack
35
- ai: AiStack
36
- cli: CliStack
37
- api?: ComputeStack
38
- cdn!: CdnStack
39
- queue?: QueueStack
40
- deployment!: DeploymentStack
41
- scope: Construct
42
- props: CloudOptions
43
-
44
- constructor(scope: Construct, id: string, props: CloudOptions) {
45
- super(scope, id, props)
46
- this.scope = scope
47
- this.props = props
48
-
49
- // please beware: be careful changing the order of the stack creations below
50
- this.dns = new DnsStack(this, props)
51
- this.security = new SecurityStack(this, {
52
- ...props,
53
- zone: this.dns.zone,
54
- })
55
-
56
- this.storage = new StorageStack(this, {
57
- ...props,
58
- kmsKey: this.security.kmsKey,
59
- originAccessIdentity: this.security.originAccessIdentity,
60
- })
61
-
62
- this.network = new NetworkStack(this, props)
63
-
64
- this.fileSystem = new FileSystemStack(this, {
65
- ...props,
66
- vpc: this.network.vpc,
67
- })
68
-
69
- this.jumpBox = new JumpBoxStack(this, {
70
- ...props,
71
- vpc: this.network.vpc,
72
- fileSystem: this.fileSystem.fileSystem,
73
- })
74
-
75
- this.docs = new DocsStack(this, props)
76
-
77
- this.email = new EmailStack(this, {
78
- ...props,
79
- zone: this.dns.zone,
80
- })
81
-
82
- this.redirects = new RedirectsStack(this, props)
83
-
84
- this.permissions = new PermissionsStack(this)
85
-
86
- // new DashboardStack(this)
87
-
88
- this.ai = new AiStack(this, props)
89
-
90
- this.cli = new CliStack(this, props)
91
- }
92
-
93
- // we use an async init() method here because we need to wait for the
94
-
95
- async init(): Promise<void> {
96
- const props = this.props
97
-
98
- if (this.shouldDeployApi()) {
99
- this.api = new ComputeStack(this, {
100
- ...props,
101
- vpc: this.network.vpc,
102
- fileSystem: this.fileSystem.fileSystem,
103
- zone: this.dns.zone,
104
- certificate: this.security.certificate,
105
- })
106
-
107
- this.queue = new QueueStack(this, {
108
- ...props,
109
- cluster: this.api.cluster,
110
- taskDefinition: this.api.taskDefinition,
111
- })
112
-
113
- await this.queue.init()
114
- }
115
-
116
- this.cdn = new CdnStack(this, {
117
- ...props,
118
- publicBucket: this.storage.publicBucket,
119
- docsBucket: this.storage.docsBucket,
120
- logBucket: this.storage.logBucket,
121
- certificate: this.security.certificate,
122
- firewall: this.security.firewall,
123
- originRequestFunction: this.docs.originRequestFunction,
124
- zone: this.dns.zone,
125
- lb: this.api?.lb,
126
- })
127
-
128
- this.deployment = new DeploymentStack(this, {
129
- ...props,
130
- publicBucket: this.storage.publicBucket,
131
- privateBucket: this.storage.privateBucket,
132
- docsBucket: this.storage.docsBucket,
133
- mainDistribution: this.cdn.mainDistribution,
134
- docsDistribution: this.cdn.docsDistribution,
135
- })
136
- }
137
-
138
- shouldDeployApi(): boolean {
139
- return config.cloud.api?.deploy ?? false
140
- }
141
- }