Skip to content

Commit

Permalink
feat(route53): New Route53 CrossAccountRecordSet construct
Browse files Browse the repository at this point in the history
\### Issue # (if applicable)

Closes aws#15213
Addresses aws#26754

\### Reason for this change

\### Description of changes

\### Description of how you validated changes

\### Checklist

- [x] My code adheres to the [CONTRIBUTING GUIDE](https://github.com/aws/aws-cdk/blob/main/CONTRIBUTING.md) and [DESIGN GUIDELINES](https://github.com/aws/aws-cdk/blob/main/docs/DESIGN_GUIDELINES.md)

---

*By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
  • Loading branch information
Luke Pafford committed Aug 22, 2024
1 parent af50620 commit e97fed7
Show file tree
Hide file tree
Showing 9 changed files with 1,360 additions and 64 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import { Route53 } from '@aws-sdk/client-route-53';
// eslint-disable-next-line import/no-extraneous-dependencies
import { fromTemporaryCredentials } from '@aws-sdk/credential-providers';
// eslint-disable-next-line import/no-extraneous-dependencies
import { route53Region } from '../sts-util';

export type CrossAccountZoneDelegationEvent = AWSLambda.CloudFormationCustomResourceEvent & {
ResourceProperties: ResourceProperties;
Expand Down Expand Up @@ -33,6 +35,7 @@ export async function handler(event: CrossAccountZoneDelegationEvent) {
async function cfnUpdateEventHandler(props: ResourceProperties, oldProps: ResourceProperties | undefined) {
if (oldProps && props.DelegatedZoneName !== oldProps.DelegatedZoneName) {
await cfnEventHandler(oldProps, true);

}
await cfnEventHandler(props, false);
}
Expand Down Expand Up @@ -91,42 +94,3 @@ async function getHostedZoneIdByName(name: string, route53: Route53): Promise<st
// will always be defined because we throw if length !==1
return matchedZones[0].Id!;
}

/**
* Return the region that hosts the Route53 endpoint
*
* Route53 is a partitional service: the control plane lives in one particular region,
* which is different for every partition.
*
* The SDK knows how to convert a "target region" to a "route53 endpoint", which
* equates to a (potentially different) region. However, when we use STS
* AssumeRole credentials, we must grab credentials that will work in that
* region.
*
* By default, STS AssumeRole will call the STS endpoint for the same region
* as the Lambda runs in. Normally, this is all good. However, when the AssumeRole
* is used to assume a role in a different account A, the AssumeRole will fail if the
* Lambda is executing in an an opt-in region R to which account A has not been opted in.
*
* To solve this, we will always AssumeRole in the same region as the Route53 call will
* resolve to.
*/
function route53Region(region: string) {
const partitions = {
'cn': 'cn-northwest-1',
'us-gov': 'us-gov-west-1',
'us-iso': 'us-iso-east-1',
'us-isob': 'us-isob-east-1',
'eu-isoe': 'eu-isoe-west-1',
'us-isof': 'us-isof-south-1',
};

for (const [prefix, mainRegion] of Object.entries(partitions)) {
if (region.startsWith(`${prefix}-`)) {
return mainRegion;
}
}

// Default for commercial partition
return 'us-east-1';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Return the region that hosts the Route53 endpoint
*
* Route53 is a partitional service: the control plane lives in one particular region,
* which is different for every partition.
*
* The SDK knows how to convert a "target region" to a "route53 endpoint", which
* equates to a (potentially different) region. However, when we use STS
* AssumeRole credentials, we must grab credentials that will work in that
* region.
*
* By default, STS AssumeRole will call the STS endpoint for the same region
* as the Lambda runs in. Normally, this is all good. However, when the AssumeRole
* is used to assume a role in a different account A, the AssumeRole will fail if the
* Lambda is executing in an an opt-in region R to which account A has not been opted in.
*
* To solve this, we will always AssumeRole in the same region as the Route53 call will
* resolve to.
*/
export function route53Region(region: string) {
const partitions = {
'cn': 'cn-northwest-1',
'us-gov': 'us-gov-west-1',
'us-iso': 'us-iso-east-1',
'us-isob': 'us-isob-east-1',
'eu-isoe': 'eu-isoe-west-1',
'us-isof': 'us-isof-south-1',
};

for (const [prefix, mainRegion] of Object.entries(partitions)) {
if (region.startsWith(`${prefix}-`)) {
return mainRegion;
}
}

// Default for commercial partition
return 'us-east-1';
}
Loading

0 comments on commit e97fed7

Please sign in to comment.