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


#1

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?


#2

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


#3

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

#4

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


#5

So it is. Thank you for that!


#6

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.


#7

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:


#8

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


#9

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.


#10

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?


#11

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


#12

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


#13

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