From 1a7d4db9477ea017732243c1532300fef9fdb0c7 Mon Sep 17 00:00:00 2001 From: CaerusKaru Date: Tue, 28 May 2019 02:37:04 -0500 Subject: [PATCH] feat(acm): allow specifying region for validated certificates (#2626) CloudFront requires certificates to be registered in the us-east-1 region, so this allows users to override the default, which places the certificates in whatever region the stack exists in. --- .../lib/index.js | 13 +++++++------ .../test/handler.test.js | 18 ++++++++++++++---- .../lib/dns-validated-certificate.ts | 11 ++++++++++- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/lib/index.js b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/lib/index.js index 0a6ecb061a888..250afa666c31a 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/lib/index.js +++ b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/lib/index.js @@ -74,9 +74,9 @@ let report = function (event, context, responseStatus, physicalResourceId, respo * @param {string} hostedZoneId the Route53 Hosted Zone ID * @returns {string} Validated certificate ARN */ -const requestCertificate = async function (requestId, domainName, subjectAlternativeNames, hostedZoneId) { +const requestCertificate = async function (requestId, domainName, subjectAlternativeNames, hostedZoneId, region) { const crypto = require('crypto'); - const acm = new aws.ACM(); + const acm = new aws.ACM({region}); const route53 = new aws.Route53(); if (waiter) { // Used by the test suite, since waiters aren't mockable yet @@ -157,8 +157,8 @@ const requestCertificate = async function (requestId, domainName, subjectAlterna * * @param {string} arn The certificate ARN */ -const deleteCertificate = async function (arn) { - const acm = new aws.ACM(); +const deleteCertificate = async function (arn, region) { + const acm = new aws.ACM({region}); console.log(`Deleting certificate ${arn}`); @@ -189,7 +189,8 @@ exports.certificateRequestHandler = async function (event, context) { event.RequestId, event.ResourceProperties.DomainName, event.ResourceProperties.SubjectAlternativeNames, - event.ResourceProperties.HostedZoneId + event.ResourceProperties.HostedZoneId, + event.ResourceProperties.Region, ); responseData.Arn = physicalResourceId = certificateArn; break; @@ -198,7 +199,7 @@ exports.certificateRequestHandler = async function (event, context) { // If the resource didn't create correctly, the physical resource ID won't be the // certificate ARN, so don't try to delete it in that case. if (physicalResourceId.startsWith('arn:')) { - await deleteCertificate(physicalResourceId); + await deleteCertificate(physicalResourceId, event.ResourceProperties.Region); } break; default: diff --git a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/test/handler.test.js b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/test/handler.test.js index 93a1de226f311..213326ac8e51d 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/test/handler.test.js +++ b/packages/@aws-cdk/aws-certificatemanager/lambda-packages/dns_validated_certificate_handler/test/handler.test.js @@ -98,7 +98,8 @@ describe('DNS Validated Certificate Handler', () => { ResourceProperties: { DomainName: testDomainName, SubjectAlternativeNames: [], - HostedZoneId: testHostedZoneId + HostedZoneId: testHostedZoneId, + Region: 'us-east-1', } }) .expectResolve(() => { @@ -138,7 +139,10 @@ describe('DNS Validated Certificate Handler', () => { .event({ RequestType: 'Delete', RequestId: testRequestId, - PhysicalResourceId: testCertificateArn + PhysicalResourceId: testCertificateArn, + ResourceProperties: { + Region: 'us-east-1', + } }) .expectResolve(() => { sinon.assert.calledWith(deleteCertificateFake, sinon.match({ @@ -162,7 +166,10 @@ describe('DNS Validated Certificate Handler', () => { .event({ RequestType: 'Delete', RequestId: testRequestId, - PhysicalResourceId: testCertificateArn + PhysicalResourceId: testCertificateArn, + ResourceProperties: { + Region: 'us-east-1', + } }) .expectResolve(() => { sinon.assert.calledWith(deleteCertificateFake, sinon.match({ @@ -186,7 +193,10 @@ describe('DNS Validated Certificate Handler', () => { .event({ RequestType: 'Delete', RequestId: testRequestId, - PhysicalResourceId: testCertificateArn + PhysicalResourceId: testCertificateArn, + ResourceProperties: { + Region: 'us-east-1', + } }) .expectResolve(() => { sinon.assert.calledWith(deleteCertificateFake, sinon.match({ diff --git a/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts b/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts index d8fc6b9468469..2707f1d8b3b60 100644 --- a/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts +++ b/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts @@ -12,6 +12,14 @@ export interface DnsValidatedCertificateProps extends CertificateProps { * must be authoritative for the domain name specified in the Certificate Request. */ readonly hostedZone: route53.IHostedZone; + /** + * AWS region that will host the certificate. This is needed especially + * for certificates used for CloudFront distributions, which require the region + * to be us-east-1. + * + * @default the region the stack is deployed in. + */ + readonly region?: string; } /** @@ -64,7 +72,8 @@ export class DnsValidatedCertificate extends cdk.Construct implements ICertifica properties: { DomainName: props.domainName, SubjectAlternativeNames: props.subjectAlternativeNames, - HostedZoneId: this.hostedZoneId + HostedZoneId: this.hostedZoneId, + Region: props.region, } });