diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.assets.json new file mode 100644 index 0000000000000..5e6fa13156374 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/cdk.out b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/cdk.out new file mode 100644 index 0000000000000..1f0068d32659a --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"36.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/integ.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/integ.json new file mode 100644 index 0000000000000..d4846f2169088 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "36.0.0", + "testCases": { + "Route53LatencyBasedRoutingInteg/DefaultTest": { + "stacks": [ + "latency-based-routing" + ], + "assertionStack": "Route53LatencyBasedRoutingInteg/DefaultTest/DeployAssert", + "assertionStackName": "Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/latency-based-routing.assets.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/latency-based-routing.assets.json new file mode 100644 index 0000000000000..65a0b9089f9bb --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/latency-based-routing.assets.json @@ -0,0 +1,19 @@ +{ + "version": "36.0.0", + "files": { + "a80ec20b957f0b1134ee759f20e89c04b7bc876c73408565ff5613e6632e3b1f": { + "source": { + "path": "latency-based-routing.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "a80ec20b957f0b1134ee759f20e89c04b7bc876c73408565ff5613e6632e3b1f.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/latency-based-routing.template.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/latency-based-routing.template.json new file mode 100644 index 0000000000000..7a46513e08aa4 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/latency-based-routing.template.json @@ -0,0 +1,92 @@ +{ + "Resources": { + "HostedZoneDB99F866": { + "Type": "AWS::Route53::HostedZone", + "Properties": { + "Name": "cdk.dev." + } + }, + "LatencyBasedRouting0C1664EAC": { + "Type": "AWS::Route53::RecordSet", + "Properties": { + "HostedZoneId": { + "Ref": "HostedZoneDB99F866" + }, + "Name": "www.cdk.dev.", + "Region": "us-east-1", + "ResourceRecords": [ + "1.2.3.4" + ], + "SetIdentifier": "REGION_us-east-1_ID_latencybasedroutintencyBasedRouting09258C5CC", + "TTL": "1800", + "Type": "A" + } + }, + "LatencyBasedRouting1D10EA109": { + "Type": "AWS::Route53::RecordSet", + "Properties": { + "HostedZoneId": { + "Ref": "HostedZoneDB99F866" + }, + "Name": "www.cdk.dev.", + "Region": "ap-northeast-1", + "ResourceRecords": [ + "2.3.4.5" + ], + "SetIdentifier": "REGION_ap-northeast-1_ID_latencybasedroucyBasedRouting193C4855F", + "TTL": "1800", + "Type": "A" + } + }, + "LatencyBasedRouting26C32588A": { + "Type": "AWS::Route53::RecordSet", + "Properties": { + "HostedZoneId": { + "Ref": "HostedZoneDB99F866" + }, + "Name": "www.cdk.dev.", + "Region": "eu-west-1", + "ResourceRecords": [ + "3.4.5.6" + ], + "SetIdentifier": "REGION_eu-west-1_ID_latencybasedroutintencyBasedRouting25966E4AD", + "TTL": "1800", + "Type": "A" + } + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/manifest.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/manifest.json new file mode 100644 index 0000000000000..b8eba09d53899 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/manifest.json @@ -0,0 +1,131 @@ +{ + "version": "36.0.0", + "artifacts": { + "latency-based-routing.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "latency-based-routing.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "latency-based-routing": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "latency-based-routing.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/a80ec20b957f0b1134ee759f20e89c04b7bc876c73408565ff5613e6632e3b1f.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "latency-based-routing.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "latency-based-routing.assets" + ], + "metadata": { + "/latency-based-routing/HostedZone/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "HostedZoneDB99F866" + } + ], + "/latency-based-routing/LatencyBasedRouting0/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LatencyBasedRouting0C1664EAC" + } + ], + "/latency-based-routing/LatencyBasedRouting1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LatencyBasedRouting1D10EA109" + } + ], + "/latency-based-routing/LatencyBasedRouting2/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "LatencyBasedRouting26C32588A" + } + ], + "/latency-based-routing/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/latency-based-routing/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "latency-based-routing" + }, + "Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.template.json", + "terminationProtection": false, + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "Route53LatencyBasedRoutingIntegDefaultTestDeployAssert0B7B9B14.assets" + ], + "metadata": { + "/Route53LatencyBasedRoutingInteg/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/Route53LatencyBasedRoutingInteg/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "Route53LatencyBasedRoutingInteg/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/tree.json b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/tree.json new file mode 100644 index 0000000000000..75c178dd1b0a1 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.js.snapshot/tree.json @@ -0,0 +1,227 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "latency-based-routing": { + "id": "latency-based-routing", + "path": "latency-based-routing", + "children": { + "HostedZone": { + "id": "HostedZone", + "path": "latency-based-routing/HostedZone", + "children": { + "Resource": { + "id": "Resource", + "path": "latency-based-routing/HostedZone/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::HostedZone", + "aws:cdk:cloudformation:props": { + "name": "cdk.dev." + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.CfnHostedZone", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.PublicHostedZone", + "version": "0.0.0" + } + }, + "LatencyBasedRouting0": { + "id": "LatencyBasedRouting0", + "path": "latency-based-routing/LatencyBasedRouting0", + "children": { + "Resource": { + "id": "Resource", + "path": "latency-based-routing/LatencyBasedRouting0/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet", + "aws:cdk:cloudformation:props": { + "hostedZoneId": { + "Ref": "HostedZoneDB99F866" + }, + "name": "www.cdk.dev.", + "region": "us-east-1", + "resourceRecords": [ + "1.2.3.4" + ], + "setIdentifier": "REGION_us-east-1_ID_latencybasedroutintencyBasedRouting09258C5CC", + "ttl": "1800", + "type": "A" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.CfnRecordSet", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.ARecord", + "version": "0.0.0" + } + }, + "LatencyBasedRouting1": { + "id": "LatencyBasedRouting1", + "path": "latency-based-routing/LatencyBasedRouting1", + "children": { + "Resource": { + "id": "Resource", + "path": "latency-based-routing/LatencyBasedRouting1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet", + "aws:cdk:cloudformation:props": { + "hostedZoneId": { + "Ref": "HostedZoneDB99F866" + }, + "name": "www.cdk.dev.", + "region": "ap-northeast-1", + "resourceRecords": [ + "2.3.4.5" + ], + "setIdentifier": "REGION_ap-northeast-1_ID_latencybasedroucyBasedRouting193C4855F", + "ttl": "1800", + "type": "A" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.CfnRecordSet", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.ARecord", + "version": "0.0.0" + } + }, + "LatencyBasedRouting2": { + "id": "LatencyBasedRouting2", + "path": "latency-based-routing/LatencyBasedRouting2", + "children": { + "Resource": { + "id": "Resource", + "path": "latency-based-routing/LatencyBasedRouting2/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Route53::RecordSet", + "aws:cdk:cloudformation:props": { + "hostedZoneId": { + "Ref": "HostedZoneDB99F866" + }, + "name": "www.cdk.dev.", + "region": "eu-west-1", + "resourceRecords": [ + "3.4.5.6" + ], + "setIdentifier": "REGION_eu-west-1_ID_latencybasedroutintencyBasedRouting25966E4AD", + "ttl": "1800", + "type": "A" + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.CfnRecordSet", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.aws_route53.ARecord", + "version": "0.0.0" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "latency-based-routing/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "latency-based-routing/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + }, + "Route53LatencyBasedRoutingInteg": { + "id": "Route53LatencyBasedRoutingInteg", + "path": "Route53LatencyBasedRoutingInteg", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "Route53LatencyBasedRoutingInteg/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "Route53LatencyBasedRoutingInteg/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "Route53LatencyBasedRoutingInteg/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "Route53LatencyBasedRoutingInteg/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "Route53LatencyBasedRoutingInteg/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "aws-cdk-lib.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests-alpha.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.3.0" + } + } + }, + "constructInfo": { + "fqn": "aws-cdk-lib.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.ts b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.ts new file mode 100644 index 0000000000000..fc83fb1630db3 --- /dev/null +++ b/packages/@aws-cdk-testing/framework-integ/test/aws-route53/test/integ.latency-based-routing.ts @@ -0,0 +1,35 @@ +import { App, Stack, StackProps } from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import * as route53 from 'aws-cdk-lib/aws-route53'; +import { IntegTest } from '@aws-cdk/integ-tests-alpha'; + +class TestStack extends Stack { + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + const hostedZone = new route53.PublicHostedZone(this, 'HostedZone', { + zoneName: 'cdk.dev', + }); + + [ + { target: '1.2.3.4', region: 'us-east-1' }, + { target: '2.3.4.5', region: 'ap-northeast-1' }, + { target: '3.4.5.6', region: 'eu-west-1' }, + ].forEach((data, index) => { + new route53.ARecord(this, `LatencyBasedRouting${index}`, { + zone: hostedZone, + recordName: 'www', + region: data.region, + target: route53.RecordTarget.fromIpAddresses(data.target), + }); + }); + } +} + +const app = new App(); +const stack = new TestStack(app, 'latency-based-routing'); + +new IntegTest(app, 'Route53LatencyBasedRoutingInteg', { + testCases: [stack], +}); +app.synth(); diff --git a/packages/aws-cdk-lib/aws-route53/README.md b/packages/aws-cdk-lib/aws-route53/README.md index fb33c8f5e7fdf..34727074040a4 100644 --- a/packages/aws-cdk-lib/aws-route53/README.md +++ b/packages/aws-cdk-lib/aws-route53/README.md @@ -163,6 +163,18 @@ new route53.ARecord(this, 'ARecordWeighted1', { }); ``` +To enable [latency based routing](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-policy-latency.html), use the `region` parameter: + +```ts +declare const myZone: route53.HostedZone; + +new route53.ARecord(this, 'ARecordLatency1', { + zone: myZone, + target: route53.RecordTarget.fromIpAddresses('1.2.3.4'), + region: 'us-east-1', +}); +``` + To specify a unique identifier to differentiate among multiple resource record sets that have the same combination of name and type, use the `setIdentifier` parameter: ```ts @@ -172,10 +184,10 @@ new route53.ARecord(this, 'ARecordWeighted1', { zone: myZone, target: route53.RecordTarget.fromIpAddresses('1.2.3.4'), weight: 10, - setIdentifier: 'weighted-record-id', + setIdentifier: 'weighted-record-id', }); ``` -**Warning** It is not possible to specify `setIdentifier` in a simple routing without one of `weight` or `geoLocation` defined. +**Warning** It is not possible to specify `setIdentifier` for a simple routing policy. Constructs are available for A, AAAA, CAA, CNAME, MX, NS, SRV and TXT records. diff --git a/packages/aws-cdk-lib/aws-route53/lib/record-set.ts b/packages/aws-cdk-lib/aws-route53/lib/record-set.ts index 02c1b2a8d3fac..8564aedae843a 100644 --- a/packages/aws-cdk-lib/aws-route53/lib/record-set.ts +++ b/packages/aws-cdk-lib/aws-route53/lib/record-set.ts @@ -200,6 +200,21 @@ export interface RecordSetOptions { */ readonly weight?: number; + /** + * The Amazon EC2 Region where you created the resource that this resource record set refers to. + * The resource typically is an AWS resource, such as an EC2 instance or an ELB load balancer, + * and is referred to by an IP address or a DNS domain name, depending on the record type. + * + * When Amazon Route 53 receives a DNS query for a domain name and type for which you have created latency resource record sets, + * Route 53 selects the latency resource record set that has the lowest latency between the end user and the associated Amazon EC2 Region. + * Route 53 then returns the value that is associated with the selected resource record set. + * + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-route53-recordset.html#cfn-route53-recordset-region + * + * @default - Do not set latency based routing + */ + readonly region?: string; + /** * A string used to distinguish between different records with the same combination of DNS name and type. * It can only be set when either weight or geoLocation is defined. @@ -268,6 +283,7 @@ export class RecordSet extends Resource implements IRecordSet { public readonly domainName: string; private readonly geoLocation?: GeoLocation; private readonly weight?: number; + private readonly region?: string; constructor(scope: Construct, id: string, props: RecordSetProps) { super(scope, id); @@ -278,15 +294,18 @@ export class RecordSet extends Resource implements IRecordSet { if (props.setIdentifier && (props.setIdentifier.length < 1 || props.setIdentifier.length > 128)) { throw new Error(`setIdentifier must be between 1 and 128 characters long, got: ${props.setIdentifier.length}`); } - if (props.weight && props.geoLocation) { - throw new Error('Only one of weight or geoLocation can be specified, not both'); + if (props.setIdentifier && !props.weight && !props.geoLocation && !props.region) { + throw new Error('setIdentifier can only be specified for non-simple routing policies'); } - if (props.setIdentifier && !props.weight && !props.geoLocation) { - throw new Error('setIdentifier can only be specified when either weight or geoLocation is defined'); + + let nonSimpleRoutingPolicies = [props.geoLocation, props.region, props.weight].filter((variable) => variable !== undefined).length; + if (nonSimpleRoutingPolicies > 1) { + throw new Error('Only one of region, weight, or geoLocation can be defined'); } this.geoLocation = props.geoLocation; this.weight = props.weight; + this.region = props.region; const ttl = props.target.aliasTarget ? undefined : ((props.ttl && props.ttl.toSeconds()) ?? 1800).toString(); @@ -307,6 +326,7 @@ export class RecordSet extends Resource implements IRecordSet { } : undefined, setIdentifier: props.setIdentifier ?? this.configureSetIdentifier(), weight: props.weight, + region: props.region, }); this.domainName = recordSet.ref; @@ -369,12 +389,20 @@ export class RecordSet extends Resource implements IRecordSet { if (this.weight) { const idPrefix = `WEIGHT_${this.weight}_ID_`; - const identifier = `${idPrefix}${Names.uniqueResourceName(this, { maxLength: 64 - idPrefix.length })}`; - return identifier; + return this.createIdentifier(idPrefix); + } + + if (this.region) { + const idPrefix= `REGION_${this.region}_ID_`; + return this.createIdentifier(idPrefix); } return undefined; } + + private createIdentifier(prefix: string): string { + return `${prefix}${Names.uniqueResourceName(this, { maxLength: 64 - prefix.length })}`; + } } /** diff --git a/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts b/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts index 871768a41893a..7f6c990af4955 100644 --- a/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts +++ b/packages/aws-cdk-lib/aws-route53/test/record-set.test.ts @@ -1166,7 +1166,12 @@ describe('record set', () => { })).toThrow('setIdentifier must be between 1 and 128 characters long, got: 129'); }); - test('throw error for the simultaneous definition of weight and geoLocation', () => { + test.each([ + { weight: 20, geoLocation: route53.GeoLocation.continent(route53.Continent.EUROPE) }, + { weight: 20, region: 'us-east-1' }, + { geoLocation: route53.GeoLocation.continent(route53.Continent.EUROPE), region: 'us-east-1' }, + { weight: 20, geoLocation: route53.GeoLocation.continent(route53.Continent.EUROPE), region: 'us-east-1' }, + ])('throw error for the simultaneous definition of weight, geoLocation and region', (props) => { // GIVEN const stack = new Stack(); @@ -1178,13 +1183,12 @@ describe('record set', () => { recordName: 'www', recordType: route53.RecordType.CNAME, target: route53.RecordTarget.fromValues('zzz'), - weight: 50, - geoLocation: route53.GeoLocation.continent(route53.Continent.EUROPE), setIdentifier: 'uniqueId', - })).toThrow('Only one of weight or geoLocation can be specified, not both'); + ...props, + })).toThrow('Only one of region, weight, or geoLocation can be defined'); }); - test('throw error for the definition of setIdentifier without weight or geoLocation', () => { + test('throw error for the definition of setIdentifier without weight, geoLocation or region', () => { // GIVEN const stack = new Stack(); @@ -1197,6 +1201,6 @@ describe('record set', () => { recordType: route53.RecordType.CNAME, target: route53.RecordTarget.fromValues('zzz'), setIdentifier: 'uniqueId', - })).toThrow('setIdentifier can only be specified when either weight or geoLocation is defined'); + })).toThrow('setIdentifier can only be specified for non-simple routing policies'); }); });