UNPKG

@scloud/cdk-patterns

Version:

Serverless CDK patterns for common infrastructure needs

65 lines 12.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.WebFrontend = void 0; const aws_certificatemanager_1 = require("aws-cdk-lib/aws-certificatemanager"); const aws_cloudfront_1 = require("aws-cdk-lib/aws-cloudfront"); const aws_route53_1 = require("aws-cdk-lib/aws-route53"); const constructs_1 = require("constructs"); const aws_route53_targets_1 = require("aws-cdk-lib/aws-route53-targets"); const aws_cloudfront_origins_1 = require("aws-cdk-lib/aws-cloudfront-origins"); const GithubActions_1 = require("./GithubActions"); const PrivateBucket_1 = require("./PrivateBucket"); const RedirectWww_1 = require("./RedirectWww"); /** * A Cloudfront distribution backed by an s3 bucket. * * The bucket and contents are treated as expendable on the basis they are assumed to be generated by a CI/CD process that can rebuild the content. * * NB us-east-1 is required for Cloudfront certificates: * https://docs.aws.amazon.com/cdk/api/v1/docs/aws-cloudfront-readme.html */ class WebFrontend extends constructs_1.Construct { constructor(scope, id, props) { super(scope, `${id}WebFrontend`); const domainName = props.domainName || props.zone.zoneName; // We consider the objects in the bucket to be expendable because // they're most likely static content we generate from source code (rather than user data). this.bucket = PrivateBucket_1.PrivateBucket.expendable(scope, `${id}Static`); (0, GithubActions_1.githubActions)(scope).addGhaBucket(id, this.bucket); this.certificate = new aws_certificatemanager_1.DnsValidatedCertificate(scope, `${id}Certificate`, { domainName, hostedZone: props.zone, region: 'us-east-1', subjectAlternativeNames: props.redirectWww !== false ? [`www.${domainName}`] : undefined, }); // This enables us to separate out the defaultBehavior props (if any) from the distributionProps (if provided) // See https://stackoverflow.com/a/34710102/723506 for an explanation of this destructuring const { defaultBehavior, ...distributionProps } = props.distributionProps || {}; this.distribution = new aws_cloudfront_1.Distribution(scope, `${id}Distribution`, { domainNames: [domainName], comment: domainName, defaultRootObject: props.defaultIndex === false ? undefined : 'index.html', defaultBehavior: { origin: aws_cloudfront_origins_1.S3BucketOrigin.withOriginAccessControl(this.bucket), viewerProtocolPolicy: aws_cloudfront_1.ViewerProtocolPolicy.REDIRECT_TO_HTTPS, ...defaultBehavior, }, certificate: this.certificate, errorResponses: props.errorResponses, ...distributionProps, }); (0, GithubActions_1.githubActions)(scope).addGhaDistribution(id, this.distribution); // DNS record for the distribution new aws_route53_1.ARecord(scope, `${id}ARecord`, { zone: props.zone, recordName: domainName, target: aws_route53_1.RecordTarget.fromAlias(new aws_route53_targets_1.CloudFrontTarget(this.distribution)), }); if (props.redirectWww !== false) { // Redirect www -> zone root new RedirectWww_1.RedirectWww(scope, id, { zone: props.zone, certificate: this.certificate, domainName }); } } } exports.WebFrontend = WebFrontend; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiV2ViRnJvbnRlbmQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvV2ViRnJvbnRlbmQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsK0VBQTZFO0FBQzdFLCtEQUVvQztBQUNwQyx5REFBNkU7QUFFN0UsMkNBQXVDO0FBQ3ZDLHlFQUFtRTtBQUNuRSwrRUFBb0U7QUFDcEUsbURBQWdEO0FBQ2hELG1EQUFnRDtBQUNoRCwrQ0FBNEM7QUFzQjVDOzs7Ozs7O0dBT0c7QUFDSCxNQUFhLFdBQVksU0FBUSxzQkFBUztJQU94QyxZQUNFLEtBQWdCLEVBQ2hCLEVBQVUsRUFDVixLQUF1QjtRQUV2QixLQUFLLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxhQUFhLENBQUMsQ0FBQztRQUVqQyxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDO1FBRTNELGlFQUFpRTtRQUNqRSwyRkFBMkY7UUFDM0YsSUFBSSxDQUFDLE1BQU0sR0FBRyw2QkFBYSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzdELElBQUEsNkJBQWEsRUFBQyxLQUFLLENBQUMsQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUVuRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksZ0RBQXVCLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUU7WUFDeEUsVUFBVTtZQUNWLFVBQVUsRUFBRSxLQUFLLENBQUMsSUFBSTtZQUN0QixNQUFNLEVBQUUsV0FBVztZQUNuQix1QkFBdUIsRUFBRSxLQUFLLENBQUMsV0FBVyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxPQUFPLFVBQVUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7U0FDekYsQ0FBQyxDQUFDO1FBRUgsOEdBQThHO1FBQzlHLDJGQUEyRjtRQUMzRixNQUFNLEVBQUUsZUFBZSxFQUFFLEdBQUcsaUJBQWlCLEVBQUUsR0FBRyxLQUFLLENBQUMsaUJBQWlCLElBQUssRUFBaUMsQ0FBQztRQUNoSCxJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksNkJBQVksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLGNBQWMsRUFBRTtZQUMvRCxXQUFXLEVBQUUsQ0FBQyxVQUFVLENBQUM7WUFDekIsT0FBTyxFQUFFLFVBQVU7WUFDbkIsaUJBQWlCLEVBQUUsS0FBSyxDQUFDLFlBQVksS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsWUFBWTtZQUMxRSxlQUFlLEVBQUU7Z0JBQ2YsTUFBTSxFQUFFLHVDQUFjLENBQUMsdUJBQXVCLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztnQkFDM0Qsb0JBQW9CLEVBQUUscUNBQW9CLENBQUMsaUJBQWlCO2dCQUM1RCxHQUFHLGVBQWU7YUFDbkI7WUFDRCxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDN0IsY0FBYyxFQUFFLEtBQUssQ0FBQyxjQUFjO1lBQ3BDLEdBQUcsaUJBQWlCO1NBQ3JCLENBQUMsQ0FBQztRQUNILElBQUEsNkJBQWEsRUFBQyxLQUFLLENBQUMsQ0FBQyxrQkFBa0IsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO1FBRS9ELGtDQUFrQztRQUNsQyxJQUFJLHFCQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUU7WUFDakMsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJO1lBQ2hCLFVBQVUsRUFBRSxVQUFVO1lBQ3RCLE1BQU0sRUFBRSwwQkFBWSxDQUFDLFNBQVMsQ0FBQyxJQUFJLHNDQUFnQixDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQztTQUN4RSxDQUFDLENBQUM7UUFFSCxJQUFJLEtBQUssQ0FBQyxXQUFXLEtBQUssS0FBSyxFQUFFLENBQUM7WUFDaEMsNEJBQTRCO1lBQzVCLElBQUkseUJBQVcsQ0FBQyxLQUFLLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztRQUM5RixDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBMURELGtDQTBEQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERuc1ZhbGlkYXRlZENlcnRpZmljYXRlIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNlcnRpZmljYXRlbWFuYWdlcic7XG5pbXBvcnQge1xuICBEaXN0cmlidXRpb24sIERpc3RyaWJ1dGlvblByb3BzLCBFcnJvclJlc3BvbnNlLCBWaWV3ZXJQcm90b2NvbFBvbGljeSxcbn0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQnO1xuaW1wb3J0IHsgQVJlY29yZCwgSUhvc3RlZFpvbmUsIFJlY29yZFRhcmdldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1yb3V0ZTUzJztcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IENsb3VkRnJvbnRUYXJnZXQgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3Mtcm91dGU1My10YXJnZXRzJztcbmltcG9ydCB7IFMzQnVja2V0T3JpZ2luIH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWNsb3VkZnJvbnQtb3JpZ2lucyc7XG5pbXBvcnQgeyBnaXRodWJBY3Rpb25zIH0gZnJvbSAnLi9HaXRodWJBY3Rpb25zJztcbmltcG9ydCB7IFByaXZhdGVCdWNrZXQgfSBmcm9tICcuL1ByaXZhdGVCdWNrZXQnO1xuaW1wb3J0IHsgUmVkaXJlY3RXd3cgfSBmcm9tICcuL1JlZGlyZWN0V3d3JztcblxuLyoqXG4gKiBAcGFyYW0gem9uZSBUaGUgRE5TIHpvbmUgZm9yIHRoaXMgd2ViIGFwcC4gQnkgZGVmYXVsdCB0aGUgZG9tYWluIG5hbWUgaXMgc2V0IHRvIHRoZSB6b25lIG5hbWVcbiAqIFRoZSB0eXBlIElIb3N0ZWRab25lIGVuYWJsZXMgbG9va3VwIG9mIHRoZSB6b25lIChJSG9zdGVkWm9uZSkgYXMgd2VsbCBhcyBhIHpvbmUgY3JlYXRkIGluIHRoZSBzdGFjayAoSG9zdGVkWm9uZSlcbiAqIEBwYXJhbSBkb21haW5OYW1lIE9wdGlvbmFsOiBieSBkZWZhdWx0IHRoZSB6b25lIG5hbWUgd2lsbCBiZSBtYXBwZWQgdG8gdGhlIENsb3VkZnJvbnQgZGlzdHJpYnV0aW9uIChlLmcuICdleGFtcGxlLmNvbScpIGJ1dCB5b3UgY2FuIHNwZWNpZnkgYSBkaWZmZXJlbnQgZG9tYWluIGhlcmUgKGUuZy4gJ3N1YmRvbWFpbi5leGFtcGxlLmNvbScpLlxuICogQHBhcmFtIGRlZmF1bHRJbmRleCBEZWZhdWx0OiB0cnVlLiBNYXBzIGEgdmlld2VyIHJlcXVlc3QgZm9yICcvJyB0byBhIHJlcXVlc3QgZm9yIC9pbmRleC5odG1sLlxuICogQHBhcmFtIHJlZGlyZWN0V3d3IERlZmF1bHQ6IHRydWUuIFJlZGlyZWN0cyB3d3cgcmVxdWVzdHMgdG8gdGhlIGJhcmUgZG9tYWluIG5hbWUsIGUuZy4gd3d3LmV4YW1wbGUuY29tLT5leGFtcGxlLmNvbSwgd3d3LnN1Yi5leGFtcGxlLmNvbS0+c3ViLmV4YW1wbGUuY29tLlxuICogQHBhcmFtIGNuYW1lQWxpYXNlcyBPcHRpb25hbDogYWRkaXRpb25hbCBDTkFNRXMgdG8gYWRkIHRvIHRoZSBDbG91ZGZyb250IGRpc3RyaWJ1dGlvbi4gVGhpcyBhbGxvd3MgeW91IHRvIHVzZSBhIGRvbWFpbiBuYW1lIGNvbmZpZ3VyZWQgb3V0c2lkZSBvZiBBV1MuXG4gKiBAcGFyYW0gZGlzdHJpYnV0aW9uUHJvcHMgT3B0aW9uYWw6IElmIHlvdSB3YW50IHRvIGFkZCBhZGRpdGlvbmFsIHByb3BlcnRpZXMgdG8gdGhlIENsb3VkZnJvbnQgZGlzdHJpYnV0aW9uLCB5b3UgY2FuIHBhc3MgdGhlbSBoZXJlLlxuICogQHBhcmFtIGVycm9yUmVzcG9uc2VzIE9wdGlvbmFsOiBJZiB5b3Ugd2FudCB0byBhZGQgY3VzdG9tIGVycm9yIHJlc3BvbnNlcyB0byB0aGUgQ2xvdWRmcm9udCBkaXN0cmlidXRpb24sIHlvdSBjYW4gcGFzcyB0aGVtIGhlcmUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2ViRnJvbnRlbmRQcm9wcyB7XG4gIHpvbmU6IElIb3N0ZWRab25lLFxuICBkb21haW5OYW1lPzogc3RyaW5nLFxuICBkZWZhdWx0SW5kZXg/OiBib29sZWFuLFxuICByZWRpcmVjdFd3dz86IGJvb2xlYW4sXG4gIGNuYW1lQWxpYXNlcz86IHN0cmluZ1tdLFxuICBkaXN0cmlidXRpb25Qcm9wcz86IFBhcnRpYWw8RGlzdHJpYnV0aW9uUHJvcHM+LFxuICBlcnJvclJlc3BvbnNlcz86IEVycm9yUmVzcG9uc2VbXSxcbn1cblxuLyoqXG4gKiBBIENsb3VkZnJvbnQgZGlzdHJpYnV0aW9uIGJhY2tlZCBieSBhbiBzMyBidWNrZXQuXG4gKlxuICogVGhlIGJ1Y2tldCBhbmQgY29udGVudHMgYXJlIHRyZWF0ZWQgYXMgZXhwZW5kYWJsZSBvbiB0aGUgYmFzaXMgdGhleSBhcmUgYXNzdW1lZCB0byBiZSBnZW5lcmF0ZWQgYnkgYSBDSS9DRCBwcm9jZXNzIHRoYXQgY2FuIHJlYnVpbGQgdGhlIGNvbnRlbnQuXG4gKlxuICogTkIgdXMtZWFzdC0xIGlzIHJlcXVpcmVkIGZvciBDbG91ZGZyb250IGNlcnRpZmljYXRlczpcbiAqIGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9jZGsvYXBpL3YxL2RvY3MvYXdzLWNsb3VkZnJvbnQtcmVhZG1lLmh0bWxcbiAqL1xuZXhwb3J0IGNsYXNzIFdlYkZyb250ZW5kIGV4dGVuZHMgQ29uc3RydWN0IHtcbiAgYnVja2V0OiBCdWNrZXQ7XG5cbiAgZGlzdHJpYnV0aW9uOiBEaXN0cmlidXRpb247XG5cbiAgY2VydGlmaWNhdGU6IERuc1ZhbGlkYXRlZENlcnRpZmljYXRlO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHNjb3BlOiBDb25zdHJ1Y3QsXG4gICAgaWQ6IHN0cmluZyxcbiAgICBwcm9wczogV2ViRnJvbnRlbmRQcm9wcyxcbiAgKSB7XG4gICAgc3VwZXIoc2NvcGUsIGAke2lkfVdlYkZyb250ZW5kYCk7XG5cbiAgICBjb25zdCBkb21haW5OYW1lID0gcHJvcHMuZG9tYWluTmFtZSB8fCBwcm9wcy56b25lLnpvbmVOYW1lO1xuXG4gICAgLy8gV2UgY29uc2lkZXIgdGhlIG9iamVjdHMgaW4gdGhlIGJ1Y2tldCB0byBiZSBleHBlbmRhYmxlIGJlY2F1c2VcbiAgICAvLyB0aGV5J3JlIG1vc3QgbGlrZWx5IHN0YXRpYyBjb250ZW50IHdlIGdlbmVyYXRlIGZyb20gc291cmNlIGNvZGUgKHJhdGhlciB0aGFuIHVzZXIgZGF0YSkuXG4gICAgdGhpcy5idWNrZXQgPSBQcml2YXRlQnVja2V0LmV4cGVuZGFibGUoc2NvcGUsIGAke2lkfVN0YXRpY2ApO1xuICAgIGdpdGh1YkFjdGlvbnMoc2NvcGUpLmFkZEdoYUJ1Y2tldChpZCwgdGhpcy5idWNrZXQpO1xuXG4gICAgdGhpcy5jZXJ0aWZpY2F0ZSA9IG5ldyBEbnNWYWxpZGF0ZWRDZXJ0aWZpY2F0ZShzY29wZSwgYCR7aWR9Q2VydGlmaWNhdGVgLCB7XG4gICAgICBkb21haW5OYW1lLFxuICAgICAgaG9zdGVkWm9uZTogcHJvcHMuem9uZSxcbiAgICAgIHJlZ2lvbjogJ3VzLWVhc3QtMScsXG4gICAgICBzdWJqZWN0QWx0ZXJuYXRpdmVOYW1lczogcHJvcHMucmVkaXJlY3RXd3cgIT09IGZhbHNlID8gW2B3d3cuJHtkb21haW5OYW1lfWBdIDogdW5kZWZpbmVkLFxuICAgIH0pO1xuXG4gICAgLy8gVGhpcyBlbmFibGVzIHVzIHRvIHNlcGFyYXRlIG91dCB0aGUgZGVmYXVsdEJlaGF2aW9yIHByb3BzIChpZiBhbnkpIGZyb20gdGhlIGRpc3RyaWJ1dGlvblByb3BzIChpZiBwcm92aWRlZClcbiAgICAvLyBTZWUgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM0NzEwMTAyLzcyMzUwNiBmb3IgYW4gZXhwbGFuYXRpb24gb2YgdGhpcyBkZXN0cnVjdHVyaW5nXG4gICAgY29uc3QgeyBkZWZhdWx0QmVoYXZpb3IsIC4uLmRpc3RyaWJ1dGlvblByb3BzIH0gPSBwcm9wcy5kaXN0cmlidXRpb25Qcm9wcyB8fCAoe30gYXMgUGFydGlhbDxEaXN0cmlidXRpb25Qcm9wcz4pO1xuICAgIHRoaXMuZGlzdHJpYnV0aW9uID0gbmV3IERpc3RyaWJ1dGlvbihzY29wZSwgYCR7aWR9RGlzdHJpYnV0aW9uYCwge1xuICAgICAgZG9tYWluTmFtZXM6IFtkb21haW5OYW1lXSxcbiAgICAgIGNvbW1lbnQ6IGRvbWFpbk5hbWUsXG4gICAgICBkZWZhdWx0Um9vdE9iamVjdDogcHJvcHMuZGVmYXVsdEluZGV4ID09PSBmYWxzZSA/IHVuZGVmaW5lZCA6ICdpbmRleC5odG1sJyxcbiAgICAgIGRlZmF1bHRCZWhhdmlvcjoge1xuICAgICAgICBvcmlnaW46IFMzQnVja2V0T3JpZ2luLndpdGhPcmlnaW5BY2Nlc3NDb250cm9sKHRoaXMuYnVja2V0KSxcbiAgICAgICAgdmlld2VyUHJvdG9jb2xQb2xpY3k6IFZpZXdlclByb3RvY29sUG9saWN5LlJFRElSRUNUX1RPX0hUVFBTLFxuICAgICAgICAuLi5kZWZhdWx0QmVoYXZpb3IsXG4gICAgICB9LFxuICAgICAgY2VydGlmaWNhdGU6IHRoaXMuY2VydGlmaWNhdGUsXG4gICAgICBlcnJvclJlc3BvbnNlczogcHJvcHMuZXJyb3JSZXNwb25zZXMsXG4gICAgICAuLi5kaXN0cmlidXRpb25Qcm9wcyxcbiAgICB9KTtcbiAgICBnaXRodWJBY3Rpb25zKHNjb3BlKS5hZGRHaGFEaXN0cmlidXRpb24oaWQsIHRoaXMuZGlzdHJpYnV0aW9uKTtcblxuICAgIC8vIEROUyByZWNvcmQgZm9yIHRoZSBkaXN0cmlidXRpb25cbiAgICBuZXcgQVJlY29yZChzY29wZSwgYCR7aWR9QVJlY29yZGAsIHtcbiAgICAgIHpvbmU6IHByb3BzLnpvbmUsXG4gICAgICByZWNvcmROYW1lOiBkb21haW5OYW1lLFxuICAgICAgdGFyZ2V0OiBSZWNvcmRUYXJnZXQuZnJvbUFsaWFzKG5ldyBDbG91ZEZyb250VGFyZ2V0KHRoaXMuZGlzdHJpYnV0aW9uKSksXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMucmVkaXJlY3RXd3cgIT09IGZhbHNlKSB7XG4gICAgICAvLyBSZWRpcmVjdCB3d3cgLT4gem9uZSByb290XG4gICAgICBuZXcgUmVkaXJlY3RXd3coc2NvcGUsIGlkLCB7IHpvbmU6IHByb3BzLnpvbmUsIGNlcnRpZmljYXRlOiB0aGlzLmNlcnRpZmljYXRlLCBkb21haW5OYW1lIH0pO1xuICAgIH1cbiAgfVxufVxuIl19