Configure a Custom Domain for AWS API Gateway

Photo by Jens Lelie on Unsplash

Categories

  • Serverless
  • Howto

In previous blog posts I’ve shown how to build serverless microservices which provide a REST API. Each service consists of a bunch of Lambda functions triggered by the AWS API Gateway. In a real world scenario multiple microservices would compose an application exposed through a single domain like api.example.com. For the consumer of the API it should not be transparent that the services offered by the API are actually broke up in multiple microservices.

How can this be done when AWS API Gateway is used?

Actually, it’s pretty easy to do. The key is to use the custom domain feature of API Gateway. Since API Gateway only supports encrypted connections via HTTPS the first thing is to provide a SSL certificate. The easiest and cheapest way is to use the Amazon Certificate Manager to provide a free SSL certificate for the domain. The certificate can be created manually or via the acm-dns-record-manager.

Next, the domain and associated DNS record needs to be set up. For this task,I’ve created a simple CloudFormation template:

AWSTemplateFormatVersion: 2010-09-09

Parameters:

  HostedZoneId:
    Type: AWS::Route53::HostedZone::Id
  Domain:
    Type: String
  Certificate:
    Type: String

Resources:

  DomainName:
    Type: AWS::ApiGateway::DomainName
    Properties:
      CertificateArn:
        Ref: Certificate
      DomainName:
        Ref: Domain
      EndpointConfiguration:
        Types:
          - EDGE

  RecordSet:
    Type: AWS::Route53::RecordSet
    Properties:
      HostedZoneId:
        Ref: HostedZoneId
      Name:
        Ref: Domain
      Type: A
      AliasTarget:
        HostedZoneId:
          Fn::GetAtt: DomainName.DistributionHostedZoneId
        DNSName:
          Fn::GetAtt: DomainName.DistributionDomainName

Outputs:

  DomainName:
    Description: The Domain name
    Value:
      Ref: Domain
    Export:
      Name:
        Fn::Sub: ${AWS::StackName}-DomainName

With this, the custom domain is configured for AWS API Gateway. The final step is to map a microservice to this domain. This is done by configuring the base path mapping. It provides the connection to the various API instances for each service. The important part is that each service has it’s own namespace expressed as a path.

For each microservice the configuration needs to be extended to extended to integrate with the custom domain. The following configuration needs to be added

BasePathMapping:
  Type: AWS::ApiGateway::BasePathMapping
  Properties:
    BasePath: tasks
    DomainName:
      Fn::ImportValue:
        Fn::Sub: ${ApiDomainStackName}-DomainName
    RestApiId:
      Ref: RestApi
    Stage:
      Ref: StageName

This setup makes it pretty easy to encapsulate the various microservices that make up an application behind a common domain. Additionally, it’s also possible to configure common cross-functional requirements across all of the services, like authentication, throttling, API keys, etc.

Following the principles and techniques outlined in this post make it possible to easily hide a microservice application behind an AWS API Gateway.