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.


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.
   - serverless-domain-manager

    domainName: "${self:custom.domain}"
    stage: ${self:provider.stage}
    createRoute53Record: true

$ serverless create-domain

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

  Run "serverless help" for a list of all available commands.
  Get Support --------------------------------------------
  Your Environment Information -----------------------------
     OS:                     darwin
     Node Version:           7.7.2
     Serverless Version:     1.18.1
$ npm --v


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


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 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.


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
Distribution Domain Name

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.


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
name: aws
runtime: java8
stage: ${opt:stage, β€˜dev’}
region: eu-west-1
config: ${file(./serverless.${self:provider.stage}.cfg.yml)} # try using this config file object
basePath: ${self:custom.config.path}
domainName: ${self:custom.config.domainName}
stage: ${opt:stage, β€˜dev’}
certificateName: ${self:custom.config.certificateName}
createRoute53Record: true

artifact: build/distributions/

handler: com.serverless.Handler
- https:
path: ${file(./}
method: get

  • serverless-domain-manager

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 (/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 (/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.

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