diff --git a/lib/cdn-site-hosting/cdn-site-hosting-with-dns-construct.ts b/lib/cdn-site-hosting/cdn-site-hosting-with-dns-construct.ts index f5bf4e41..01c7d797 100644 --- a/lib/cdn-site-hosting/cdn-site-hosting-with-dns-construct.ts +++ b/lib/cdn-site-hosting/cdn-site-hosting-with-dns-construct.ts @@ -6,7 +6,10 @@ import { CdnSiteHostingConstruct } from "./cdn-site-hosting-construct"; import { getSiteDomain } from "./utils"; import { CommonCdnSiteHostingProps } from "./cdn-site-hosting-props"; -export type CdnSiteHostingWithDnsConstructProps = CommonCdnSiteHostingProps; +export interface CdnSiteHostingWithDnsConstructProps + extends CommonCdnSiteHostingProps { + certificateArn?: string; +} /** * Establishes infrastructure to host a static-site or single-page-application in S3 via CloudFront, @@ -36,16 +39,21 @@ export class CdnSiteHostingWithDnsConstruct extends cdk.Construct { }); new cdk.CfnOutput(this, "Site", { value: `https://${siteDomain}` }); - // Create a new TLS certificate - it has to be in `us-east-1` - const certificateArn = new certificatemanager.DnsValidatedCertificate( - this, - "SiteCertificate", - { - domainName: siteDomain, - hostedZone: zone, - region: "us-east-1", // Cloudfront only checks this region for certificates. - } - ).certificateArn; + // certificateArn is an option in props, if one is passed in, use it + // otherwise create one. + let certificateArn = props.certificateArn; + if (!certificateArn) { + // Create a new TLS certificate - it has to be in `us-east-1` + certificateArn = new certificatemanager.DnsValidatedCertificate( + this, + "SiteCertificate", + { + domainName: siteDomain, + hostedZone: zone, + region: "us-east-1", // Cloudfront only checks this region for certificates. + } + ).certificateArn; + } new cdk.CfnOutput(this, "Certificate", { value: certificateArn }); // Create the underpinning hosting infrastructure diff --git a/test/infra/cdn-site-hosting/cdn-site-hosting-with-dns-construct.test.ts b/test/infra/cdn-site-hosting/cdn-site-hosting-with-dns-construct.test.ts index f6303127..c3770da7 100644 --- a/test/infra/cdn-site-hosting/cdn-site-hosting-with-dns-construct.test.ts +++ b/test/infra/cdn-site-hosting/cdn-site-hosting-with-dns-construct.test.ts @@ -93,6 +93,33 @@ describe("CdnSiteHostingWithDnsConstruct", () => { }); }); + describe("When certificate is provided", () => { + let stack: Stack; + + beforeAll(() => { + const app = new cdk.App(); + stack = new cdk.Stack(app, "TestStack", { env: testEnv }); + new CdnSiteHostingWithDnsConstruct(stack, "MyTestConstruct", { + siteSubDomain: fakeSiteSubDomain, + domainName: fakeDomain, + removalPolicy: RemovalPolicy.DESTROY, + sources: [s3deploy.Source.asset("./")], + websiteErrorDocument: "error.html", + websiteIndexDocument: "index.html", + certificateArn: "test-cert", + }); + }); + + test("does not provisions a new ACM TLS certificate covering the domain", () => { + expectCDK(stack).notTo( + haveResourceLike("AWS::CloudFormation::CustomResource", { + DomainName: fakeFqdn, + Region: "us-east-1", + }) + ); + }); + }); + describe("When no error document is provided", () => { let stack: Stack;