Skip to content

Commit 2672a55

Browse files
authored
feat(aws-route53-targets): add global accelerator target to route53 alias targets (#13407)
Closes #12839 ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 42f3740 commit 2672a55

File tree

7 files changed

+199
-0
lines changed

7 files changed

+199
-0
lines changed

packages/@aws-cdk/aws-route53-targets/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,19 @@ This library contains Route53 Alias Record targets for:
6363

6464
For example, if the Amazon-provided DNS for the load balancer is `ALB-xxxxxxx.us-west-2.elb.amazonaws.com`, CDK will create alias target in Route 53 will be `dualstack.ALB-xxxxxxx.us-west-2.elb.amazonaws.com`.
6565

66+
* GlobalAccelerator
67+
68+
```ts
69+
new route53.ARecord(stack, 'AliasRecord', {
70+
zone,
71+
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorTarget(accelerator)),
72+
// or - route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorDomainTarget('xyz.awsglobalaccelerator.com')),
73+
});
74+
```
75+
76+
**Important:** If you use GlobalAcceleratorDomainTarget, passing a string rather than an instance of IAccelerator, ensure that the string is a valid domain name of an existing Global Accelerator instance.
77+
See [the documentation on DNS addressing](https://docs.aws.amazon.com/global-accelerator/latest/dg/dns-addressing-custom-domains.dns-addressing.html) with Global Accelerator for more info.
78+
6679
* InterfaceVpcEndpoints
6780

6881
**Important:** Based on the CFN docs for VPCEndpoints - [see here](attrDnsEntries) - the attributes returned for DnsEntries in CloudFormation is a combination of the hosted zone ID and the DNS name. The entries are ordered as follows: regional public DNS, zonal public DNS, private DNS, and wildcard DNS. This order is not enforced for AWS Marketplace services, and therefore this CDK construct is ONLY guaranteed to work with non-marketplace services.
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import * as globalaccelerator from '@aws-cdk/aws-globalaccelerator';
2+
import * as route53 from '@aws-cdk/aws-route53';
3+
4+
5+
/**
6+
* Use a Global Accelerator domain name as an alias record target.
7+
*/
8+
export class GlobalAcceleratorDomainTarget implements route53.IAliasRecordTarget {
9+
/**
10+
* The hosted zone Id if using an alias record in Route53.
11+
* This value never changes.
12+
* Ref: https://docs.aws.amazon.com/general/latest/gr/global_accelerator.html
13+
*/
14+
public static readonly GLOBAL_ACCELERATOR_ZONE_ID = 'Z2BJ6XQ5FK7U4H';
15+
16+
/**
17+
* Create an Alias Target for a Global Accelerator domain name.
18+
*/
19+
constructor(private readonly acceleratorDomainName: string) {
20+
}
21+
22+
bind(_record: route53.IRecordSet): route53.AliasRecordTargetConfig {
23+
return {
24+
hostedZoneId: GlobalAcceleratorTarget.GLOBAL_ACCELERATOR_ZONE_ID,
25+
dnsName: this.acceleratorDomainName,
26+
};
27+
}
28+
}
29+
30+
/**
31+
* Use a Global Accelerator instance domain name as an alias record target.
32+
*/
33+
export class GlobalAcceleratorTarget extends GlobalAcceleratorDomainTarget {
34+
35+
/**
36+
* Create an Alias Target for a Global Accelerator instance.
37+
*/
38+
constructor(accelerator: globalaccelerator.IAccelerator) {
39+
super(accelerator.dnsName);
40+
}
41+
}

packages/@aws-cdk/aws-route53-targets/lib/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ export * from './cloudfront-target';
66
export * from './load-balancer-target';
77
export * from './interface-vpc-endpoint-target';
88
export * from './userpool-domain';
9+
export * from './global-accelerator-target';

packages/@aws-cdk/aws-route53-targets/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
"@aws-cdk/aws-elasticloadbalancing": "0.0.0",
8181
"@aws-cdk/aws-elasticloadbalancingv2": "0.0.0",
8282
"@aws-cdk/aws-iam": "0.0.0",
83+
"@aws-cdk/aws-globalaccelerator": "0.0.0",
8384
"@aws-cdk/aws-route53": "0.0.0",
8485
"@aws-cdk/aws-s3": "0.0.0",
8586
"@aws-cdk/core": "0.0.0",
@@ -96,6 +97,7 @@
9697
"@aws-cdk/aws-elasticloadbalancing": "0.0.0",
9798
"@aws-cdk/aws-elasticloadbalancingv2": "0.0.0",
9899
"@aws-cdk/aws-iam": "0.0.0",
100+
"@aws-cdk/aws-globalaccelerator": "0.0.0",
99101
"@aws-cdk/aws-route53": "0.0.0",
100102
"@aws-cdk/aws-s3": "0.0.0",
101103
"@aws-cdk/core": "0.0.0",
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import '@aws-cdk/assert/jest';
2+
import * as globalaccelerator from '@aws-cdk/aws-globalaccelerator';
3+
import * as route53 from '@aws-cdk/aws-route53';
4+
import { Stack } from '@aws-cdk/core';
5+
import * as targets from '../lib';
6+
7+
test('GlobalAcceleratorTarget exposes a public constant of the zone id', () => {
8+
expect(targets.GlobalAcceleratorTarget.GLOBAL_ACCELERATOR_ZONE_ID).toStrictEqual('Z2BJ6XQ5FK7U4H');
9+
expect(targets.GlobalAcceleratorDomainTarget.GLOBAL_ACCELERATOR_ZONE_ID).toStrictEqual('Z2BJ6XQ5FK7U4H');
10+
});
11+
12+
test('GlobalAcceleratorTarget creates an alias resource with a string domain name', () => {
13+
// GIVEN
14+
const stack = new Stack();
15+
const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });
16+
17+
// WHEN
18+
new route53.ARecord(stack, 'GlobalAcceleratorAlias', {
19+
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorDomainTarget('xyz.awsglobalaccelerator.com')),
20+
recordName: 'test',
21+
zone,
22+
});
23+
24+
// THEN
25+
expect(stack).toHaveResource('AWS::Route53::RecordSet', {
26+
AliasTarget: {
27+
DNSName: 'xyz.awsglobalaccelerator.com',
28+
HostedZoneId: 'Z2BJ6XQ5FK7U4H',
29+
},
30+
});
31+
});
32+
33+
test('GlobalAcceleratorTarget creates an alias resource with a Global Accelerator reference domain name', () => {
34+
// GIVEN
35+
const stack = new Stack();
36+
const accelerator = new globalaccelerator.Accelerator(stack, 'Accelerator');
37+
const logicalId = stack.getLogicalId(<globalaccelerator.CfnAccelerator>accelerator.node.defaultChild);
38+
const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });
39+
40+
// WHEN
41+
new route53.ARecord(stack, 'GlobalAcceleratorAlias', {
42+
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorTarget(accelerator)),
43+
recordName: 'test',
44+
zone,
45+
});
46+
47+
// THEN
48+
expect(stack).toHaveResource('AWS::Route53::RecordSet', {
49+
AliasTarget: {
50+
DNSName: {
51+
'Fn::GetAtt': [
52+
logicalId,
53+
'DnsName',
54+
],
55+
},
56+
HostedZoneId: 'Z2BJ6XQ5FK7U4H',
57+
},
58+
});
59+
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"Resources": {
3+
"Accelerator8EB0B6B1": {
4+
"Type": "AWS::GlobalAccelerator::Accelerator",
5+
"Properties": {
6+
"Name": "aws-cdk-globalaccelerator-integ",
7+
"Enabled": true
8+
}
9+
},
10+
"HostedZoneDB99F866": {
11+
"Type": "AWS::Route53::HostedZone",
12+
"Properties": {
13+
"Name": "test.public."
14+
}
15+
},
16+
"LocalGlobalAcceleratorAlias18B4A87A": {
17+
"Type": "AWS::Route53::RecordSet",
18+
"Properties": {
19+
"Name": "test-local.test.public.",
20+
"Type": "A",
21+
"AliasTarget": {
22+
"DNSName": {
23+
"Fn::GetAtt": [
24+
"Accelerator8EB0B6B1",
25+
"DnsName"
26+
]
27+
},
28+
"HostedZoneId": "Z2BJ6XQ5FK7U4H"
29+
},
30+
"Comment": "Alias to the locally created Global Accelerator",
31+
"HostedZoneId": {
32+
"Ref": "HostedZoneDB99F866"
33+
}
34+
}
35+
},
36+
"ExistingGlobalAcceleratorAlias7ACF888C": {
37+
"Type": "AWS::Route53::RecordSet",
38+
"Properties": {
39+
"Name": "test-existing.test.public.",
40+
"Type": "A",
41+
"AliasTarget": {
42+
"DNSName": "someexisting.awsglobalaccelerator.com",
43+
"HostedZoneId": "Z2BJ6XQ5FK7U4H"
44+
},
45+
"Comment": "Alias to the an existing Global Accelerator",
46+
"HostedZoneId": {
47+
"Ref": "HostedZoneDB99F866"
48+
}
49+
}
50+
}
51+
}
52+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/usr/bin/env node
2+
import * as globalaccelerator from '@aws-cdk/aws-globalaccelerator';
3+
import * as route53 from '@aws-cdk/aws-route53';
4+
import * as cdk from '@aws-cdk/core';
5+
import * as targets from '../lib';
6+
7+
const app = new cdk.App();
8+
const stack = new cdk.Stack(app, 'aws-cdk-globalaccelerator-integ');
9+
10+
let accelerator = new globalaccelerator.Accelerator(stack, 'Accelerator', {
11+
acceleratorName: `${stack.stackName}`,
12+
enabled: true,
13+
});
14+
15+
const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });
16+
17+
new route53.ARecord(stack, 'LocalGlobalAcceleratorAlias', {
18+
comment: 'Alias to the locally created Global Accelerator',
19+
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorTarget(accelerator)),
20+
recordName: 'test-local',
21+
zone,
22+
});
23+
24+
new route53.ARecord(stack, 'ExistingGlobalAcceleratorAlias', {
25+
comment: 'Alias to the an existing Global Accelerator',
26+
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorDomainTarget('someexisting.awsglobalaccelerator.com')),
27+
recordName: 'test-existing',
28+
zone,
29+
});
30+
31+
app.synth();

0 commit comments

Comments
 (0)