I'm managing a REST API for an app with Serverless and want to extend this setup with a WebSockets API in the same region. Everything should be handled with the same certificate, but different subdomains.
At first I created a new custom domain with sls create_domain --stage=...
.
Then I tried to add it to the new WebSockets stack, but ended with this error:
Error: Failed to find CloudFormation resources for ...
I found it on Github that this seems to be not supported by CloudFormation right now so Serverless does not support it.
So I tried to attach my stage to the custom domain name manually in the UI:
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.
More confusion arises, as it's not even the same domain name in this case. The new domain name was sockets.<DOMAIN>.com
and the existing one was api.<DOMAIN>.com
. Or do different subdomains are falling into 'same domain name'?
Nevertheless I tried to create the custom domain again via the apigatewayv2 CLI:
aws apigatewayv2 create-domain-name --domain-name <DOMAIN> --domain-name-configurations file://domain-configuration.json --region eu-west-1
domain-configuration.json:
[
{
"ApiGatewayDomainName": "<DOMAIN>",
"CertificateArn": "arn:aws:acm:us-east-1:<ACCOUNT_ID>:certificate/<CERT_ID>",
"CertificateName": "<DOMAIN>",
"DomainNameStatus": "AVAILABLE",
"EndpointType": "EDGE",
"SecurityPolicy": "TLS_1_2"
}
]
But this results in the following error:
An error occurred (BadRequestException) when calling the CreateDomainName operation: Invalid certificate ARN: arn:aws:acm:us-east-1:924441585974:certificate/b88f0a3f-1393-4a16-a876-9830852b5207. Certificate must be in 'eu-west-1'.
My current state was that API Gateway only allows custom certificates to be located in us-east-1, so this error confuses me even more.
Summary: I'm completely stuck on how to get a custom domain name attached to my WebSocket API stage. I'm happy about every hint in the right direction!
You create a certificate for the given domain name (or import a certificate), set up the domain name in API Gateway with the ARN of the certificate provided by ACM, and map a base path under the custom domain name to a deployed stage of the API.
To set up a custom domain name for your API Gateway API, do the following: Request or import an SSL/TLS certificate. Create the custom domain name for your REST API, HTTP API, or WebSocket API. Test the setup by calling your API using the new custom domain name.
Sign in to the AWS Management Console and open the Amplify console . Choose your app that you want to add a custom domain to. In the navigation pane, choose App Settings, Domain management. On the Domain management page, choose Add domain.
Found a solution with a custom CloudFormation resource template:
resources:
Resources:
WebSocketDomainName:
Type: AWS::ApiGatewayV2::DomainName
Properties:
DomainName: <domain-name>
DomainNameConfigurations:
- EndpointType: 'REGIONAL'
CertificateArn: <cert-arn>
WebSocketMapping:
Type: AWS::ApiGatewayV2::ApiMapping
Properties:
ApiId: <api-id>
DomainName: !Ref WebSocketDomainName
Stage: <stage-name>
DNSRecord:
Type: AWS::Route53::RecordSet
Properties:
HostedZoneName: <hosted-zone-name>.
TTL: '900'
ResourceRecords:
- !GetAtt [ WebSocketDomainName, RegionalDomainName ]
Name: <domain-name>
Type: CNAME
Edit: Now working with serverless-domain-manager! 🎉
custom:
customDomain:
rest:
domainName: rest.serverless.foo.com
stage: ci
basePath: api
certificateName: '*.foo.com'
createRoute53Record: true
endpointType: 'regional'
securityPolicy: tls_1_2
http:
domainName: http.serverless.foo.com
stage: ci
basePath: api
certificateName: '*.foo.com'
createRoute53Record: true
endpointType: 'regional'
securityPolicy: tls_1_2
websocket:
domainName: ws.serverless.foo.com
stage: ci
basePath: api
certificateName: '*.foo.com'
createRoute53Record: true
endpointType: 'regional'
securityPolicy: tls_1_2
Thanks @tpschmidt for the helpful response! Just to add, in case you want a BasePathMapping for your websocket domain, add ApiMappingKey to the Cloudformation provided above. E.g.:
WebSocketMapping:
Type: AWS::ApiGatewayV2::ApiMapping
Properties:
ApiId: <api-id>
DomainName: !Ref WebSocketDomainName
Stage: <stage-name>
ApiMappingKey: <stage-name> #(e.g. prod)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With