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(route53): added EvaluateTargetHealth to Route53 Alias targets (#9481) #30664

Merged
merged 45 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
e7ceac5
feat(route53): added EvaluateTargetHealth to Route53 Alias targets
wladyslawczyzewski Jun 25, 2024
5d6aa97
feat(route53): revert some previous changes to not introducing the
wladyslawczyzewski Jun 25, 2024
070eda9
feat(route53): update integration tests for EvalueateTargetHealth pro…
wladyslawczyzewski Jun 25, 2024
d004bc9
feat(route53): update README file
wladyslawczyzewski Jun 25, 2024
3ea3441
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Jul 2, 2024
83f2a95
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Jul 11, 2024
c93b2c9
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Jul 17, 2024
127acb3
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Jul 24, 2024
cab0113
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Jul 28, 2024
c524487
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Aug 2, 2024
a804541
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Aug 5, 2024
222d3da
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Aug 22, 2024
dd2b02f
Update packages/aws-cdk-lib/aws-route53-targets/lib/bucket-website-ta…
wladyslawczyzewski Nov 10, 2024
98c02af
Update packages/aws-cdk-lib/aws-route53-targets/lib/classic-load-bala…
wladyslawczyzewski Nov 10, 2024
953964a
Update packages/aws-cdk-lib/aws-route53-targets/lib/elastic-beanstalk…
wladyslawczyzewski Nov 10, 2024
cf76e59
Update packages/aws-cdk-lib/aws-route53-targets/lib/global-accelerato…
wladyslawczyzewski Nov 10, 2024
272294e
Update packages/aws-cdk-lib/aws-route53-targets/lib/load-balancer-tar…
wladyslawczyzewski Nov 10, 2024
60629b7
revert some prev changes (should be in 5d6aa97726)
wladyslawczyzewski Nov 10, 2024
0642fca
Merge remote-tracking branch 'origin/main' into route53_evaluate_alia…
wladyslawczyzewski Nov 10, 2024
ada7c31
upadate jsdoc
wladyslawczyzewski Nov 10, 2024
08bdd8c
fix types
wladyslawczyzewski Nov 10, 2024
22352d1
few more integration tests
wladyslawczyzewski Nov 11, 2024
2c27f3a
added integration test to evaluate elastic beanstalk environment health
wladyslawczyzewski Nov 13, 2024
4ded7a5
Merge remote-tracking branch 'origin/main' into route53_evaluate_alia…
wladyslawczyzewski Nov 13, 2024
fc74f19
fix script name
wladyslawczyzewski Nov 13, 2024
27860eb
fix integration test in ci env
wladyslawczyzewski Nov 13, 2024
e798c47
fix test in ci env
wladyslawczyzewski Nov 13, 2024
b5e4d80
Merge branch 'main' into route53_evaluate_alias_health
wladyslawczyzewski Nov 14, 2024
c07bab4
extract common interface
wladyslawczyzewski Nov 21, 2024
f63ff1f
Merge remote-tracking branch 'origin/main' into route53_evaluate_alia…
wladyslawczyzewski Nov 21, 2024
0740f45
fix build on CI
wladyslawczyzewski Nov 21, 2024
0ed30d1
fix CI build
wladyslawczyzewski Nov 22, 2024
1883fc1
Merge remote-tracking branch 'origin/main' into route53_evaluate_alia…
wladyslawczyzewski Nov 22, 2024
963ba80
added docstring
wladyslawczyzewski Nov 22, 2024
4ef99bb
rename the file with shared interface
wladyslawczyzewski Nov 23, 2024
823e263
Merge remote-tracking branch 'origin/main' into route53_evaluate_alia…
wladyslawczyzewski Nov 23, 2024
d145d85
fix import paths
wladyslawczyzewski Nov 23, 2024
a309400
Merge branch 'main' into route53_evaluate_alias_health
GavinZZ Nov 26, 2024
ae19705
Merge branch 'main' into route53_evaluate_alias_health
GavinZZ Nov 28, 2024
2081fc5
Merge branch 'main' into route53_evaluate_alias_health
mergify[bot] Nov 28, 2024
2c78477
Merge branch 'main' into route53_evaluate_alias_health
mergify[bot] Nov 29, 2024
5043d97
Merge remote-tracking branch 'origin/main' into route53_evaluate_alia…
wladyslawczyzewski Dec 6, 2024
a4c4781
Merge remote-tracking branch 'fork/route53_evaluate_alias_health' int…
wladyslawczyzewski Dec 6, 2024
ec0f368
Merge remote-tracking branch 'origin/main' into route53_evaluate_alia…
wladyslawczyzewski Dec 11, 2024
0ccd555
Merge branch 'main' into route53_evaluate_alias_health
kaizencc Dec 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import { RegionInfo } from '../../region-info';
* Use a S3 as an alias record target
*/
export class BucketWebsiteTarget implements route53.IAliasRecordTarget {
constructor(private readonly bucket: s3.IBucket) {
}
constructor(private readonly bucket: s3.IBucket, private readonly props?: BucketWebsiteTargetProps) {}

public bind(_record: route53.IRecordSet, _zone?: route53.IHostedZone): route53.AliasRecordTargetConfig {
const { region } = Stack.of(this.bucket.stack);
Expand All @@ -27,6 +26,17 @@ export class BucketWebsiteTarget implements route53.IAliasRecordTarget {
throw new Error(`Bucket website target is not supported for the "${region}" region`);
}

return { hostedZoneId, dnsName };
return { hostedZoneId, dnsName, evaluateTargetHealth: this.props?.evaluateTargetHealth };
}
}

/**
* Properties for a bucket website target
*/
export interface BucketWebsiteTargetProps {
/**
* Evaluate target health
* @default - no health check configuration
*/
readonly evaluateTargetHealth?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,24 @@ import * as route53 from '../../aws-route53';
* Use a classic ELB as an alias record target
*/
export class ClassicLoadBalancerTarget implements route53.IAliasRecordTarget {
constructor(private readonly loadBalancer: elb.LoadBalancer) {
}
constructor(private readonly loadBalancer: elb.LoadBalancer, private readonly props?: ClassicLoadBalancerTargetProps) {}

public bind(_record: route53.IRecordSet, _zone?: route53.IHostedZone): route53.AliasRecordTargetConfig {
return {
hostedZoneId: this.loadBalancer.loadBalancerCanonicalHostedZoneNameId,
dnsName: `dualstack.${this.loadBalancer.loadBalancerDnsName}`,
evaluateTargetHealth: this.props?.evaluateTargetHealth,
};
}
}

/**
* Properties for a classic ELB target
*/
export interface ClassicLoadBalancerTargetProps {
/**
* Evaluate target health
* @default - no health check configuration
*/
readonly evaluateTargetHealth?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ import { RegionInfo } from '../../region-info';
* Only supports Elastic Beanstalk environments created after 2016 that have a regional endpoint.
*/
export class ElasticBeanstalkEnvironmentEndpointTarget implements route53.IAliasRecordTarget {
constructor(private readonly environmentEndpoint: string) {
}
constructor(
private readonly environmentEndpoint: string,
private readonly props: ElasticBeanstalkEnvironmentEndpointTargetProps = { evaluateTargetHealth: false },
) {}

public bind(_record: route53.IRecordSet, _zone?: route53.IHostedZone): route53.AliasRecordTargetConfig {
if (cdk.Token.isUnresolved(this.environmentEndpoint)) {
Expand All @@ -31,6 +33,18 @@ export class ElasticBeanstalkEnvironmentEndpointTarget implements route53.IAlias
return {
hostedZoneId,
dnsName,
evaluateTargetHealth: this.props.evaluateTargetHealth,
};
}
}

/**
* Properties for an Elastic Beanstalk environment URL target
*/
export interface ElasticBeanstalkEnvironmentEndpointTargetProps {
/**
* Evaluate target health
* @default - false
*/
readonly evaluateTargetHealth?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ export class GlobalAcceleratorDomainTarget implements route53.IAliasRecordTarget
/**
* Create an Alias Target for a Global Accelerator domain name.
*/
constructor(private readonly acceleratorDomainName: string) {
}
constructor(private readonly acceleratorDomainName: string, private readonly props?: GlobalAcceleratorDomainTargetProps) {}

bind(_record: route53.IRecordSet, _zone?: route53.IHostedZone): route53.AliasRecordTargetConfig {
return {
hostedZoneId: GlobalAcceleratorTarget.GLOBAL_ACCELERATOR_ZONE_ID,
dnsName: this.acceleratorDomainName,
evaluateTargetHealth: this.props?.evaluateTargetHealth,
};
}
}
Expand All @@ -30,11 +30,21 @@ export class GlobalAcceleratorDomainTarget implements route53.IAliasRecordTarget
* 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);
constructor(accelerator: globalaccelerator.IAccelerator, props?: GlobalAcceleratorDomainTargetProps) {
super(accelerator.dnsName, props);
}
}

/**
* Properties for a Global Accelerator domain name target
*/
export interface GlobalAcceleratorDomainTargetProps {
/**
* Evaluate target health
* @default - no health check configuration
*/
readonly evaluateTargetHealth?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,24 @@ import * as route53 from '../../aws-route53';
* Use an ELBv2 as an alias record target
*/
export class LoadBalancerTarget implements route53.IAliasRecordTarget {
constructor(private readonly loadBalancer: elbv2.ILoadBalancerV2) {
}
constructor(private readonly loadBalancer: elbv2.ILoadBalancerV2, private readonly props?: LoadBalancerTargetProps) {}

public bind(_record: route53.IRecordSet, _zone?: route53.IHostedZone): route53.AliasRecordTargetConfig {
return {
hostedZoneId: this.loadBalancer.loadBalancerCanonicalHostedZoneId,
dnsName: `dualstack.${this.loadBalancer.loadBalancerDnsName}`,
evaluateTargetHealth: this.props?.evaluateTargetHealth,
};
}
}

/**
* Properties for an ELBv2 target
*/
export interface LoadBalancerTargetProps {
/**
* Evaluate target health
* @default - no health check configuration
*/
readonly evaluateTargetHealth?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,33 @@ test('use S3 bucket website as record target', () => {
});
});

test('use S3 bucket website as record target with health check', () => {
// GIVEN
const app = new App();
const stack = new Stack(app, 'test', { env: { region: 'us-east-1' } });

const bucketWebsite = new s3.Bucket(stack, 'Bucket', { bucketName });

// WHEN
const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName });
new route53.ARecord(zone, 'Alias', {
zone,
recordName,
target: route53.RecordTarget.fromAlias(
new targets.BucketWebsiteTarget(bucketWebsite, {
evaluateTargetHealth: true,
}),
),
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Route53::RecordSet', {
AliasTarget: {
EvaluateTargetHealth: true,
},
});
});

test('use S3 bucket website as record target (fromBucketName)', () => {
// GIVEN
const app = new App();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,35 @@ test('use classic ELB as record target', () => {
},
});
});

test('use classic ELB as record target with health check', () => {
// GIVEN
const stack = new Stack();
const vpc = new ec2.Vpc(stack, 'VPC', {
maxAzs: 2,
});
const lb = new elb.LoadBalancer(stack, 'LB', {
vpc,
internetFacing: true,
});

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

// WHEN
new route53.ARecord(zone, 'Alias', {
zone,
recordName: '_foo',
target: route53.RecordTarget.fromAlias(
new targets.ClassicLoadBalancerTarget(lb, {
evaluateTargetHealth: true,
}),
),
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Route53::RecordSet', {
AliasTarget: {
EvaluateTargetHealth: true,
},
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ test('use EBS environment as record target', () => {
new route53.ARecord(stack, 'Alias', {
zone,
recordName: '_foo',
target: route53.RecordTarget.fromAlias(new targets.ElasticBeanstalkEnvironmentEndpointTarget('mysampleenvironment.xyz.us-east-1.elasticbeanstalk.com')),
target: route53.RecordTarget.fromAlias(
new targets.ElasticBeanstalkEnvironmentEndpointTarget('mysampleenvironment.xyz.us-east-1.elasticbeanstalk.com'),
),
});

// THEN
Expand Down Expand Up @@ -44,3 +46,27 @@ test('support 4-levels subdomain URLs for EBS environments', () => {
},
});
});

test('use EBS environment as record target with health check', () => {
// GIVEN
const stack = new Stack();
const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });

// WHEN
new route53.ARecord(stack, 'Alias', {
zone,
recordName: '_foo',
target: route53.RecordTarget.fromAlias(
new targets.ElasticBeanstalkEnvironmentEndpointTarget('mysampleenvironment.xyz.us-east-1.elasticbeanstalk.com', {
evaluateTargetHealth: true,
}),
),
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Route53::RecordSet', {
AliasTarget: {
EvaluateTargetHealth: true,
},
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,34 @@ test('GlobalAcceleratorTarget creates an alias resource with a Global Accelerato
Template.fromStack(stack).hasResourceProperties('AWS::Route53::RecordSet', {
AliasTarget: {
DNSName: {
'Fn::GetAtt': [
logicalId,
'DnsName',
],
'Fn::GetAtt': [logicalId, 'DnsName'],
},
HostedZoneId: 'Z2BJ6XQ5FK7U4H',
},
});
});
});

test('GlobalAcceleratorTarget creates an alias resource with health check', () => {
// GIVEN
const stack = new Stack();
const accelerator = new globalaccelerator.Accelerator(stack, 'Accelerator');
const zone = new route53.PublicHostedZone(stack, 'HostedZone', { zoneName: 'test.public' });

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

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Route53::RecordSet', {
AliasTarget: {
EvaluateTargetHealth: true,
},
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,35 @@ test('use ALB as record target', () => {
},
});
});

test('use ALB as record target with health check', () => {
// GIVEN
const stack = new Stack();
const vpc = new ec2.Vpc(stack, 'VPC', {
maxAzs: 2,
});
const lb = new elbv2.ApplicationLoadBalancer(stack, 'LB', {
vpc,
internetFacing: true,
});

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

// WHEN
new route53.ARecord(zone, 'Alias', {
zone,
recordName: '_foo',
target: route53.RecordTarget.fromAlias(
new targets.LoadBalancerTarget(lb, {
evaluateTargetHealth: true,
}),
),
});

// THEN
Template.fromStack(stack).hasResourceProperties('AWS::Route53::RecordSet', {
AliasTarget: {
EvaluateTargetHealth: true,
},
});
});
7 changes: 7 additions & 0 deletions packages/aws-cdk-lib/aws-route53/lib/alias-record-target.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@ export interface AliasRecordTargetConfig {
* DNS name of the target
*/
readonly dnsName: string;

/**
* Evaluate the target health
*
* @default - undefined
*/
readonly evaluateTargetHealth?: boolean;
}
Loading
Loading