@thunder-so/thunder 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.kiro/settings/lsp.json +198 -0
- package/README.md +60 -118
- package/docs/fargate-basic.md +222 -0
- package/docs/fargate-full.md +177 -0
- package/docs/fargate-nixpacks.md +199 -0
- package/docs/frameworks/analogjs-fargate.md +115 -0
- package/docs/frameworks/analogjs-serverless.md +121 -0
- package/docs/frameworks/astro-fargate.md +120 -0
- package/docs/frameworks/astro-serverless.md +112 -0
- package/docs/frameworks/astro-static.md +108 -0
- package/docs/frameworks/nextjs-fargate-dockerfile.md +227 -0
- package/docs/frameworks/nextjs-fargate-nixpacks.md +113 -0
- package/docs/frameworks/nextjs-static.md +160 -0
- package/docs/frameworks/nuxt-fargate.md +115 -0
- package/docs/frameworks/nuxt-serverless.md +122 -0
- package/docs/frameworks/solidstart-fargate.md +115 -0
- package/docs/frameworks/solidstart-serverless.md +116 -0
- package/docs/frameworks/sveltekit-fargate.md +130 -0
- package/docs/frameworks/sveltekit-serverless.md +120 -0
- package/docs/frameworks/tanstack-start-fargate.md +115 -0
- package/docs/frameworks/tanstack-start-serverless.md +205 -0
- package/docs/lambda-basic.md +178 -0
- package/docs/lambda-containers.md +179 -0
- package/docs/lambda-full.md +185 -0
- package/docs/serverless.md +267 -0
- package/docs/static-basic.md +151 -0
- package/docs/static-edge-functions.md +187 -0
- package/docs/static-full.md +145 -0
- package/index.ts +8 -8
- package/package.json +1 -1
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Deploy a Serverless API with AWS Lambda and API Gateway
|
|
2
|
+
|
|
3
|
+
Run your Node.js backend on [AWS Lambda](https://aws.amazon.com/lambda/) with an [API Gateway HTTP API](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html) as the public endpoint. No servers to provision, scales to zero when idle, and pay only for what you use.
|
|
4
|
+
|
|
5
|
+
Works with any framework that exports a Lambda handler: [Express.js](https://expressjs.com/), [Hono](https://hono.dev/), [Fastify](https://fastify.dev/), [NestJS](https://nestjs.com/), [Koa](https://koajs.com/), and more.
|
|
6
|
+
|
|
7
|
+
## AWS Resources
|
|
8
|
+
|
|
9
|
+
| Resource | Purpose |
|
|
10
|
+
|---|---|
|
|
11
|
+
| [Lambda Function](https://aws.amazon.com/lambda/) | Runs your server code |
|
|
12
|
+
| [API Gateway HTTP API](https://aws.amazon.com/api-gateway/) | Public HTTP endpoint, routes all traffic to Lambda |
|
|
13
|
+
| [CloudWatch Logs](https://aws.amazon.com/cloudwatch/) | Function logs, retained for 1 month |
|
|
14
|
+
| [ACM Certificate](https://aws.amazon.com/certificate-manager/) | SSL for custom domain (optional) |
|
|
15
|
+
| [Route53](https://aws.amazon.com/route53/) | DNS A + AAAA records (optional) |
|
|
16
|
+
|
|
17
|
+
## Prerequisites
|
|
18
|
+
|
|
19
|
+
- [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html) configured
|
|
20
|
+
- [AWS CDK](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) bootstrapped:
|
|
21
|
+
```bash
|
|
22
|
+
cdk bootstrap aws://YOUR_ACCOUNT_ID/us-east-1
|
|
23
|
+
```
|
|
24
|
+
- Your function built to a `dist/` directory with an `index.handler` export
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
bun add @thunder-so/thunder --development
|
|
30
|
+
# or
|
|
31
|
+
npm install @thunder-so/thunder --save-dev
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Handler Requirements
|
|
35
|
+
|
|
36
|
+
Your Lambda handler must follow the [AWS Lambda handler signature](https://docs.aws.amazon.com/lambda/latest/dg/nodejs-handler.html). For HTTP APIs, use the v2 payload format:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
// src/index.ts
|
|
40
|
+
export const handler = async (event: any) => {
|
|
41
|
+
return {
|
|
42
|
+
statusCode: 200,
|
|
43
|
+
body: JSON.stringify({ message: 'Hello from Lambda' }),
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
For Express/Hono/Fastify, use an adapter like [`@hono/node-server`](https://hono.dev/docs/getting-started/aws-lambda) or [`serverless-http`](https://github.com/dougmoscrop/serverless-http):
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// src/index.ts (Hono example)
|
|
52
|
+
import { Hono } from 'hono';
|
|
53
|
+
import { handle } from 'hono/aws-lambda';
|
|
54
|
+
|
|
55
|
+
const app = new Hono();
|
|
56
|
+
app.get('/', (c) => c.json({ message: 'Hello' }));
|
|
57
|
+
|
|
58
|
+
export const handler = handle(app);
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Stack File
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { Cdk, Lambda, type LambdaProps } from '@thunder-so/thunder';
|
|
65
|
+
|
|
66
|
+
const config: LambdaProps = {
|
|
67
|
+
env: {
|
|
68
|
+
account: '123456789012',
|
|
69
|
+
region: 'us-east-1',
|
|
70
|
+
},
|
|
71
|
+
application: 'myapp',
|
|
72
|
+
service: 'api',
|
|
73
|
+
environment: 'dev',
|
|
74
|
+
|
|
75
|
+
rootDir: '.',
|
|
76
|
+
|
|
77
|
+
functionProps: {
|
|
78
|
+
runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
|
|
79
|
+
architecture: Cdk.aws_lambda.Architecture.ARM_64,
|
|
80
|
+
codeDir: 'dist', // directory containing your built handler
|
|
81
|
+
handler: 'index.handler',
|
|
82
|
+
memorySize: 512,
|
|
83
|
+
timeout: 10,
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
new Lambda(
|
|
88
|
+
new Cdk.App(),
|
|
89
|
+
`${config.application}-${config.service}-${config.environment}-stack`,
|
|
90
|
+
config
|
|
91
|
+
);
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Deploy
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Build your app first
|
|
98
|
+
npm run build
|
|
99
|
+
|
|
100
|
+
# Deploy
|
|
101
|
+
npx cdk deploy --app "npx tsx stack/dev.ts" --profile default
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
CDK outputs the API Gateway URL:
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
Outputs:
|
|
108
|
+
myapp-api-dev-stack.ApiGatewayUrl = https://abc123.execute-api.us-east-1.amazonaws.com
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Custom Domain (Optional)
|
|
112
|
+
|
|
113
|
+
1. [Create a Route53 Hosted Zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/AboutHZWorkingWith.html)
|
|
114
|
+
2. [Request an ACM certificate](https://docs.aws.amazon.com/acm/latest/userguide/gs-acm-request-public.html) in the **same region as your function**
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const config: LambdaProps = {
|
|
118
|
+
// ...
|
|
119
|
+
domain: 'api.example.com',
|
|
120
|
+
regionalCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/abc-123',
|
|
121
|
+
hostedZoneId: 'Z1234567890ABC',
|
|
122
|
+
};
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
> Unlike Static, the Lambda certificate must be **regional** (same region as the function), not global.
|
|
126
|
+
|
|
127
|
+
## Environment Variables
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
functionProps: {
|
|
131
|
+
// ...
|
|
132
|
+
variables: [
|
|
133
|
+
{ NODE_ENV: 'production' },
|
|
134
|
+
{ API_BASE_URL: 'https://api.example.com' },
|
|
135
|
+
],
|
|
136
|
+
},
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Secrets from AWS Secrets Manager
|
|
140
|
+
|
|
141
|
+
Store sensitive values in [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) and inject them as environment variables at deploy time:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
aws secretsmanager create-secret \
|
|
145
|
+
--name "/myapp/DATABASE_URL" \
|
|
146
|
+
--secret-string "postgres://user:pass@host/db"
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```typescript
|
|
150
|
+
functionProps: {
|
|
151
|
+
// ...
|
|
152
|
+
secrets: [
|
|
153
|
+
{ key: 'DATABASE_URL', resource: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:/myapp/DATABASE_URL-abc123' },
|
|
154
|
+
],
|
|
155
|
+
},
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Thunder automatically grants the Lambda execution role `secretsmanager:GetSecretValue` on each secret.
|
|
159
|
+
|
|
160
|
+
## Stack Outputs
|
|
161
|
+
|
|
162
|
+
| Output | Description |
|
|
163
|
+
|---|---|
|
|
164
|
+
| `ApiGatewayUrl` | API Gateway endpoint URL |
|
|
165
|
+
| `LambdaFunction` | Lambda function name |
|
|
166
|
+
| `LambdaFunctionUrl` | Direct Lambda URL (only if `url: true`) |
|
|
167
|
+
| `Route53Domain` | Custom domain URL (only if domain is configured) |
|
|
168
|
+
|
|
169
|
+
## Destroy
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
npx cdk destroy --app "npx tsx stack/dev.ts" --profile default
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Next Steps
|
|
176
|
+
|
|
177
|
+
- [lambda-containers.md](./lambda-containers.md) - Container images and Bun runtime with Lambda
|
|
178
|
+
- [lambda-full.md](./lambda-full.md) - Full configuration reference
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
# AWS Lambda with Container Images and Bun Runtime
|
|
2
|
+
|
|
3
|
+
Deploy AWS Lambda functions as Docker container images to use custom runtimes like [Bun](https://bun.sh/), ship larger packages, or include system-level dependencies. Thunder builds and pushes the image to [Amazon ECR](https://aws.amazon.com/ecr/) automatically during `cdk deploy`.
|
|
4
|
+
|
|
5
|
+
Use container Lambda when:
|
|
6
|
+
|
|
7
|
+
- Your deployment package exceeds the 250 MB zip limit
|
|
8
|
+
- You need a runtime not natively supported by Lambda (e.g. Bun)
|
|
9
|
+
- You want to use system-level dependencies (native modules, binaries)
|
|
10
|
+
## Node.js Container Image
|
|
11
|
+
|
|
12
|
+
### 1. Create a Dockerfile
|
|
13
|
+
|
|
14
|
+
```dockerfile
|
|
15
|
+
# Dockerfile
|
|
16
|
+
FROM public.ecr.aws/lambda/nodejs:22 AS builder
|
|
17
|
+
WORKDIR ${LAMBDA_TASK_ROOT}
|
|
18
|
+
|
|
19
|
+
COPY . .
|
|
20
|
+
RUN npm ci
|
|
21
|
+
RUN npm run build
|
|
22
|
+
|
|
23
|
+
FROM public.ecr.aws/lambda/nodejs:22
|
|
24
|
+
WORKDIR ${LAMBDA_TASK_ROOT}
|
|
25
|
+
|
|
26
|
+
COPY --from=builder /var/task/dist/ ./
|
|
27
|
+
COPY --from=builder /var/task/node_modules ./node_modules
|
|
28
|
+
|
|
29
|
+
CMD ["index.handler"]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### 2. Stack File
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
import { Cdk, Lambda, type LambdaProps } from '@thunder-so/thunder';
|
|
36
|
+
|
|
37
|
+
const config: LambdaProps = {
|
|
38
|
+
env: { account: '123456789012', region: 'us-east-1' },
|
|
39
|
+
application: 'myapp',
|
|
40
|
+
service: 'api',
|
|
41
|
+
environment: 'prod',
|
|
42
|
+
rootDir: '.',
|
|
43
|
+
|
|
44
|
+
functionProps: {
|
|
45
|
+
dockerFile: 'Dockerfile', // path relative to rootDir
|
|
46
|
+
memorySize: 1792,
|
|
47
|
+
timeout: 10,
|
|
48
|
+
variables: [{ NODE_ENV: 'production' }],
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
new Lambda(new Cdk.App(), 'myapp-api-prod-stack', config);
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
> When `dockerFile` is set, `runtime`, `architecture`, `codeDir`, `handler`, `include`, and `exclude` are ignored - the Dockerfile controls the build entirely.
|
|
56
|
+
|
|
57
|
+
## Bun Runtime Container Image
|
|
58
|
+
|
|
59
|
+
[Bun](https://bun.sh/) is a fast JavaScript runtime with native TypeScript support. Since Lambda doesn't have a managed Bun runtime, you deploy it as a container.
|
|
60
|
+
|
|
61
|
+
### 1. Create the Bun Dockerfile
|
|
62
|
+
|
|
63
|
+
```dockerfile
|
|
64
|
+
# Dockerfile.bun
|
|
65
|
+
|
|
66
|
+
# Stage 1: Build the Bun Lambda bootstrap
|
|
67
|
+
FROM oven/bun:latest AS bun
|
|
68
|
+
WORKDIR /tmp
|
|
69
|
+
RUN apt-get update && apt-get install -y curl
|
|
70
|
+
RUN curl -fsSL https://raw.githubusercontent.com/oven-sh/bun/main/packages/bun-lambda/runtime.ts -o runtime.ts
|
|
71
|
+
RUN bun install aws4fetch
|
|
72
|
+
RUN bun build --compile runtime.ts --outfile bootstrap
|
|
73
|
+
|
|
74
|
+
# Stage 2: Build your app
|
|
75
|
+
FROM oven/bun:latest AS builder
|
|
76
|
+
WORKDIR /tmp
|
|
77
|
+
COPY . .
|
|
78
|
+
RUN bun install
|
|
79
|
+
RUN bun run build
|
|
80
|
+
|
|
81
|
+
# Stage 3: Runtime image
|
|
82
|
+
FROM public.ecr.aws/lambda/provided:al2023
|
|
83
|
+
WORKDIR ${LAMBDA_TASK_ROOT}
|
|
84
|
+
|
|
85
|
+
COPY --from=bun /usr/local/bin/bun /opt/bun
|
|
86
|
+
COPY --from=bun /tmp/bootstrap ${LAMBDA_RUNTIME_DIR}
|
|
87
|
+
COPY --from=builder /tmp/dist/ ./
|
|
88
|
+
COPY --from=builder /tmp/node_modules ./node_modules
|
|
89
|
+
COPY --from=builder /tmp/lambda-bun.js ./lambda-bun.js
|
|
90
|
+
|
|
91
|
+
CMD ["lambda-bun.fetch"]
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### 2. Create the Bun Handler Shim
|
|
95
|
+
|
|
96
|
+
Bun's Lambda runtime expects a `fetch`-compatible handler:
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
// lambda-bun.js
|
|
100
|
+
const { handler } = require('./index.js');
|
|
101
|
+
exports.fetch = handler;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
If you're using [Hono](https://hono.dev/) with Bun:
|
|
105
|
+
|
|
106
|
+
```typescript
|
|
107
|
+
// src/index.ts
|
|
108
|
+
import { Hono } from 'hono';
|
|
109
|
+
|
|
110
|
+
const app = new Hono();
|
|
111
|
+
app.get('/', (c) => c.json({ ok: true }));
|
|
112
|
+
|
|
113
|
+
export default app; // Bun's fetch handler
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 3. Stack File
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
import { Cdk, Lambda, type LambdaProps } from '@thunder-so/thunder';
|
|
120
|
+
|
|
121
|
+
const config: LambdaProps = {
|
|
122
|
+
env: { account: '123456789012', region: 'us-east-1' },
|
|
123
|
+
application: 'myapp',
|
|
124
|
+
service: 'api',
|
|
125
|
+
environment: 'prod',
|
|
126
|
+
rootDir: '.',
|
|
127
|
+
|
|
128
|
+
functionProps: {
|
|
129
|
+
dockerFile: 'Dockerfile.bun',
|
|
130
|
+
memorySize: 512,
|
|
131
|
+
timeout: 10,
|
|
132
|
+
keepWarm: true,
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
new Lambda(new Cdk.App(), 'myapp-api-prod-stack', config);
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Docker Build Arguments
|
|
140
|
+
|
|
141
|
+
Pass build-time arguments to your Dockerfile:
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
functionProps: {
|
|
145
|
+
dockerFile: 'Dockerfile',
|
|
146
|
+
dockerBuildArgs: ['NODE_ENV=production', 'APP_VERSION=1.2.3'],
|
|
147
|
+
},
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
In your Dockerfile:
|
|
151
|
+
```dockerfile
|
|
152
|
+
ARG NODE_ENV
|
|
153
|
+
ARG APP_VERSION
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
## Keep Warm
|
|
157
|
+
|
|
158
|
+
Container Lambdas have longer cold starts than zip-based functions. Use `keepWarm` to schedule an EventBridge ping every 5 minutes:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
functionProps: {
|
|
162
|
+
dockerFile: 'Dockerfile',
|
|
163
|
+
keepWarm: true,
|
|
164
|
+
},
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
This creates an [EventBridge rule](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-rules.html) that invokes the function with a synthetic API Gateway v2 event.
|
|
168
|
+
|
|
169
|
+
## Notes on Container Deployments
|
|
170
|
+
|
|
171
|
+
- The entire `rootDir` is used as the Docker build context
|
|
172
|
+
- CDK builds and pushes the image to [Amazon ECR](https://aws.amazon.com/ecr/) automatically during `cdk deploy`
|
|
173
|
+
- `timeout`, `memorySize`, `tracing`, `keepWarm`, `variables`, and `secrets` all work the same as zip deployments
|
|
174
|
+
- For more on Lambda container images, see the [AWS docs](https://docs.aws.amazon.com/lambda/latest/dg/images-create.html)
|
|
175
|
+
|
|
176
|
+
## Related
|
|
177
|
+
|
|
178
|
+
- [lambda-basic.md](./lambda-basic.md) - Basic zip-based deployment
|
|
179
|
+
- [lambda-full.md](./lambda-full.md) - Full configuration reference
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# Lambda Configuration Reference
|
|
2
|
+
|
|
3
|
+
Complete reference for every option available in the `Lambda` construct. Covers zip and container deployments, concurrency, secrets, custom domains, and VPC integration. For a quick start see [lambda-basic.md](./lambda-basic.md).
|
|
4
|
+
|
|
5
|
+
## Examples
|
|
6
|
+
|
|
7
|
+
### Zip Deployment
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { Cdk, Lambda, type LambdaProps } from '@thunder-so/thunder';
|
|
11
|
+
|
|
12
|
+
const config: LambdaProps = {
|
|
13
|
+
env: { account: '123456789012', region: 'us-east-1' },
|
|
14
|
+
application: 'myapp',
|
|
15
|
+
service: 'api',
|
|
16
|
+
environment: 'prod',
|
|
17
|
+
rootDir: '.',
|
|
18
|
+
|
|
19
|
+
domain: 'api.example.com',
|
|
20
|
+
regionalCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/abc-123',
|
|
21
|
+
hostedZoneId: 'Z1234567890ABC',
|
|
22
|
+
|
|
23
|
+
functionProps: {
|
|
24
|
+
runtime: Cdk.aws_lambda.Runtime.NODEJS_22_X,
|
|
25
|
+
architecture: Cdk.aws_lambda.Architecture.ARM_64,
|
|
26
|
+
codeDir: 'dist',
|
|
27
|
+
handler: 'index.handler',
|
|
28
|
+
include: ['package.json'],
|
|
29
|
+
exclude: ['**/*.test.js'],
|
|
30
|
+
memorySize: 1792,
|
|
31
|
+
timeout: 10,
|
|
32
|
+
tracing: true,
|
|
33
|
+
reservedConcurrency: 10,
|
|
34
|
+
provisionedConcurrency: 2,
|
|
35
|
+
keepWarm: true,
|
|
36
|
+
url: true,
|
|
37
|
+
variables: [
|
|
38
|
+
{ NODE_ENV: 'production' },
|
|
39
|
+
{ LOG_LEVEL: 'info' },
|
|
40
|
+
],
|
|
41
|
+
secrets: [
|
|
42
|
+
{ key: 'DATABASE_URL', resource: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:/myapp/db-abc123' },
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
new Lambda(new Cdk.App(), 'myapp-api-prod-stack', config);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Container Deployment
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import { Cdk, Lambda, type LambdaProps } from '@thunder-so/thunder';
|
|
54
|
+
|
|
55
|
+
const config: LambdaProps = {
|
|
56
|
+
env: { account: '123456789012', region: 'us-east-1' },
|
|
57
|
+
application: 'myapp',
|
|
58
|
+
service: 'api',
|
|
59
|
+
environment: 'prod',
|
|
60
|
+
rootDir: '.',
|
|
61
|
+
|
|
62
|
+
domain: 'api.example.com',
|
|
63
|
+
regionalCertificateArn: 'arn:aws:acm:us-east-1:123456789012:certificate/abc-123',
|
|
64
|
+
hostedZoneId: 'Z1234567890ABC',
|
|
65
|
+
|
|
66
|
+
functionProps: {
|
|
67
|
+
dockerFile: 'Dockerfile',
|
|
68
|
+
dockerBuildArgs: ['NODE_ENV=production'],
|
|
69
|
+
memorySize: 1792,
|
|
70
|
+
timeout: 10,
|
|
71
|
+
tracing: true,
|
|
72
|
+
keepWarm: true,
|
|
73
|
+
variables: [
|
|
74
|
+
{ NODE_ENV: 'production' },
|
|
75
|
+
],
|
|
76
|
+
secrets: [
|
|
77
|
+
{ key: 'DATABASE_URL', resource: 'arn:aws:secretsmanager:us-east-1:123456789012:secret:/myapp/db-abc123' },
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
new Lambda(new Cdk.App(), 'myapp-api-prod-stack', config);
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Property Reference
|
|
86
|
+
|
|
87
|
+
### Identity (`AppProps`)
|
|
88
|
+
|
|
89
|
+
| Property | Type | Required | Default | Description |
|
|
90
|
+
|---|---|---|---|---|
|
|
91
|
+
| `env.account` | `string` | Yes | - | AWS account ID |
|
|
92
|
+
| `env.region` | `string` | Yes | - | AWS region |
|
|
93
|
+
| `application` | `string` | Yes | - | Project name |
|
|
94
|
+
| `service` | `string` | Yes | - | Service name |
|
|
95
|
+
| `environment` | `string` | Yes | - | Environment label |
|
|
96
|
+
| `rootDir` | `string` | No | `.` | Root of your app |
|
|
97
|
+
| `debug` | `boolean` | No | `false` | Enable verbose logging |
|
|
98
|
+
|
|
99
|
+
### Custom Domain
|
|
100
|
+
|
|
101
|
+
| Property | Type | Description |
|
|
102
|
+
|---|---|---|
|
|
103
|
+
| `domain` | `string` | Public domain, e.g. `api.example.com` |
|
|
104
|
+
| `regionalCertificateArn` | `string` | ACM certificate ARN - **must be in the same region as the function** |
|
|
105
|
+
| `hostedZoneId` | `string` | Route53 hosted zone ID |
|
|
106
|
+
|
|
107
|
+
### `functionProps`
|
|
108
|
+
|
|
109
|
+
#### Zip Deployment
|
|
110
|
+
|
|
111
|
+
| Property | Type | Default | Description |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| `runtime` | `Runtime` | `NODEJS_20_X` | Lambda runtime. See [supported runtimes](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html) |
|
|
114
|
+
| `architecture` | `Architecture` | `ARM_64` | `ARM_64` or `X86_64`. ARM is cheaper and often faster |
|
|
115
|
+
| `codeDir` | `string` | `.` | Directory containing your built handler, relative to `rootDir` |
|
|
116
|
+
| `handler` | `string` | `index.handler` | Handler in `file.export` format |
|
|
117
|
+
| `include` | `string[]` | - | Extra files to copy into `codeDir` before packaging (e.g. `package.json`) |
|
|
118
|
+
| `exclude` | `string[]` | `['**/*.svg', '**/*.map', ...]` | Glob patterns to exclude from the zip |
|
|
119
|
+
|
|
120
|
+
#### Container Deployment
|
|
121
|
+
|
|
122
|
+
| Property | Type | Description |
|
|
123
|
+
|---|---|---|
|
|
124
|
+
| `dockerFile` | `string` | Path to Dockerfile relative to `rootDir`. Enables container mode. |
|
|
125
|
+
| `dockerBuildArgs` | `string[]` | Build args in `KEY=VALUE` format, passed to `docker build --build-arg` |
|
|
126
|
+
|
|
127
|
+
When `dockerFile` is set, `runtime`, `architecture`, `codeDir`, `handler`, `include`, and `exclude` are ignored.
|
|
128
|
+
|
|
129
|
+
#### Performance
|
|
130
|
+
|
|
131
|
+
| Property | Type | Default | Description |
|
|
132
|
+
|---|---|---|---|
|
|
133
|
+
| `memorySize` | `number` | `1792` | Memory in MB. Also controls proportional CPU allocation. [Pricing](https://aws.amazon.com/lambda/pricing/) |
|
|
134
|
+
| `timeout` | `number` | `10` | Max execution time in seconds (max 900) |
|
|
135
|
+
| `tracing` | `boolean` | `false` | Enable [AWS X-Ray](https://aws.amazon.com/xray/) tracing |
|
|
136
|
+
|
|
137
|
+
#### Concurrency
|
|
138
|
+
|
|
139
|
+
| Property | Type | Description |
|
|
140
|
+
|---|---|---|
|
|
141
|
+
| `reservedConcurrency` | `number` | Hard cap on simultaneous executions. Prevents the function from consuming all account concurrency. |
|
|
142
|
+
| `provisionedConcurrency` | `number` | Pre-warmed instances. Eliminates cold starts for latency-sensitive workloads. Incurs additional cost. |
|
|
143
|
+
|
|
144
|
+
See [Lambda concurrency docs](https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html).
|
|
145
|
+
|
|
146
|
+
#### Warm-up
|
|
147
|
+
|
|
148
|
+
| Property | Type | Default | Description |
|
|
149
|
+
|---|---|---|---|
|
|
150
|
+
| `keepWarm` | `boolean` | `false` | Creates an EventBridge rule that pings the function every 5 minutes to prevent cold starts |
|
|
151
|
+
| `url` | `boolean` | `false` | Enables a [Lambda Function URL](https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html) (public, no auth) in addition to API Gateway |
|
|
152
|
+
|
|
153
|
+
#### Environment
|
|
154
|
+
|
|
155
|
+
| Property | Type | Description |
|
|
156
|
+
|---|---|---|
|
|
157
|
+
| `variables` | `Array<{ [key: string]: string }>` | Plain environment variables |
|
|
158
|
+
| `secrets` | `{ key: string; resource: string }[]` | Secrets Manager ARNs injected as env vars. Lambda is automatically granted read access. |
|
|
159
|
+
|
|
160
|
+
### VPC
|
|
161
|
+
|
|
162
|
+
| Property | Type | Description |
|
|
163
|
+
|---|---|---|
|
|
164
|
+
| `vpc` | `IVpc \| IVpcLink` | Attach the Lambda to an existing VPC. Useful for accessing RDS, ElastiCache, or other private resources. |
|
|
165
|
+
|
|
166
|
+
## API Gateway Details
|
|
167
|
+
|
|
168
|
+
- Uses [HTTP API](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api.html) (v2) - lower latency and cost than REST API
|
|
169
|
+
- Routes `GET` and `HEAD /{proxy+}` to the Lambda function
|
|
170
|
+
- No CORS preflight configured by default (add it in your handler if needed)
|
|
171
|
+
- Custom domain uses a regional endpoint with TLS 1.2
|
|
172
|
+
|
|
173
|
+
## Stack Outputs
|
|
174
|
+
|
|
175
|
+
| Output | Description |
|
|
176
|
+
|---|---|
|
|
177
|
+
| `ApiGatewayUrl` | API Gateway endpoint |
|
|
178
|
+
| `LambdaFunction` | Lambda function name |
|
|
179
|
+
| `LambdaFunctionUrl` | Lambda Function URL (only if `url: true`) |
|
|
180
|
+
| `Route53Domain` | Custom domain URL (only if domain is configured) |
|
|
181
|
+
|
|
182
|
+
## Related
|
|
183
|
+
|
|
184
|
+
- [lambda-basic.md](./lambda-basic.md) - Quick start
|
|
185
|
+
- [lambda-containers.md](./lambda-containers.md) - Container images and Bun runtime with Lambda
|