@maestro-js/aws-cdk-recipes 1.0.0-alpha.0
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/README.md +391 -0
- package/dist/index.d.ts +2284 -0
- package/dist/index.js +2252 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
## Overview
|
|
2
|
+
|
|
3
|
+
`@maestro-js/aws-cdk-recipes` provides opinionated AWS CDK constructs that simplify deploying cloud infrastructure. Each construct wraps multiple CDK resources behind a concise props interface with sensible defaults, and exposes a `transform` escape hatch for full customization of underlying CDK props.
|
|
4
|
+
|
|
5
|
+
## Quick Setup
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import {
|
|
9
|
+
Vpc,
|
|
10
|
+
Cluster,
|
|
11
|
+
Bucket,
|
|
12
|
+
MySqlDatabase,
|
|
13
|
+
AuroraDatabase,
|
|
14
|
+
LambdaFunction,
|
|
15
|
+
EcsFargateService,
|
|
16
|
+
StaticSite,
|
|
17
|
+
ReactRouterSsrSiteLambda,
|
|
18
|
+
ReactRouterSsrSiteEcsFargateService,
|
|
19
|
+
ReactRouterEcrImage
|
|
20
|
+
} from '@maestro-js/aws-cdk-recipes'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Package dependencies:
|
|
24
|
+
- `constructs` (dependency)
|
|
25
|
+
- `aws-cdk-lib` (peer dependency, ^2.178.0)
|
|
26
|
+
|
|
27
|
+
## Available Constructs
|
|
28
|
+
|
|
29
|
+
### Vpc
|
|
30
|
+
Multi-AZ VPC with public and private subnets, configurable NAT strategy (none, single, onePerAz, ec2), optional WireGuard VPN, and VPC Flow Logs.
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
const network = new Vpc(this, 'Network', {
|
|
34
|
+
natGateways: 'single',
|
|
35
|
+
wireguard: true
|
|
36
|
+
})
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Key props: `cidr`, `maxAzs`, `natGateways`, `subnetConfiguration`, `wireguard`, `flowLogs`.
|
|
40
|
+
|
|
41
|
+
Exposes: `vpc`, `publicSubnets`, `privateSubnets`, `securityGroup`, `wireguard`, `wireguardPublicKeyParam`.
|
|
42
|
+
|
|
43
|
+
### Cluster
|
|
44
|
+
ECS cluster inside a VPC with optional Fargate capacity providers for Spot pricing.
|
|
45
|
+
|
|
46
|
+
```ts
|
|
47
|
+
const cluster = new Cluster(this, 'Cluster', {
|
|
48
|
+
vpc: network.vpc,
|
|
49
|
+
enableFargateCapacityProviders: true
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Key props: `vpc`, `enableFargateCapacityProviders`, `transform`.
|
|
54
|
+
|
|
55
|
+
Exposes: `cluster`.
|
|
56
|
+
|
|
57
|
+
### Bucket
|
|
58
|
+
S3 bucket with HTTPS enforcement, configurable CORS, lifecycle rules, and custom bucket policies.
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
const uploads = new Bucket(this, 'Uploads', {
|
|
62
|
+
versioning: true,
|
|
63
|
+
lifecycle: [{ prefix: 'tmp/', expiresIn: '7 days' }]
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Key props: `access` (`'public' | 'private'`), `cors`, `versioning`, `enforceHttps`, `lifecycle`, `policy`, `transform`.
|
|
68
|
+
|
|
69
|
+
Exposes: `bucket`.
|
|
70
|
+
|
|
71
|
+
### MySqlDatabase
|
|
72
|
+
RDS MySQL instance in private subnets with encrypted storage, automated backups, and optional RDS Proxy.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const db = new MySqlDatabase(this, 'Database', {
|
|
76
|
+
vpc: network.vpc,
|
|
77
|
+
database: 'ecommerce',
|
|
78
|
+
multiAz: true,
|
|
79
|
+
proxy: true
|
|
80
|
+
})
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Key props: `vpc`, `database`, `username`, `version`, `instance`, `storage`, `multiAz`, `proxy`, `performanceInsights`, `backupRetentionDays`, `deletionProtection`, `transform`.
|
|
84
|
+
|
|
85
|
+
Exposes: `instance`, `securityGroup`, `secret`, `connections`, `rdsProxy`, `host`, `port`, `proxyEndpoint`.
|
|
86
|
+
|
|
87
|
+
### AuroraDatabase
|
|
88
|
+
Aurora Serverless v2 cluster (MySQL or PostgreSQL) with auto-scaling, optional auto-pause, read replicas, and RDS Proxy.
|
|
89
|
+
|
|
90
|
+
```ts
|
|
91
|
+
const db = new AuroraDatabase(this, 'Database', {
|
|
92
|
+
vpc: network.vpc,
|
|
93
|
+
engine: 'postgres',
|
|
94
|
+
version: rds.AuroraPostgresEngineVersion.VER_17_4,
|
|
95
|
+
database: 'myapp',
|
|
96
|
+
scaling: { min: 0, max: 4, pauseAfter: '10 minutes' }
|
|
97
|
+
})
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Key props: `vpc`, `engine` (`'postgres' | 'mysql'`), `version`, `database`, `scaling` (`min`, `max`, `pauseAfter`), `readers`, `proxy`, `dataApi`, `performanceInsights`, `backupRetentionDays`, `deletionProtection`, `transform`.
|
|
101
|
+
|
|
102
|
+
Exposes: `cluster`, `securityGroup`, `secret`, `connections`, `rdsProxy`, `host`, `port`, `readerHost`, `proxyEndpoint`.
|
|
103
|
+
|
|
104
|
+
### LambdaFunction
|
|
105
|
+
Lambda function with esbuild bundling, VPC placement, function URLs, streaming responses, concurrency controls, and IAM permissions.
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
const api = new LambdaFunction(this, 'Api', {
|
|
109
|
+
handler: 'src/api.handler',
|
|
110
|
+
memory: 512,
|
|
111
|
+
url: true
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Supports three modes:
|
|
116
|
+
- **Bundling mode** (default): esbuild bundles from SST-style handler path (`path/to/file.exportName`)
|
|
117
|
+
- **Pre-built code**: pass `code` (a `lambda.Code` asset)
|
|
118
|
+
- **Pre-built directory**: pass `bundle` (path string packaged via `Code.fromAsset`)
|
|
119
|
+
|
|
120
|
+
Key props: `handler`, `code`, `bundle`, `runtime`, `architecture`, `memory`, `timeout`, `storage`, `environment`, `permissions`, `policies`, `vpc`, `concurrency`, `retries`, `streaming`, `versioning`, `url`, `logging`, `tags`, `nodejs` (esbuild options), `hook`, `transform`.
|
|
121
|
+
|
|
122
|
+
Exposes: `function`, `logGroup`, `url`, `version`, `alias`.
|
|
123
|
+
|
|
124
|
+
### EcsFargateService
|
|
125
|
+
Fargate service with task definition, containers, optional ALB, auto-scaling, Spot capacity, and IAM permissions. Supports multi-container sidecars and conditional ALB routing rules.
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
new EcsFargateService(this, 'Api', {
|
|
129
|
+
cluster: cluster.cluster,
|
|
130
|
+
cpu: 512,
|
|
131
|
+
memoryLimitMiB: 1024,
|
|
132
|
+
containers: [{ port: 3000, environment: { NODE_ENV: 'production' } }],
|
|
133
|
+
loadBalancer: {
|
|
134
|
+
domain: { name: 'api.example.com', certificateArn: '...' }
|
|
135
|
+
},
|
|
136
|
+
scaling: { min: 2, max: 10, cpuTarget: 70 }
|
|
137
|
+
})
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Key props: `cluster`, `architecture`, `cpu`, `memoryLimitMiB`, `containers` (array with `name`, `image`, `port`, `environment`, `ssm`, `secrets`, `health`, `logging`), `loadBalancer` (with `domain`, `health`, `rules`), `scaling`, `capacity` (`'spot'` or mixed), `permissions`, `transform`.
|
|
141
|
+
|
|
142
|
+
Exposes: `service`, `taskDefinition`, `containers`, `logGroups`, `securityGroup`, `alb`, `listener`, `targetGroups`.
|
|
143
|
+
|
|
144
|
+
### StaticSite
|
|
145
|
+
Static site (SPA or static HTML) deployed to S3 with CloudFront distribution, custom domain, and configurable cache control.
|
|
146
|
+
|
|
147
|
+
```ts
|
|
148
|
+
new StaticSite(this, 'Website', {
|
|
149
|
+
path: 'dist',
|
|
150
|
+
domain: {
|
|
151
|
+
name: 'example.com',
|
|
152
|
+
aliases: ['www.example.com'],
|
|
153
|
+
certificateArn: 'arn:aws:acm:us-east-1:123456789:certificate/abc-123'
|
|
154
|
+
}
|
|
155
|
+
})
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Key props: `path`, `indexPage`, `errorPage`, `domain`, `assets.fileOptions`, `edge`, `invalidation`, `transform`.
|
|
159
|
+
|
|
160
|
+
Exposes: `bucket`, `distribution`.
|
|
161
|
+
|
|
162
|
+
### ReactRouterSsrSiteLambda
|
|
163
|
+
Full-stack React Router SSR application on Lambda with CloudFront and S3 static assets. Auto-generates a Lambda handler that bridges React Router's `createRequestHandler` to Lambda function URL events, with streaming and buffered response support.
|
|
164
|
+
|
|
165
|
+
Run `react-router build` before deploying.
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
new ReactRouterSsrSiteLambda(this, 'App', {
|
|
169
|
+
domain: {
|
|
170
|
+
name: 'app.example.com',
|
|
171
|
+
certificateArn: 'arn:aws:acm:us-east-1:123456789:certificate/abc-123'
|
|
172
|
+
},
|
|
173
|
+
environment: { DATABASE_URL: 'mysql://...' }
|
|
174
|
+
})
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Key props: `path`, `buildDirectory`, `environment`, `vpc`, `permissions`, `server` (`mode`, `runtime`, `memory`, `timeout`, `architecture`, `layers`, `install`, `external`), `assets`, `domain`, `edge`, `invalidation`, `transform`.
|
|
178
|
+
|
|
179
|
+
Exposes: `lambda`, `functionUrl`, `bucket`, `distribution`.
|
|
180
|
+
|
|
181
|
+
### ReactRouterSsrSiteEcsFargateService
|
|
182
|
+
Full-stack React Router SSR application on ECS Fargate with ALB, CloudFront, and S3 static assets. Auto-generates a Dockerfile when none is provided.
|
|
183
|
+
|
|
184
|
+
Run `react-router build` before deploying.
|
|
185
|
+
|
|
186
|
+
```ts
|
|
187
|
+
new ReactRouterSsrSiteEcsFargateService(this, 'App', {
|
|
188
|
+
cluster: cluster.cluster,
|
|
189
|
+
cpu: 512,
|
|
190
|
+
memoryLimitMiB: 1024,
|
|
191
|
+
domain: {
|
|
192
|
+
name: 'app.example.com',
|
|
193
|
+
certificateArn: 'arn:aws:acm:us-east-1:123456789:certificate/abc-123'
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
Key props: `cluster`, `path`, `buildDirectory`, `image`, `port`, `environment`, `ssm`, `secrets`, `architecture`, `cpu`, `memoryLimitMiB`, `capacity`, `healthCheck`, `scaling`, `permissions`, `assets`, `domain`, `edge`, `invalidation`, `transform`.
|
|
199
|
+
|
|
200
|
+
Exposes: `bucket`, `distribution`, `ecsService`.
|
|
201
|
+
|
|
202
|
+
### ReactRouterEcrImage
|
|
203
|
+
Builds a Docker image for a React Router app and pushes it to ECR. Auto-generates a Dockerfile when none is provided. Use to pre-build an image shared across multiple ECS services.
|
|
204
|
+
|
|
205
|
+
Run `react-router build` before deploying.
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
const image = new ReactRouterEcrImage(this, 'AppImage', {
|
|
209
|
+
path: './packages/web',
|
|
210
|
+
architecture: 'ARM64'
|
|
211
|
+
})
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
Key props: `path`, `buildDirectory`, `port`, `image`, `architecture`, `platform`.
|
|
215
|
+
|
|
216
|
+
Exposes: `asset` (DockerImageAsset).
|
|
217
|
+
|
|
218
|
+
## API Reference
|
|
219
|
+
|
|
220
|
+
### Exports (from `src/index.ts`)
|
|
221
|
+
|
|
222
|
+
```ts
|
|
223
|
+
export { Bucket } from './bucket.ts'
|
|
224
|
+
export { Vpc } from './vpc.ts'
|
|
225
|
+
export { Cluster } from './cluster.ts'
|
|
226
|
+
export { StaticSite } from './static-site.ts'
|
|
227
|
+
export { ReactRouterSsrSiteLambda } from './react-router-ssr-site-lambda.ts'
|
|
228
|
+
export { ReactRouterSsrSiteEcsFargateService } from './react-router-ssr-site-ecs-fargate-service.ts'
|
|
229
|
+
export { ReactRouterEcrImage } from './react-router-ecr-image.ts'
|
|
230
|
+
export { MySqlDatabase } from './mysql-database.ts'
|
|
231
|
+
export { AuroraDatabase } from './aurora-database.ts'
|
|
232
|
+
export { LambdaFunction } from './lambda-function.ts'
|
|
233
|
+
export { EcsFargateService } from './ecs-fargate-service.ts'
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
### Construct Signatures
|
|
237
|
+
|
|
238
|
+
| Construct | Constructor |
|
|
239
|
+
|-----------|------------|
|
|
240
|
+
| `Vpc` | `new Vpc(scope, id, props?: Vpc.Props)` |
|
|
241
|
+
| `Cluster` | `new Cluster(scope, id, props: Cluster.Props)` |
|
|
242
|
+
| `Bucket` | `new Bucket(scope, id, props?: Bucket.Props)` |
|
|
243
|
+
| `MySqlDatabase` | `new MySqlDatabase(scope, id, props: MySqlDatabase.Props)` |
|
|
244
|
+
| `AuroraDatabase` | `new AuroraDatabase(scope, id, props: AuroraDatabase.Props)` |
|
|
245
|
+
| `LambdaFunction` | `new LambdaFunction(scope, id, props: LambdaFunction.Props)` |
|
|
246
|
+
| `EcsFargateService` | `new EcsFargateService(scope, id, props: EcsFargateService.Props)` |
|
|
247
|
+
| `StaticSite` | `new StaticSite(scope, id, props: StaticSite.Props)` |
|
|
248
|
+
| `ReactRouterSsrSiteLambda` | `new ReactRouterSsrSiteLambda(scope, id, props: ReactRouterSsrSiteLambda.Props)` |
|
|
249
|
+
| `ReactRouterSsrSiteEcsFargateService` | `new ReactRouterSsrSiteEcsFargateService(scope, id, props: ReactRouterSsrSiteEcsFargateService.Props)` |
|
|
250
|
+
| `ReactRouterEcrImage` | `new ReactRouterEcrImage(scope, id, props?: ReactRouterEcrImage.Props)` |
|
|
251
|
+
|
|
252
|
+
## Common Patterns
|
|
253
|
+
|
|
254
|
+
### Full-stack application with VPC, database, and API
|
|
255
|
+
|
|
256
|
+
```ts
|
|
257
|
+
const network = new Vpc(this, 'Network', { natGateways: 'single' })
|
|
258
|
+
|
|
259
|
+
const cluster = new Cluster(this, 'Cluster', {
|
|
260
|
+
vpc: network.vpc,
|
|
261
|
+
enableFargateCapacityProviders: true
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
const db = new AuroraDatabase(this, 'Database', {
|
|
265
|
+
vpc: network.vpc,
|
|
266
|
+
engine: 'postgres',
|
|
267
|
+
version: rds.AuroraPostgresEngineVersion.VER_17_4,
|
|
268
|
+
database: 'myapp',
|
|
269
|
+
scaling: { min: 0, max: 4, pauseAfter: '10 minutes' }
|
|
270
|
+
})
|
|
271
|
+
|
|
272
|
+
new EcsFargateService(this, 'Api', {
|
|
273
|
+
cluster: cluster.cluster,
|
|
274
|
+
containers: [{
|
|
275
|
+
port: 3000,
|
|
276
|
+
environment: { DATABASE_HOST: db.host }
|
|
277
|
+
}],
|
|
278
|
+
loadBalancer: {
|
|
279
|
+
domain: { name: 'api.example.com', certificateArn: '...' }
|
|
280
|
+
},
|
|
281
|
+
scaling: { min: 2, max: 10 }
|
|
282
|
+
})
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### React Router SSR on Lambda with custom domain
|
|
286
|
+
|
|
287
|
+
```ts
|
|
288
|
+
new ReactRouterSsrSiteLambda(this, 'App', {
|
|
289
|
+
path: './packages/web',
|
|
290
|
+
server: { mode: 'streaming', memory: 1024 },
|
|
291
|
+
domain: {
|
|
292
|
+
name: 'app.example.com',
|
|
293
|
+
certificateArn: 'arn:aws:acm:us-east-1:123456789:certificate/abc-123'
|
|
294
|
+
},
|
|
295
|
+
environment: { DATABASE_URL: 'mysql://...' }
|
|
296
|
+
})
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
### React Router SSR on ECS Fargate with Spot pricing
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
new ReactRouterSsrSiteEcsFargateService(this, 'App', {
|
|
303
|
+
cluster: cluster.cluster,
|
|
304
|
+
cpu: 512,
|
|
305
|
+
memoryLimitMiB: 1024,
|
|
306
|
+
capacity: 'spot',
|
|
307
|
+
domain: {
|
|
308
|
+
name: 'app.example.com',
|
|
309
|
+
certificateArn: 'arn:aws:acm:us-east-1:123456789:certificate/abc-123'
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
### Transform escape hatch for customizing underlying CDK props
|
|
315
|
+
|
|
316
|
+
Every construct supports a `transform` prop that receives default CDK props and returns modified versions:
|
|
317
|
+
|
|
318
|
+
```ts
|
|
319
|
+
new MySqlDatabase(this, 'Database', {
|
|
320
|
+
vpc: network.vpc,
|
|
321
|
+
database: 'app',
|
|
322
|
+
transform: {
|
|
323
|
+
instance: (props) => ({ ...props, publiclyAccessible: false })
|
|
324
|
+
}
|
|
325
|
+
})
|
|
326
|
+
|
|
327
|
+
new AuroraDatabase(this, 'Database', {
|
|
328
|
+
vpc: network.vpc,
|
|
329
|
+
engine: 'postgres',
|
|
330
|
+
version: rds.AuroraPostgresEngineVersion.VER_17_4,
|
|
331
|
+
database: 'myapp',
|
|
332
|
+
transform: {
|
|
333
|
+
cluster: (props) => ({ ...props, storageType: rds.DBClusterStorageType.AURORA_IOPT1 })
|
|
334
|
+
}
|
|
335
|
+
})
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
### SSM secrets and environment injection in ECS
|
|
339
|
+
|
|
340
|
+
```ts
|
|
341
|
+
new EcsFargateService(this, 'Api', {
|
|
342
|
+
cluster: cluster.cluster,
|
|
343
|
+
containers: [{
|
|
344
|
+
port: 3000,
|
|
345
|
+
environment: { NODE_ENV: 'production' },
|
|
346
|
+
ssm: {
|
|
347
|
+
DATABASE_URL: 'arn:aws:secretsmanager:us-east-1:123456789:secret:db-url',
|
|
348
|
+
API_KEY: '/my-app/api-key'
|
|
349
|
+
}
|
|
350
|
+
}]
|
|
351
|
+
})
|
|
352
|
+
```
|
|
353
|
+
|
|
354
|
+
Values starting with `arn:aws:secretsmanager:` are resolved as Secrets Manager secrets; all others are resolved as SSM SecureString parameters.
|
|
355
|
+
|
|
356
|
+
### Cost-effective VPC with EC2 NAT
|
|
357
|
+
|
|
358
|
+
```ts
|
|
359
|
+
const network = new Vpc(this, 'Network', {
|
|
360
|
+
natGateways: 'ec2',
|
|
361
|
+
maxAzs: 2,
|
|
362
|
+
wireguard: true,
|
|
363
|
+
flowLogs: { retention: RetentionDays.ONE_WEEK }
|
|
364
|
+
})
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
The `'ec2'` NAT option uses a `t4g.nano` instance running the fck-nat AMI (~$3/month vs ~$33/month for managed NAT Gateway).
|
|
368
|
+
|
|
369
|
+
## Cross-Package Integration
|
|
370
|
+
|
|
371
|
+
`@maestro-js/aws-cdk-recipes` is a standalone infrastructure package. It has no dependencies on other Maestro packages. Use it in CDK apps to deploy infrastructure for Maestro-based applications. The React Router constructs auto-generate Dockerfiles and Lambda handlers that work with both monorepo (`pnpm deploy`) and standalone project layouts.
|
|
372
|
+
|
|
373
|
+
## Key Source Files
|
|
374
|
+
|
|
375
|
+
- `packages/aws-cdk-recipes/src/index.ts` - Package exports
|
|
376
|
+
- `packages/aws-cdk-recipes/src/vpc.ts` - Vpc construct
|
|
377
|
+
- `packages/aws-cdk-recipes/src/cluster.ts` - Cluster construct
|
|
378
|
+
- `packages/aws-cdk-recipes/src/bucket.ts` - Bucket construct
|
|
379
|
+
- `packages/aws-cdk-recipes/src/mysql-database.ts` - MySqlDatabase construct
|
|
380
|
+
- `packages/aws-cdk-recipes/src/aurora-database.ts` - AuroraDatabase construct
|
|
381
|
+
- `packages/aws-cdk-recipes/src/lambda-function.ts` - LambdaFunction construct
|
|
382
|
+
- `packages/aws-cdk-recipes/src/ecs-fargate-service.ts` - EcsFargateService construct
|
|
383
|
+
- `packages/aws-cdk-recipes/src/static-site.ts` - StaticSite construct
|
|
384
|
+
- `packages/aws-cdk-recipes/src/react-router-ssr-site-lambda.ts` - ReactRouterSsrSiteLambda construct
|
|
385
|
+
- `packages/aws-cdk-recipes/src/react-router-ssr-site-ecs-fargate-service.ts` - ReactRouterSsrSiteEcsFargateService construct
|
|
386
|
+
- `packages/aws-cdk-recipes/src/react-router-ecr-image.ts` - ReactRouterEcrImage construct
|
|
387
|
+
- `packages/aws-cdk-recipes/src/helpers/cloudfront.ts` - Shared CloudFront/S3 deployment helpers
|
|
388
|
+
- `packages/aws-cdk-recipes/src/helpers/ecs.ts` - Shared ECS helpers (log retention, secrets)
|
|
389
|
+
- `packages/aws-cdk-recipes/src/helpers/docker.ts` - React Router Dockerfile generation
|
|
390
|
+
- `packages/aws-cdk-recipes/src/helpers/ssr-site-lambda.ts` - SSR site Lambda orchestration
|
|
391
|
+
- `packages/aws-cdk-recipes/src/helpers/ssr-site-ecs-service.ts` - SSR site ECS orchestration
|