forked from open-constructs/cdk-serverless
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathasset-cdn.ts
78 lines (65 loc) · 2.48 KB
/
asset-cdn.ts
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
import * as certificatemanager from '@aws-cdk/aws-certificatemanager';
import * as cloudfront from '@aws-cdk/aws-cloudfront';
import * as route53 from '@aws-cdk/aws-route53';
import * as route53Targets from '@aws-cdk/aws-route53-targets';
import * as s3 from '@aws-cdk/aws-s3';
import * as cdk from '@aws-cdk/core';
export interface AssetCdnProps {
/**
* Domain name of the asset content delivery network (e.g. example.com)
*/
domainName: string;
/**
* Hostname of the asset content delivery network (e.g. cdn)
*/
hostName: string;
}
export class AssetCdn extends cdk.Construct {
public readonly zone: route53.IHostedZone;
public readonly assetBucket: s3.Bucket;
public readonly assetDomainName: string;
constructor(scope: cdk.Construct, id: string, props: AssetCdnProps) {
super(scope, id);
this.zone = route53.HostedZone.fromLookup(this, 'HostedZone', {
domainName: props.domainName,
});
this.assetBucket = new s3.Bucket(this, 'AssetBucket', {
blockPublicAccess: s3.BlockPublicAccess.BLOCK_ALL,
});
this.assetBucket.addCorsRule({
allowedHeaders: ['*'],
allowedMethods: [s3.HttpMethods.PUT],
allowedOrigins: ['*'],
});
this.assetDomainName = `${props.hostName}.${props.domainName}`;
const cert = new certificatemanager.DnsValidatedCertificate(this, 'Certificate', {
hostedZone: this.zone,
domainName: this.assetDomainName,
region: 'us-east-1',
});
const originAccessIdentity = new cloudfront.OriginAccessIdentity(this, 'OAI', { comment: `S3 Frontend ${this.assetDomainName}` });
this.assetBucket.grantRead(originAccessIdentity);
const distribution = new cloudfront.CloudFrontWebDistribution(this, 'Distribution', {
originConfigs: [
{
behaviors: [{ isDefaultBehavior: true }],
s3OriginSource: {
s3BucketSource: this.assetBucket,
originAccessIdentity,
},
},
],
viewerCertificate: cloudfront.ViewerCertificate.fromAcmCertificate(cert, {
aliases: [this.assetDomainName],
}),
comment: `Asset endpoint for ${this.assetDomainName}`,
priceClass: cloudfront.PriceClass.PRICE_CLASS_ALL,
viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
});
new route53.ARecord(this, 'AliasRecord', {
recordName: this.assetDomainName,
zone: this.zone,
target: route53.RecordTarget.fromAlias(new route53Targets.CloudFrontTarget(distribution)),
});
}
}