Correct way to add custom domain to API Gateway in Serverless.yml?

What is the correct way to add a custom domain to a serverless api gateway? It seems like an obvious use case but a search finds a lot of headaches, unanswered questions, hacks, and errors.

Is there a working example somewhere?

@nford Agreed that it’s not easy to find. I’ll add that to my list of content to create.

In the meantime, try this plugin: serverless-domain-manager. It claims to make it easy to set up. I strongly prefer using plugins rather than writing my own custom CloudFormation whenever possible.

If you do try it, please report back and let me know if it works for you. I haven’t had the time to try it yet.

2 Likes

Not much luck with that:

$ npm install serverless-domain-manager

project@1.0.0 /Users/me/project
└─┬ serverless-domain-manager@1.1.9 
  ├─┬ aws-sdk@2.103.0 
  │ ├─┬ buffer@4.9.1 
  │ │ ├── base64-js@1.2.1 
  │ │ ├── ieee754@1.1.8 
  │ │ └── isarray@1.0.0 
  │ ├── crypto-browserify@1.0.9 
  │ ├── events@1.1.1 
  │ ├── jmespath@0.15.0 
  │ ├── querystring@0.2.0 
  │ ├── sax@1.2.1 
  │ ├─┬ url@0.10.3 
  │ │ └── punycode@1.3.2 
  │ ├── uuid@3.0.1 
  │ ├── xml2js@0.4.17 
  │ └─┬ xmlbuilder@4.2.1 
  │   └── lodash@4.17.4 
  └─┬ chalk@2.1.0 
    ├─┬ ansi-styles@3.2.0 
    │ └─┬ color-convert@1.9.0 
    │   └── color-name@1.1.3 
    ├── escape-string-regexp@1.0.5 
    └─┬ supports-color@4.2.1 
      └── has-flag@2.0.0 

npm WARN project@1.0.0 No description
npm WARN project@1.0.0 No repository field.
[snip]
plugins:
   - serverless-domain-manager

custom:
  customDomain:
    domainName: "${self:custom.domain}"
    stage: ${self:provider.stage}
    createRoute53Record: true
[snip]

$ serverless create-domain

Serverless Error ---------------------------------------
 
  Serverless command "create-domain" not found

  Run "serverless help" for a list of all available commands.
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
     Forums:        forum.serverless.com
     Chat:          gitter.im/serverless/serverless
 
  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           7.7.2
     Serverless Version:     1.18.1
$ npm --v
4.1.2
1 Like

Hey @nford – it’s actually an underscore, not a dash – serverless create_domain.

1 Like

So it is. Thank you for that!

I very much would like this to work, except that I’m creating my certificate in the Resources section with configuration based on https://github.com/ImmobilienScout24/aws-cf-verified-ssl-certificate. Unless there is a way for this plugin to wait for that creation step to complete, since this requires a certificate configured, it would probably make more sense to do the domain setup in Resources as well.

Hmm, yea you would probably have to do it in Resources then. You could copy the code from the domain manager plugin – it’s a lot of CloudFormation under the hood.

One thing to note – it takes upwards of 40 minutes to create a new CloudFront distribution anyway. Because of this, I’d recommend using the plugin and just manually approving a certificate. But, it’s up to you! :slight_smile:

Actually, if you look at the plugin there’s no CloudFormation under the hood. It uses the JS SDK.

1 Like

I’m a +1 here, would be great to have a recommended way of achieving this.

I’ve tried the serverless-domain-manager plugin.

Initially, it didn’t work for me as my certificate wasn’t us-east-1 (it only supports that region).

I’ve now moved my certificate over, and the plugin is successfully invoked on deploy. At the end of deployment, it outputs:

Serverless Domain Manager Summary
Domain Name
  _MY_DOMAIN_
Distribution Domain Name
  _ID_.cloudfront.net

However, the Lambda functions still aren’t available on that custom domain.

I tried serverless-domain-manager, but it only works in us-east-1.
I’m located in eu-west-1.
Are there other ways to add custom domain to API Gateway?

Just create your certificate on us-east-1 and it’ll work on any region you are creating the custom domain.

1 Like

@juanangosto
I created the certificates in the us-east-1 region, but i still receive the same error when i execute sls create_domain:
Error: Could not find the certificate “my-certificat-name” “my-domain” was not created in API Gateway.
Any idea what i’m missing?

My serverless.yml looks like

service: my-serverless-service
provider:
name: aws
runtime: java8
stage: ${opt:stage, ‘dev’}
region: eu-west-1
custom:
config: ${file(./serverless.${self:provider.stage}.cfg.yml)} # try using this config file object
customDomain:
basePath: ${self:custom.config.path}
domainName: ${self:custom.config.domainName}
stage: ${opt:stage, ‘dev’}
certificateName: ${self:custom.config.certificateName}
createRoute53Record: true

package:
artifact: build/distributions/hello.zip

functions:
hello:
handler: com.serverless.Handler
events:
- https:
path: ${file(./serverless.dev.cfg.yml):path}
method: get
plugins:

  • serverless-domain-manager

UPDATE:
Nevermind, i was using the wrong certificationName. It has to be the “Domain Name” of the certificate, not the “Name”.

Next stop:

  • “sls create_domain” works fine. New entry is created in Rout53
  • “sls deploy” doesn’t work:

Error: Error: Cannot find AWS::ApiGateway::Deployment Try running sls create_domain first.
at /Users/vandercp/intellij/my-serverless-service/node_modules/serverless-domain-manager/index.js:97:13
at process._tickDomainCallback (node.js:412:9)
From previous event:
at PluginManager.invoke (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:366:22)
at PluginManager.spawn (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:384:17)
at Deploy. (/usr/local/lib/node_modules/serverless/lib/plugins/deploy/deploy.js:120:50)
From previous event:
at Object.Deploy.hooks.before:deploy:deploy [as hook] (/usr/local/lib/node_modules/serverless/lib/plugins/deploy/deploy.js:110:10)
at /usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:366:55
From previous event:
at PluginManager.invoke (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:366:22)
at PluginManager.run (/usr/local/lib/node_modules/serverless/lib/classes/PluginManager.js:397:17)
at /usr/local/lib/node_modules/serverless/lib/Serverless.js:104:33
at processImmediate [as _immediateCallback] (timers.js:383:17)
From previous event:
at Serverless.run (/usr/local/lib/node_modules/serverless/lib/Serverless.js:91:74)
at /usr/local/lib/node_modules/serverless/bin/serverless:42:50

Someone any idea?
create_domain is already successfully called at this point.

Update:
There was a type in the events config: https -> http solved this issue

I’ve used this plugin successfully and I have a working example at https://github.com/Vadorequest/serverless-with-next, the example is actually much more than just serverless-domain-manager, but it partially relies on it.

But it’s still a real headache, one year later, to configure custom domains and certificate.
I always setup my custom domain and certificates from the AWS console and do it manually, mostly because most examples show how to do it that way.

But it’s become so complicated for me now, I’m really looking forward a way of doing it through the serverless.yml, I’m looking for examples and best practices. I read that most people suggest to have a different serverless.yml to do this kind of stuff, it’s totally fine. But I’m really missing examples of this.

I’m no sysadmin and I’m literally wasting days of work on this kind of setup, I’m currently working on a new project with a very complicated AWS Accounts architecture and I’ve been failing for almost 3 days now, despite AWS Support helping me.

A guide would definitely be useful and I haven’t seen any, besides https://serverless.com/blog/serverless-api-gateway-domain/ which doesn’t cover enough things and relies on a lot of manual operations.

i am getting error with create_domain

PS C:\Users\parik\Desktop\test_ser_custopm> serverless create_domain

Serverless Error ---------------------------------------

Serverless command “create_domain” not found. Did you mean “create”? Run “serverless help” for a list of all available commands.

i did run npm install serverless-domain-manager i am getting the the below warning
npm WARN aws-python@0.1.0 No description
npm WARN aws-python@0.1.0 No repository field.
npm WARN aws-python@0.1.0 No license field.

@parikannappan It looks like the serverless-domain-manager plugin is not loaded.

Did you add it to the list of plugins in your serverless.yml (as indicated by the documentation)?
It should look like this:

plugins:
  - serverless-domain-manager