Serverless: Breaking a large serverless.yml into manageable chunks
The Serverlerss Framework uses a serverless.yml file to manage all the functions. All the configurations related to our environment, our functions and the Cloud Resources that the functions are dependent on reside in this serverless.yml file.
Because of this, the size of this file can quickly get out of hand even with a few functions thus making it unmanageable and prone to errors and merge conflicts in the long run.
Lets look at how we can break a large serverless.yml file into manageable chunks!
Setting up the base code
Clone this repository from the last part. We should have the following project structure:
- functions
- randomGenerator
- node_modules
- package.json
- package-lock.json
- randomGenerator.js
- uuidGenerator
- node_modules
- package.json
- package-lock.json
- uuidGenerator.js
- .gitignore
- serverless.yml
And this should be the content of the serverless.yml:
service: serveless-medium
provider:
name: aws
runtime: nodejs12.x
functions:
randomGenerator:
handler: functions/randomGenerator/randomGenerator.handler
package:
individually: true
exclude:
- "./**"
include:
- ./functions/randomGenerator/randomGenerator.js
- ./functions/randomGenerator/node_modules/**
- ./functions/randomGenerator/package.json
uuidGenerator:
handler: functions/uuidGenerator/uuidGenerator.handler
package:
individually: true
exclude:
- "./**"
include:
- ./functions/uuidGenerator/uuidGenerator.js
- ./functions/uuidGenerator/node_modules/**
- ./functions/uuidGenerator/package.json
You can see the size of this file with just 2 minimalist functions and 0 additional configurations. This size will only increase as our functions and configurations grow.
Breaking the file
Start by creating 2 new serverless.yml files in the function sub folders randomGenerator and uuidGenerator. And copy the configuration of each function to its respective serverless.yml file:
// functions/randomGenerator/serverless.ymlrandomGenerator:
handler: functions/randomGenerator/randomGenerator.handler
package:
individually: true
exclude:
- "./**"
include:
- ./functions/randomGenerator/randomGenerator.js
- ./functions/randomGenerator/node_modules/**
- ./functions/randomGenerator/package.json
// functions/uuidGenerator/serverless.ymluuidGenerator:
handler: functions/uuidGenerator/uuidGenerator.handler
package:
individually: true
exclude:
- "./**"
include:
- ./functions/uuidGenerator/uuidGenerator.js
- ./functions/uuidGenerator/node_modules/**
- ./functions/uuidGenerator/package.json
Once this is done, update the main serverless.yml in the root directory:
functions:
- ${file(./functions/randomGenerator/serverless.yml)}
- ${file(./functions/uuidGenerator/serverless.yml)}
And thats it! We’ve successfully broken down our main serverless.yml template file into 3. The main file contains provider level settings and references to all the functions that we have. The remaining 2 sub files in the function sub folders contain only the configuration related to those respective functions.
We can keep on doing this for as many functions as we want. When deploying, Serverless will go through these references and compile the entire configuration itself.
Our folder structure at this point should be almost as similar as before with the addition of 2 new serverless.yml files:
- functions
- randomGenerator
- node_modules
- package.json
- package-lock.json
- randomGenerator.js
- serverless.yml - uuidGenerator
- node_modules
- package.json
- package-lock.json
- serverless.yml
- uuidGenerator.js
- .gitignore
- serverless.yml
Doing a serverless print
at this point should result in the exact same output that we had at the start of this post. Go ahead and run serverless print
and then serverless deploy
to verify the output and the lambda functions.
This might look trivial but is a very powerful concept that can be reused across multiple use cases in order to have maintainable folder structures and files.
Whats next?
In the next part, We’ll build on top of the same concept of breaking down serverless.yml template files and look into how we can reuse common configurations across multiple functions.
PS: The Source Code for this part has been uploaded on Github for reference.
This article is a part of my 5 Article Series on the Serverless Framework!
Part 1: Serverless: Managing environment variables efficiently with stages
Part 2: Serverless: Managing config for different environments with S3 and Bash Scripts
Part 3: Serverless: Creating light and lean function packages
Part 4: Serverless: Breaking a large serverless.yml into manageable chunks
Part 5: Serverless: Reusing common configurations across functions