v2.4.2

Serverless

Each services/<name>/ is an independent Serverless v4 service with own serverless.yml, IAM roles, and CloudFormation stack.

Service shape

yaml
# services/leads/serverless.yml
app: drive-api
service: drive-api-leads
frameworkVersion: '>=4.17.2'

provider:
  # from serverless.common.yml via ${file(...)} — NO inheritance,
  # each consumed section must be included explicitly
  stage: ${opt:stage, 'dev'}
  runtime: nodejs22.x
  region: ${opt:region, 'ap-southeast-2'}
  apiGateway:
    restApiId: ${ssm:/${self:provider.stage}/drive/apig/drive-api/id}
    ...

Shared config (serverless.common.yml)

Not a base class — a YAML file whose sections are included verbatim via ${file(../../serverless.common.yml):<section>}. Defines:

  • stages — observability defaults
  • provider — runtime defaults, apiGateway (shared restApiId + auto-created keys), memory/timeout, log retention, tags, deployment bucket, tracing, full environment block, IAM
  • pluginsserverless-stack-output, serverless-offline, serverless-prune-plugin
  • build.esbuild — sourcemaps, resolve extensions, externals
  • package — individual packaging, patterns
  • customoffline, ssmExtension.layerArn, otelCollect.layerArn, otelInstrument.layerArn, tracing, prune, contentEncoding, output, domainConfig, three alert tiers

No inheritance — a service wanting any section must include it explicitly or redeclare.

Build

Each function bundled individually with esbuild (package.individually: true):

yaml
build:
  esbuild:
    sourcemap: true
    sourcesContent: false
    resolveExtensions: ['.ts', '.js', '.mjs']
    external: ['aws-sdk']

source-map-support bundled; root collector.yaml copied into each package.

Layers

Three per function:

LayerPurpose
AWS Parameters-and-Secrets ExtensionSSM + Secrets caching (port 2773)
Grafana collector-lambda-extensionOTLP collector (4318 → Grafana)
aws-otel-nodejsNode instrumentation (AWS_LAMBDA_EXEC_WRAPPER)

Runtime

  • nodejs20.x (cmstosocial) or nodejs22.x (rest)
  • arm64
  • memorySize: 256 default (marketplace stockColours = 512)
  • timeout: 29 (under the API Gateway 30s limit)

Deploy

From inside a service folder:

bash
yarn g:deploy          # dev
yarn g:deploy:staging  # staging
yarn g:deploy:prod     # prod (uses aws-drive-prod-admin profile)

See CI/CD.

Esc