@wolsok/spa-cdk-stack 1.1.2 → 1.2.1
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.
- package/README.md +8 -3
- package/package.json +1 -1
- package/src/lib/spa/spa.construct.d.ts +14 -0
- package/src/lib/spa/spa.construct.js +33 -23
- package/src/lib/spa/spa.construct.js.map +1 -1
- package/src/lib/spa/spa.stack.d.ts +16 -0
- package/src/lib/spa/spa.stack.js +41 -3
- package/src/lib/spa/spa.stack.js.map +1 -1
package/README.md
CHANGED
|
@@ -6,8 +6,13 @@ It creates an S3 bucket and a CloudFront distribution to serve the SPA.
|
|
|
6
6
|
Features are:
|
|
7
7
|
|
|
8
8
|
- Deployment of your build files to the S3 bucket.
|
|
9
|
-
-
|
|
10
|
-
|
|
9
|
+
- CloudFront invalidation with every deployment; the deploy only waits for the
|
|
10
|
+
one issued with index.html, the last upload
|
|
11
|
+
- Creation of a certificate for your domain. CloudFront only takes certificates
|
|
12
|
+
from us-east-1, so in any other region `SpaStack` puts it into a second stack,
|
|
13
|
+
`<name>Certificate` in us-east-1, referenced across regions. Deploy such an
|
|
14
|
+
app with `cdk deploy --all`, or name the SPA stack, and bootstrap both
|
|
15
|
+
regions.
|
|
11
16
|
- Redirect from HTTP to HTTPS with an ACM certificate.
|
|
12
17
|
- Route53 alias record creation,
|
|
13
18
|
|
|
@@ -19,7 +24,7 @@ headers:
|
|
|
19
24
|
|
|
20
25
|
```ts
|
|
21
26
|
new SpaStack(app, 'MyApp', {
|
|
22
|
-
env: { region: '
|
|
27
|
+
env: { region: 'eu-central-1', account: '123456789012' },
|
|
23
28
|
buildOutputPath: 'dist/apps/my-app',
|
|
24
29
|
domainName: 'my-app.example.com',
|
|
25
30
|
noCacheFiles: ['remoteEntry.json'],
|
package/package.json
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RemovalPolicy } from 'aws-cdk-lib';
|
|
2
|
+
import { ICertificate } from 'aws-cdk-lib/aws-certificatemanager';
|
|
2
3
|
import { CacheControl, ISource } from 'aws-cdk-lib/aws-s3-deployment';
|
|
3
4
|
import { Construct } from 'constructs';
|
|
4
5
|
export interface SpaProps {
|
|
@@ -6,6 +7,12 @@ export interface SpaProps {
|
|
|
6
7
|
buildOutputPath: string;
|
|
7
8
|
bucketRemovalPolicy?: RemovalPolicy;
|
|
8
9
|
extraAllowedOrigins?: string[];
|
|
10
|
+
/**
|
|
11
|
+
* The certificate of the distribution, which CloudFront only takes from
|
|
12
|
+
* us-east-1. Without it the construct creates one, so it must then sit in a
|
|
13
|
+
* us-east-1 stack. SpaStack passes one when its region is another.
|
|
14
|
+
*/
|
|
15
|
+
certificate?: ICertificate;
|
|
9
16
|
/**
|
|
10
17
|
* Files that keep their names across releases, such as a service worker,
|
|
11
18
|
* its ngsw.json or an import map, as globs relative to buildOutputPath.
|
|
@@ -29,6 +36,11 @@ export interface CacheOverride {
|
|
|
29
36
|
cacheControl: CacheControl;
|
|
30
37
|
contentType?: string;
|
|
31
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* The names the certificate of a SPA covers: the main domain, and the site
|
|
41
|
+
* domain as well when it is a subdomain.
|
|
42
|
+
*/
|
|
43
|
+
export declare function certificateDomainNames(domainName: string): string[];
|
|
32
44
|
/**
|
|
33
45
|
* SPA infrastructure, which deploys spa content to an S3 bucket.
|
|
34
46
|
*
|
|
@@ -51,6 +63,8 @@ export declare class SpaConstruct extends Construct {
|
|
|
51
63
|
* or they are uploaded twice.
|
|
52
64
|
*/
|
|
53
65
|
addExtraAssets(assets: ISource[], cacheControl?: CacheControl, contentType?: string): void;
|
|
66
|
+
/** Adds a deployment that runs after the uploads so far and before index.html. */
|
|
67
|
+
private addUpload;
|
|
54
68
|
private createBucket;
|
|
55
69
|
private createCertificate;
|
|
56
70
|
private createDistribution;
|
|
@@ -27,6 +27,14 @@ function onlyInclude(files) {
|
|
|
27
27
|
}
|
|
28
28
|
return ['**', ...[...included].map((glob) => '!' + glob)];
|
|
29
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* The names the certificate of a SPA covers: the main domain, and the site
|
|
32
|
+
* domain as well when it is a subdomain.
|
|
33
|
+
*/
|
|
34
|
+
export function certificateDomainNames(domainName) {
|
|
35
|
+
const mainDomain = domainName.split('.').slice(-2).join('.');
|
|
36
|
+
return mainDomain === domainName ? [mainDomain] : [mainDomain, domainName];
|
|
37
|
+
}
|
|
30
38
|
const defaultBucketRemovalPolicy = RemovalPolicy.DESTROY;
|
|
31
39
|
/**
|
|
32
40
|
* SPA infrastructure, which deploys spa content to an S3 bucket.
|
|
@@ -54,13 +62,8 @@ export class SpaConstruct extends Construct {
|
|
|
54
62
|
domainName: mainDomain,
|
|
55
63
|
});
|
|
56
64
|
new CfnOutput(this, `${spaName}-Site:`, { value: 'https://' + siteDomain });
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
certificate = this.createCertificate(zone, mainDomain);
|
|
60
|
-
}
|
|
61
|
-
else {
|
|
62
|
-
certificate = this.createCertificate(zone, mainDomain, siteDomain);
|
|
63
|
-
}
|
|
65
|
+
const certificate = props.certificate ??
|
|
66
|
+
this.createCertificate(zone, ...certificateDomainNames(siteDomain));
|
|
64
67
|
this.bucket = this.createBucket(siteDomain, removalPolicy);
|
|
65
68
|
this.distribution = this.createDistribution(siteDomain, certificate, this.bucket, extraAllowedOrigins);
|
|
66
69
|
this.createARecord(siteDomain, this.distribution, zone);
|
|
@@ -69,18 +72,21 @@ export class SpaConstruct extends Construct {
|
|
|
69
72
|
// again to restore it. Old bundles stay for tabs still running them.
|
|
70
73
|
// The first deployment owns the handler that all of them share, so the
|
|
71
74
|
// build output comes first and index.html, which waits for the rest, second.
|
|
75
|
+
// Every deployment invalidates the distribution when its content changed,
|
|
76
|
+
// but only the last one, index.html, waits for its invalidation: one wait
|
|
77
|
+
// at the end instead of one per deployment.
|
|
72
78
|
this.lastUpload = this.createBucketDeployment([
|
|
73
79
|
Source.asset(buildOutputPath, {
|
|
74
80
|
exclude: ['index.html', ...overrides.flatMap(({ files }) => files)],
|
|
75
81
|
}),
|
|
76
|
-
]
|
|
82
|
+
]);
|
|
77
83
|
this.bucketDeployments.push(this.lastUpload);
|
|
78
84
|
// index.html goes last, once every file it points at is uploaded.
|
|
79
|
-
this.indexDeployment = this.createBucketDeployment([Source.asset(buildOutputPath, { exclude: ['**', '!index.html'] })], CacheControl.noCache()
|
|
85
|
+
this.indexDeployment = this.createBucketDeployment([Source.asset(buildOutputPath, { exclude: ['**', '!index.html'] })], { cacheControl: CacheControl.noCache() }, true);
|
|
80
86
|
this.bucketDeployments.push(this.indexDeployment);
|
|
81
87
|
this.indexDeployment.node.addDependency(this.lastUpload);
|
|
82
88
|
for (const { files, cacheControl, contentType } of overrides) {
|
|
83
|
-
this.
|
|
89
|
+
this.addUpload([Source.asset(buildOutputPath, { exclude: onlyInclude(files) })], { cacheControl, contentType });
|
|
84
90
|
}
|
|
85
91
|
}
|
|
86
92
|
/**
|
|
@@ -89,12 +95,16 @@ export class SpaConstruct extends Construct {
|
|
|
89
95
|
* buildOutputPath; for those that are, use noCacheFiles or cacheOverrides,
|
|
90
96
|
* or they are uploaded twice.
|
|
91
97
|
*/
|
|
92
|
-
addExtraAssets(assets, cacheControl
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
this.
|
|
98
|
+
addExtraAssets(assets, cacheControl, contentType) {
|
|
99
|
+
this.addUpload(assets, { cacheControl, contentType });
|
|
100
|
+
}
|
|
101
|
+
/** Adds a deployment that runs after the uploads so far and before index.html. */
|
|
102
|
+
addUpload(sources, options) {
|
|
103
|
+
const deployment = this.createBucketDeployment(sources, options);
|
|
104
|
+
deployment.node.addDependency(this.lastUpload);
|
|
105
|
+
this.lastUpload = deployment;
|
|
106
|
+
this.bucketDeployments.push(deployment);
|
|
107
|
+
this.indexDeployment.node.addDependency(deployment);
|
|
98
108
|
}
|
|
99
109
|
createBucket(siteDomain, removalPolicy = RemovalPolicy.DESTROY) {
|
|
100
110
|
// Content bucket
|
|
@@ -186,17 +196,17 @@ export class SpaConstruct extends Construct {
|
|
|
186
196
|
});
|
|
187
197
|
new CfnOutput(this, `${this.spaName}-ARecord`, { value: siteDomain });
|
|
188
198
|
}
|
|
189
|
-
createBucketDeployment(sources, cacheControl = CacheControl.maxAge(Duration.days(365)),
|
|
190
|
-
// Deploy site contents to S3 spaBucket
|
|
199
|
+
createBucketDeployment(sources, { cacheControl = CacheControl.maxAge(Duration.days(365)), contentType, } = {}, waitForDistributionInvalidation = false) {
|
|
191
200
|
return new BucketDeployment(this, 'DeployWithInvalidation' + (this.bucketDeployments.length + 1), {
|
|
192
201
|
sources,
|
|
193
|
-
destinationBucket,
|
|
194
|
-
distribution,
|
|
195
|
-
prune,
|
|
196
|
-
memoryLimit: 1024,
|
|
202
|
+
destinationBucket: this.bucket,
|
|
203
|
+
distribution: this.distribution,
|
|
197
204
|
distributionPaths: ['/*'],
|
|
205
|
+
waitForDistributionInvalidation,
|
|
206
|
+
prune: false,
|
|
207
|
+
memoryLimit: 1024,
|
|
198
208
|
cacheControl: [cacheControl],
|
|
199
|
-
|
|
209
|
+
contentType,
|
|
200
210
|
});
|
|
201
211
|
}
|
|
202
212
|
extractDomains(domainName) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spa.construct.js","sourceRoot":"","sources":["../../../../../../../libs/public/spa-cdk-stack/src/lib/spa/spa.construct.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjE,OAAO,EACL,WAAW,EACX,qBAAqB,
|
|
1
|
+
{"version":3,"file":"spa.construct.js","sourceRoot":"","sources":["../../../../../../../libs/public/spa-cdk-stack/src/lib/spa/spa.construct.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,28 @@
|
|
|
1
1
|
import { Stack, StackProps } from 'aws-cdk-lib';
|
|
2
|
+
import { Certificate } from 'aws-cdk-lib/aws-certificatemanager';
|
|
2
3
|
import { Construct } from 'constructs';
|
|
3
4
|
import { SpaConstruct, SpaProps } from './spa.construct';
|
|
4
5
|
export type SpaStackProps = StackProps & SpaProps;
|
|
6
|
+
/** CloudFront only takes certificates from this region. */
|
|
7
|
+
export declare const CLOUDFRONT_CERTIFICATE_REGION = "us-east-1";
|
|
5
8
|
/**
|
|
6
9
|
* A stack that holds a single SpaConstruct with the same id as the stack.
|
|
7
10
|
* Extend it and call `spa.addExtraAssets` to deploy further files.
|
|
11
|
+
*
|
|
12
|
+
* In a region other than us-east-1 the certificate goes into a second stack,
|
|
13
|
+
* `<name>Certificate` in us-east-1, which the SPA stack references across
|
|
14
|
+
* regions. Deploy the app with `--all`, or name the SPA stack: CDK deploys
|
|
15
|
+
* the certificate stack first either way.
|
|
8
16
|
*/
|
|
9
17
|
export declare class SpaStack extends Stack {
|
|
10
18
|
readonly spa: SpaConstruct;
|
|
11
19
|
constructor(parent: Construct, name: string, props: SpaStackProps);
|
|
12
20
|
}
|
|
21
|
+
export interface SpaCertificateStackProps extends StackProps {
|
|
22
|
+
domainName: string;
|
|
23
|
+
}
|
|
24
|
+
/** The certificate of a SPA, in a stack that other regions can reference. */
|
|
25
|
+
export declare class SpaCertificateStack extends Stack {
|
|
26
|
+
readonly certificate: Certificate;
|
|
27
|
+
constructor(parent: Construct, name: string, { domainName, ...props }: SpaCertificateStackProps);
|
|
28
|
+
}
|
package/src/lib/spa/spa.stack.js
CHANGED
|
@@ -1,14 +1,52 @@
|
|
|
1
1
|
import { Stack } from 'aws-cdk-lib';
|
|
2
|
-
import {
|
|
2
|
+
import { Certificate, CertificateValidation, } from 'aws-cdk-lib/aws-certificatemanager';
|
|
3
|
+
import { HostedZone } from 'aws-cdk-lib/aws-route53';
|
|
4
|
+
import { certificateDomainNames, SpaConstruct, } from './spa.construct';
|
|
5
|
+
/** CloudFront only takes certificates from this region. */
|
|
6
|
+
export const CLOUDFRONT_CERTIFICATE_REGION = 'us-east-1';
|
|
3
7
|
/**
|
|
4
8
|
* A stack that holds a single SpaConstruct with the same id as the stack.
|
|
5
9
|
* Extend it and call `spa.addExtraAssets` to deploy further files.
|
|
10
|
+
*
|
|
11
|
+
* In a region other than us-east-1 the certificate goes into a second stack,
|
|
12
|
+
* `<name>Certificate` in us-east-1, which the SPA stack references across
|
|
13
|
+
* regions. Deploy the app with `--all`, or name the SPA stack: CDK deploys
|
|
14
|
+
* the certificate stack first either way.
|
|
6
15
|
*/
|
|
7
16
|
export class SpaStack extends Stack {
|
|
8
17
|
constructor(parent, name, props) {
|
|
9
|
-
|
|
18
|
+
const region = props.env?.region;
|
|
19
|
+
const certificateElsewhere = !props.certificate &&
|
|
20
|
+
region !== undefined &&
|
|
21
|
+
region !== CLOUDFRONT_CERTIFICATE_REGION;
|
|
22
|
+
super(parent, name, {
|
|
23
|
+
...props,
|
|
24
|
+
crossRegionReferences: props.crossRegionReferences || certificateElsewhere,
|
|
25
|
+
});
|
|
26
|
+
const certificate = certificateElsewhere
|
|
27
|
+
? new SpaCertificateStack(parent, `${name}Certificate`, {
|
|
28
|
+
env: { ...props.env, region: CLOUDFRONT_CERTIFICATE_REGION },
|
|
29
|
+
domainName: props.domainName,
|
|
30
|
+
}).certificate
|
|
31
|
+
: props.certificate;
|
|
10
32
|
// SpaConstruct only reads its own props, so new SpaProps fields pass through.
|
|
11
|
-
this.spa = new SpaConstruct(this, name, props);
|
|
33
|
+
this.spa = new SpaConstruct(this, name, { ...props, certificate });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** The certificate of a SPA, in a stack that other regions can reference. */
|
|
37
|
+
export class SpaCertificateStack extends Stack {
|
|
38
|
+
constructor(parent, name, { domainName, ...props }) {
|
|
39
|
+
super(parent, name, { ...props, crossRegionReferences: true });
|
|
40
|
+
const [mainDomain, ...otherDomains] = certificateDomainNames(domainName);
|
|
41
|
+
const zone = HostedZone.fromLookup(this, 'Zone', {
|
|
42
|
+
privateZone: false,
|
|
43
|
+
domainName: mainDomain,
|
|
44
|
+
});
|
|
45
|
+
this.certificate = new Certificate(this, 'Certificate', {
|
|
46
|
+
validation: CertificateValidation.fromDns(zone),
|
|
47
|
+
domainName: mainDomain,
|
|
48
|
+
subjectAlternativeNames: otherDomains,
|
|
49
|
+
});
|
|
12
50
|
}
|
|
13
51
|
}
|
|
14
52
|
//# sourceMappingURL=spa.stack.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spa.stack.js","sourceRoot":"","sources":["../../../../../../../libs/public/spa-cdk-stack/src/lib/spa/spa.stack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAc,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"spa.stack.js","sourceRoot":"","sources":["../../../../../../../libs/public/spa-cdk-stack/src/lib/spa/spa.stack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAc,MAAM,aAAa,CAAC;AAChD,OAAO,EACL,WAAW,EACX,qBAAqB,GACtB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErD,OAAO,EACL,sBAAsB,EACtB,YAAY,GAEb,MAAM,iBAAiB,CAAC;AAIzB,2DAA2D;AAC3D,MAAM,CAAC,MAAM,6BAA6B,GAAG,WAAW,CAAC;AAEzD;;;;;;;;GAQG;AACH,MAAM,OAAO,QAAS,SAAQ,KAAK;IAGjC,YAAY,MAAiB,EAAE,IAAY,EAAE,KAAoB;QAC/D,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC;QACjC,MAAM,oBAAoB,GACxB,CAAC,KAAK,CAAC,WAAW;YAClB,MAAM,KAAK,SAAS;YACpB,MAAM,KAAK,6BAA6B,CAAC;QAC3C,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE;YAClB,GAAG,KAAK;YACR,qBAAqB,EACnB,KAAK,CAAC,qBAAqB,IAAI,oBAAoB;SACtD,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,oBAAoB;YACtC,CAAC,CAAC,IAAI,mBAAmB,CAAC,MAAM,EAAE,GAAG,IAAI,aAAa,EAAE;gBACpD,GAAG,EAAE,EAAE,GAAG,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,6BAA6B,EAAE;gBAC5D,UAAU,EAAE,KAAK,CAAC,UAAU;aAC7B,CAAC,CAAC,WAAW;YAChB,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC;QAEtB,8EAA8E;QAC9E,IAAI,CAAC,GAAG,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,GAAG,KAAK,EAAE,WAAW,EAAE,CAAC,CAAC;IACrE,CAAC;CACF;AAMD,6EAA6E;AAC7E,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAG5C,YACE,MAAiB,EACjB,IAAY,EACZ,EAAE,UAAU,EAAE,GAAG,KAAK,EAA4B;QAElD,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,GAAG,KAAK,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,CAAC;QAE/D,MAAM,CAAC,UAAU,EAAE,GAAG,YAAY,CAAC,GAAG,sBAAsB,CAAC,UAAU,CAAC,CAAC;QACzE,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE;YAC/C,WAAW,EAAE,KAAK;YAClB,UAAU,EAAE,UAAU;SACvB,CAAC,CAAC;QACH,IAAI,CAAC,WAAW,GAAG,IAAI,WAAW,CAAC,IAAI,EAAE,aAAa,EAAE;YACtD,UAAU,EAAE,qBAAqB,CAAC,OAAO,CAAC,IAAI,CAAC;YAC/C,UAAU,EAAE,UAAU;YACtB,uBAAuB,EAAE,YAAY;SACtC,CAAC,CAAC;IACL,CAAC;CACF"}
|