aws-cdk: route53.HostedZone.fromLookup returned error

I have a hosted zone on route53, and use the following CDK code (typescript) to look up that zone using domainName, but got error while running cdk synth, cdk diff and cdk deploy. After changing to use route53.HostedZone.fromHostedZoneAttributes(), it works.

Reproduction Steps

const zone = route53.HostedZone.fromLookup(this, 'Zone', { domainName: props.domainName });

Error Log

Cannot retrieve value from context provider hosted-zone since account/region are not specified at the stack level. Either configure "env" with explicit account and region when you define your stack, or use the environment variables "CDK_DEFAULT_ACCOUNT" and "CDK_DEFAULT_REGION" to inherit environment information from the CLI (not recommended for production stacks)
Subprocess exited with error 1

Environment

  • CLI Version : 1.19.0 (build 5597bbe)
  • Framework Version:1.19.0
  • OS :macOS Mojave version 10.14.6
  • **Language :typescript **

Other


This is šŸ› Bug Report

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 22
  • Comments: 21 (10 by maintainers)

Commits related to this issue

Most upvoted comments

cdk 2.29.0

I think the reason synth succeeds while deploy fails when using HostedZoneFromLookup is that the cdk optimistically assumes a successful lookup.

Here’s the synth output for domainHostedZone.HostedZoneId() (using Golang): DUMMY

That looks like a placeholder value in case of unsuccessful lookups.

In fact, after having fought this for a couple of hours, I think the answer to ā€œwhy does the zone lookup sometimes failā€ in my case is eventual consistency. After deleting and recreating the stack/zone in question a few times, I went for a walk, retried and the zone was now ā€œfoundā€.

I have not looked into the JS or Golang implementations yet, but I suspect many may be falling victims to the CDK trying to fallback to a dummy zone instead of failing outright.

Hi, I found what is the problem:

Is related to my alias creatio. Before I was using:

     new RecordSet(this, "ApiRecordSetA", {
       zone: props.zone,
       recordName: 'sub.domain.com',
       recordType: RecordType.A,
       target: RecordTarget.fromAlias(new ApiGatewayDomain(customDomain)),
     });

I changed it to:

    new ARecord(this, "ApiRecordA", {
      zone: props.zone,
      recordName: 'sub.domain.com',
      target: RecordTarget.fromAlias(new ApiGatewayDomain(customDomain)),
    });

And now its working o0

Thanks guys

@BryanPan342 I think the primary issue is confusion on when to use which API and the pre-requisites for each (local vs. requiring environment configuration). To reduce friction and avoid this common point of confusion, we need to shore up the README

Additionally, there’s also fromHostedZoneId(...) and fromHostedZoneName(...) which will return an IHostedZone with just the ZoneId or the ZoneName field present. This is also done without having make an API call so it can be done entirely locally.

fromHostedZoneAttributes() returns an IHostedZone with both the hostedZoneId and the zoneName

finally, there’s fromLookup() which populates context by making a service call to AWS through a context provider and stores it in cdk.context.json. If this is performed once and saved, subsequent calls will be cached and will not require making a service call.

If the entry does not exist in cdk.context.json, then it requires an environment to be configured and takes the attributes and performs an API call to determine which exact HostedZone is deployed and updates its behavior accordingly.

If hostedZoneNameServers property from an IHostedZone is desired, fromLookup() is the only fromXxX method that will support it.

@diogoap - fromLookup uses a context provider where a service call is made to Route53to retrieve the hostedZoneId given a domain name.

fromHostedZoneAttributes on the other hand requires that the hostedZoneId be provided and therefore does not need that lookup.


@optinirr can you help me with a repro of your issue (or trace if you can run cdk commands with the -v flag.

Here’s what I’m doing (v1.41.0) Stack 1:

new r53.HostedZone(this, 'my-hosted-zone', {
  zoneName: 'www.test.nala',
});

Stack 2 where I will look up the created hosted zone:

const imported = r53.HostedZone.fromLookup(this, 'my-looked-up-hz', {
  domainName: 'www.test.nala',
});

It’s created by providing the environment. i.e.

new ReferenceRoute53Stack(app, 'ReferenceRoute53Stack', {
  env: {
    account: '123456789012',
    region: 'us-east-1',
  },
});

When I run cdk synth, the context is not there, it gets looked up and populated into cdk.context.json which looks like this

{
  "hosted-zone:account=123456789012:domainName=www.test.nala:region=us-east-1": {
    "Id": "/hostedzone/Z0577316FL60KM8IZ7KT",
    "Name": "www.test.nala."
  }
}

Additionally, the context lookup is not performed if the cdk.context.json is already populated. Context lookup is only done when the information is not available during synthesis.

@gsm1011 @solshark - as @moofish32 mentioned, I’d also like to get a clearer idea of the repro steps to narrow this issue down. Does using env in your source work? Here’s an example in the docs if you have not done it before

But why adding the region and account required only when using route53.HostedZone.fromLookup?

Cannot it be inferred like all the other commands?

@shivlaks sorry for late reply. Yep, I’ve tried to set env with no luck. Time was flying for that specific project so I went with:

    const hostedZone = PublicHostedZone.fromHostedZoneAttributes(
      this,
      'XXXXXX',
      { hostedZoneId: 'XXXXXX', zoneName: 'XXXXXX' }
    )