aws / aws/aws-cdk

(cdk-route53): Unable to create VPC Endpoint Service private DNS name in existing PublicHostedZone

Open
#18,698 4 comments 0 reactions 0 assignees View on GitHub
@aws-cdk/aws-route53 bug effort/medium p2
Dominant language
TypeScript
Stars
12.9k
Forks
4.6k
Avg merge
1d 19h
Merged PRs (30d)
74

Description

### What is the problem?

I'm trying to add a private DNS name to VPC Endpoint Service using `VpcEndpointServiceDomainName` construct.
For that, I need to pass `IPublicHostedZone` as one of the parameters to the builder.
There is a public hosted zone already created in the AWS account I'm deploying to, so I just need to use an existing one, not create a new one. I'm using `PublicHostedZone.fromPublicHostedZoneId()` method to get the public hosted zone and then pass it as an argument to `VpcEndpointServiceDomainName` builder.
However, when I try to run CDK deployment, I get the following error:
`Error: cannot retrieve "zoneName" from an an imported hosted zone`

I tried to replace `PublicHostedZone.fromPublicHostedZoneId()` method with creating a new instance of `PublicHostedZone`, as described [here](https://docs.aws.amazon.com/cdk/api/v1/docs/aws-route53-readme.html#vpc-endpoint-service-private-dns). In this case deployment succeeds, but it creates a duplicate hosted zone with the same DNS name along with already existing one.

Also, I can't use other lookup methods, like `PublicHostedZone.fromLookup()` or `PublicHostedZone.fromHostedZoneAttributes()` because they return an instance of `IHostedZone`, while `VpcEndpointServiceDomainName` builder requires an instance of `IPublicHostedZone`.

### Reproduction Steps

```java
var vpcEndpointService = VpcEndpointService.Builder
.create(this, "vpce-srv")
.vpcEndpointServiceLoadBalancers(List.of(nlb))
.acceptanceRequired(false)
.allowedPrincipals(new ArnPrincipal(String.format("arn:aws:iam::%s:root", accountId)))
.build();

var phz = PublicHostedZone.fromPublicHostedZoneId(this, "phz", "SOME_HZ_ID");
// or, alternatively, which creates duplicate hosted zone
// var phz = new PublicHostedZone(this, "phz", PublicHostedZoneProps.builder().zoneName(domainName).build());

var vpcEndpointServiceDomain = VpcEndpointServiceDomainName.Builder
.create(this, "vpce-srv-dns")
.domainName("some-stuff.my-public-domain.com")
.endpointService(vpcEndpointService)
.publicHostedZone(phz)
.build();
```

### What did you expect to happen?

- Private DNS name is added to VPC Endpoint Service
- TXT record in the existing public hosted zone is created for domain verification
- Domain verification status in VPC Endpoint Service is `Verified`

### What actually happened?

When using `var phz = PublicHostedZone.fromPublicHostedZoneId(this, "phz", "SOME_HZ_ID");` statement:
- Error is produced while trying to perform CDK deployment:

```sh
Error: cannot retrieve "zoneName" from an an imported hosted zone
at Import.get zoneName [as zoneName] (/private/var/folders/nf/r64fmvdj09gfsfgdbmkt2mbm0000gp/T/jsii-kernel-F9jYTv/node_modules/@aws-cdk/aws-route53/lib/hosted-zone.js:202:36)
at Object.determineFullyQualifiedDomainName (/private/var/folders/nf/r64fmvdj09gfsfgdbmkt2mbm0000gp/T/jsii-kernel-F9jYTv/node_modules/@aws-cdk/aws-route53/lib/util.js:52:39)
at new RecordSet (/private/var/folders/nf/r64fmvdj09gfsfgdbmkt2mbm0000gp/T/jsii-kernel-F9jYTv/node_modules/@aws-cdk/aws-route53/lib/record-set.js:97:26)
at new TxtRecord (/private/var/folders/nf/r64fmvdj09gfsfgdbmkt2mbm0000gp/T/jsii-kernel-F9jYTv/node_modules/@aws-cdk/aws-route53/lib/record-set.js:197:9)
at VpcEndpointServiceDomainName.verifyPrivateDnsConfiguration (/private/var/folders/nf/r64fmvdj09gfsfgdbmkt2mbm0000gp/T/jsii-kernel-F9jYTv/node_modules/@aws-cdk/aws-route53/lib/vpc-endpoint-service-domain-name.js:134:36)
at new VpcEndpointServiceDomainName (/private/var/folders/nf/r64fmvdj09gfsfgdbmkt2mbm0000gp/T/jsii-kernel-F9jYTv/node_modules/@aws-cdk/aws-route53/lib/vpc-endpoint-service-domain-name.js:43:14)
```

OR
When using `var phz = new PublicHostedZone(this, "phz", PublicHostedZoneProps.builder().zoneName(domainName).build());` statement:
- Second hosted zone with the same name is created along with existing one

### CDK CLI Version

1.136.0

### Framework Version

_No response_

### Node.js Version

v16.10.0

### OS

MacOS Big Sur 11.6

### Language

Java

### Language Version

openjdk 17.0.1

### Other information

Similar issues:
https://github.com/aws/aws-cdk/issues/3558
https://github.com/aws/aws-cdk/issues/8406
https://github.com/aws/aws-cdk/issues/3663

The only workaround solution I found so far is to create a new IPublicHostedZone implementation with IHostedZone member instance, and delegate all interface calls to it.

```java
public class PublicHostedZoneDelegate extends Construct implements IPublicHostedZone {
private final IHostedZone zone;
public PublicHostedZoneDelegate(@NotNull Construct scope, @NotNull String id, @NotNull IHostedZone zone) {
super(scope, id);
this.zone = zone;
}
@Override
public @NotNull String getHostedZoneArn() {
return zone.getHostedZoneArn();
}
// ... Other interface methods using the same delegation approach
}
```
Usage:
```java
IHostedZone zone = PublicHostedZone.fromLookup(scope, "domain", HostedZoneProviderProps
.builder()
.domainName(domainName)
.build());

var phz = new PublicHostedZoneDelegate(scope, "phz", zone);
var vpcEndpointServiceDomain = VpcEndpointServiceDomainName.Builder
.create(scope, "vpce-srv-dns")
.domainName("some-stuff.my-public-domain.com")
.endpointService(vpcEndpointService)
.publicHostedZone(phz)
.build();
```

Contributor guide

Open the contributing guide

Research direction

Start with aws-route53/lib/vpc-endpoint-service-domain-name.js and follow its call into util.js and record-set.js, where the imported hosted zone error occurs. Reproduce the Java example with PublicHostedZone.fromPublicHostedZoneId() and compare it with the fromLookup() and fromHostedZoneAttributes() paths. Done means an existing public hosted zone can be used without creating a duplicate and the TXT verification record is created successfully.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, java, typescript
Domain
cloud, infrastructure
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.