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

(aws-route53): use same set of PublicHostedZone NameServer records between deploys #12756

Closed
themasalamill opened this issue Jan 28, 2021 · 4 comments
Assignees
Labels
@aws-cdk/aws-route53 Related to Amazon Route 53 closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. guidance Question that needs advice or information. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@themasalamill
Copy link

themasalamill commented Jan 28, 2021

❓ General Issue

The Question

Hi! When creating a PublicHostedZone, CDK creates a new set of NameServers each time the stack is created, which then requires the NameServers to be manually updated at the domain register to point to the newly created zone. Is there any way (using CDK) to create a fixed set of NS that will be used each time the stack is created?

Environment

  • CDK CLI Version: 1.87.1 (build 9eeaa93)
  • Module Version: 1.87.1
  • Node.js Version: v12.14.0
  • OS: macOS Big Sur 11.1 ]
  • Language (Version): TypeScript (3.9.7)

Other information

@themasalamill themasalamill added guidance Question that needs advice or information. needs-triage This issue or PR still needs to be triaged. labels Jan 28, 2021
@themasalamill themasalamill changed the title aws-route53: short issue description aws-route53: use same set of PublicHostedZone NameServer records between deploys Jan 28, 2021
@NetaNir NetaNir changed the title aws-route53: use same set of PublicHostedZone NameServer records between deploys (aws-route53): use same set of PublicHostedZone NameServer records between deploys Jan 29, 2021
@github-actions github-actions bot added the @aws-cdk/aws-route53 Related to Amazon Route 53 label Jan 29, 2021
@njlynch
Copy link
Contributor

njlynch commented Feb 8, 2021

The blog post you linked to seems to be accurate; given there is no CloudFormation support for reusable delegation sets, the only option currently is to use a Custom Resource. The solution in the blog post looks to be a good starting point to build off of.

As an alternative, is it possible to separate out your public hosted zone(s) from the rest of your infrastructure? If the deleting + creating the hosted zone requires additional manual effort out-of-band, I would separate that out as its own component, and then you can freely set up + tear down the rest of your infrastructure without needing to update the name servers. Your mileage may vary and that approach may not work for your particular architecture and use case, but it's worth considering.

@njlynch njlynch added response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. and removed needs-triage This issue or PR still needs to be triaged. labels Feb 8, 2021
@github-actions
Copy link

This issue has not received a response in a while. If you want to keep this issue open, please leave a comment below and auto-close will be canceled.

@github-actions github-actions bot added closing-soon This issue will automatically close in 4 days unless further comments are made. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. and removed closing-soon This issue will automatically close in 4 days unless further comments are made. labels Feb 16, 2021
@hughevans
Copy link

hughevans commented Feb 24, 2021

If possible I’d be placing this feature in the queue as it makes sense to have fixed delegation sets when using other domain registrars.

Edit:

I have successfully used @Pablissimo's code. The only thing I changed was to make the CallerReference unique:

hosted-zone.ts
// Allows CDK to use a reusable delegation set. Sourced from:
// https://pablissimo.com/1100/creating-a-route-53-public-hosted-zone-with-a-reusable-delegation-set-id-in-cdk

import {
  AwsCustomResource,
  AwsCustomResourcePolicy,
} from "@aws-cdk/custom-resources";
import { Construct, Fn, Names } from "@aws-cdk/core";
import {
  IPublicHostedZone,
  PublicHostedZone,
  PublicHostedZoneProps,
} from "@aws-cdk/aws-route53";
import { PhysicalResourceId } from "@aws-cdk/custom-resources";

export interface PublicHostedZoneWithReusableDelegationSetProps
  extends PublicHostedZoneProps {
  delegationSetId: string;
}

export class PublicHostedZoneWithReusableDelegationSet extends Construct {
  private publicHostedZone: AwsCustomResource;
  private hostedZoneName: string;

  constructor(
    scope: Construct,
    id: string,
    props: PublicHostedZoneWithReusableDelegationSetProps
  ) {
    super(scope, id);

    this.hostedZoneName = props.zoneName;

    const normaliseId = (id: string) => id.split("/").slice(-1)[0];
    const normalisedDelegationSetId = normaliseId(props.delegationSetId);

    this.publicHostedZone = new AwsCustomResource(
      this,
      "CreatePublicHostedZone",
      {
        onCreate: {
          service: "Route53",
          action: "createHostedZone",
          parameters: {
            CallerReference: Names.uniqueId(this),
            Name: this.hostedZoneName,
            DelegationSetId: normalisedDelegationSetId,
            HostedZoneConfig: {
              Comment: props.comment,
              PrivateZone: false,
            },
          },
          physicalResourceId: PhysicalResourceId.fromResponse("HostedZone.Id"),
        },
        policy: AwsCustomResourcePolicy.fromSdkCalls({
          resources: AwsCustomResourcePolicy.ANY_RESOURCE,
        }),
      }
    );

    new AwsCustomResource(this, "DeletePublicHostedZone", {
      onDelete: {
        service: "Route53",
        action: "deleteHostedZone",
        parameters: {
          Id: this.publicHostedZone.getResponseField("HostedZone.Id"),
        },
      },
      policy: AwsCustomResourcePolicy.fromSdkCalls({
        resources: AwsCustomResourcePolicy.ANY_RESOURCE,
      }),
    });
  }

  asPublicHostedZone(): IPublicHostedZone {
    return PublicHostedZone.fromHostedZoneAttributes(
      this,
      "CreatedPublicHostedZone",
      {
        hostedZoneId: Fn.select(
          2,
          Fn.split("/", this.publicHostedZone.getResponseField("HostedZone.Id"))
        ),
        zoneName: this.hostedZoneName,
      }
    );
  }
}

I think this is close to being ready to incorporate. It cleans up after itself fine too.

@MyNameIsOka
Copy link

Is this implemented, yet? I have been using the custom resource implementation as described here but the solution from @hughevans is not fully functional. Updating the stack doesn't work, as well as destroying and re-deploying it. The error log is as follows:

/home/runner/work/my-repo/my-repo/packages/infrastructure/node_modules/constructs/src/construct.ts:447
      throw new Error(`There is already a Construct with name '${childName}' in ${typeName}${name.length > 0 ? ' [' + name + ']' : ''}`);
            ^
Error: There is already a Construct with name 'CreatedPublicHostedZone' in PublicHostedZoneWithReusableDelegationSet [MyHostedZone]
    at Node.addChild (/home/runner/work/my-repo/my-repo/packages/infrastructure/node_modules/constructs/src/construct.ts:447:13)
    at new Node (/home/runner/work/my-repo/my-repo/packages/infrastructure/node_modules/constructs/src/construct.ts:71:17)
    at new Construct (/home/runner/work/my-repo/my-repo/packages/infrastructure/node_modules/constructs/src/construct.ts:499:17)
    at new Resource (/home/runner/work/my-repo/my-repo/packages/infrastructure/node_modules/aws-cdk-lib/core/lib/resource.js:1:1309)
    at new Import (/home/runner/work/my-repo/my-repo/packages/infrastructure/node_modules/aws-cdk-lib/aws-route53/lib/hosted-zone.js:1:1887)
    at Function.fromHostedZoneAttributes (/home/runner/work/my-repo/my-repo/packages/infrastructure/node_modules/aws-cdk-lib/aws-route53/lib/hosted-zone.js:1:2154)
    at PublicHostedZoneWithReusableDelegationSet.asPublicHostedZone (/home/runner/work/my-repo/my-repo/packages/infrastructure/src/my-repo-stack.ts:106:27)
    at new LodzInfraCdkStack (/home/runner/work/my-repo/my-repo/packages/infrastructure/src/my-repo-stack.ts:360:21)
    at Object.<anonymous> (/home/runner/work/my-repo/my-repo/packages/infrastructure/src/my-repo-stack.ts:575:1)
    at Module._compile (node:internal/modules/cjs/loader:1356:14)
Subprocess exited with error 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-route53 Related to Amazon Route 53 closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. guidance Question that needs advice or information. response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.
Projects
None yet
Development

No branches or pull requests

4 participants