@serverless/compose-beta v0.0.10
BETA: This repository contains a beta version of a new Serverless Framework feature.
Deploy and orchestrate multiple Serverless Framework services in monorepositories.
- Deploy multiple services in parallel
- Deploy dependent services in a specific order
- Share outputs from one service to another
- Run commands across multiple services
name: myapp
services:
subscriptions:
path: subscriptions
users:
path: users
...You can also check out and deploy the example.
Beta version
This repository contains a beta version of Serverless Framework Compose: a new feature providing multi-service deployments.
While in beta, this feature is in a separate repository and NPM package. Eventually, it will be merged in the main serverless CLI and project.
We use GitHub issues to discuss ideas and features. We encourage you to:
- watch the GitHub repository to be notified of releases and discussions
- get involved in GitHub issues
Installation
While in beta, the feature ships as a separate package and CLI. Install it via NPM:
npm -g i @serverless/compose-betaThe CLI can now be used via the following command:
serverless-composeor for short:
slscNote: while in beta, the feature is available via the serverless-compose command, not the main serverless CLI.
Usage
The multi-service deployment feature is designed for monorepositories.
Assuming you have an application containing multiple Serverless Framework services, for example:
my-app/
service-a/
src/
...
serverless.yml
service-b/
src/
...
serverless.ymlYou can now create a serverless-compose.yml configuration file at the root of your monorepository.
In that new file, you can reference existing Serverless Framework projects by their relative paths:
# Name of the application
name: myapp
services:
service-a:
# Relative path to the Serverless Framework service
path: service-a
service-b:
# Relative path to the Serverless Framework service
path: service-b
# If the file is not named "serverless.yml" it is possible to configure that:
# config: serverless.api.ymlTo deploy all services, instead of running serverless deploy in each service, you can now deploy all services at once via:
$ serverless-compose deploy
Deploying myapp to stage dev
✔ service-a › deployed › 15s
✔ service-b › deployed › 31s⚠️ Warning: The deployment will run serverless deploy in each service directory. If Serverless Framework is installed locally (in node_modules/) in some services, you need to make sure Serverless Framework v3.3.0 or greater is installed.
Service dependencies and variables
Service variables let us:
- order deployments
- inject outputs from one service into another
This is possible via the ${service.output} syntax. For example:
services:
service-a:
path: service-a
service-b:
path: service-b
params:
queueUrl: ${service-a.queueUrl}Let's break down the example above into 3 steps:
${service-a.queueUrl}will resolve to thequeueUrloutput of theservice-aservice.The outputs of a Serverless Framework service are resolved from its CloudFormation outputs. Here is how we can expose the
queueUrloutput in theservice-a/serverless.ymlconfig:# service-a/serverless.yml # ... resources: Resources: MyQueue: Type: AWS::SQS::Queue # ... Outputs: queueUrl: Value: !Ref MyQueueBecause of the dependency introduced by the variable,
serverless-compose deploywill automatically deployservice-afirst, and thenservice-b.The value will be passed to
service-bas a parameter namedqueueUrl. Parameters can be referenced in Serverless Framework configuration via the${param:xxx}syntax:# service-b/serverless.yml provider: ... environment: # Here we inject the queue URL as a Lambda environment variable SERVICE_A_QUEUE_URL: ${param:queueUrl}
Cross-services variables are a great way to share API URLs, queue URLs, database table names, and more, without having to hardcode resource names or use SSM.
Alternatively, you can also specify explicit dependencies without passing any variables between services by setting dependsOn to a name of service in configuration. For example:
services:
service-a:
path: service-a
service-b:
path: service-b
dependsOn: service-a
service-c:
path: service-c
service-d:
path: service-d
dependsOn:
- service-a
- service-cAs seen in the above example, it is possible to configure more than one dependency by providing dependsOn as a list.
Global commands
On top of serverless-compose deploy, the following commands can be run globally across all services:
serverless-compose infoto view all services outputsserverless-compose removeto remove all servicesserverless-compose refresh-outputsto refresh outputs of all servicesserverless-compose logsto fetch logs from all functions across all servicesserverless-compose outputsto view all services outputs
For example, it is possible to tail logs for all functions at once:
$ serverless-compose logs --tail
service-a › users › START
service-a › users › 2021-12-31 16:54:14 INFO New user created
service-a › users › END Duration: 13 ms ...
service-b › subscriptions › START
service-b › subscriptions › 2021-12-31 16:54:14 INFO New subscription enabled
service-b › subscriptions › END Duration: 7 ms ...
⠴ service-a › logs › 2s
⠦ service-a › logs › 2sService-specific commands
It is possible to run commands for a specific service only. For example to deploy only a specific service:
serverless-compose deploy --service=service-a
# Shortcut alternative
serverless-compose service-a:deployOr tail logs of a single function:
serverless-compose logs --service=service-a --function=index
# Shortcut alternative
serverless-compose service-a:logs --function=indexAll Serverless Framework commands are supported via service-specific commands, including custom commands from plugins.
Service-specific commands when using parameters
The serverless-compose service-a:deploy command is the equivalent of running serverless deploy in service-a's directory. Both approaches can be used.
However, if "service-a" uses ${param:xxx} to reference serverless-compose.yml parameters, then serverless deploy will not work. Indeed, ${param:xxx} cannot be resolved outside of Serverless Framework compose.
In these cases, you must run all commands from the root: serverless-compose service-a:deploy.
Differences with serverless.yml
Unless documented here, expect any serverless.yml feature to not be supported in serverless-compose.yml. For example, it is not possible to include plugins or use serverless.yml variables (like ${env:, ${opt:, etc.) inside serverless-compose.yml.
Feel free to open an issue if you need a feature that isn't supported at the moment.
Refreshing outputs of already deployed services
If you need to refresh outputs of services that you already deployed previously, e.g. from different development machine, you can do it with the following command:
serverless-compose refresh-outputsRemoving services
To delete the whole project (and all its services), run serverless-compose remove. This will run serverless remove in each service.
To delete only one service:
- run
serverless-compose <component>:remove - then remove the service from
serverless-compose.yml
If you remove the service from serverless-compose.yml without doing step 1 first the service will still be deployed in your AWS account.
Remember to do this for every stage you may have previously deployed.