Monorepo containing several services

Hi team,

As we add more features, we finally hit the 200 resources Cloudformation limit so we split it into several services. It happens that we are also turning our code into a monorepo structure, as it allows us to re-use code easily across all functions. So we end up with a monorepo containing several services and found a few challenges:

  • Support for several services on the same template
    If I’m not mistaken, as it is now we would need to manage each service independently, meaning each of them would be defined in a different serverless.yml, packaged and deployed. Is there a way we can define several services on the same template? This would allow us, for example, to define alarms and other common resources and then reuse them across services. Or defining environment variables and be able to import it on each individual service.

Alternatively to define everything in a single serverless.yml, to import a global serverless.yml common to several services?

  • Only package and deploy if a service code has changed.
    It also becomes quite often that an update only affects one service. So for this use case it becomes quite important to monitor if the code inside a service (or even each individual function) has change so we can ignore it on the packaging and deployment steps. It seems the folks at Seed.run are doing it, but not sure if this feature is available on the Serverless framework.

  • Split the cloudformation stack
    Maybe an alternative to the previous points is to split the deployment of the stack: for example, a reason we hit the 200 resources limit is that we have defined alarms (with its corresponding metrics) for each lambda function, or domain and API Gateway endpoints linked to the lambdas.
    I feel it shouldn’t be necessary to deploy these resources at each time we modify an individual lambda function, but even if we can still use function command to deploy a single lambda, we still need to deploy the whole stack once. Is there any way serverless can split those resources into different cloudformation stacks avoiding the 200 resource limit?

I’m particularly interested in knowing how other users have overcome these challenges, or if there are related improvements coming on the roadmap :wink:

Thank you for your help!

Here is how we are doing it:

  • All the shared serverless resources are defined in a separate “shared-serverless-resources” project. We export all the IDs and ARNs from that project as Cloud Formation outputs, so they can be used in other projects.
  • “shared-serverless-resources” project also contains shared serverless configs which are imported into serverless.yml templates defined by other projects.
  • For CI/CD we use “Seed” (seed.run) service which allows us to define monorepo project inter-dependencies, so the projects would be build and deployed in specific order. “Seed” also takes care of only deploying changed monorepo projects. There isn’t anything serverless framework itself has to do, it’s all done by “Seed”.
  • Serverless framework allows you to reuse the same API Gateway across multiple lambda functions defined in different serverless templates. That’s not an issue.

Honestly, I don’t think it should be serverless framework responsibility to split your Cloud Formation stack. It should be done by you.

2 Likes