Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Serverless Lifecycle Cheat Sheet

Serverless plugin author's cheat sheet

This cheat sheet provides a detailed overview of the exposed lifecycle events and available commands (and entrypoints) of the Serverless framework, that can be hooked by plugins (internal and external ones). The document is structured by the commands invoked by the user.

Lifecycle events are shown as the globally available outer events (all providers) and sub lifecycle events that are provider specific in the called order. Currently only the AWS provider is shown. If you have information about the other provider, please let me know and I will add the sub lifecycles accordingly.

The current event system can be improved in the future. Only package, deploy and info provide detailed event lifecycles for now, that make the plugin integration much more fine-grained.

Plugins can spawn any command or entrypoint with this.serverless.pluginManager.spawn() and invoke a sub lifecycle.

Lifecycle events / commands

package

package:cleanup

-> aws:common:validate:validate
-> aws:common:cleanupTempDir:cleanup

package:initialize

package:setupProviderConfiguration

package:createDeploymentArtifacts

package:compileFunctions

package:compileEvents

package:finalize

-> aws:package:finalize:mergeCustomProviderResources
-> aws:package:finalize:saveServiceState
-> aws:common:moveArtifactsToPackage:move

deploy

before:deploy:deploy

-> aws:common:validate:validate
-> aws:common:moveArtifactsToTemp:move

deploy:deploy

-> aws:deploy:deploy:createStack
-> aws:deploy:deploy:checkForChanges (1.17->)
-> aws:deploy:deploy:uploadArtifacts
-> aws:deploy:deploy:validateTemplate
-> aws:deploy:deploy:updateStack

deploy:finalize

-> aws:deploy:finalize:cleanup

deploy function

deploy:function:initialize

deploy:function:packageFunction

-> package:function:package

deploy:function:deploy

-> aws:common:cleanupTempDir:cleanup

deploy list

deploy:list:log

info

info:info

-> aws:info:validate
-> aws:info:gatherData
-> aws:info:displayServiceInfo
-> aws:info:displayApiKeys
-> aws:info:displayEndpoints
-> aws:info:displayFunctions
-> aws:info:displayStackOutputs

remove

remove:remove

rollback

rollback:initialize

rollback:rollback

rollback function

rollback:function:rollback

logs

logs:logs

invoke

invoke:invoke

invoke local

invoke:local:loadEnvVars

invoke:local:invoke

create

create:create

config

config:credentials:config

install

install:install

login

login:login

logout

logout:logout

metrics

metrics:metrics

slstats

slstats:slstats

@AdrienFromToulouse

This comment has been minimized.

Copy link

AdrienFromToulouse commented Aug 24, 2017

Would be super great to update the plugin section of the online doc. It is pretty hard to get the right info :)

@iDVB

This comment has been minimized.

Copy link

iDVB commented Dec 4, 2017

Anyone know the order plugins execute when they share the same hook? It doesn’t seem to be based on the order in the serverless.yml file.

I have a plugin set to after:deploy:finalize and its still running before another plugin. (I want it after)

@HyperBrain

This comment has been minimized.

Copy link
Owner Author

HyperBrain commented Dec 11, 2017

@iDVB The order should definitely be set by the order in which the plugins appear in the serverless.yml. Internally the hooks are stored in an array and when the serverless.yml:plugins array is evaluated in order the hooks are pushed into the hooks array.
In general, that means, that the system plugins are executed first and then the 3rd party plugin in order.

@HyperBrain

This comment has been minimized.

Copy link
Owner Author

HyperBrain commented Dec 11, 2017

Regarding the after:deploy:finalize you have to be careful: For AWS, it spawns a sublifecycle (aws:deploy:...). If another plugin hooks some after:aws:deploy:finalize:cleanup it will naturally be called before your hook, because the after:deploy:finalize event is the very last event in the whole outer lifecycle. If your plugin is AWS only, you should hook into the more fine-grained sublifecycle instead.

@tommedema

This comment has been minimized.

Copy link

tommedema commented Dec 11, 2017

The cheat sheet is very useful, thanks!

My major concern is to what extent we are supposed to fiddle with serverless internals. I.e. when is something good / bad practice when done with plugins.

For example, take this practical case: I have created a custom resource that requests ACM certificates. This works fine. However, cloudfront only accepts ACM certificates that have been fully validated (i.e. issued). This means that you can only pass such certificate to cloudfront after it has been validated. Unfortunately, you cannot have a custom resource wait until validation has passed due to the 5 minute timeout of Lambda. The only solution seems to be to create a cloudformation condition like so:

resources:
  Conditions:
    # true when requested SSL certificate can be consumed (is valid)
    # this is automatically determined and substituted during build
    ShouldConsumeCertificate:
      Fn::Equals: ['%SCRIPT_SUBSTITUTE_CERTIFICATE_IS_VALID%', 'true']

And then have cloudfront only consume the certificate if it is indeed said to be valid:

...
          ViewerCertificate:
            Fn::If:
              - ShouldConsumeCertificate
              - 
                AcmCertificateArn:
                  Fn::GetAtt: [CertificateResource, acmArn]
                SslSupportMethod: sni-only
              - CloudFrontDefaultCertificate: true

Now, something has to substitute this string for it to equal true or false, depending on whether the certificate is ready to be consumed by cloudfront. I created a plugin that does this. This plugin is then run before the package:createDeploymentArtifacts event. But are these expected practices? Or are there cleaner way to do these sort of things? I think it would be great to add some guidelines in terms of "dos" and "donts" to the developer documentation.

@HyperBrain

This comment has been minimized.

Copy link
Owner Author

HyperBrain commented Jan 10, 2018

@tommedema. thanks for the question. In general, the package lifecycle is executed on a build server and the deploy lifecycle on a deployment server in a CI/CD system. So my advise here is, that plugins that are invoked somewhere during the package lifecycle should not access external resources (like the AWS REST API) as build servers might not have access to them. It is safer to have a plugin that does that hooked into one of the deploy lifecycles and let it operate on the generated CF template (that is available during deploy in-memory).
I fully agree that there should be a section of dos and don'ts in the docs - good idea.

@HyperBrain

This comment has been minimized.

Copy link
Owner Author

HyperBrain commented Jan 10, 2018

Just saw, that I missed the deploy:function lifecycle completely in the document. I will add them soon.
UPDATE: Added "deploy function" and "deploy list" commands.

@j-hannah

This comment has been minimized.

Copy link

j-hannah commented Feb 18, 2019

@HyperBrain Thank you for this resource! It doesn't look like it's in the official docs, though. Is there a reason? I'm asking because this is super useful information. Would you be interested in having help making a PR?

@falconmick

This comment has been minimized.

Copy link

falconmick commented Apr 2, 2019

Why isn't this in the docs... This isn't even enough..

@anwarhamr

This comment has been minimized.

Copy link

anwarhamr commented Apr 3, 2019

I'm trying to get a file copied to the project directory when the user types sls deploy, can this be done? I've tried so many versions of this

custom:
  scripts:
    hooks:
      'package:initialize': cp ../../deployment_configurations/aura_cloud/${self:service}/env.yml .
      'deploy:createDeploymentArtifacts':  node scripts/replace_stage_in_env.js ${opt:stage, self:provider.stage} && node scripts/createParameters.js ${opt:service, self:service} ${opt:stage, self:provider.stage}

I've tried these but not limited to these...

before:deploy:deploy
before:initialize
deploy:deploy:checkForChanges
deploy:deploy:validateTemplate
...

the second hook works but I've added the cp and get this message when the file does not exist for my env.yml

Serverless Warning --------------------------------------

  A valid file to satisfy the declaration 'file(./env.yml):dev.artifacts.s3ReportingBucket' could not be found.

is it possible to run a script prior to loading the provider object at time of run?

@lielran

This comment has been minimized.

Copy link

lielran commented Apr 4, 2019

@anwarhamr you can link your plugin project directly via npm/yarn link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.