|
| 1 | +# AWS Lambda Deployment Guide |
| 2 | + |
| 3 | +This guide covers deploying safe-settings to AWS Lambda using Docker containers with automated GitHub Actions deployment. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +`safe-settings` can be deployed to AWS Lambda using a containerized approach that provides: |
| 8 | + |
| 9 | +- **Docker-based deployment** using the official Safe Settings source |
| 10 | +- **Dual Lambda functions** for webhooks and scheduled sync operations |
| 11 | +- **GitHub Actions CI/CD** with automated testing and deployment |
| 12 | +- **Production-ready architecture** with proper error handling and monitoring |
| 13 | + |
| 14 | +## Template Repository |
| 15 | + |
| 16 | +For a complete working example, use the [SafeSettings-Template](https://github.com/bheemreddy181/SafeSettings-Template) repository. This template provides: |
| 17 | + |
| 18 | +- **🏗️ Modular Architecture** - Clean separation with utility modules |
| 19 | +- **🧪 Comprehensive Testing** - Unit tests with coverage reporting |
| 20 | +- **🚀 Automated CI/CD** - GitHub Actions for testing, building, and deployment |
| 21 | +- **📊 Smart Routing** - Handles both GitHub webhooks and scheduled sync operations |
| 22 | +- **🐳 Containerized** - Uses official Safe Settings source with Lambda adapter |
| 23 | +- **⚡ Serverless** - Pay only for execution time, auto-scaling included |
| 24 | + |
| 25 | +**To get started**: Click "Use this template" on the repository page to create your own deployment. |
| 26 | + |
| 27 | +## Architecture |
| 28 | + |
| 29 | +The template uses a **dual Lambda function architecture**: |
| 30 | + |
| 31 | +- **`safe-settings-lambda`**: Handles GitHub webhook events via Function URL |
| 32 | +- **`safe-settings-scheduler`**: Handles scheduled sync operations via EventBridge |
| 33 | +- **Shared Docker Image**: Both functions use the same container with different entry points |
| 34 | +- **Smart Handler Routing**: Automatically routes events to appropriate handlers |
| 35 | + |
| 36 | +## Prerequisites |
| 37 | + |
| 38 | +- AWS Account with ECR and Lambda access |
| 39 | +- GitHub repository with Actions enabled |
| 40 | +- **Node.js 20+ (Latest LTS recommended)** for local development |
| 41 | +- npm 10+ (comes with Node.js 20+) |
| 42 | +- GitHub App created with proper permissions |
| 43 | + |
| 44 | +## Quick Setup |
| 45 | + |
| 46 | +### 1. Use the Template |
| 47 | + |
| 48 | +1. Go to [SafeSettings-Template](https://github.com/bheemreddy181/SafeSettings-Template) |
| 49 | +2. Click **"Use this template"** button |
| 50 | +3. Create a new repository in your organization |
| 51 | +4. Clone your new repository locally |
| 52 | + |
| 53 | +### 2. AWS Infrastructure Setup |
| 54 | + |
| 55 | +Create the required AWS resources: |
| 56 | + |
| 57 | +```bash |
| 58 | +# Create ECR repository |
| 59 | +aws ecr create-repository --repository-name safe-settings-lambda --region YOUR_AWS_REGION |
| 60 | + |
| 61 | +# Create main Lambda function for webhooks |
| 62 | +aws lambda create-function \ |
| 63 | + --function-name safe-settings-lambda \ |
| 64 | + --code ImageUri=YOUR_ACCOUNT.dkr.ecr.YOUR_AWS_REGION.amazonaws.com/safe-settings-lambda:latest \ |
| 65 | + --role arn:aws:iam::YOUR_ACCOUNT:role/lambda-execution-role \ |
| 66 | + --package-type Image \ |
| 67 | + --timeout 30 \ |
| 68 | + --memory-size 512 \ |
| 69 | + --image-config '{"Command":["safe-settings-handler.webhooks"]}' |
| 70 | + |
| 71 | +# Create scheduler Lambda function (same image, different handler) |
| 72 | +aws lambda create-function \ |
| 73 | + --function-name safe-settings-scheduler \ |
| 74 | + --code ImageUri=YOUR_ACCOUNT.dkr.ecr.YOUR_AWS_REGION.amazonaws.com/safe-settings-lambda:latest \ |
| 75 | + --role arn:aws:iam::YOUR_ACCOUNT:role/lambda-execution-role \ |
| 76 | + --package-type Image \ |
| 77 | + --timeout 60 \ |
| 78 | + --memory-size 512 \ |
| 79 | + --image-config '{"Command":["safe-settings-handler.scheduler"]}' |
| 80 | + |
| 81 | +# Create Function URL for GitHub webhooks |
| 82 | +aws lambda create-function-url-config \ |
| 83 | + --function-name safe-settings-lambda \ |
| 84 | + --auth-type NONE \ |
| 85 | + --cors '{"AllowOrigins":["*"],"AllowMethods":["POST"]}' |
| 86 | +``` |
| 87 | + |
| 88 | +### 3. GitHub Configuration |
| 89 | + |
| 90 | +#### Repository Variables |
| 91 | +Configure these in your GitHub repository settings → Variables: |
| 92 | + |
| 93 | +``` |
| 94 | +AWS_REGION=your-aws-region |
| 95 | +AWS_ACCOUNT_ID=your-aws-account-id |
| 96 | +ECR_REPOSITORY=safe-settings-lambda |
| 97 | +LAMBDA_FUNCTION_NAME=safe-settings-lambda |
| 98 | +SCHEDULER_FUNCTION_NAME=safe-settings-scheduler |
| 99 | +GH_ORG=your-organization |
| 100 | +APP_ID=your-github-app-id |
| 101 | +WEBHOOK_SECRET=your-webhook-secret |
| 102 | +SAFE_SETTINGS_GITHUB_CLIENT_ID=your-client-id |
| 103 | +``` |
| 104 | + |
| 105 | +#### Repository Secrets |
| 106 | +Configure these in your GitHub repository settings → Secrets: |
| 107 | + |
| 108 | +``` |
| 109 | +PRIVATE_KEY=your-github-app-private-key |
| 110 | +SAFE_SETTINGS_GITHUB_CLIENT_SECRET=your-client-secret |
| 111 | +``` |
| 112 | + |
| 113 | +### 4. Deploy |
| 114 | + |
| 115 | +Push to the `master` branch to trigger automatic deployment: |
| 116 | + |
| 117 | +```bash |
| 118 | +git push origin master |
| 119 | +``` |
| 120 | + |
| 121 | +The GitHub Actions workflow will: |
| 122 | +1. Run tests and generate coverage reports |
| 123 | +2. Build the Docker image using multi-stage build |
| 124 | +3. Push to ECR with SHA and latest tags |
| 125 | +4. Update both Lambda functions |
| 126 | +5. Configure environment variables |
| 127 | + |
| 128 | +## Local Development |
| 129 | + |
| 130 | +### Project Structure |
| 131 | + |
| 132 | +The template includes: |
| 133 | + |
| 134 | +``` |
| 135 | +├── safe-settings-handler.js # Main Lambda handler with smart routing |
| 136 | +├── utils/ |
| 137 | +│ └── keyUtils.js # Private key validation & normalization |
| 138 | +├── tests/ |
| 139 | +│ ├── keyUtils.test.js # Unit tests for key utilities |
| 140 | +│ └── simple-integration.test.js # Integration tests |
| 141 | +├── .github/workflows/ |
| 142 | +│ ├── test.yml # CI/CD pipeline for testing & building |
| 143 | +│ └── deploy_to_lambda.yml # Production deployment workflow |
| 144 | +├── Dockerfile # Multi-stage Lambda container build |
| 145 | +└── package.json # Dependencies & test configuration |
| 146 | +``` |
| 147 | + |
| 148 | +### Handler Logic |
| 149 | + |
| 150 | +The main handler intelligently routes events: |
| 151 | + |
| 152 | +```javascript |
| 153 | +// EventBridge scheduled events → Scheduler handler |
| 154 | +if (event.source === 'aws.events' || event.sync === true) { |
| 155 | + return await schedulerHandler(event, context) |
| 156 | +} |
| 157 | + |
| 158 | +// GitHub webhooks → Webhook handler |
| 159 | +return await webhookHandler(event, context) |
| 160 | +``` |
| 161 | + |
| 162 | +### Running Tests |
| 163 | + |
| 164 | +```bash |
| 165 | +# Install dependencies |
| 166 | +npm install |
| 167 | + |
| 168 | +# Run all tests |
| 169 | +npm test |
| 170 | + |
| 171 | +# Run tests with coverage |
| 172 | +npm run test:coverage |
| 173 | + |
| 174 | +# Run tests in watch mode for development |
| 175 | +npm run test:watch |
| 176 | + |
| 177 | +# Run specific test file |
| 178 | +npx jest tests/keyUtils.test.js |
| 179 | +``` |
| 180 | + |
| 181 | +## Scheduling Sync Operations |
| 182 | + |
| 183 | +Set up EventBridge to trigger periodic syncs: |
| 184 | + |
| 185 | +```bash |
| 186 | +# Create EventBridge rule for scheduled sync |
| 187 | +aws events put-rule \ |
| 188 | + --name safe-settings-sync-schedule \ |
| 189 | + --schedule-expression "rate(5 minutes)" |
| 190 | + |
| 191 | +# Add Lambda target (scheduler function) |
| 192 | +aws events put-targets \ |
| 193 | + --rule safe-settings-sync-schedule \ |
| 194 | + --targets "Id"="1","Arn"="arn:aws:lambda:YOUR_AWS_REGION:YOUR_ACCOUNT:function:safe-settings-scheduler" |
| 195 | + |
| 196 | +# Grant EventBridge permission to invoke Lambda |
| 197 | +aws lambda add-permission \ |
| 198 | + --function-name safe-settings-scheduler \ |
| 199 | + --statement-id allow-eventbridge \ |
| 200 | + --action lambda:InvokeFunction \ |
| 201 | + --principal events.amazonaws.com \ |
| 202 | + --source-arn arn:aws:events:YOUR_AWS_REGION:YOUR_ACCOUNT:rule/safe-settings-sync-schedule |
| 203 | +``` |
| 204 | + |
| 205 | +### Manual Sync |
| 206 | + |
| 207 | +Trigger a manual sync operation: |
| 208 | + |
| 209 | +```bash |
| 210 | +# Invoke with sync flag |
| 211 | +aws lambda invoke \ |
| 212 | + --function-name safe-settings-lambda \ |
| 213 | + --payload '{"sync": true}' \ |
| 214 | + response.json |
| 215 | +``` |
| 216 | + |
| 217 | +## Container Architecture |
| 218 | + |
| 219 | +The template uses a **multi-stage Docker build**: |
| 220 | + |
| 221 | +1. **Stage 1**: Copies the official Safe Settings source from `ghcr.io/github/safe-settings:2.1.17` |
| 222 | +2. **Stage 2**: Creates Lambda runtime with Node.js 20, adds the Probot Lambda adapter, and includes the custom handler |
| 223 | + |
| 224 | +Both Lambda functions use the same Docker image but with different entry points: |
| 225 | +- **Webhook function**: `safe-settings-handler.webhooks` |
| 226 | +- **Scheduler function**: `safe-settings-handler.scheduler` |
| 227 | + |
| 228 | +## Features |
| 229 | + |
| 230 | +### Smart Handler Routing |
| 231 | +- **Webhook Handler**: Processes GitHub webhook events using Probot |
| 232 | +- **Scheduler Handler**: Handles EventBridge scheduled sync operations |
| 233 | +- **Development Support**: Includes mock functionality for local testing |
| 234 | +- **Error Handling**: Comprehensive error logging with request IDs |
| 235 | + |
| 236 | +### Testing & Quality |
| 237 | +- **Unit Tests**: Jest-based test suite with coverage reporting |
| 238 | +- **Integration Tests**: Validates module loading and file structure |
| 239 | +- **CI/CD Pipeline**: Automated testing on every PR and push |
| 240 | +- **Security Scanning**: Automated security audits and secret detection |
| 241 | + |
| 242 | +## Monitoring |
| 243 | + |
| 244 | +### CloudWatch Logs |
| 245 | + |
| 246 | +Monitor Lambda execution: |
| 247 | + |
| 248 | +```bash |
| 249 | +# View recent logs (replace with your function name) |
| 250 | +aws logs tail /aws/lambda/safe-settings-lambda --follow |
| 251 | + |
| 252 | +# Filter for errors |
| 253 | +aws logs filter-log-events \ |
| 254 | + --log-group-name /aws/lambda/safe-settings-lambda \ |
| 255 | + --filter-pattern "ERROR" |
| 256 | +``` |
| 257 | + |
| 258 | +### GitHub Actions |
| 259 | + |
| 260 | +Monitor deployments and test results in the Actions tab of your repository. Each PR will automatically: |
| 261 | + |
| 262 | +- Run tests on Node.js 20 |
| 263 | +- Generate coverage reports |
| 264 | +- Comment with test results |
| 265 | +- Validate Docker builds |
| 266 | +- Run security audits |
| 267 | + |
| 268 | +## Troubleshooting |
| 269 | + |
| 270 | +### Common Issues |
| 271 | + |
| 272 | +1. **Module not found errors**: Ensure `utils/` directory is included in Dockerfile |
| 273 | +2. **Environment variables**: Verify all required secrets are set in GitHub repository settings |
| 274 | +3. **Permissions**: Check IAM roles have ECR and Lambda access |
| 275 | +4. **Webhook URL**: Use the Lambda Function URL as your GitHub App webhook URL |
| 276 | +5. **Docker build failures**: Check that the base image `ghcr.io/github/safe-settings:2.1.17` is accessible |
| 277 | + |
| 278 | +### Debug Mode |
| 279 | + |
| 280 | +Enable debug logging by setting `LOG_LEVEL=debug` in the Lambda environment variables. |
| 281 | + |
| 282 | +### Template-Specific Issues |
| 283 | + |
| 284 | +- **Handler routing**: Verify the handler commands are correctly set: |
| 285 | + - Webhook function: `safe-settings-handler.webhooks` |
| 286 | + - Scheduler function: `safe-settings-handler.scheduler` |
| 287 | +- **GitHub Actions failures**: Check that all required repository variables and secrets are configured |
| 288 | +- **ECR push failures**: Ensure AWS credentials have ECR push permissions |
| 289 | + |
| 290 | +## Template Features |
| 291 | + |
| 292 | +✅ **Production Ready**: Battle-tested deployment pattern |
| 293 | +✅ **Fully Generic**: No organization-specific code |
| 294 | +✅ **Comprehensive Documentation**: Step-by-step setup guide |
| 295 | +✅ **CI/CD Included**: GitHub Actions workflows |
| 296 | +✅ **Local Development**: Mock implementation for testing |
| 297 | +✅ **Multi-Environment**: Template supports staging/production |
| 298 | +✅ **Security Focused**: IAM roles, secrets management |
| 299 | +✅ **Monitoring Ready**: CloudWatch integration |
| 300 | + |
| 301 | +## Support |
| 302 | + |
| 303 | +For template-specific issues: |
| 304 | +- Check the [SafeSettings-Template repository](https://github.com/bheemreddy181/SafeSettings-Template) for updates |
| 305 | +- Review GitHub Actions logs for deployment failures |
| 306 | +- Verify AWS resource configuration matches the template requirements |
| 307 | + |
| 308 | +For general safe-settings issues, refer to the main [README](../README.md) and [deployment guide](deploy.md). |
0 commit comments