API Gateway with DNS record in another account

Viewed 73

In our environment there is a dedicated AWS account that contains registered domain as well as hosting zone in Route53. Also an IAM role is created that allows specific set of other accounts to create records in that hosted zone.

Using AWS CDK (v2) is there a way to create API Gateway in one account with DNS record (A Record?) created for it in that dedicated one?

This is an example of setup:

export class CdkRoute53ExampleStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    const backend = new lambda.Function(this, 'HelloHandler', {
      runtime: lambda.Runtime.NODEJS_14_X,
      code: lambda.Code.fromAsset('src'),
      handler: 'hello.handler'
    });

    const restApi = new apigw.LambdaRestApi(this, 'Endpoint', {
      handler: backend,
      domainName: {
        domainName: `cdk53.${Config.domainName}`,
        certificate: acm.Certificate.fromCertificateArn(
          this,
          "my-cert",
          Config.certificateARN
        ),
      },
      endpointTypes: [apigw.EndpointType.REGIONAL]
    });

    new route53.ARecord(this, "apiDNS", {
      zone: route53.HostedZone.fromLookup(this, "baseZone", {
        domainName: Config.domainName,
      }),
      recordName: "cdk53",
      target: route53.RecordTarget.fromAlias(
        new route53targets.ApiGateway(restApi)
      ),
    });


  }
}

Basically I need that last ARecord construct to be created under credentials from assumed role in another account.

1 Answers

As far as I am aware, a CDK stack is built and deployed entirely within the context of a single IAM user (aka identity). I.e. you can't run different bits of the stack as different IAM users. (As an aside, code which uses the regular AWS SDK - such as lambdas - can switch identities using STS.)

The solution therefore is to do as much as you can using the CDK (in account B). After this is complete, then the final step - registering the DNS record - is done using a different identity which operates within account A.

Registering the DNS record could be done using AWS CLI commands, or you could even create another (mini) stack just for this purpose.

Either way you would execute the second step as an identity which is allowed to write records to the hosted zone in account A.

This could be achieved by using a different --profile with your CLI or CDK commands. Or you could use STS to assume a role which is allowed to create the DNS record in account A.

Using STS has the advantage that you don't need to know credentials of account A. But I've found STS to have a steep learning curve and can be a little confusing to get right.

EDIT: it seems the CDK stack in account B can actually switch roles when registering a DNS record by virtue of the CrossAccountZoneDelegationRecord construct and the delegationRole attribute - see https://stackoverflow.com/a/72097522/226513 This means that you can keep all your code in the account B CDK stack.

Related