I am developing an API using AWS Lambda, AWS API Gateway and aws-sam. I have implemented firebase authentication. I also use nested stacks.
I am trying to use a custom domain for my API endpoints, so I can call like api.mydomain.com/products
, api.mydomain.com/sales
and so on. I have the domain ready, and a certificate from the AWS Certificate Manager. I even managed to deploy my aws-sam
application without the domain configurations and then assign the custom domain and domain mappings manually via the AWS API Gateway
web console.
But I need to do that part in the aws-sam
itself. Below is what I tried.
Root Stack
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
# More info about Globals: https://github.com/awslabs/serverless-application-model/blob/master/docs/globals.rst
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f215425921e8e
SubnetIds:
- subnet-0251b2d
Parameters:
FirebaseProjectId:
Type: String
DomainName:
Type: String
Default: api.example.com
Resources:
AuthGatewayHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
Auth:
Authorizers:
FirebaseAuthorizer:
IdentitySource: $request.header.Authorization
JwtConfiguration:
audience:
- !Ref FirebaseProjectId
issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
DefaultAuthorizer: FirebaseAuthorizer
AppDomainName:
Type: AWS::ApiGateway::DomainName
Properties:
CertificateArn: arn:aws:acm:us-east-1:xxxxxxx43:certificate/1axxxf-3234-xxx2f-a61c-924eeexxxx9
DomainName: !Ref DomainName
APIBasePathMapping:
Type: AWS::ApiGateway::BasePathMapping
Properties:
BasePath: "api"
DomainName: !Ref AppDomainName
Stage: "default"
RestApiId: !Ref AuthGatewayHttpApi
AuthFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: aws-restapi/
Handler: source/testfile.lambdaHandler
Runtime: nodejs14.x
Events:
Gateway:
Type: HttpApi
Properties:
ApiId: !Ref AuthGatewayHttpApi
Path: /hello
Method: get
GetAllAccountingTypesFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-getall.getallaccountingtypes
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
ApiId: !Ref AuthGatewayHttpApi
Path: /accountingtypes/getall
Method: get
GetAccountingTypeByIDFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/accounting-types/accountingtypes-byid.getbyid
Runtime: nodejs14.x
Events:
GetAllAccountingTypesAPIEvent:
Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /accountingtypes/getbyid
Method: get
nested stack
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
aws-restapi
Sample SAM Template for aws-restapi
Globals:
Function:
Timeout: 5
VpcConfig:
SecurityGroupIds:
- sg-041f2459xxxx1e8e
SubnetIds:
- subnet-03xxxx2d
Parameters:
FirebaseProjectId:
Type: String
Resources:
AuthGatewayHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
Auth:
Authorizers:
FirebaseAuthorizer:
IdentitySource: $request.header.Authorization
JwtConfiguration:
audience:
- !Ref FirebaseProjectId
issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
DefaultAuthorizer: FirebaseAuthorizer
GetAllPromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-getall.getAllPromotions
Runtime: nodejs14.x
Events:
GetAllPromotionsAPIEvent:
Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/getall
Method: get
ApiId: !Ref AuthGatewayHttpApi
SavePromotionsFunction:
Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
Properties:
CodeUri: aws-restapi/
Handler: source/promotions/promotions-save.savePromotions
Runtime: nodejs14.x
Events:
SavePromotionsAPIEvent:
Type: HttpApi # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
Properties:
Path: /promotions/save
Method: get
However I cant get this to work. i even tried applying this only for the root stack, then i ended up with the following error.
Mixing of REST APIs and HTTP APIs on the same domain name can only be accomplished through API Gateway's V2 DomainName interface.
Currently, WebSocket APIs can only be attached to a domain name with other WebSocket APIs.
This must also occur through API Gateway's V2 DomainName interface.
(Service: AmazonApiGateway; Status Code: 400; Error Code: BadRequestException; Request ID: 2f44d53b-8175-47f5-8bc8-db5 19aa484e7; Proxy: null)
How can I successfully configure a custom domain to be used with the API Gateway?
Add the Domain property config, here is an example:
AuthGatewayHttpApi:
Type: AWS::Serverless::HttpApi
Properties:
Auth:
Authorizers:
FirebaseAuthorizer:
IdentitySource: $request.header.Authorization
JwtConfiguration:
audience:
- !Ref FirebaseProjectId
issuer: !Sub https://securetoken.google.com/${FirebaseProjectId}
DefaultAuthorizer: FirebaseAuthorizer
Domain:
DomainName: www.example.com
CertificateArn: arn-example
EndpointConfiguration: REGIONAL
Route53:
HostedZoneId: Z1PA6795UKMFR9