Excluding Resources When Preparing Package for Serverless Application

Different sizes of packages

Problem

During the development of a Serverless Framework application I accidentally realized that I’m not using properly the package / exclude configuration.

In my project there are a few directories that are used only for local development and should never go to the remote repository.
Well, that’s easy, right? We have .gitignore and we can nicely mark what files nad folders should not be committed.

Now, most likely on the server-side, in your CI/CD you have a process that builds a package for your Serverless Framework application. Let’s say this application package is a Python code and it’s 10 kB of size. The size is not very alarming at the first sight, right?

What is alarming is that if you try to locally run sls deploy in the logs you can see that it actually pushes like more than 100 MB of payload to S3. This IS definitely alarming:

Large payload size

(--stage local in my case is my name for local – per-developer – environment)

Reason

What is actually happening is that if you don’t specify the package section in serverless.yml it will wrap everything you have in a project. Well, maybe not everything as it does have some nice defaults that will omit most common do-not-commit folders.

However, it might still be a quite large payload assuming that you can have things like node_modules folder or some cache folders (visible on previous screenshot.)

Solution

You don’t need any of this in your serverless package and at the same time such folders can grow quit large.

In the matter of fact in my case the only thing I needed was the src directory where source-code lies (and even this directory needed some cleanup from Python cache folders):

Structure of a project

So I ended up with following package section in serverless.yml:

package:
  exclude:
    ${file(./serverless-package-excludes.yml)}

and mentioned serverless-package-excludes.yml:

- "**/**"
- "!src/**"
- "**/.pytest_cache/**"
- "**/__pycache__/**"

It excludes everything that is not src directory and its children and then it removes .pytest_cache and __pycache__ from all children directories.

Package size looks much better after the excludes:

More reasonable upload size

Plugin?

Maybe it’s a fine idea for a plugin? It might apply “exclude” section for all the entries from .gitignore file. The idea would be that if you don’t want it in remote repository, you should not need it while packaging.

Of course it will not solve all issues as you still might want to have some finer cuts, but it will be a nice addon!