(cdk-route53): Unable to create VPC Endpoint Service private DNS name in existing PublicHostedZone
- 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
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