This guide covers deploying safe-settings to AWS Lambda using Docker containers with automated GitHub Actions deployment.
safe-settings can be deployed to AWS Lambda using a containerized approach that provides:
- Docker-based deployment using the official Safe Settings source
- Dual Lambda functions for webhooks and scheduled sync operations
- GitHub Actions CI/CD with automated testing and deployment
- Production-ready architecture with proper error handling and monitoring
For a complete working example, use the SafeSettings-Template repository. This template provides:
- 🏗️ Modular Architecture - Clean separation with utility modules
- 🧪 Comprehensive Testing - Unit tests with coverage reporting
- 🚀 Automated CI/CD - GitHub Actions for testing, building, and deployment
- 📊 Smart Routing - Handles both GitHub webhooks and scheduled sync operations
- 🐳 Containerized - Uses official Safe Settings source with Lambda adapter
- ⚡ Serverless - Pay only for execution time, auto-scaling included
To get started: Click "Use this template" on the repository page to create your own deployment.
The template uses a dual Lambda function architecture:
safe-settings-lambda: Handles GitHub webhook events via Function URLsafe-settings-scheduler: Handles scheduled sync operations via EventBridge- Shared Docker Image: Both functions use the same container with different entry points
- Smart Handler Routing: Automatically routes events to appropriate handlers
- AWS Account with ECR and Lambda access
- GitHub repository with Actions enabled
- Node.js 20+ (Latest LTS recommended) for local development
- npm 10+ (comes with Node.js 20+)
- GitHub App created with proper permissions
- Go to SafeSettings-Template
- Click "Use this template" button
- Create a new repository in your organization
- Clone your new repository locally
Create the required AWS resources:
# Create ECR repository
aws ecr create-repository --repository-name safe-settings-lambda --region YOUR_AWS_REGION
# Create main Lambda function for webhooks
aws lambda create-function \
--function-name safe-settings-lambda \
--code ImageUri=YOUR_ACCOUNT.dkr.ecr.YOUR_AWS_REGION.amazonaws.com/safe-settings-lambda:latest \
--role arn:aws:iam::YOUR_ACCOUNT:role/lambda-execution-role \
--package-type Image \
--timeout 30 \
--memory-size 512 \
--image-config '{"Command":["safe-settings-handler.webhooks"]}'
# Create scheduler Lambda function (same image, different handler)
aws lambda create-function \
--function-name safe-settings-scheduler \
--code ImageUri=YOUR_ACCOUNT.dkr.ecr.YOUR_AWS_REGION.amazonaws.com/safe-settings-lambda:latest \
--role arn:aws:iam::YOUR_ACCOUNT:role/lambda-execution-role \
--package-type Image \
--timeout 60 \
--memory-size 512 \
--image-config '{"Command":["safe-settings-handler.scheduler"]}'
# Create Function URL for GitHub webhooks
aws lambda create-function-url-config \
--function-name safe-settings-lambda \
--auth-type NONE \
--cors '{"AllowOrigins":["*"],"AllowMethods":["POST"]}'Configure these in your GitHub repository settings → Variables:
AWS_REGION=your-aws-region
AWS_ACCOUNT_ID=your-aws-account-id
ECR_REPOSITORY=safe-settings-lambda
LAMBDA_FUNCTION_NAME=safe-settings-lambda
SCHEDULER_FUNCTION_NAME=safe-settings-scheduler
GH_ORG=your-organization
APP_ID=your-github-app-id
WEBHOOK_SECRET=your-webhook-secret
SAFE_SETTINGS_GITHUB_CLIENT_ID=your-client-id
Configure these in your GitHub repository settings → Secrets:
PRIVATE_KEY=your-github-app-private-key
SAFE_SETTINGS_GITHUB_CLIENT_SECRET=your-client-secret
Push to the master branch to trigger automatic deployment:
git push origin masterThe GitHub Actions workflow will:
- Run tests and generate coverage reports
- Build the Docker image using multi-stage build
- Push to ECR with SHA and latest tags
- Update both Lambda functions
- Configure environment variables
The template includes:
├── safe-settings-handler.js # Main Lambda handler with smart routing
├── utils/
│ └── keyUtils.js # Private key validation & normalization
├── tests/
│ ├── keyUtils.test.js # Unit tests for key utilities
│ └── simple-integration.test.js # Integration tests
├── .github/workflows/
│ ├── test.yml # CI/CD pipeline for testing & building
│ └── deploy_to_lambda.yml # Production deployment workflow
├── Dockerfile # Multi-stage Lambda container build
└── package.json # Dependencies & test configuration
The main handler intelligently routes events:
// EventBridge scheduled events → Scheduler handler
if (event.source === 'aws.events' || event.sync === true) {
return await schedulerHandler(event, context)
}
// GitHub webhooks → Webhook handler
return await webhookHandler(event, context)# Install dependencies
npm install
# Run all tests
npm test
# Run tests with coverage
npm run test:coverage
# Run tests in watch mode for development
npm run test:watch
# Run specific test file
npx jest tests/keyUtils.test.jsSet up EventBridge to trigger periodic syncs:
# Create EventBridge rule for scheduled sync
aws events put-rule \
--name safe-settings-sync-schedule \
--schedule-expression "rate(5 minutes)"
# Add Lambda target (scheduler function)
aws events put-targets \
--rule safe-settings-sync-schedule \
--targets "Id"="1","Arn"="arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT:function:safe-settings-scheduler"
# Grant EventBridge permission to invoke Lambda
aws lambda add-permission \
--function-name safe-settings-scheduler \
--statement-id allow-eventbridge \
--action lambda:InvokeFunction \
--principal events.amazonaws.com \
--source-arn arn:aws:events:YOUR_AWS_REGION:YOUR_ACCOUNT:rule/safe-settings-sync-scheduleTrigger a manual sync operation:
# Invoke with sync flag
aws lambda invoke \
--function-name safe-settings-lambda \
--payload '{"sync": true}' \
response.jsonThe template uses a multi-stage Docker build:
- Stage 1: Copies the official Safe Settings source from
ghcr.io/github/safe-settings:2.1.17 - Stage 2: Creates Lambda runtime with Node.js 20, adds the Probot Lambda adapter, and includes the custom handler
Both Lambda functions use the same Docker image but with different entry points:
- Webhook function:
safe-settings-handler.webhooks - Scheduler function:
safe-settings-handler.scheduler
- Webhook Handler: Processes GitHub webhook events using Probot
- Scheduler Handler: Handles EventBridge scheduled sync operations
- Development Support: Includes mock functionality for local testing
- Error Handling: Comprehensive error logging with request IDs
- Unit Tests: Jest-based test suite with coverage reporting
- Integration Tests: Validates module loading and file structure
- CI/CD Pipeline: Automated testing on every PR and push
- Security Scanning: Automated security audits and secret detection
Monitor Lambda execution:
# View recent logs (replace with your function name)
aws logs tail /aws/lambda/safe-settings-lambda --follow
# Filter for errors
aws logs filter-log-events \
--log-group-name /aws/lambda/safe-settings-lambda \
--filter-pattern "ERROR"Monitor deployments and test results in the Actions tab of your repository. Each PR will automatically:
- Run tests on Node.js 20
- Generate coverage reports
- Comment with test results
- Validate Docker builds
- Run security audits
- Module not found errors: Ensure
utils/directory is included in Dockerfile - Environment variables: Verify all required secrets are set in GitHub repository settings
- Permissions: Check IAM roles have ECR and Lambda access
- Webhook URL: Use the Lambda Function URL as your GitHub App webhook URL
- Docker build failures: Check that the base image
ghcr.io/github/safe-settings:2.1.17is accessible
Enable debug logging by setting LOG_LEVEL=debug in the Lambda environment variables.
- Handler routing: Verify the handler commands are correctly set:
- Webhook function:
safe-settings-handler.webhooks - Scheduler function:
safe-settings-handler.scheduler
- Webhook function:
- GitHub Actions failures: Check that all required repository variables and secrets are configured
- ECR push failures: Ensure AWS credentials have ECR push permissions
✅ Production Ready: Battle-tested deployment pattern
✅ Fully Generic: No organization-specific code
✅ Comprehensive Documentation: Step-by-step setup guide
✅ CI/CD Included: GitHub Actions workflows
✅ Local Development: Mock implementation for testing
✅ Multi-Environment: Template supports staging/production
✅ Security Focused: IAM roles, secrets management
✅ Monitoring Ready: CloudWatch integration
For template-specific issues:
- Check the SafeSettings-Template repository for updates
- Review GitHub Actions logs for deployment failures
- Verify AWS resource configuration matches the template requirements
For general safe-settings issues, refer to the main README and deployment guide.