Skip to content

AWS Lambda

Deploy serverless functions to AWS Lambda with the AWS Serverless Application Model (SAM). Pilum runs sam build and sam deploy in the service directory; your SAM template.yaml defines the function.

Prerequisites

  1. AWS CLI installed and configured
  2. AWS SAM CLI installed
  3. AWS credentials allowed to deploy CloudFormation stacks, create IAM roles and manage Lambda functions
Terminal window
# Install AWS CLI
brew install awscli
# Install SAM CLI
brew install aws-sam-cli
# Configure credentials
aws configure

Service Configuration

name: my-function
type: aws-lambda
region: us-east-1
project: my-company

Put this pilum.yaml next to the function’s template.yaml. The CloudFormation stack is named after the service (my-function above).

Required Fields

FieldDescription
nameService name. Used as the CloudFormation stack name, and by pilum status/logs as the Lambda function name.
typeaws-lambda (with only provider: aws, this recipe is also chosen, as it is the only AWS recipe)
regionAWS region, e.g. us-east-1
projectRequired by the recipe, but not used in any command

pilum check does not report a missing region or project, because the recipe gives them defaults (us-east-1, my-project). The defaults are not applied when deploying, so always set region: without it, sam deploy gets an empty --region.

What Pilum Ignores

Pilum drives the build and deploy; SAM owns the function. For aws-lambda services:

  • build.cmd is not run. The build step is always sam build.
  • The lambda: block (memory, timeout, runtime) is ignored. Set these in template.yaml.
  • env_vars and secrets are not applied to the function. See Environment Variables.
  • No Docker image is built and no registry is used.

SAM Template

Pilum works with your existing SAM template. A minimal Go function:

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Globals:
Function:
Timeout: 30
MemorySize: 128
Resources:
MyFunction:
Type: AWS::Serverless::Function
Metadata:
BuildMethod: go1.x
Properties:
FunctionName: my-function # match the pilum.yaml name so status/logs find it
CodeUri: .
Handler: bootstrap
Runtime: provided.al2023
Architectures:
- arm64
Events:
Api:
Type: Api
Properties:
Path: /
Method: ANY

Deployment Steps

The aws-lambda recipe runs two commands in the service directory (check them with pilum dry-run):

  1. build [build] — sam build
  2. deploy [push, deploy] —
    Terminal window
    sam deploy --stack-name <name> --region <region> \
    --resolve-s3 --capabilities CAPABILITY_IAM \
    --no-confirm-changeset --no-fail-on-empty-changeset --no-progressbar \
    --tags pilum:service=<name> pilum:version=<tag>
  • There is no separate package step: --resolve-s3 makes SAM create or reuse its own managed S3 bucket for artifacts. You do not need to create a bucket.
  • --capabilities CAPABILITY_IAM lets the stack create the function’s execution role.
  • --no-fail-on-empty-changeset makes redeploying an unchanged service a success.
  • The stack is tagged with the service name and the --tag value. Without --tag, the version tag is empty.
  • The deploy step retries once on failure.

Because the deploy step is tagged both push and deploy, pilum push runs sam deploy, and pilum publish (which skips deploy-tagged steps) only runs sam build.

Example Commands

Terminal window
# Build and deploy
pilum deploy my-function --tag=v1.0.0
# Build only
pilum build my-function
# Deploy only, using the existing .aws-sam/build output
pilum deploy my-function --only-tags=deploy --tag=v1.0.0
# Preview commands
pilum dry-run my-function --tag=v1.0.0

Environment Variables

Set Lambda environment variables in your SAM template:

Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
LOG_LEVEL: info
TABLE_NAME: !Ref MyTable

Secrets

Use AWS Secrets Manager dynamic references in the template:

Resources:
MyFunction:
Type: AWS::Serverless::Function
Properties:
Environment:
Variables:
DATABASE_URL: '{{resolve:secretsmanager:my-db-secret:SecretString:url}}'

Status and Logs

Terminal window
pilum status my-function # aws lambda get-function --function-name my-function
pilum logs my-function # aws logs tail /aws/lambda/my-function
pilum logs my-function --follow # stream new log events

Both use the service name as the function name, so they only work when the template sets FunctionName to the same value. --lines has no effect for Lambda.

There is no pilum rollback for Lambda. To go back, redeploy an earlier commit with its tag.

Troubleshooting

Credentials not found

Unable to locate credentials

Configure AWS:

Terminal window
aws configure
# Or use environment variables
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_REGION=us-east-1

Requires capabilities error

The template creates IAM resources with explicit names, which need CAPABILITY_NAMED_IAM. Pilum passes only CAPABILITY_IAM. Remove explicit role names from the template, or write a custom recipe with the extra capability.

Stack update failed

Check the CloudFormation events. The stack name is the service name:

Terminal window
aws cloudformation describe-stack-events --stack-name my-function

Status says the function was not found

The template’s FunctionName differs from the pilum.yaml name, or is not set (CloudFormation then generates a name). Set FunctionName to the service name.

Next Steps