Skip to content
Latchkey

CI/CD for a Serverless API on AWS Lambda with GitHub Actions

A serverless API tests its handlers locally, then deploys to AWS Lambda with OIDC - no stored AWS keys.

This recipe deploys a serverless API to AWS Lambda from GitHub Actions. It tests handler logic, then deploys with the Serverless Framework (or SAM) using OIDC role assumption on main.

What the pipeline does

  • npm ci
  • Lint
  • Test handlers (mock or local DB)
  • Assume an AWS role via OIDC
  • Deploy the stack on main

The workflow

OIDC gives the deploy job short-lived AWS credentials instead of long-lived secrets.

.github/workflows/deploy.yml
name: Deploy
on: [push, pull_request]
permissions:
  id-token: write
  contents: read
jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: npm
      - run: npm ci
      - run: npm run lint
      - run: npm test
  deploy:
    needs: test
    if: github.ref == 'refs/heads/main'
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
          cache: npm
      - run: npm ci
      - uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: us-east-1
      - run: npx serverless deploy --stage prod

Testing and dependencies

Handler logic is plain functions, so unit-test them directly with mocked events. For integration tests against a database, add a Postgres service container and point the handler at DATABASE_URL, or use the local emulator (serverless-offline / sam local). Keep DynamoDB access tested with a local DynamoDB container if your API uses it.

Deploying

serverless deploy (or sam deploy) packages the functions and rolls the CloudFormation stack - API Gateway, Lambda, and IAM in one shot. Use stages (--stage prod) to separate environments. The OIDC role needs permissions for CloudFormation, Lambda, API Gateway, and IAM. Managed runners that auto-retry transient AWS API and registry flakes keep deploys green, at about 69% less than GitHub-hosted runners.

Key takeaways

  • Unit-test Lambda handlers directly with mocked events - they are plain functions.
  • Deploy with OIDC role assumption instead of stored AWS keys.
  • serverless/sam deploy rolls API Gateway, Lambda, and IAM as one stack.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →