Configure a Custom Domain for AWS API Gateway
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. Additionally, 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
Resources:
DomainName:
Type: AWS::ApiGateway::DomainName
Properties:
CertificateArn:
Ref: Certificate
DomainName:
Ref: Domain
EndpointConfiguration:
Types:
- EDGE
SecurityPolicy: TLS_1_2
Certificate:
Type: AWS::CertificateManager::Certificate
Properties:
DomainName:
Ref: Domain
ValidationMethod: DNS
DomainValidationOptions:
- DomainName:
Ref: Domain
HostedZoneId:
Ref: HostedZoneId
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.