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-apigateway: RegionalCertificateArn is not supported for PRIVATE custom domain name #32551

Closed
1 task
successkrisz opened this issue Dec 17, 2024 · 7 comments
Closed
1 task
Assignees
Labels
@aws-cdk/aws-apigateway Related to Amazon API Gateway bug This issue is a bug. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. needs-reproduction This issue needs reproduction. p2 response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days.

Comments

@successkrisz
Copy link

Describe the bug

When trying to use a custom domain for a private API gateway, using a public hosted zone + acm certificate, CDK fails with the following error message:

CREATE_FAILED        | AWS::ApiGateway::DomainName      | PrivateApiGateway/PrivateApi/CustomDomain (PrivateApiGatewayPrivateApiCustomDomainDEF6FEC5) Resource handler returned message: "Invalid request provided: RegionalCertificateArn is not supported for PRIVATE custom domain name. (Service: ApiGateway, Status Code: 400, Request ID: 397a2f2f-1442-468f-939d-b7a770000000)" (RequestToken: cdd58010-f394-96ac-234d-cfffe0000000, HandlerErrorCode: InvalidRequest)

The very same thing I can set up using the AWS Console when following this guide: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-custom-domains-tutorial.html

Regression Issue

  • Select this option if this issue appears to be a regression.

Last Known Working CDK Version

No response

Expected Behavior

Based on the documentation here: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-custom-domains-tutorial.html, I'd expect to be able to:

  • Use a public hosted zone & acm certificate covering the domain I'd like to use
  • Create a private API Gateway RestApi with:
import * as cdk from 'aws-cdk-lib'
// ...
new apigateway.RestApi(this, 'PrivateApi', {
   ...otherApiProps,
   domainName: {
     domainName:'foo.example.com',
     certificate,
     endpointType: apigateway.EndpointType.PRIVATE,
   },
})

Current Behavior

When it gets to the stage where the domain name is created it always fail creation with the following error

private-api | 0/5 | 09:08:39 | CREATE_FAILED | AWS::ApiGateway::DomainName | PrivateApiGateway2/DomainName (PrivateApiGateway2DomainName89C927F5) Resource handler returned message: "Invalid request provided: RegionalCertificateArn is not supported for PRIVATE custom domain name. (Service: ApiGateway, Status Code: 400, Request ID: 151b2d57-b415-489f-baed-db0a606921ea)" (RequestToken: 0c796725-c410-88ff-d0d5-a449e4731ea4, HandlerErrorCode: InvalidRequest)

Reproduction Steps

As it fails on the step for the DomainName creation step it can be reproduced by:

import * as cdk from 'aws-cdk-lib'
import * as apigateway from 'aws-cdk-lib/aws-apigateway'
import { Construct } from 'constructs'

export class PrivateApiGateway extends Construct {
  constructor(scope: BaseStack, id: string, props: PrivateApiGatewayProps) {
    super(scope, id)
    const hostedZone = cdk.aws_route53.HostedZone.fromLookup(this, 'HostedZone', { domainName: 'example.com' })
    const certificate = cdk.aws_certificatemanager.Certificate.fromCertificateArn(
            this,
            'Certificate',
            process.env.CERTIFICATE_ARN,
        )
    const domainName = new apigateway.DomainName(this, 'DomainName', { // <= this step fails
            domainName: 'api.example.com',
            certificate,
            endpointType: apigateway.EndpointType.PRIVATE,
    })
  })
}

Possible Solution

No response

Additional Information/Context

No response

CDK CLI Version

2.173.1 (build 4eac959)

Framework Version

No response

Node.js Version

22.11.0

OS

MacOS

Language

TypeScript

Language Version

5.7.2

Other information

No response

@successkrisz successkrisz added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Dec 17, 2024
@github-actions github-actions bot added the @aws-cdk/aws-apigateway Related to Amazon API Gateway label Dec 17, 2024
@khushail khushail added needs-reproduction This issue needs reproduction. p2 and removed needs-triage This issue or PR still needs to be triaged. labels Dec 17, 2024
@khushail khushail self-assigned this Dec 17, 2024
@khushail
Copy link
Contributor

@successkrisz , thanks for reaching out. could you please share the synthesized template output generated after cdk synth step ?

@khushail khushail added the response-requested Waiting on additional info and feedback. Will move to "closing-soon" in 7 days. label Dec 20, 2024
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 Dec 22, 2024
@dviryamin
Copy link
Contributor

It seems that the logic determining whether to use CertificateArn or RegionalCertificateArn in CfnDomainName does not account for the possibility of a PrivateEndpoint with a custom domain name, likely because this is a new feature. Unfortunately, I couldn’t get it to work in my tests. If possible, I kindly ask the maintainers to revisit this issue, as it might impact others trying to use this configuration. I hope to explore this further in the coming weeks if time allows.

@wassil
Copy link

wassil commented Jan 2, 2025

As @dviryamin wrote, the construct uses RegionalCertificateArn instead of CertificateArn. I have fixed that issue locally, but the deployment gets stuck in "update in progress" in Cloudformation.
I found this resource: https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-private-custom-domains-cfn.html
It mentions you need to use AWS::ApiGateway::DomainNameV2 which is only available in CDK as a Level 1 construct CfnDomainNameV2.
I was able to get private APIs with custom domain to work with CfnDomainNameV2 and CfnBasePathMappingV2 following the guide linked above.

@OrRosenblatt
Copy link

@wassil can you kindly provide an example for the CDK code using CfnDomainNameV2 and CfnBasePathMappingV2 to define custom domain name for PRIVATE API Gateway? I'm experiencing the same issue in which the deployment gets stuck on the certificate.

@khushail
Copy link
Contributor

Hi there, since this issue is closed and comments on the closed issues are not tracked, so I would request you to either re-open the issue and create a new one with sample repro code and instructions. Thanks

@wassil
Copy link

wassil commented Jan 22, 2025

@OrRosenblatt
It's a bit complicated, and our infra setup is a mix of CDK and SAM.
You need a VPCInterface endpoint for API Gateway, then you need a certificate for your domain. The certificate manager won't give you one for a private domain, because it cannot verify it - it's private. So I have created 2 hosted zones with the same domains, one private one public where the certificate can be validated.

  // 2 hosted zones, one is public, one is private. Private one it the one we'll be using, public one is just for cert verification
  const privateHostedZone = AWSHostedZone.fromHostedZoneAttributes(this.stack, id, {
    props.privateHostedZoneId,
    props.hostedZoneDomain
  });
  const hostedZoneForCertificate = AWSHostedZone.fromHostedZoneAttributes(this.stack, id, {
    props.hostedZoneForCertificateId,
    props.hostedZoneDomain
  });
  // we get the certificate and for validation we use the public hosted zone, it has the same domain as the private one
  const certificate = new Certificate(this.stack, `${this.stackId}-PrivateDomain-SSLCert`, {
    domainName: this.props.domain,
    certificateName: this.props.domain,
    validation: CertificateValidation.fromDns(hostedZoneForCertificate.zone)
  });
  // we create a private domain name with the certificate we got above
  const domainName = new CfnDomainNameV2(this.stack, `${this.stackId}-PrivateDomainName`, {
      domainName: this.props.domain,
      certificateArn: certificate.certificateArn,
      endpointConfiguration: {
        types: [EndpointType.PRIVATE]
      },
      policy: new PolicyDocument({
        statements: [
          new PolicyStatement({
            principals: [new StarPrincipal()],
            effect: Effect.ALLOW,
            actions: ['execute-api:Invoke'],
            resources: ['execute-api:/*']
          }),
          new PolicyStatement({
            principals: [new StarPrincipal()],
            effect: Effect.DENY,
            actions: ['execute-api:Invoke'],
            resources: ['execute-api:/*'],
            conditions: {
              StringNotEquals: {
                'aws:SourceVpce': this.props.vpcEndpointApiGatewayId
              }
            }
          })
        ]
      })
    });
    // CNAME is created in the private hosted zone
    new CnameRecord(this.stack, `${this.stackId}-PrivateDomain-Cname`, {
      zone: privateHostedZone,
      recordName: `${this.props.domain}.`,
      domainName: this.props.vpcEndpointApiGatewayDnsEntry
    });

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
@aws-cdk/aws-apigateway Related to Amazon API Gateway bug This issue is a bug. closed-for-staleness This issue was automatically closed because it hadn't received any attention in a while. needs-reproduction This issue needs reproduction. p2 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

5 participants