• Documentation
  • Pricing
© 2026 Serverless, Inc. All rights reserved.

Framework

  • Overview
  • Documentation
  • Plugins360
  • Pricing

Learn

  • Blog
  • GuidesUpdated
  • Examples240
  • Courses

Resources

  • Support
  • Security
  • Trust Center
  • Status

Community

  • Slack
  • GitHub47k
  • Forum
  • Meetups

Company

  • About
  • Careers
  • Contact
  • Partners

Legal

  • Terms of Service
  • Privacy Policy
  • Trademark
  • DMCA
Updated March 2026

Serverless CI/CD Workflow Guide

A comprehensive guide to building reliable CI/CD pipelines for serverless applications. Learn the four-step workflow pattern used by the best serverless teams.

Get StartedView Docs

What is CI/CD

Continuous Integration and Continuous Delivery (CI/CD) is the practice of automating the build, test, and deployment process for your applications. For serverless applications, CI/CD is especially important because the deployment unit is typically a single function or service, and teams often manage dozens or hundreds of independently deployable services.

A well-designed CI/CD workflow ensures that every code change is automatically tested, reviewed, staged, and deployed to production with minimal manual intervention. This reduces human error, increases deployment frequency, and gives teams confidence that their changes work correctly before reaching users.

The Serverless Framework includes a built-in CI/CD service through Serverless Framework Pro. It is purpose-built for serverless workflows and handles deployment orchestration, secrets management, and multi-service coordination out of the box. The free tier includes one concurrent build, making it easy to get started. For teams that prefer to use their own CI provider, GitHub Actions is a popular alternative that pairs well with the Serverless Framework CLI. This guide covers both approaches.

Core Requirements

Before building your CI/CD pipeline, ensure your workflow meets these fundamental requirements:

Version Control

All application code and infrastructure definitions (serverless.yml) must be stored in version control (Git).

Automated Testing

Unit tests, integration tests, and end-to-end tests should run automatically on every commit and pull request.

Environment Isolation

Development, staging, and production environments must be isolated to prevent cross-environment contamination.

Configuration Management

Secrets, environment variables, and configuration must be managed separately from code and injected at deploy time.

The Four-Step Workflow

The recommended CI/CD workflow for serverless applications follows four stages, each with a clear purpose and set of actions.

1

Develop

Developers work on feature branches and deploy to personal development stages. Each developer gets their own isolated environment to test changes without affecting others.

Deploy to personal dev stage
# Each developer deploys to their own stage
serverless deploy --stage dev-john

# Test your changes
serverless invoke --function hello --stage dev-john

# View logs in real-time
serverless logs --function hello --stage dev-john --tail
2

Review

When a feature is ready, the developer opens a pull request. The CI pipeline automatically deploys a preview environment and runs the test suite. Reviewers can test the changes in an isolated environment before approving.

CI pipeline on pull request
# .github/workflows/review.yml
name: Review
on:
  pull_request:
    branches: [main]

jobs:
  deploy-preview:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm test
      - run: npx serverless deploy --stage preview-${{ github.event.number }}
3

Stage

After the pull request is merged to the main branch, the CI pipeline automatically deploys to the staging environment. Staging mirrors production and serves as the final validation step before release.

CI pipeline on merge to main
# .github/workflows/stage.yml
name: Stage
on:
  push:
    branches: [main]

jobs:
  deploy-staging:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm test
      - run: npx serverless deploy --stage staging
      - run: npm run test:integration
4

Release

After staging validation passes, the same artifact is promoted to production. This can be triggered automatically or require manual approval depending on your team's risk tolerance.

Production release workflow
# .github/workflows/release.yml
name: Release
on:
  workflow_dispatch:
  # Or trigger automatically after staging succeeds

jobs:
  deploy-production:
    runs-on: ubuntu-latest
    environment: production  # Requires manual approval
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx serverless deploy --stage prod

Preview Deployments

Preview deployments give every pull request its own isolated serverless environment. When a developer opens a PR, the CI pipeline automatically deploys all services to a stage named after the branch (or PR number). Reviewers can test the changes against real AWS resources without affecting staging or production.

When the branch is deleted or the PR is closed, a cleanup workflow removes the preview stage automatically. This prevents unused stacks from accumulating and keeps your AWS account tidy.

Preview deploy and cleanup workflows
# .github/workflows/preview-deploy.yml
name: Preview Deploy
on:
  pull_request:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npm test
      - run: npx serverless deploy --stage preview-${{ github.event.number }}

# ---

# .github/workflows/preview-cleanup.yml
name: Preview Cleanup
on:
  delete:
    branches:

jobs:
  remove:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx serverless remove --stage preview-${{ github.event.ref }}

With Serverless Framework Pro, preview deployments are handled natively. The Pro CI/CD system detects pull requests, deploys a preview stage using the branch name, and tears it down when the branch is deleted. No workflow files are required.

Example Application

Throughout this guide, we will reference a workshop-style full-stack application composed of three Serverless Framework services. This is a realistic example that demonstrates multi-service coordination, shared outputs, and stage-specific parameters.

fullstack-database

Provisions a DynamoDB table using custom variables. Publishes the table name and ARN as outputs so other services can consume them without hardcoding resource identifiers.

fullstack-restapi

A Lambda-backed API Gateway service that handles HTTP requests. It consumes the outputs from fullstack-database to read and write data, keeping the two services loosely coupled.

fullstack-tasks

A Lambda function that runs on a 5-minute interval schedule. It pulls configuration values using parameters stored in the Serverless Framework Pro dashboard, such as API keys and feature toggles.

Repository Organization

For larger applications, organize your serverless services within a monorepo structure. Each service has its own serverless.yml and can be deployed independently.

Recommended monorepo structure
my-app/
  services/
    api/
      serverless.yml
      handler.js
      package.json
    auth/
      serverless.yml
      handler.js
      package.json
    notifications/
      serverless.yml
      handler.js
      package.json
  shared/
    lib/
      utils.js
      database.js
  tests/
    integration/
    e2e/
  package.json
  README.md

Environment Setup

Use Serverless Framework stages to manage multiple environments. Each stage creates a completely isolated set of resources with its own CloudFormation stack.

serverless.yml - Stage-specific configuration
service: my-api

provider:
  name: aws
  runtime: nodejs20.x
  stage: ${opt:stage, 'dev'}
  region: us-east-1
  environment:
    STAGE: ${sls:stage}
    TABLE_NAME: ${self:service}-${sls:stage}-table

custom:
  # Stage-specific settings
  domainName:
    prod: api.example.com
    staging: staging-api.example.com
    dev: ${sls:stage}-api.example.com

functions:
  hello:
    handler: handler.hello
    events:
      - httpApi:
          path: /hello
          method: get

resources:
  Resources:
    DataTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: ${self:service}-${sls:stage}-table
        BillingMode: PAY_PER_REQUEST
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH

Deployment Profiles

Use different AWS credentials and configuration profiles for each environment. This ensures separation of concerns and prevents accidental deployments to the wrong environment.

Development

Individual developer AWS accounts or sandboxed roles with broad permissions for experimentation.

Staging

Shared staging account with production-like settings. CI/CD pipeline uses a dedicated IAM role with scoped permissions.

Production

Locked-down production account. Deployments only via CI/CD with manual approval gates and audit logging.

AWS Organizations and Separate Accounts

The recommended approach is to use three separate AWS accounts managed through AWS Organizations: one each for development, staging, and production. Account-level isolation is the strongest boundary AWS provides. It prevents configuration mistakes in one environment from affecting another, and it makes cost attribution straightforward.

AWS Access Roles for Short-Lived Credentials

Serverless Framework Pro supports AWS Access Roles, which generate short-lived credentials that rotate every hour. This eliminates the need to store long-lived AWS access keys in your CI system. You link each deployment profile to an IAM role in the target account, and the framework handles credential exchange automatically.

Stage-Specific Parameters

Store stage-specific configuration values (API keys, feature toggles, resource identifiers) in the Serverless Framework Pro dashboard under each deployment profile. Reference them in your serverless.yml using the ${param:...} syntax. When the service is deployed to a given stage, the framework resolves each parameter from the matching profile automatically.

Using parameters in serverless.yml
provider:
  environment:
    STRIPE_KEY: ${param:stripeKey}
    SENDGRID_KEY: ${param:sendgridKey}
    SENTRY_DSN: ${param:sentryDsn}

Third-Party Service Accounts

Just as you use separate AWS accounts per environment, use separate accounts for third-party services like Stripe, SendGrid, and Sentry. Store each set of credentials in the corresponding deployment profile. This keeps test data out of production systems and prevents accidental charges or notifications from non-production environments.

Sharing Resources

When multiple services need to share resources (like a DynamoDB table or an SQS queue), use CloudFormation outputs and Fn::ImportValue to share resource references across stacks.

CloudFormation Approach

Exporting and importing resources across services
# Service A: Export the table ARN
resources:
  Outputs:
    DataTableArn:
      Value: !GetAtt DataTable.Arn
      Export:
        Name: ${sls:stage}-data-table-arn

# ---

# Service B: Import the table ARN
provider:
  iam:
    role:
      statements:
        - Effect: Allow
          Action:
            - dynamodb:GetItem
            - dynamodb:PutItem
          Resource:
            Fn::ImportValue: ${sls:stage}-data-table-arn

Serverless Framework Pro Approach

Serverless Framework Pro provides a simpler alternative for sharing values between services. Use the outputs block in your serverless.yml to publish values, then reference them from other services with the ${output:...} syntax. This avoids the CloudFormation export/import coupling and works across stages and regions.

Publishing and consuming outputs via Serverless Framework Pro
# fullstack-database/serverless.yml - Publish outputs
outputs:
  tableArn: !GetAtt DataTable.Arn
  tableName: !Ref DataTable

# ---

# fullstack-restapi/serverless.yml - Consume outputs (same app, stage, region)
provider:
  environment:
    TABLE_ARN: ${output:fullstack-database.tableArn}
    TABLE_NAME: ${output:fullstack-database.tableName}

# Cross-stage reference (full syntax)
# ${output:<app>:<stage>:<region>:<service>.<key>}
# Example: ${output:myapp:prod:us-east-1:fullstack-database.tableArn}

Promotion and Rollback

A robust CI/CD pipeline needs clear strategies for promoting code between environments and rolling back when issues are detected.

Promotion Strategy

  • Deploy to staging automatically on merge to main
  • Run integration and smoke tests in staging
  • Require manual approval for production deploys
  • Use the same build artifact across all environments
  • Tag releases in Git for traceability

Rollback Strategy

  • Redeploy the previous known-good commit
  • Use CloudFormation rollback for infrastructure changes
  • Keep deployment history for quick recovery
  • Monitor error rates and latency post-deploy
  • Automate rollback on health check failures

Git-Based Promotion and Rollback

A common pattern is to use Git branches as the source of truth for each environment. The main branch maps to staging and a prod branch maps to production. Promoting to production is as simple as merging main into prod. Your CI pipeline watches the prod branch and deploys automatically on push.

To roll back, revert the merge commit on the prod branch via a pull request. This creates a clean audit trail in Git, triggers the CI pipeline to redeploy the previous known-good state, and lets the team review the revert before it takes effect. Because the revert goes through the same PR workflow, it benefits from the same automated tests and approval gates as any other change.

Feature Flagging

Feature flags allow you to decouple deployment from release. Deploy code to production with features hidden behind flags, then enable them gradually for specific users or percentages of traffic.

Gradual Rollouts

Enable new features for a percentage of users, gradually increasing as confidence grows.

Instant Kill Switch

Disable a problematic feature immediately without redeploying code.

A/B Testing

Run experiments by exposing different feature variants to different user segments.

Environment Overrides

Enable features in staging but keep them disabled in production until ready.

Start Building Your CI/CD Pipeline

The Serverless Framework makes it easy to build robust CI/CD workflows for your serverless applications. Get started today.

Get StartedView Documentation