2

I want to move my existing Rest API to HTTP API, and getting error in custom domain configuration. My SAM file for HTTP API is:

  resHttpApiGateway:
    Type: AWS::Serverless::HttpApi
    Properties:
      StageName: !Sub "${paramEnvironment}"
      CorsConfiguration:
        AllowOrigins:
          - "*"
        AllowHeaders:
          - Content-Type
          - X-Amz-Date
          - Authorization
          - X-Api-Key
          - correlation-object
        AllowMethods:
          - GET
          - POST
          - PUT
          - DELETE
      Auth:
        Authorizers:
          authTokenAuthorizer:
            AuthorizerPayloadFormatVersion: 1.0
            FunctionArn: !Ref paramLambdaAuthorizer
            Identity:
              Headers:
                - Authorization
              ReauthorizeEvery: 0
      Domain:
        EndpointConfiguration: REGIONAL
        DomainName: !If
          - condIsLocal
          - !Sub "dev.${paramBaseDomain}"
          - !Sub "${paramEnvironment}.${paramBaseDomain}"
        CertificateArn: arn:aws:acm:xxx
        Route53:
          HostedZoneId: xxx
        BasePath: "company-api"

Error I get in Cloudformation:

The domain name you provided already exists. (Service: AmazonApiGatewayV2; Status Code: 400; Error Code: BadRequestException; Request ID: ddba8c65-63de-4be4-9316-afd777e8b63f; Proxy: null)

Because I have an existing custom domain configured in API Gateway. Looks like it tries to create a custom domain name, is there a way to map HTTP API instance to an existing custom domain? For REST API I was using AWS::ApiGateway::BasePathMapping for mapping for this task, but cannot find HTTP API alternative.

0bj3ct
  • 1,400
  • 4
  • 22
  • 51
  • Have you tried `AWS::ApiGatewayV2::ApiMapping`? https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigatewayv2-apimapping.html – acm Aug 10 '21 at 16:11
  • thanks @acm for comment, yeah I did check ApiMapping docs, but couldn't see base path mapping configuration for it, it only has domain name config. In my current implementation I have several apis (company api, user api, analytics api etc) that are using same domain name but with different base path mappings, so when a request is received with www.my-api.com/company-api/companies it hits company api gateway instance, do you know how I can achieve same result with ApiMapping? – 0bj3ct Aug 10 '21 at 16:33
  • you use `ApiMappingKey` for that: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigatewayv2-apimapping.html#cfn-apigatewayv2-apimapping-apimappingkey. Actually that's what SAM does under the hood for `BasePath`. Can you try and see if it works as you expect? – acm Aug 11 '21 at 21:45
  • @acm thank you, that worked for me! put your comment as answer and I'll accept it :) – 0bj3ct Aug 15 '21 at 22:53
  • 1
    Glad to hear it helped, added it as an answer below. – acm Aug 16 '21 at 08:47
  • Hi @Obj3ct, I am facing a similar issue, can you please give some help on that? - https://stackoverflow.com/questions/69049471/aws-why-i-am-unable-to-assign-a-custom-domain-to-the-nested-stack/69053259?noredirect=1#comment122046087_69053259 – PeakGen Sep 04 '21 at 12:59

2 Answers2

1

I don't think there's a way to do this since this is a pretty radical change (internally) between the old REST APIs from API Gateway and the newer HTTP APIs.

In the old REST APIs custom domain names are always configured using a CloudFront distribution (even if that's not visible in the CloudFront UI) and in CloudFront, it is impossible to associate more than one distribution with the same CNAME. If I'm not mistaken, this is even true cross-account.

There might be a workaround using wildcard domains though I have no experience with this myself.

Depending on where the API is running and what the SLA requirements of the APIs are, it might be easier to simply have some downtime to ensure this change goes smoothly. In the case of downtime, don't forget to reduce your TTL value of the Route53 DNS entry beforehand so your new record will be propagated more quickly to all DNS caches.

(Edit) Turns out it is possible, as long as you're not using AWS SAM to create the mappings. Below is a shortened example from this source

[...]
Resources:
 [...]

  CustomDomainName: # Creates the domain name only
    Type: AWS::ApiGatewayV2::DomainName
    Properties: 
      DomainName: !Ref DomainName
      DomainNameConfigurations: 
        - EndpointType: REGIONAL
          CertificateArn: !If [CreateCert, !Ref GeneratedCert, !Ref CertArn]

  HttpApiMapping: # Create a mapping to an HTTP API (V2)
    Type: AWS::ApiGatewayV2::ApiMapping
    Properties: 
      ApiId: !Ref HttpApiGateway
      ApiMappingKey: http
      DomainName: !Ref CustomDomainName
      Stage: !Ref HttpApiGatewayApiGatewayDefaultStage ## = {LogicalName} + ApiGateway + {StageName} + Stage

  RestApiMapping: #Create a maooing to a REST API (V1)
    Type: AWS::ApiGatewayV2::ApiMapping
    Properties: 
      ApiId: !Ref RestApiGateway
      ApiMappingKey: rest
      DomainName: !Ref CustomDomainName
      Stage: !Ref RestApiGatewayProdStage ## = {Logicalname} + {StageName} + Stage

  HttpApiGateway: # Creates a HTTP API endpoint under the customm domian
    Type: AWS::Serverless::HttpApi

  RestApiGateway: # Creates a Rest API endpoint under the customm domian
    Type: AWS::Serverless::Api
    Properties:
      StageName: Prod
  [...]

  RecordSet: # Creates a record set in the hosted zone for custom domain to point at the APICustomDomain alias
    Type: AWS::Route53::RecordSet
    Properties:
      Name: !Ref DomainName
      HostedZoneId: !If [CreateZone, !Ref GeneratedZone, !Ref ZoneId]
      AliasTarget: 
        DNSName: !GetAtt CustomDomainName.RegionalDomainName
        HostedZoneId: !GetAtt CustomDomainName.RegionalHostedZoneId
      Type: A
stijndepestel
  • 3,076
  • 2
  • 18
  • 22
  • thanks for response, downtime is not a problem at this time, I just want to move from Rest API to Http API. It would be very helpful if you can point to some aws sam example docs how to configure multiple api gateway instances under single custom domain name with different base path mappings. In my current API I have multiple nested cfn stacks that are creating their own API gateway instances, with AWS::ApiGateway::BasePathMapping I map each API gateway instance to the same custom domain name with unique base path as: 1. api.com/company-api/x - company api gw 2. api.com/user-api/x - user api – 0bj3ct Aug 10 '21 at 16:40
  • @Obj3ct I've edited the answer and added an example I encountered of a custom domain name that is used for a Rest API as well as a newer HTTP API. Hope it helps you out. – stijndepestel Aug 10 '21 at 21:25
1

You can use AWS::ApiGatewayV2::ApiMapping. It allows you to link an existing custom domain name to AWS::Serverless::HttpApi. You can use ApiMappingKey for your different path mappings (BasePath) as that's what SAM does under the hood.

acm
  • 2,086
  • 3
  • 16
  • 34
  • Hi @acm, I am facing a similar issue, can you help with this please? - https://stackoverflow.com/questions/69049471/aws-why-i-am-unable-to-assign-a-custom-domain-to-the-nested-stack/69053259?noredirect=1#comment122046087_69053259 – PeakGen Sep 04 '21 at 12:59