Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(aws-route53-targets): add global accelerator target to route53 alias targets #13407

Merged
merged 15 commits into from Mar 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 13 additions & 0 deletions packages/@aws-cdk/aws-route53-targets/README.md
Expand Up @@ -63,6 +63,19 @@ This library contains Route53 Alias Record targets for:

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`.

* GlobalAccelerator

```ts
new route53.ARecord(stack, 'AliasRecord', {
zone,
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorTarget(accelerator)),
// or - route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorDomainTarget('xyz.awsglobalaccelerator.com')),
});
```

**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.
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.

* InterfaceVpcEndpoints

**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.
Expand Down
@@ -0,0 +1,41 @@
import * as globalaccelerator from '@aws-cdk/aws-globalaccelerator';
import * as route53 from '@aws-cdk/aws-route53';


/**
* Use a Global Accelerator domain name as an alias record target.
*/
export class GlobalAcceleratorDomainTarget implements route53.IAliasRecordTarget {
/**
* The hosted zone Id if using an alias record in Route53.
* This value never changes.
* Ref: https://docs.aws.amazon.com/general/latest/gr/global_accelerator.html
*/
public static readonly GLOBAL_ACCELERATOR_ZONE_ID = 'Z2BJ6XQ5FK7U4H';

/**
* Create an Alias Target for a Global Accelerator domain name.
*/
constructor(private readonly acceleratorDomainName: string) {
}

bind(_record: route53.IRecordSet): route53.AliasRecordTargetConfig {
return {
hostedZoneId: GlobalAcceleratorTarget.GLOBAL_ACCELERATOR_ZONE_ID,
dnsName: this.acceleratorDomainName,
};
}
}

/**
* Use a Global Accelerator instance domain name as an alias record target.
*/
export class GlobalAcceleratorTarget extends GlobalAcceleratorDomainTarget {

/**
* Create an Alias Target for a Global Accelerator instance.
*/
constructor(accelerator: globalaccelerator.IAccelerator) {
super(accelerator.dnsName);
}
}
1 change: 1 addition & 0 deletions packages/@aws-cdk/aws-route53-targets/lib/index.ts
Expand Up @@ -6,3 +6,4 @@ export * from './cloudfront-target';
export * from './load-balancer-target';
export * from './interface-vpc-endpoint-target';
export * from './userpool-domain';
export * from './global-accelerator-target';
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-route53-targets/package.json
Expand Up @@ -80,6 +80,7 @@
"@aws-cdk/aws-elasticloadbalancing": "0.0.0",
"@aws-cdk/aws-elasticloadbalancingv2": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-globalaccelerator": "0.0.0",
"@aws-cdk/aws-route53": "0.0.0",
"@aws-cdk/aws-s3": "0.0.0",
"@aws-cdk/core": "0.0.0",
Expand All @@ -96,6 +97,7 @@
"@aws-cdk/aws-elasticloadbalancing": "0.0.0",
"@aws-cdk/aws-elasticloadbalancingv2": "0.0.0",
"@aws-cdk/aws-iam": "0.0.0",
"@aws-cdk/aws-globalaccelerator": "0.0.0",
"@aws-cdk/aws-route53": "0.0.0",
"@aws-cdk/aws-s3": "0.0.0",
"@aws-cdk/core": "0.0.0",
Expand Down
@@ -0,0 +1,59 @@
import '@aws-cdk/assert/jest';
import * as globalaccelerator from '@aws-cdk/aws-globalaccelerator';
import * as route53 from '@aws-cdk/aws-route53';
import { Stack } from '@aws-cdk/core';
import * as targets from '../lib';

test('GlobalAcceleratorTarget exposes a public constant of the zone id', () => {
expect(targets.GlobalAcceleratorTarget.GLOBAL_ACCELERATOR_ZONE_ID).toStrictEqual('Z2BJ6XQ5FK7U4H');
expect(targets.GlobalAcceleratorDomainTarget.GLOBAL_ACCELERATOR_ZONE_ID).toStrictEqual('Z2BJ6XQ5FK7U4H');
});

test('GlobalAcceleratorTarget creates an alias resource with a string domain name', () => {
// GIVEN
const stack = new Stack();
const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });

// WHEN
new route53.ARecord(stack, 'GlobalAcceleratorAlias', {
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorDomainTarget('xyz.awsglobalaccelerator.com')),
recordName: 'test',
zone,
});

// THEN
expect(stack).toHaveResource('AWS::Route53::RecordSet', {
AliasTarget: {
DNSName: 'xyz.awsglobalaccelerator.com',
HostedZoneId: 'Z2BJ6XQ5FK7U4H',
},
});
});

test('GlobalAcceleratorTarget creates an alias resource with a Global Accelerator reference domain name', () => {
// GIVEN
const stack = new Stack();
const accelerator = new globalaccelerator.Accelerator(stack, 'Accelerator');
const logicalId = stack.getLogicalId(<globalaccelerator.CfnAccelerator>accelerator.node.defaultChild);
const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });

// WHEN
new route53.ARecord(stack, 'GlobalAcceleratorAlias', {
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorTarget(accelerator)),
recordName: 'test',
zone,
});

// THEN
expect(stack).toHaveResource('AWS::Route53::RecordSet', {
AliasTarget: {
DNSName: {
'Fn::GetAtt': [
logicalId,
'DnsName',
],
},
HostedZoneId: 'Z2BJ6XQ5FK7U4H',
},
});
});
@@ -0,0 +1,52 @@
{
"Resources": {
"Accelerator8EB0B6B1": {
"Type": "AWS::GlobalAccelerator::Accelerator",
"Properties": {
"Name": "aws-cdk-globalaccelerator-integ",
"Enabled": true
}
},
"HostedZoneDB99F866": {
"Type": "AWS::Route53::HostedZone",
"Properties": {
"Name": "test.public."
}
},
"LocalGlobalAcceleratorAlias18B4A87A": {
"Type": "AWS::Route53::RecordSet",
"Properties": {
"Name": "test-local.test.public.",
"Type": "A",
"AliasTarget": {
"DNSName": {
"Fn::GetAtt": [
"Accelerator8EB0B6B1",
"DnsName"
]
},
"HostedZoneId": "Z2BJ6XQ5FK7U4H"
},
"Comment": "Alias to the locally created Global Accelerator",
"HostedZoneId": {
"Ref": "HostedZoneDB99F866"
}
}
},
"ExistingGlobalAcceleratorAlias7ACF888C": {
"Type": "AWS::Route53::RecordSet",
"Properties": {
"Name": "test-existing.test.public.",
"Type": "A",
"AliasTarget": {
"DNSName": "someexisting.awsglobalaccelerator.com",
"HostedZoneId": "Z2BJ6XQ5FK7U4H"
},
"Comment": "Alias to the an existing Global Accelerator",
"HostedZoneId": {
"Ref": "HostedZoneDB99F866"
}
}
}
}
}
@@ -0,0 +1,31 @@
#!/usr/bin/env node
import * as globalaccelerator from '@aws-cdk/aws-globalaccelerator';
import * as route53 from '@aws-cdk/aws-route53';
import * as cdk from '@aws-cdk/core';
import * as targets from '../lib';

const app = new cdk.App();
const stack = new cdk.Stack(app, 'aws-cdk-globalaccelerator-integ');

let accelerator = new globalaccelerator.Accelerator(stack, 'Accelerator', {
acceleratorName: `${stack.stackName}`,
enabled: true,
});

const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });

new route53.ARecord(stack, 'LocalGlobalAcceleratorAlias', {
comment: 'Alias to the locally created Global Accelerator',
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorTarget(accelerator)),
recordName: 'test-local',
zone,
});

new route53.ARecord(stack, 'ExistingGlobalAcceleratorAlias', {
njlynch marked this conversation as resolved.
Show resolved Hide resolved
comment: 'Alias to the an existing Global Accelerator',
target: route53.RecordTarget.fromAlias(new targets.GlobalAcceleratorDomainTarget('someexisting.awsglobalaccelerator.com')),
recordName: 'test-existing',
zone,
});

app.synth();