Skip to content

API Gateway Custom Domain Names #783

@brettstack

Description

@brettstack

SAM Input:

MyApiSimpleDomain:
  Type: AWS::Serverless::Api
  Properties:
    ...
    EndpointConfiguration: REGIONAL
    # Simple usecase - specify just the Domain Name and we create the rest using sane defaults.
    # A cert is created as well as a base path mapping from '/' to {MyApi.StageName}
    # The `EndpointConfiguration` of the API is used (or default to EDGE)
    Domain: example.com
    
    # The above expands into:
    # Domain:
    #   DomainName: example.com
    # 
    #   # TODO: Should ConfigureRoute53 be on by default? This is useful if
    #   # Route53 is your domain provider and you don't want to manage the domain
    #   # records through some other means (e.g console/manually; separate stack)
    #   Route53: true
    # 
    #   EndpointConfiguration: REGIONAL # {MyApiSimpleDomain.EndpointConfiguration}
    #   Certificate: !Ref MyApiSimpleDomainCertificate # Automatically created
    #   BasePath: /


MyApiAdvancedDomain:
  Type: AWS::Serverless::Api
  Properties:
    ...
    Domain:
      # Domain accepts either a string (DomainName), an Object, or an Array of Objects
      - DomainName: example.com # Required
      
        # Set this to false to create the Route53 (or your domain provider) records yourself
        Route53:
          EvaluateTargetHealth: true # Default to false

        # TODO: What happens when this isn't the same as the API's EndpointConfiguration?
        # Allowed values: REGIONAL, EDGE; defaults to MyApi.EndpointConfiguration
        EndpointConfiguration: REGIONAL
        
        # If `EndpointConfiguration` is REGIONAL, this needs to be an ACM cert created in the same region as the API
        # If `EndpointConfiguration` is EDGE, this needs to be an ACM cert created in IAD
        # SAM doesn't need to perform any additional validation here
        # Default: An ACM Certificate is created for you
        Certificate: arn:...

        # Advanced Certificate:
        Certificate:
          CertificateArn: !Ref MyCertificate
          ValidationMethod: DNS # Default: {Route53 == true ? DNS : EMAIL}; Allowed: EMAIL|DNS

        # Default: '/' which creates a BasePathMapping from the root of the domain
        # to this API's StageName
        BasePath: /api

        # Either BasePathMappings OR BasePath should be specified; if both are specified an error should be thrown.
        # Including here to advanced configuration
        BasePathMappings:
          - BasePath: /api # Default: '/'
            Api: !Ref MyApiAdvancedDomain # Default: !Ref MyApiAdvancedDomain; use case: mapping this domain to additional APIs
            Stage: '' # Default: {MyApi.Stage}
            # Setting `Stage` to '' sets up a mapping which allows clients to specify
            # the Stage in the path when making requests.
            # e.g http://example.com/api/Prod/users, http://example.com/api/Beta/users
          - BasePath: /other-api
            Api: !Ref MyOtherApi # Add a Domain mapping which points to a different API+Stage

CloudFormation Output:

Resources:
  ...
  # This is only created if `Domain.Certificate` isn't provided
  MyApiCertificate:
    Type: 'AWS::CertificateManager::Certificate'
    Properties:
      DomainName: example.com
  
  MyApiDomainName:
    Type: 'AWS::ApiGateway::DomainName'
    Properties:
      # If `Domain.EndpointConfiguration` is 'REGIONAL', set `RegionalCertificateArn` instead of `CertificateArn`
      # If `Domain.Certificate` is provided, the value gets passed through instead of creating `MyApiCertificate`
      CertificateArn: !Ref MyApiCertificate

      DomainName: example.com
  
  # Create one `BasePathMapping` Resource per `Domain.BasePathMappings`
  MyApiBasePathMapping:
    Type: 'AWS::ApiGateway::BasePathMapping'
    Properties:
      RestApiId: !Ref MyApi
      DomainName: !Ref MyApiDomainName
      BasePath: /
      Stage: Prod
  
  MyApi:
    Type: 'AWS::ApiGateway::RestApi'
    Properties:
      ...

  MyApiRoute53RecordSetGroup:
    Type: AWS::Route53::RecordSetGroup
    Properties:
      HostedZoneName: example.com.
      RecordSets:
        - Name: example.com.
          Type: A
          AliasTarget:
            EvaluateTargetHealth: false
            HostedZoneId: !GetAtt MyApiDomainName.DistributionHostedZoneId
            DNSName: !GetAtt MyApiDomainName.DistributionDomainName
            
            # For REGIONAL:
            # HostedZoneId: !GetAtt MyApiDomainName.RegionalHostedZoneId
            # DNSName: !GetAtt MyApiDomainName.RegionalDomainName

Related Issues

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions