In this post we’ll be looking at why the artifacts generated by Serverless Framework cannot be reused across stages (or environments).

Standard CI/CD pipelines

Let’s start by looking at what happens in a standard CI/CD pipeline. A continuous integration workflow always starts with the build server pulling the code and running tests against them. If the tests pass, the code is packaged into an artifact and assigned a build id. The artifact then gets deployed to your dev environment for further tests. If the process goes smoothly, the same artifact propagates through the various downstream stages and finally gets deployed to the production environment.

An artifact that is reused in this way is called an Immutable Artifact. The idea being that, once the code is tested and packaged, the artifact is frozen. And no changes are made to it as it propagates downstream. You might be a small team with only a dev and a prod environment, but the idea still holds true.

Serverless Framework CI/CD pipelines

Unfortunately, this is not the case for Serverless Framework apps. When you generate an artifact by running the serverless package --stage dev command; the artifact can only be used for the dev stage. Here is why. The artifact is made up of three parts. Here is a quick recap of how Serverless Framework generates these artifacts.

  1. One or more zip files containing the Lambda code for your service(s).
  2. A CloudFormation template file that describes the resources defined in your serverless.yml.
  3. A serverless-state.json file that is used internally by Serverless Framework.

The Lambda code is environment/stage agnostic, and can be reused across multiple environments. The CloudFormation template on the other hand, is stage specific because the stage name is used in naming the resources. Consider this serverless.yml definition as an example:

service: my-service
    handler: path_to_handler_file/billing.main
      - http:
          path: /billing

If you run serverless package --stage dev and inspect the generated CloudFormation template, you will see:

  • An AWS::Logs::LogGroup resource named /aws/lambda/my-service-dev-billing.
  • An AWS::IAM::Role resource named my-service-dev-us-east-1-lambdaRole.
  • An AWS::Lambda::Function resource named my-service-dev-billing.
  • An AWS::ApiGateway::RestApi resource named dev-my-service.

You’ll notice that all the resource names contains the name of the stage (dev). This means that you’ll get an error if you tried to use this same package to deploy to your production environment.

So while creating your Serverless CI/CD pipeline, keep in mind that you cannot reuse the artifacts across stages. However, you can reuse the same artifact when you want to rollback to a previous deployment within the same stage.