stacktape 3.5.8 → 3.6.0-beta.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.
Files changed (123) hide show
  1. package/.tsconfig.bun-build.json +1 -0
  2. package/ai-docs/cli-ref/aws-profile-create.md +22 -0
  3. package/ai-docs/cli-ref/aws-profile-delete.md +22 -0
  4. package/ai-docs/cli-ref/aws-profile-list.md +20 -0
  5. package/ai-docs/cli-ref/aws-profile-update.md +22 -0
  6. package/ai-docs/cli-ref/bastion-session.md +29 -0
  7. package/ai-docs/cli-ref/bastion-tunnel.md +30 -0
  8. package/ai-docs/cli-ref/bucket-sync.md +30 -0
  9. package/ai-docs/cli-ref/cf-module-update.md +26 -0
  10. package/ai-docs/cli-ref/cf-rollback.md +28 -0
  11. package/ai-docs/cli-ref/codebuild-deploy.md +34 -0
  12. package/ai-docs/cli-ref/compile-template.md +25 -0
  13. package/ai-docs/cli-ref/container-session.md +30 -0
  14. package/ai-docs/cli-ref/debug-alarms.md +28 -0
  15. package/ai-docs/cli-ref/debug-aws-sdk.md +33 -0
  16. package/ai-docs/cli-ref/debug-container-exec.md +36 -0
  17. package/ai-docs/cli-ref/debug-dynamodb.md +35 -0
  18. package/ai-docs/cli-ref/debug-logs.md +34 -0
  19. package/ai-docs/cli-ref/debug-metrics.md +33 -0
  20. package/ai-docs/cli-ref/debug-opensearch.md +35 -0
  21. package/ai-docs/cli-ref/debug-redis.md +36 -0
  22. package/ai-docs/cli-ref/debug-sql.md +35 -0
  23. package/ai-docs/cli-ref/defaults-configure.md +29 -0
  24. package/ai-docs/cli-ref/defaults-list.md +20 -0
  25. package/ai-docs/cli-ref/delete.md +24 -0
  26. package/ai-docs/cli-ref/deploy.md +25 -0
  27. package/ai-docs/cli-ref/deployment-script-run.md +28 -0
  28. package/ai-docs/cli-ref/dev-stop.md +26 -0
  29. package/ai-docs/cli-ref/dev.md +45 -0
  30. package/ai-docs/cli-ref/domain-add.md +26 -0
  31. package/ai-docs/cli-ref/help.md +18 -0
  32. package/ai-docs/cli-ref/info-operations.md +22 -0
  33. package/ai-docs/cli-ref/info-stack.md +30 -0
  34. package/ai-docs/cli-ref/info-stacks.md +26 -0
  35. package/ai-docs/cli-ref/info-whoami.md +22 -0
  36. package/ai-docs/cli-ref/init.md +30 -0
  37. package/ai-docs/cli-ref/login.md +20 -0
  38. package/ai-docs/cli-ref/logout.md +18 -0
  39. package/ai-docs/cli-ref/mcp-add.md +22 -0
  40. package/ai-docs/cli-ref/mcp.md +20 -0
  41. package/ai-docs/cli-ref/org-create.md +24 -0
  42. package/ai-docs/cli-ref/org-delete.md +24 -0
  43. package/ai-docs/cli-ref/org-list.md +22 -0
  44. package/ai-docs/cli-ref/package-workloads.md +25 -0
  45. package/ai-docs/cli-ref/param-get.md +26 -0
  46. package/ai-docs/cli-ref/preview-changes.md +23 -0
  47. package/ai-docs/cli-ref/project-create.md +22 -0
  48. package/ai-docs/cli-ref/projects-list.md +22 -0
  49. package/ai-docs/cli-ref/rollback.md +28 -0
  50. package/ai-docs/cli-ref/script-run.md +29 -0
  51. package/ai-docs/cli-ref/secret-create.md +28 -0
  52. package/ai-docs/cli-ref/secret-delete.md +26 -0
  53. package/ai-docs/cli-ref/secret-get.md +26 -0
  54. package/ai-docs/cli-ref/upgrade.md +20 -0
  55. package/ai-docs/cli-ref/version.md +18 -0
  56. package/ai-docs/concept/connecting-resources.md +369 -0
  57. package/ai-docs/concept/directives.md +371 -0
  58. package/ai-docs/concept/extending-cloudformation.md +315 -0
  59. package/ai-docs/concept/overrides-and-transforms.md +352 -0
  60. package/ai-docs/concept/stages-and-environments.md +347 -0
  61. package/ai-docs/concept/typescript-config.md +447 -0
  62. package/ai-docs/concept/yaml-config.md +338 -0
  63. package/ai-docs/config-ref/_root.md +142 -0
  64. package/ai-docs/config-ref/application-load-balancer.md +1109 -0
  65. package/ai-docs/config-ref/astro-web.md +115 -0
  66. package/ai-docs/config-ref/aws-cdk-construct.md +68 -0
  67. package/ai-docs/config-ref/bastion.md +93 -0
  68. package/ai-docs/config-ref/batch-job.md +179 -0
  69. package/ai-docs/config-ref/bucket.md +348 -0
  70. package/ai-docs/config-ref/cdn.md +496 -0
  71. package/ai-docs/config-ref/custom-resource.md +80 -0
  72. package/ai-docs/config-ref/deployment-script.md +79 -0
  73. package/ai-docs/config-ref/dynamo-db-table.md +202 -0
  74. package/ai-docs/config-ref/edge-lambda-function.md +87 -0
  75. package/ai-docs/config-ref/efs-filesystem.md +72 -0
  76. package/ai-docs/config-ref/event-bus.md +63 -0
  77. package/ai-docs/config-ref/function.md +409 -0
  78. package/ai-docs/config-ref/hosting-bucket.md +171 -0
  79. package/ai-docs/config-ref/http-api-gateway.md +149 -0
  80. package/ai-docs/config-ref/http-endpoint.md +92 -0
  81. package/ai-docs/config-ref/kinesis-stream.md +97 -0
  82. package/ai-docs/config-ref/mongo-db-atlas-cluster.md +254 -0
  83. package/ai-docs/config-ref/multi-container-workload.md +399 -0
  84. package/ai-docs/config-ref/network-load-balancer.md +118 -0
  85. package/ai-docs/config-ref/nextjs-web.md +147 -0
  86. package/ai-docs/config-ref/nuxt-web.md +81 -0
  87. package/ai-docs/config-ref/open-search.md +206 -0
  88. package/ai-docs/config-ref/private-service.md +75 -0
  89. package/ai-docs/config-ref/redis-cluster.md +223 -0
  90. package/ai-docs/config-ref/relational-database.md +525 -0
  91. package/ai-docs/config-ref/remix-web.md +74 -0
  92. package/ai-docs/config-ref/sns-topic.md +69 -0
  93. package/ai-docs/config-ref/solidstart-web.md +75 -0
  94. package/ai-docs/config-ref/sqs-queue-not-empty.md +405 -0
  95. package/ai-docs/config-ref/sqs-queue.md +232 -0
  96. package/ai-docs/config-ref/state-machine.md +235 -0
  97. package/ai-docs/config-ref/sveltekit-web.md +81 -0
  98. package/ai-docs/config-ref/tanstack-web.md +75 -0
  99. package/ai-docs/config-ref/upstash-redis.md +59 -0
  100. package/ai-docs/config-ref/user-auth-pool.md +876 -0
  101. package/ai-docs/config-ref/web-app-firewall.md +212 -0
  102. package/ai-docs/config-ref/web-service.md +178 -0
  103. package/ai-docs/config-ref/worker-service.md +41 -0
  104. package/ai-docs/getting-started/console.md +232 -0
  105. package/ai-docs/getting-started/deployment.md +434 -0
  106. package/ai-docs/getting-started/dev-mode.md +118 -0
  107. package/ai-docs/getting-started/how-it-works.md +119 -0
  108. package/ai-docs/getting-started/intro.md +157 -0
  109. package/ai-docs/getting-started/using-with-ai.md +228 -0
  110. package/ai-docs/getting-started/workflow.md +197 -0
  111. package/ai-docs/index.json +1514 -0
  112. package/ai-docs/recipe/background-jobs.md +183 -0
  113. package/ai-docs/recipe/database-migrations.md +240 -0
  114. package/ai-docs/recipe/graphql-api.md +211 -0
  115. package/ai-docs/recipe/monorepo-setup.md +183 -0
  116. package/ai-docs/recipe/nextjs-full-stack.md +188 -0
  117. package/ai-docs/recipe/rest-api-with-database.md +156 -0
  118. package/ai-docs/recipe/scheduled-tasks.md +186 -0
  119. package/ai-docs/recipe/static-website.md +241 -0
  120. package/ai-docs/troubleshooting/cloudformation-stack-states.md +189 -0
  121. package/bin/stacktape.js +0 -12
  122. package/package.json +1 -1
  123. package/plain.d.ts +309 -54
@@ -0,0 +1,352 @@
1
+ ---
2
+ docType: concept
3
+ title: Overrides & Transforms
4
+ tags:
5
+ - overrides
6
+ - transforms
7
+ - concept
8
+ source: docs/_curated-docs/concepts/overrides-and-transforms.mdx
9
+ priority: 1
10
+ ---
11
+
12
+ # Overrides & Transforms
13
+
14
+ Stacktape generates CloudFormation templates from your configuration. Sometimes you need to customize the underlying AWS resources beyond what Stacktape exposes. Overrides and transforms give you this power.
15
+
16
+ ## Understanding Child Resources
17
+
18
+ Each Stacktape resource creates one or more CloudFormation resources ("child resources"). For example, a `function` creates:
19
+
20
+ - AWS Lambda Function
21
+ - IAM Role
22
+ - CloudWatch Log Group
23
+ - (Optionally) Event Source Mappings, Permissions, etc.
24
+
25
+ You can view the child resources for any Stacktape resource:
26
+
27
+ ```bash
28
+ stacktape stack-info --stage dev --region us-east-1 --detailed
29
+ ```
30
+
31
+ Or use the Stacktape Console's resource inspector.
32
+
33
+ `[IMAGE PLACEHOLDER: console-child-resources-view]`
34
+
35
+ ## Overrides
36
+
37
+ Overrides let you set specific properties on child CloudFormation resources.
38
+
39
+ ### Basic Override
40
+
41
+ ```yaml
42
+ resources:
43
+ handler:
44
+ type: function
45
+ properties:
46
+ packaging:
47
+ type: stacktape-lambda-buildpack
48
+ properties:
49
+ entryfilePath: ./src/handler.ts
50
+ overrides:
51
+ # Override the Lambda function's description
52
+ StpLambdaFunction:
53
+ Description: 'My custom description'
54
+ ```
55
+
56
+ ### Finding Child Resource Names
57
+
58
+ To override a property, you need to know the logical name of the child resource. Use:
59
+
60
+ 1. **CLI**: `stacktape stack-info --detailed`
61
+ 2. **Console**: View resource details
62
+ 3. **Compile template**: `stacktape compile-template` and inspect the output
63
+
64
+ Common child resource names:
65
+
66
+ | Stacktape Resource | Child Resources |
67
+ | --------------------- | ------------------------------------------------------------------------- |
68
+ | `function` | `StpLambdaFunction`, `StpLambdaFunctionRole`, `StpLambdaFunctionLogGroup` |
69
+ | `web-service` | `StpEcsService`, `StpEcsTaskDefinition`, `StpEcsTaskRole` |
70
+ | `relational-database` | `StpRdsInstance`, `StpRdsSecurityGroup`, `StpRdsSubnetGroup` |
71
+ | `bucket` | `StpS3Bucket` |
72
+ | `http-api-gateway` | `StpHttpApi` |
73
+
74
+ ### Override Example: Lambda Reserved Concurrency
75
+
76
+ ```yaml
77
+ resources:
78
+ handler:
79
+ type: function
80
+ properties:
81
+ packaging:
82
+ type: stacktape-lambda-buildpack
83
+ properties:
84
+ entryfilePath: ./src/handler.ts
85
+ overrides:
86
+ StpLambdaFunction:
87
+ ReservedConcurrentExecutions: 100
88
+ ```
89
+
90
+ ### Override Example: S3 Bucket Policy
91
+
92
+ ```yaml
93
+ resources:
94
+ uploads:
95
+ type: bucket
96
+ properties:
97
+ overrides:
98
+ StpS3Bucket:
99
+ PublicAccessBlockConfiguration:
100
+ BlockPublicAcls: true
101
+ BlockPublicPolicy: true
102
+ IgnorePublicAcls: true
103
+ RestrictPublicBuckets: true
104
+ ```
105
+
106
+ ### Override Example: RDS Parameter Group
107
+
108
+ ```yaml
109
+ resources:
110
+ database:
111
+ type: relational-database
112
+ properties:
113
+ engine:
114
+ type: postgres
115
+ properties:
116
+ version: '16'
117
+ overrides:
118
+ StpRdsParameterGroup:
119
+ Parameters:
120
+ max_connections: '200'
121
+ shared_buffers: '256MB'
122
+ ```
123
+
124
+ ## Transforms
125
+
126
+ Transforms are functions that modify the CloudFormation properties. They're more powerful than overrides because you can compute values based on existing properties.
127
+
128
+ ### Basic Transform
129
+
130
+ ```yaml
131
+ resources:
132
+ handler:
133
+ type: function
134
+ properties:
135
+ packaging:
136
+ type: stacktape-lambda-buildpack
137
+ properties:
138
+ entryfilePath: ./src/handler.ts
139
+ memory: 128
140
+ transforms:
141
+ StpLambdaFunction: |
142
+ (props) => ({
143
+ ...props,
144
+ MemorySize: props.MemorySize * 2 // Double the memory
145
+ })
146
+ ```
147
+
148
+ ### TypeScript Transforms
149
+
150
+ In TypeScript configuration, transforms are cleaner:
151
+
152
+ ```typescript
153
+ import { defineConfig, LambdaFunction, StacktapeLambdaBuildpackPackaging } from 'stacktape';
154
+
155
+ export default defineConfig(() => {
156
+ const handler = new LambdaFunction({
157
+ packaging: new StacktapeLambdaBuildpackPackaging({
158
+ entryfilePath: './src/handler.ts'
159
+ }),
160
+ memory: 128,
161
+ transforms: {
162
+ StpLambdaFunction: (props) => ({
163
+ ...props,
164
+ MemorySize: (props.MemorySize ?? 128) * 2,
165
+ Description: `Handler with ${props.MemorySize}MB memory`
166
+ })
167
+ }
168
+ });
169
+
170
+ return { resources: { handler } };
171
+ });
172
+ ```
173
+
174
+ ### Transform Example: Add Lambda Layers
175
+
176
+ ```typescript
177
+ const handler = new LambdaFunction({
178
+ packaging: new StacktapeLambdaBuildpackPackaging({
179
+ entryfilePath: './src/handler.ts'
180
+ }),
181
+ transforms: {
182
+ StpLambdaFunction: (props) => ({
183
+ ...props,
184
+ Layers: [...(props.Layers || []), 'arn:aws:lambda:us-east-1:123456789:layer:my-layer:1']
185
+ })
186
+ }
187
+ });
188
+ ```
189
+
190
+ ### Transform Example: Custom ECS Task Definition
191
+
192
+ ```typescript
193
+ const api = new WebService({
194
+ packaging: new StacktapeImageBuildpackPackaging({
195
+ entryfilePath: './src/server.ts'
196
+ }),
197
+ transforms: {
198
+ StpEcsTaskDefinition: (props) => ({
199
+ ...props,
200
+ ContainerDefinitions: props.ContainerDefinitions.map((container) => ({
201
+ ...container,
202
+ Ulimits: [{ Name: 'nofile', SoftLimit: 65536, HardLimit: 65536 }]
203
+ }))
204
+ })
205
+ }
206
+ });
207
+ ```
208
+
209
+ ## Overrides vs Transforms
210
+
211
+ | Feature | Overrides | Transforms |
212
+ | -------------- | ----------------------- | ------------------------ |
213
+ | Syntax | Static values | JavaScript function |
214
+ | Use case | Set specific properties | Compute or modify values |
215
+ | Complexity | Simple | More powerful |
216
+ | Merge behavior | Shallow merge | Full control |
217
+
218
+ Use **overrides** when you know the exact value you want to set.
219
+ Use **transforms** when you need to compute values or modify existing properties.
220
+
221
+ ## Viewing Generated CloudFormation
222
+
223
+ To see the final CloudFormation template after overrides and transforms:
224
+
225
+ ```bash
226
+ stacktape compile-template --stage dev --region us-east-1
227
+ ```
228
+
229
+ This outputs `compiled-template.yaml` which you can inspect.
230
+
231
+ ## Adding Raw CloudFormation Resources
232
+
233
+ For resources Stacktape doesn't support, add raw CloudFormation:
234
+
235
+ ```yaml
236
+ resources:
237
+ handler:
238
+ type: function
239
+ properties:
240
+ packaging:
241
+ type: stacktape-lambda-buildpack
242
+ properties:
243
+ entryfilePath: ./src/handler.ts
244
+
245
+ cloudformationResources:
246
+ # Add a custom SNS topic
247
+ MyCustomTopic:
248
+ Type: AWS::SNS::Topic
249
+ Properties:
250
+ TopicName: my-custom-topic
251
+ DisplayName: My Custom Topic
252
+
253
+ # Subscribe the function to the topic
254
+ MyTopicSubscription:
255
+ Type: AWS::SNS::Subscription
256
+ Properties:
257
+ Protocol: lambda
258
+ TopicArn: !Ref MyCustomTopic
259
+ Endpoint: !GetAtt StpHandlerStpLambdaFunction.Arn
260
+ ```
261
+
262
+ Reference CloudFormation resources in Stacktape:
263
+
264
+ ```yaml
265
+ resources:
266
+ handler:
267
+ type: function
268
+ properties:
269
+ environment:
270
+ - name: TOPIC_ARN
271
+ value: $CfResourceParam('MyCustomTopic', 'Arn')
272
+ ```
273
+
274
+ ## AWS CDK Constructs
275
+
276
+ For complex extensions, use AWS CDK constructs:
277
+
278
+ ```typescript
279
+ // cdk/monitoring.ts
280
+ import { Construct } from 'constructs';
281
+ import * as cloudwatch from 'aws-cdk-lib/aws-cloudwatch';
282
+
283
+ export class MonitoringDashboard extends Construct {
284
+ constructor(scope: Construct, id: string) {
285
+ super(scope, id);
286
+
287
+ new cloudwatch.Dashboard(this, 'Dashboard', {
288
+ dashboardName: 'my-app-dashboard',
289
+ widgets: [
290
+ // Dashboard configuration
291
+ ]
292
+ });
293
+ }
294
+ }
295
+ ```
296
+
297
+ Reference in config:
298
+
299
+ ```yaml
300
+ resources:
301
+ handler:
302
+ type: function
303
+
304
+ cdkConstructs:
305
+ - constructPath: ./cdk/monitoring.ts
306
+ constructName: MonitoringDashboard
307
+ ```
308
+
309
+ See [Extending with CDK](/extending/cdk-constructs) for more details.
310
+
311
+ ## Best Practices
312
+
313
+ 1. **Try Stacktape properties first**: Many customizations are available through standard properties
314
+ 2. **Use overrides for simple changes**: Static values that don't depend on other properties
315
+ 3. **Use transforms for computed values**: When you need to modify or compute based on existing values
316
+ 4. **Document your overrides**: Explain why you needed to override
317
+ 5. **Test thoroughly**: Overrides bypass Stacktape's validation
318
+ 6. **Keep it minimal**: The more you override, the more you need to maintain
319
+
320
+ ## Common Override Scenarios
321
+
322
+ ### Custom Lambda Runtime
323
+
324
+ ```yaml
325
+ overrides:
326
+ StpLambdaFunction:
327
+ Runtime: provided.al2023
328
+ ```
329
+
330
+ ### ECS Health Check
331
+
332
+ ```yaml
333
+ overrides:
334
+ StpEcsTaskDefinition:
335
+ ContainerDefinitions:
336
+ - HealthCheck:
337
+ Command: ['CMD-SHELL', 'curl -f http://localhost:3000/health || exit 1']
338
+ Interval: 30
339
+ Timeout: 5
340
+ Retries: 3
341
+ ```
342
+
343
+ ### RDS Enhanced Monitoring
344
+
345
+ ```yaml
346
+ overrides:
347
+ StpRdsInstance:
348
+ MonitoringInterval: 60
349
+ MonitoringRoleArn: arn:aws:iam::123456789:role/rds-monitoring-role
350
+ ```
351
+
352
+ ## Next Steps
@@ -0,0 +1,347 @@
1
+ ---
2
+ docType: concept
3
+ title: Stages & Environments
4
+ tags:
5
+ - stages
6
+ - environments
7
+ - concept
8
+ source: docs/_curated-docs/concepts/stages-and-environments.mdx
9
+ priority: 1
10
+ ---
11
+
12
+ # Stages & Environments
13
+
14
+ Stages allow you to deploy multiple isolated environments from the same codebase. Each stage creates a completely separate set of AWS resources.
15
+
16
+ ## What is a Stage?
17
+
18
+ A **stage** is an environment identifier like `dev`, `staging`, or `production`. When you deploy with different stages, Stacktape creates completely separate resources:
19
+
20
+ ```bash
21
+ # Development environment
22
+ stacktape deploy --stage dev --region us-east-1
23
+ # Creates: my-app-dev stack with its own database, functions, etc.
24
+
25
+ # Production environment
26
+ stacktape deploy --stage production --region us-east-1
27
+ # Creates: my-app-production stack with completely separate resources
28
+ ```
29
+
30
+ ## Stack Naming
31
+
32
+ Your stack name is derived from your project name and stage:
33
+
34
+ ```
35
+ {projectName}-{stage}
36
+ ```
37
+
38
+ For example:
39
+
40
+ - Project: `my-api`, Stage: `dev` → Stack: `my-api-dev`
41
+ - Project: `my-api`, Stage: `production` → Stack: `my-api-production`
42
+
43
+ ## Stage-Based Configuration
44
+
45
+ ### TypeScript (Recommended)
46
+
47
+ Use the `stage` parameter in `defineConfig`:
48
+
49
+ ```typescript
50
+ import { defineConfig, RelationalDatabase, LambdaFunction, RdsEnginePostgres, $Secret } from 'stacktape';
51
+
52
+ export default defineConfig(({ stage }) => {
53
+ const isProduction = stage === 'production';
54
+
55
+ const database = new RelationalDatabase({
56
+ engine: new RdsEnginePostgres({
57
+ version: '16',
58
+ primaryInstance: {
59
+ // Larger instance for production
60
+ instanceSize: isProduction ? 'db.t4g.medium' : 'db.t4g.micro',
61
+ // Multi-AZ only in production
62
+ multiAz: isProduction
63
+ }
64
+ }),
65
+ credentials: {
66
+ masterUserPassword: $Secret(`db-password-${stage}`)
67
+ },
68
+ // Different backup retention
69
+ automatedBackupRetentionDays: isProduction ? 7 : 1
70
+ });
71
+
72
+ const handler = new LambdaFunction({
73
+ // More memory for production
74
+ memory: isProduction ? 1024 : 256,
75
+ // Longer timeout for production
76
+ timeout: isProduction ? 30 : 10,
77
+ environment: {
78
+ NODE_ENV: isProduction ? 'production' : 'development',
79
+ LOG_LEVEL: isProduction ? 'warn' : 'debug'
80
+ }
81
+ });
82
+
83
+ return { resources: { database, handler } };
84
+ });
85
+ ```
86
+
87
+ ### YAML with Directives
88
+
89
+ In YAML, use variables and the `$Stage()` directive:
90
+
91
+ ```yaml
92
+ variables:
93
+ instanceSize:
94
+ $CfIf:
95
+ - $CfEquals: [$Stage(), 'production']
96
+ - db.t4g.medium
97
+ - db.t4g.micro
98
+
99
+ resources:
100
+ database:
101
+ type: relational-database
102
+ properties:
103
+ engine:
104
+ type: postgres
105
+ properties:
106
+ primaryInstance:
107
+ instanceSize: $Var('instanceSize')
108
+ credentials:
109
+ masterUserPassword: $Secret($Format('db-password-{}', $Stage()))
110
+ ```
111
+
112
+ ## Common Stage Patterns
113
+
114
+ ### Development → Staging → Production
115
+
116
+ ```typescript
117
+ export default defineConfig(({ stage }) => {
118
+ const config =
119
+ {
120
+ dev: {
121
+ instanceSize: 'db.t4g.micro',
122
+ minInstances: 1,
123
+ maxInstances: 1,
124
+ multiAz: false
125
+ },
126
+ staging: {
127
+ instanceSize: 'db.t4g.small',
128
+ minInstances: 1,
129
+ maxInstances: 3,
130
+ multiAz: false
131
+ },
132
+ production: {
133
+ instanceSize: 'db.t4g.medium',
134
+ minInstances: 2,
135
+ maxInstances: 10,
136
+ multiAz: true
137
+ }
138
+ }[stage] || config.dev; // Default to dev for unknown stages
139
+
140
+ return {
141
+ resources: {
142
+ database: new RelationalDatabase({
143
+ engine: new RdsEnginePostgres({
144
+ version: '16',
145
+ primaryInstance: {
146
+ instanceSize: config.instanceSize,
147
+ multiAz: config.multiAz
148
+ }
149
+ })
150
+ }),
151
+ api: new WebService({
152
+ scaling: {
153
+ minInstances: config.minInstances,
154
+ maxInstances: config.maxInstances
155
+ }
156
+ })
157
+ }
158
+ };
159
+ });
160
+ ```
161
+
162
+ ### Feature Branch Stages
163
+
164
+ Create temporary environments for feature branches:
165
+
166
+ ```bash
167
+ # Deploy feature branch
168
+ stacktape deploy --stage feature-123 --region us-east-1
169
+
170
+ # Test the feature
171
+ curl https://feature-123.api.example.com
172
+
173
+ # Delete when done
174
+ stacktape delete --stage feature-123 --region us-east-1
175
+ ```
176
+
177
+ ### Preview Environments
178
+
179
+ The Stacktape Console can automatically create preview environments for pull requests:
180
+
181
+ 1. Open a PR
182
+ 2. Stacktape automatically deploys a `preview-{pr-number}` stage
183
+ 3. PR gets a comment with the deployment URL
184
+ 4. When PR is merged/closed, the environment is deleted
185
+
186
+ `[IMAGE PLACEHOLDER: console-preview-environments]`
187
+
188
+ ## Stage-Specific Secrets
189
+
190
+ Create separate secrets for each stage:
191
+
192
+ ```bash
193
+ # Development secrets
194
+ stacktape secret:create --region us-east-1
195
+ # name: db-password-dev
196
+ # value: dev-password
197
+
198
+ # Production secrets
199
+ stacktape secret:create --region us-east-1
200
+ # name: db-password-production
201
+ # value: super-secure-production-password
202
+ ```
203
+
204
+ Reference in config:
205
+
206
+ ```typescript
207
+ export default defineConfig(({ stage }) => {
208
+ const database = new RelationalDatabase({
209
+ credentials: {
210
+ masterUserPassword: $Secret(`db-password-${stage}`)
211
+ }
212
+ });
213
+
214
+ return { resources: { database } };
215
+ });
216
+ ```
217
+
218
+ ## Stage-Specific Domains
219
+
220
+ ```typescript
221
+ export default defineConfig(({ stage }) => {
222
+ const api = new HttpApiGateway({
223
+ customDomains:
224
+ stage === 'production' ? [{ domainName: 'api.example.com' }] : [{ domainName: `${stage}.api.example.com` }]
225
+ });
226
+
227
+ return { resources: { api } };
228
+ });
229
+ ```
230
+
231
+ Results:
232
+
233
+ - `production` → `api.example.com`
234
+ - `staging` → `staging.api.example.com`
235
+ - `dev` → `dev.api.example.com`
236
+
237
+ ## Conditional Resources
238
+
239
+ Only create certain resources in specific stages:
240
+
241
+ ```typescript
242
+ export default defineConfig(({ stage }) => {
243
+ const resources: Record<string, any> = {};
244
+
245
+ // Always create API
246
+ resources.api = new HttpApiGateway({});
247
+
248
+ // Database only in non-ephemeral stages
249
+ if (!stage.startsWith('preview-')) {
250
+ resources.database = new RelationalDatabase({
251
+ engine: new RdsEnginePostgres({ version: '16' })
252
+ });
253
+ }
254
+
255
+ // Monitoring only in production
256
+ if (stage === 'production') {
257
+ resources.firewall = new WebAppFirewall({ scope: 'regional' });
258
+ }
259
+
260
+ return { resources };
261
+ });
262
+ ```
263
+
264
+ ## Sharing Resources Across Stages
265
+
266
+ Sometimes you want to share certain resources (like a database) across stages. Use a separate "shared infrastructure" stack:
267
+
268
+ **shared-infra/stacktape.ts:**
269
+
270
+ ```typescript
271
+ export default defineConfig(() => {
272
+ const database = new RelationalDatabase({
273
+ engine: new RdsEnginePostgres({ version: '16' })
274
+ });
275
+
276
+ return { resources: { database } };
277
+ });
278
+ ```
279
+
280
+ **api/stacktape.ts:**
281
+
282
+ ```typescript
283
+ export default defineConfig(({ stage }) => {
284
+ const handler = new LambdaFunction({
285
+ environment: {
286
+ DATABASE_URL: $StackOutput(`shared-infra-${stage}`, 'database', 'connectionString')
287
+ }
288
+ });
289
+
290
+ return { resources: { handler } };
291
+ });
292
+ ```
293
+
294
+ ## Default Stage and Region
295
+
296
+ Set defaults to avoid typing them every time:
297
+
298
+ ```bash
299
+ stacktape defaults:configure
300
+ # Set default stage: dev
301
+ # Set default region: us-east-1
302
+ ```
303
+
304
+ Now you can deploy without specifying stage/region:
305
+
306
+ ```bash
307
+ stacktape deploy
308
+ # Uses stage=dev, region=us-east-1
309
+ ```
310
+
311
+ Override when needed:
312
+
313
+ ```bash
314
+ stacktape deploy --stage production --region eu-west-1
315
+ ```
316
+
317
+ ## Listing Stages
318
+
319
+ View all deployed stacks:
320
+
321
+ ```bash
322
+ stacktape stack:list --region us-east-1
323
+ ```
324
+
325
+ Output:
326
+
327
+ ```
328
+ ┌──────────────────────┬─────────────┬─────────────────────────┐
329
+ │ Stack Name │ Status │ Last Updated │
330
+ ├──────────────────────┼─────────────┼─────────────────────────┤
331
+ │ my-api-dev │ DEPLOYED │ 2024-01-15 10:30:00 │
332
+ │ my-api-staging │ DEPLOYED │ 2024-01-14 15:45:00 │
333
+ │ my-api-production │ DEPLOYED │ 2024-01-10 09:00:00 │
334
+ │ my-api-feature-123 │ DEPLOYED │ 2024-01-15 11:00:00 │
335
+ └──────────────────────┴─────────────┴─────────────────────────┘
336
+ ```
337
+
338
+ ## Best Practices
339
+
340
+ 1. **Use consistent naming**: `dev`, `staging`, `production` or `development`, `test`, `prod`
341
+ 2. **Separate secrets per stage**: Never share production secrets with development
342
+ 3. **Start small in dev**: Use minimal resources in development to save costs
343
+ 4. **Test in staging**: Make staging as close to production as possible
344
+ 5. **Protect production**: Add additional safeguards (WAF, monitoring, multi-AZ)
345
+ 6. **Clean up feature stages**: Delete temporary stages when no longer needed
346
+
347
+ ## Next Steps