From 030c5c58e2cedda8e74d7988dc44b042def9e703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20W=C3=BCrbach?= Date: Fri, 6 Nov 2020 05:44:01 +0100 Subject: [PATCH] feat(route53-targets): aws-apigatewayv2 target (#10191) Add support for [aws-apigatewayv2](https://docs.aws.amazon.com/cdk/api/latest/docs/aws-apigatewayv2-readme.html#custom-domain) `DomainName` as target. Closes https://github.com/aws/aws-cdk/issues/8941 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license* --- .../@aws-cdk/aws-route53-targets/README.md | 15 ++++-- .../lib/api-gateway-domain-name.ts | 2 +- .../lib/api-gatewayv2-domain-name.ts | 16 ++++++ .../@aws-cdk/aws-route53-targets/lib/index.ts | 1 + .../@aws-cdk/aws-route53-targets/package.json | 2 + .../test/apigatewayv2-target.test.ts | 49 +++++++++++++++++++ 6 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 packages/@aws-cdk/aws-route53-targets/lib/api-gatewayv2-domain-name.ts create mode 100644 packages/@aws-cdk/aws-route53-targets/test/apigatewayv2-target.test.ts diff --git a/packages/@aws-cdk/aws-route53-targets/README.md b/packages/@aws-cdk/aws-route53-targets/README.md index 3bd36f68ba46f..06d7dd6568255 100644 --- a/packages/@aws-cdk/aws-route53-targets/README.md +++ b/packages/@aws-cdk/aws-route53-targets/README.md @@ -16,6 +16,13 @@ This library contains Route53 Alias Record targets for: // or - route53.RecordTarget.fromAlias(new alias.ApiGatewayDomain(domainName)), }); ``` +* API Gateway V2 custom domains + ```ts + new route53.ARecord(this, 'AliasRecord', { + zone, + target: route53.RecordTarget.fromAlias(new alias.ApiGatewayv2Domain(domainName)), + }); + ``` * CloudFront distributions ```ts new route53.ARecord(this, 'AliasRecord', { @@ -55,17 +62,17 @@ For example, if the Amazon-provided DNS for the load balancer is `ALB-xxxxxxx.us ``` * S3 Bucket Website: -**Important:** The Bucket name must strictly match the full DNS name. -See [the Developer Guide](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started.html) for more info. +**Important:** The Bucket name must strictly match the full DNS name. +See [the Developer Guide](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/getting-started.html) for more info. ```ts const [recordName, domainName] = ['www', 'example.com']; - + const bucketWebsite = new Bucket(this, 'BucketWebsite', { bucketName: [recordName, domainName].join('.'), // www.example.com publicReadAccess: true, websiteIndexDocument: 'index.html', }); - + const zone = HostedZone.fromLookup(this, 'Zone', {domainName}); // example.com new route53.ARecord(this, 'AliasRecord', { diff --git a/packages/@aws-cdk/aws-route53-targets/lib/api-gateway-domain-name.ts b/packages/@aws-cdk/aws-route53-targets/lib/api-gateway-domain-name.ts index 3668a4858ac59..5aa40d5a52f10 100644 --- a/packages/@aws-cdk/aws-route53-targets/lib/api-gateway-domain-name.ts +++ b/packages/@aws-cdk/aws-route53-targets/lib/api-gateway-domain-name.ts @@ -5,7 +5,7 @@ import * as route53 from '@aws-cdk/aws-route53'; * Defines an API Gateway domain name as the alias target. * * Use the `ApiGateway` class if you wish to map the alias to an REST API with a - * domain name defined throug the `RestApiProps.domainName` prop. + * domain name defined through the `RestApiProps.domainName` prop. */ export class ApiGatewayDomain implements route53.IAliasRecordTarget { constructor(private readonly domainName: apig.IDomainName) { } diff --git a/packages/@aws-cdk/aws-route53-targets/lib/api-gatewayv2-domain-name.ts b/packages/@aws-cdk/aws-route53-targets/lib/api-gatewayv2-domain-name.ts new file mode 100644 index 0000000000000..b78078fca525a --- /dev/null +++ b/packages/@aws-cdk/aws-route53-targets/lib/api-gatewayv2-domain-name.ts @@ -0,0 +1,16 @@ +import * as apigv2 from '@aws-cdk/aws-apigatewayv2'; +import * as route53 from '@aws-cdk/aws-route53'; + +/** + * Defines an API Gateway V2 domain name as the alias target. + */ +export class ApiGatewayv2Domain implements route53.IAliasRecordTarget { + constructor(private readonly domainName: apigv2.IDomainName) { } + + public bind(_record: route53.IRecordSet): route53.AliasRecordTargetConfig { + return { + dnsName: this.domainName.regionalDomainName, + hostedZoneId: this.domainName.regionalHostedZoneId, + }; + } +} diff --git a/packages/@aws-cdk/aws-route53-targets/lib/index.ts b/packages/@aws-cdk/aws-route53-targets/lib/index.ts index 6df1bd67d6037..af574aa599519 100644 --- a/packages/@aws-cdk/aws-route53-targets/lib/index.ts +++ b/packages/@aws-cdk/aws-route53-targets/lib/index.ts @@ -1,4 +1,5 @@ export * from './api-gateway-domain-name'; +export * from './api-gatewayv2-domain-name'; export * from './bucket-website-target'; export * from './classic-load-balancer-target'; export * from './cloudfront-target'; diff --git a/packages/@aws-cdk/aws-route53-targets/package.json b/packages/@aws-cdk/aws-route53-targets/package.json index 87dd1a8969ad8..52e3e252fb960 100644 --- a/packages/@aws-cdk/aws-route53-targets/package.json +++ b/packages/@aws-cdk/aws-route53-targets/package.json @@ -74,6 +74,7 @@ }, "dependencies": { "@aws-cdk/aws-apigateway": "0.0.0", + "@aws-cdk/aws-apigatewayv2": "0.0.0", "@aws-cdk/aws-cloudfront": "0.0.0", "@aws-cdk/aws-cognito": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", @@ -89,6 +90,7 @@ "homepage": "https://github.com/aws/aws-cdk", "peerDependencies": { "@aws-cdk/aws-apigateway": "0.0.0", + "@aws-cdk/aws-apigatewayv2": "0.0.0", "@aws-cdk/aws-cloudfront": "0.0.0", "@aws-cdk/aws-cognito": "0.0.0", "@aws-cdk/aws-ec2": "0.0.0", diff --git a/packages/@aws-cdk/aws-route53-targets/test/apigatewayv2-target.test.ts b/packages/@aws-cdk/aws-route53-targets/test/apigatewayv2-target.test.ts new file mode 100644 index 0000000000000..66a504f630157 --- /dev/null +++ b/packages/@aws-cdk/aws-route53-targets/test/apigatewayv2-target.test.ts @@ -0,0 +1,49 @@ +import { expect as expectStack, haveResource } from '@aws-cdk/assert'; +import * as apigwv2 from '@aws-cdk/aws-apigatewayv2'; +import * as acm from '@aws-cdk/aws-certificatemanager'; +import * as route53 from '@aws-cdk/aws-route53'; +import { Stack } from '@aws-cdk/core'; +import * as targets from '../lib'; + +test('targets.ApiGatewayv2Domain can be used to directly reference a domain', () => { + // GIVEN + const stack = new Stack(); + const domainName = 'example.com'; + const cert = new acm.Certificate(stack, 'cert', { domainName }); + const dn = new apigwv2.DomainName(stack, 'DN', { + domainName, + certificate: cert, + }); + const zone = new route53.HostedZone(stack, 'zone', { + zoneName: 'example.com', + }); + + // WHEN + new route53.ARecord(stack, 'A', { + zone, + target: route53.RecordTarget.fromAlias(new targets.ApiGatewayv2Domain(dn)), + }); + + // THEN + expectStack(stack).to(haveResource('AWS::Route53::RecordSet', { + Name: 'example.com.', + Type: 'A', + AliasTarget: { + DNSName: { + 'Fn::GetAtt': [ + 'DNFDC76583', + 'RegionalDomainName', + ], + }, + HostedZoneId: { + 'Fn::GetAtt': [ + 'DNFDC76583', + 'RegionalHostedZoneId', + ], + }, + }, + HostedZoneId: { + Ref: 'zoneEB40FF1E', + }, + })); +});