stacktape 3.5.7 → 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.
- package/.tsconfig.bun-build.json +1 -0
- package/ai-docs/cli-ref/aws-profile-create.md +22 -0
- package/ai-docs/cli-ref/aws-profile-delete.md +22 -0
- package/ai-docs/cli-ref/aws-profile-list.md +20 -0
- package/ai-docs/cli-ref/aws-profile-update.md +22 -0
- package/ai-docs/cli-ref/bastion-session.md +29 -0
- package/ai-docs/cli-ref/bastion-tunnel.md +30 -0
- package/ai-docs/cli-ref/bucket-sync.md +30 -0
- package/ai-docs/cli-ref/cf-module-update.md +26 -0
- package/ai-docs/cli-ref/cf-rollback.md +28 -0
- package/ai-docs/cli-ref/codebuild-deploy.md +34 -0
- package/ai-docs/cli-ref/compile-template.md +25 -0
- package/ai-docs/cli-ref/container-session.md +30 -0
- package/ai-docs/cli-ref/debug-alarms.md +28 -0
- package/ai-docs/cli-ref/debug-aws-sdk.md +33 -0
- package/ai-docs/cli-ref/debug-container-exec.md +36 -0
- package/ai-docs/cli-ref/debug-dynamodb.md +35 -0
- package/ai-docs/cli-ref/debug-logs.md +34 -0
- package/ai-docs/cli-ref/debug-metrics.md +33 -0
- package/ai-docs/cli-ref/debug-opensearch.md +35 -0
- package/ai-docs/cli-ref/debug-redis.md +36 -0
- package/ai-docs/cli-ref/debug-sql.md +35 -0
- package/ai-docs/cli-ref/defaults-configure.md +29 -0
- package/ai-docs/cli-ref/defaults-list.md +20 -0
- package/ai-docs/cli-ref/delete.md +24 -0
- package/ai-docs/cli-ref/deploy.md +25 -0
- package/ai-docs/cli-ref/deployment-script-run.md +28 -0
- package/ai-docs/cli-ref/dev-stop.md +26 -0
- package/ai-docs/cli-ref/dev.md +45 -0
- package/ai-docs/cli-ref/domain-add.md +26 -0
- package/ai-docs/cli-ref/help.md +18 -0
- package/ai-docs/cli-ref/info-operations.md +22 -0
- package/ai-docs/cli-ref/info-stack.md +30 -0
- package/ai-docs/cli-ref/info-stacks.md +26 -0
- package/ai-docs/cli-ref/info-whoami.md +22 -0
- package/ai-docs/cli-ref/init.md +30 -0
- package/ai-docs/cli-ref/login.md +20 -0
- package/ai-docs/cli-ref/logout.md +18 -0
- package/ai-docs/cli-ref/mcp-add.md +22 -0
- package/ai-docs/cli-ref/mcp.md +20 -0
- package/ai-docs/cli-ref/org-create.md +24 -0
- package/ai-docs/cli-ref/org-delete.md +24 -0
- package/ai-docs/cli-ref/org-list.md +22 -0
- package/ai-docs/cli-ref/package-workloads.md +25 -0
- package/ai-docs/cli-ref/param-get.md +26 -0
- package/ai-docs/cli-ref/preview-changes.md +23 -0
- package/ai-docs/cli-ref/project-create.md +22 -0
- package/ai-docs/cli-ref/projects-list.md +22 -0
- package/ai-docs/cli-ref/rollback.md +28 -0
- package/ai-docs/cli-ref/script-run.md +29 -0
- package/ai-docs/cli-ref/secret-create.md +28 -0
- package/ai-docs/cli-ref/secret-delete.md +26 -0
- package/ai-docs/cli-ref/secret-get.md +26 -0
- package/ai-docs/cli-ref/upgrade.md +20 -0
- package/ai-docs/cli-ref/version.md +18 -0
- package/ai-docs/concept/connecting-resources.md +369 -0
- package/ai-docs/concept/directives.md +371 -0
- package/ai-docs/concept/extending-cloudformation.md +315 -0
- package/ai-docs/concept/overrides-and-transforms.md +352 -0
- package/ai-docs/concept/stages-and-environments.md +347 -0
- package/ai-docs/concept/typescript-config.md +447 -0
- package/ai-docs/concept/yaml-config.md +338 -0
- package/ai-docs/config-ref/_root.md +142 -0
- package/ai-docs/config-ref/application-load-balancer.md +1109 -0
- package/ai-docs/config-ref/astro-web.md +115 -0
- package/ai-docs/config-ref/aws-cdk-construct.md +68 -0
- package/ai-docs/config-ref/bastion.md +93 -0
- package/ai-docs/config-ref/batch-job.md +179 -0
- package/ai-docs/config-ref/bucket.md +348 -0
- package/ai-docs/config-ref/cdn.md +496 -0
- package/ai-docs/config-ref/custom-resource.md +80 -0
- package/ai-docs/config-ref/deployment-script.md +79 -0
- package/ai-docs/config-ref/dynamo-db-table.md +202 -0
- package/ai-docs/config-ref/edge-lambda-function.md +87 -0
- package/ai-docs/config-ref/efs-filesystem.md +72 -0
- package/ai-docs/config-ref/event-bus.md +63 -0
- package/ai-docs/config-ref/function.md +409 -0
- package/ai-docs/config-ref/hosting-bucket.md +171 -0
- package/ai-docs/config-ref/http-api-gateway.md +149 -0
- package/ai-docs/config-ref/http-endpoint.md +92 -0
- package/ai-docs/config-ref/kinesis-stream.md +97 -0
- package/ai-docs/config-ref/mongo-db-atlas-cluster.md +254 -0
- package/ai-docs/config-ref/multi-container-workload.md +399 -0
- package/ai-docs/config-ref/network-load-balancer.md +118 -0
- package/ai-docs/config-ref/nextjs-web.md +147 -0
- package/ai-docs/config-ref/nuxt-web.md +81 -0
- package/ai-docs/config-ref/open-search.md +206 -0
- package/ai-docs/config-ref/private-service.md +75 -0
- package/ai-docs/config-ref/redis-cluster.md +223 -0
- package/ai-docs/config-ref/relational-database.md +525 -0
- package/ai-docs/config-ref/remix-web.md +74 -0
- package/ai-docs/config-ref/sns-topic.md +69 -0
- package/ai-docs/config-ref/solidstart-web.md +75 -0
- package/ai-docs/config-ref/sqs-queue-not-empty.md +405 -0
- package/ai-docs/config-ref/sqs-queue.md +232 -0
- package/ai-docs/config-ref/state-machine.md +235 -0
- package/ai-docs/config-ref/sveltekit-web.md +81 -0
- package/ai-docs/config-ref/tanstack-web.md +75 -0
- package/ai-docs/config-ref/upstash-redis.md +59 -0
- package/ai-docs/config-ref/user-auth-pool.md +876 -0
- package/ai-docs/config-ref/web-app-firewall.md +212 -0
- package/ai-docs/config-ref/web-service.md +178 -0
- package/ai-docs/config-ref/worker-service.md +41 -0
- package/ai-docs/getting-started/console.md +232 -0
- package/ai-docs/getting-started/deployment.md +434 -0
- package/ai-docs/getting-started/dev-mode.md +118 -0
- package/ai-docs/getting-started/how-it-works.md +119 -0
- package/ai-docs/getting-started/intro.md +157 -0
- package/ai-docs/getting-started/using-with-ai.md +228 -0
- package/ai-docs/getting-started/workflow.md +197 -0
- package/ai-docs/index.json +1514 -0
- package/ai-docs/recipe/background-jobs.md +183 -0
- package/ai-docs/recipe/database-migrations.md +240 -0
- package/ai-docs/recipe/graphql-api.md +211 -0
- package/ai-docs/recipe/monorepo-setup.md +183 -0
- package/ai-docs/recipe/nextjs-full-stack.md +188 -0
- package/ai-docs/recipe/rest-api-with-database.md +156 -0
- package/ai-docs/recipe/scheduled-tasks.md +186 -0
- package/ai-docs/recipe/static-website.md +241 -0
- package/ai-docs/troubleshooting/cloudformation-stack-states.md +189 -0
- package/bin/stacktape.js +206 -41
- package/package.json +1 -1
- package/plain.d.ts +309 -54
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
---
|
|
2
|
+
docType: concept
|
|
3
|
+
title: Directives
|
|
4
|
+
tags:
|
|
5
|
+
- directives
|
|
6
|
+
- concept
|
|
7
|
+
source: docs/_curated-docs/concepts/directives.mdx
|
|
8
|
+
priority: 1
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Directives
|
|
12
|
+
|
|
13
|
+
Directives are special functions (prefixed with `$`) that add dynamic behavior to your configuration. They allow you to reference secrets, resource parameters, and other dynamic values.
|
|
14
|
+
|
|
15
|
+
## Types of Directives
|
|
16
|
+
|
|
17
|
+
There are two categories of directives:
|
|
18
|
+
|
|
19
|
+
1. **Local directives**: Resolved when Stacktape parses your config (before deployment)
|
|
20
|
+
2. **Runtime directives**: Resolved by CloudFormation during deployment
|
|
21
|
+
|
|
22
|
+
## Local Directives
|
|
23
|
+
|
|
24
|
+
These are resolved immediately when Stacktape reads your configuration.
|
|
25
|
+
|
|
26
|
+
### $Stage()
|
|
27
|
+
|
|
28
|
+
Returns the current stage name.
|
|
29
|
+
|
|
30
|
+
```yaml
|
|
31
|
+
resources:
|
|
32
|
+
api:
|
|
33
|
+
type: http-api-gateway
|
|
34
|
+
properties:
|
|
35
|
+
customDomains:
|
|
36
|
+
- domainName: $Format('api-{}.example.com', $Stage())
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### $Region()
|
|
40
|
+
|
|
41
|
+
Returns the current AWS region.
|
|
42
|
+
|
|
43
|
+
```yaml
|
|
44
|
+
resources:
|
|
45
|
+
handler:
|
|
46
|
+
type: function
|
|
47
|
+
properties:
|
|
48
|
+
environment:
|
|
49
|
+
- name: AWS_REGION
|
|
50
|
+
value: $Region()
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### $Var()
|
|
54
|
+
|
|
55
|
+
References a value from the `variables` section.
|
|
56
|
+
|
|
57
|
+
```yaml
|
|
58
|
+
variables:
|
|
59
|
+
instanceSize: db.t4g.micro
|
|
60
|
+
apiDomain: api.example.com
|
|
61
|
+
|
|
62
|
+
resources:
|
|
63
|
+
database:
|
|
64
|
+
type: relational-database
|
|
65
|
+
properties:
|
|
66
|
+
engine:
|
|
67
|
+
type: postgres
|
|
68
|
+
properties:
|
|
69
|
+
primaryInstance:
|
|
70
|
+
instanceSize: $Var('instanceSize')
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### $File()
|
|
74
|
+
|
|
75
|
+
Loads and parses a file. Supports `.env`, `.json`, `.yml`, `.yaml`, and `.ini` files.
|
|
76
|
+
|
|
77
|
+
```yaml
|
|
78
|
+
resources:
|
|
79
|
+
handler:
|
|
80
|
+
type: function
|
|
81
|
+
properties:
|
|
82
|
+
# Load environment variables from .env file
|
|
83
|
+
environment: $File('.env')
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
For `.env` files, this returns an array of `{ name, value }` objects.
|
|
87
|
+
|
|
88
|
+
### $FileRaw()
|
|
89
|
+
|
|
90
|
+
Reads a file as a raw UTF-8 string.
|
|
91
|
+
|
|
92
|
+
```yaml
|
|
93
|
+
resources:
|
|
94
|
+
handler:
|
|
95
|
+
type: function
|
|
96
|
+
properties:
|
|
97
|
+
environment:
|
|
98
|
+
- name: CONFIG
|
|
99
|
+
value: $FileRaw('./config.json')
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### $Format()
|
|
103
|
+
|
|
104
|
+
String interpolation using `{}` placeholders.
|
|
105
|
+
|
|
106
|
+
```yaml
|
|
107
|
+
resources:
|
|
108
|
+
api:
|
|
109
|
+
type: http-api-gateway
|
|
110
|
+
properties:
|
|
111
|
+
customDomains:
|
|
112
|
+
- domainName: $Format('{}-api.example.com', $Stage())
|
|
113
|
+
# dev -> "dev-api.example.com"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Multiple placeholders:
|
|
117
|
+
|
|
118
|
+
```yaml
|
|
119
|
+
environment:
|
|
120
|
+
- name: APP_URL
|
|
121
|
+
value: $Format('https://{}.{}.example.com', $Stage(), $Region())
|
|
122
|
+
# -> "https://dev.us-east-1.example.com"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### $GitInfo()
|
|
126
|
+
|
|
127
|
+
Returns information about the current git repository.
|
|
128
|
+
|
|
129
|
+
```yaml
|
|
130
|
+
resources:
|
|
131
|
+
handler:
|
|
132
|
+
type: function
|
|
133
|
+
properties:
|
|
134
|
+
environment:
|
|
135
|
+
- name: GIT_COMMIT
|
|
136
|
+
value: $GitInfo('commit')
|
|
137
|
+
- name: GIT_BRANCH
|
|
138
|
+
value: $GitInfo('branch')
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Available properties:
|
|
142
|
+
|
|
143
|
+
- `commit` - Current commit SHA
|
|
144
|
+
- `branch` - Current branch name
|
|
145
|
+
- `username` - Git username
|
|
146
|
+
- `gitUrl` - Repository URL
|
|
147
|
+
|
|
148
|
+
### $CliArgs()
|
|
149
|
+
|
|
150
|
+
Accesses additional CLI arguments passed after `--`.
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
stacktape deploy --stage dev --region us-east-1 -- --myArg=value
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
```yaml
|
|
157
|
+
variables:
|
|
158
|
+
myArg: $CliArgs('myArg')
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
### $StackOutput()
|
|
162
|
+
|
|
163
|
+
References outputs from another Stacktape stack.
|
|
164
|
+
|
|
165
|
+
```yaml
|
|
166
|
+
resources:
|
|
167
|
+
handler:
|
|
168
|
+
type: function
|
|
169
|
+
properties:
|
|
170
|
+
environment:
|
|
171
|
+
- name: SHARED_DB_URL
|
|
172
|
+
value: $StackOutput('shared-infra-dev', 'database', 'connectionString')
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Arguments: `(stackName, resourceName, paramName)`
|
|
176
|
+
|
|
177
|
+
## Runtime Directives
|
|
178
|
+
|
|
179
|
+
These are resolved by CloudFormation during deployment. Use them for values that don't exist until resources are created.
|
|
180
|
+
|
|
181
|
+
### $Secret()
|
|
182
|
+
|
|
183
|
+
References a secret from AWS Secrets Manager.
|
|
184
|
+
|
|
185
|
+
```yaml
|
|
186
|
+
resources:
|
|
187
|
+
database:
|
|
188
|
+
type: relational-database
|
|
189
|
+
properties:
|
|
190
|
+
credentials:
|
|
191
|
+
masterUserPassword: $Secret('db-password')
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
Create secrets using the CLI:
|
|
195
|
+
|
|
196
|
+
```bash
|
|
197
|
+
stacktape secret:create --region us-east-1
|
|
198
|
+
# Enter name: db-password
|
|
199
|
+
# Enter value: your-secure-password
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
#### JSON Secrets
|
|
203
|
+
|
|
204
|
+
If your secret contains JSON, access specific keys with dot notation:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
# Create a JSON secret
|
|
208
|
+
stacktape secret:create --region us-east-1
|
|
209
|
+
# name: api-keys
|
|
210
|
+
# value: {"stripe": "sk_...", "sendgrid": "SG..."}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
```yaml
|
|
214
|
+
resources:
|
|
215
|
+
handler:
|
|
216
|
+
type: function
|
|
217
|
+
properties:
|
|
218
|
+
environment:
|
|
219
|
+
- name: STRIPE_KEY
|
|
220
|
+
value: $Secret('api-keys.stripe')
|
|
221
|
+
- name: SENDGRID_KEY
|
|
222
|
+
value: $Secret('api-keys.sendgrid')
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### $ResourceParam()
|
|
226
|
+
|
|
227
|
+
References a parameter from another resource. Used for values that are only known after deployment (URLs, ARNs, etc.).
|
|
228
|
+
|
|
229
|
+
```yaml
|
|
230
|
+
resources:
|
|
231
|
+
api:
|
|
232
|
+
type: http-api-gateway
|
|
233
|
+
|
|
234
|
+
frontend:
|
|
235
|
+
type: hosting-bucket
|
|
236
|
+
properties:
|
|
237
|
+
environment:
|
|
238
|
+
- name: API_URL
|
|
239
|
+
value: $ResourceParam('api', 'url')
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
Common parameters by resource type:
|
|
243
|
+
|
|
244
|
+
| Resource Type | Parameters |
|
|
245
|
+
| --------------------- | ------------------------------------------------- |
|
|
246
|
+
| `http-api-gateway` | `url`, `arn`, `id` |
|
|
247
|
+
| `relational-database` | `connectionString`, `host`, `port`, `name`, `arn` |
|
|
248
|
+
| `dynamo-db-table` | `tableName`, `tableArn`, `streamArn` |
|
|
249
|
+
| `bucket` | `bucketName`, `bucketArn`, `domainName` |
|
|
250
|
+
| `sqs-queue` | `queueUrl`, `queueArn` |
|
|
251
|
+
| `sns-topic` | `topicArn` |
|
|
252
|
+
| `user-auth-pool` | `id`, `arn`, `clientId` |
|
|
253
|
+
|
|
254
|
+
### $CfResourceParam()
|
|
255
|
+
|
|
256
|
+
References a parameter from a raw CloudFormation resource.
|
|
257
|
+
|
|
258
|
+
```yaml
|
|
259
|
+
cloudformationResources:
|
|
260
|
+
mySnsTopic:
|
|
261
|
+
Type: AWS::SNS::Topic
|
|
262
|
+
Properties:
|
|
263
|
+
TopicName: my-topic
|
|
264
|
+
|
|
265
|
+
resources:
|
|
266
|
+
handler:
|
|
267
|
+
type: function
|
|
268
|
+
properties:
|
|
269
|
+
environment:
|
|
270
|
+
- name: TOPIC_ARN
|
|
271
|
+
value: $CfResourceParam('mySnsTopic', 'Arn')
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### $CfFormat()
|
|
275
|
+
|
|
276
|
+
Like `$Format()`, but resolved at CloudFormation deployment time. Use when combining runtime values.
|
|
277
|
+
|
|
278
|
+
```yaml
|
|
279
|
+
resources:
|
|
280
|
+
database:
|
|
281
|
+
type: relational-database
|
|
282
|
+
|
|
283
|
+
handler:
|
|
284
|
+
type: function
|
|
285
|
+
properties:
|
|
286
|
+
environment:
|
|
287
|
+
- name: JDBC_URL
|
|
288
|
+
value: $CfFormat('jdbc:postgresql://{}:{}/{}',
|
|
289
|
+
$ResourceParam('database', 'host'),
|
|
290
|
+
$ResourceParam('database', 'port'),
|
|
291
|
+
$ResourceParam('database', 'name'))
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
### $CfStackOutput()
|
|
295
|
+
|
|
296
|
+
Like `$StackOutput()`, but resolved at deployment time with deletion protection.
|
|
297
|
+
|
|
298
|
+
```yaml
|
|
299
|
+
resources:
|
|
300
|
+
handler:
|
|
301
|
+
type: function
|
|
302
|
+
properties:
|
|
303
|
+
environment:
|
|
304
|
+
- name: SHARED_QUEUE_URL
|
|
305
|
+
value: $CfStackOutput('shared-infra-dev', 'queue', 'queueUrl')
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
## TypeScript Equivalents
|
|
309
|
+
|
|
310
|
+
In TypeScript configuration, import directive functions:
|
|
311
|
+
|
|
312
|
+
```typescript
|
|
313
|
+
import { defineConfig, $Secret, $ResourceParam, $Format } from 'stacktape';
|
|
314
|
+
|
|
315
|
+
export default defineConfig(({ stage }) => {
|
|
316
|
+
const database = new RelationalDatabase({
|
|
317
|
+
credentials: {
|
|
318
|
+
masterUserPassword: $Secret('db-password')
|
|
319
|
+
}
|
|
320
|
+
});
|
|
321
|
+
|
|
322
|
+
const handler = new LambdaFunction({
|
|
323
|
+
environment: {
|
|
324
|
+
DB_HOST: $ResourceParam('database', 'host'),
|
|
325
|
+
APP_URL: $Format('https://{}.example.com', stage)
|
|
326
|
+
}
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
return { resources: { database, handler } };
|
|
330
|
+
});
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
## Directive Nesting
|
|
334
|
+
|
|
335
|
+
Directives can be nested up to 2 levels deep:
|
|
336
|
+
|
|
337
|
+
```yaml
|
|
338
|
+
# ✅ Valid - 2 levels
|
|
339
|
+
environment:
|
|
340
|
+
- name: URL
|
|
341
|
+
value: $Format('{}/api', $ResourceParam('api', 'url'))
|
|
342
|
+
|
|
343
|
+
# ❌ Invalid - 3 levels (use $Var to work around)
|
|
344
|
+
environment:
|
|
345
|
+
- name: URL
|
|
346
|
+
value: $Format('{}/{}', $Format('{}', $Stage()), $ResourceParam('api', 'url'))
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
Workaround using `$Var()`:
|
|
350
|
+
|
|
351
|
+
```yaml
|
|
352
|
+
variables:
|
|
353
|
+
stagePrefix: $Format('{}-', $Stage())
|
|
354
|
+
|
|
355
|
+
resources:
|
|
356
|
+
handler:
|
|
357
|
+
type: function
|
|
358
|
+
properties:
|
|
359
|
+
environment:
|
|
360
|
+
- name: URL
|
|
361
|
+
value: $Format('{}/{}', $Var('stagePrefix'), $ResourceParam('api', 'url'))
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Where Directives Can Be Used
|
|
365
|
+
|
|
366
|
+
| Directive Type | Where Usable |
|
|
367
|
+
| ------------------------------------- | ------------------------------------------ |
|
|
368
|
+
| Local (`$Stage`, `$File`, etc.) | Anywhere in config |
|
|
369
|
+
| Runtime (`$Secret`, `$ResourceParam`) | Only in `resources` and `scripts` sections |
|
|
370
|
+
|
|
371
|
+
## Next Steps
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
---
|
|
2
|
+
docType: concept
|
|
3
|
+
title: CloudFormation Resources
|
|
4
|
+
tags:
|
|
5
|
+
- cloudformation
|
|
6
|
+
- resources
|
|
7
|
+
- concept
|
|
8
|
+
source: docs/_curated-docs/concepts/extending-cloudformation.mdx
|
|
9
|
+
priority: 1
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# CloudFormation Resources
|
|
13
|
+
|
|
14
|
+
Use the `cloudformationResources` section to add native CloudFormation resources to your stack. This gives you access to any AWS resource that CloudFormation supports.
|
|
15
|
+
|
|
16
|
+
## When to Use
|
|
17
|
+
|
|
18
|
+
- AWS resource not natively supported by Stacktape
|
|
19
|
+
- Need low-level control over resource configuration
|
|
20
|
+
- Migrating existing CloudFormation templates
|
|
21
|
+
|
|
22
|
+
## Basic Example
|
|
23
|
+
|
|
24
|
+
Add an SNS topic using CloudFormation:
|
|
25
|
+
|
|
26
|
+
```ts
|
|
27
|
+
import { defineConfig } from 'stacktape';
|
|
28
|
+
|
|
29
|
+
export default defineConfig({
|
|
30
|
+
resources: {
|
|
31
|
+
processData: {
|
|
32
|
+
type: 'function',
|
|
33
|
+
properties: {
|
|
34
|
+
packaging: {
|
|
35
|
+
type: 'stacktape-lambda-buildpack',
|
|
36
|
+
properties: {
|
|
37
|
+
entryfilePath: 'src/process.ts'
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
environment: [
|
|
41
|
+
{
|
|
42
|
+
name: 'SNS_TOPIC_ARN',
|
|
43
|
+
value: '$CfResourceParam(\'AlertTopic\', \'TopicArn\')'
|
|
44
|
+
}
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
cloudformationResources: {
|
|
51
|
+
AlertTopic: {
|
|
52
|
+
Type: 'AWS::SNS::Topic',
|
|
53
|
+
Properties: {
|
|
54
|
+
TopicName: 'my-alert-topic',
|
|
55
|
+
DisplayName: 'Alert Notifications'
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Syntax
|
|
64
|
+
|
|
65
|
+
CloudFormation resources use the standard CloudFormation syntax:
|
|
66
|
+
|
|
67
|
+
```ts
|
|
68
|
+
cloudformationResources: {
|
|
69
|
+
LogicalResourceName: {
|
|
70
|
+
Type: 'AWS::Service::Resource',
|
|
71
|
+
Properties: {
|
|
72
|
+
// Resource-specific properties
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Referencing CloudFormation Resources
|
|
79
|
+
|
|
80
|
+
### Get Resource Attributes
|
|
81
|
+
|
|
82
|
+
Use `$CfResourceParam()` to get attributes from CloudFormation resources:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
// Get the ARN of an SNS topic
|
|
86
|
+
'$CfResourceParam(\'AlertTopic\', \'TopicArn\')';
|
|
87
|
+
|
|
88
|
+
// Get the name of an S3 bucket
|
|
89
|
+
'$CfResourceParam(\'DataBucket\', \'BucketName\')';
|
|
90
|
+
|
|
91
|
+
// Get the physical ID (usually the resource name)
|
|
92
|
+
'$CfResourceParam(\'AlertTopic\', \'Ref\')';
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### In Environment Variables
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
{
|
|
99
|
+
myFunction: {
|
|
100
|
+
type: 'function',
|
|
101
|
+
properties: {
|
|
102
|
+
packaging: {
|
|
103
|
+
type: 'stacktape-lambda-buildpack',
|
|
104
|
+
properties: { entryfilePath: 'src/handler.ts' }
|
|
105
|
+
},
|
|
106
|
+
environment: [
|
|
107
|
+
{
|
|
108
|
+
name: 'TOPIC_ARN',
|
|
109
|
+
value: '$CfResourceParam(\'AlertTopic\', \'TopicArn\')'
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'BUCKET_NAME',
|
|
113
|
+
value: '$CfResourceParam(\'DataBucket\', \'BucketName\')'
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Common CloudFormation Resources
|
|
122
|
+
|
|
123
|
+
### SNS Topic
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
cloudformationResources: {
|
|
127
|
+
AlertTopic: {
|
|
128
|
+
Type: 'AWS::SNS::Topic',
|
|
129
|
+
Properties: {
|
|
130
|
+
TopicName: 'alerts',
|
|
131
|
+
DisplayName: 'Alert Notifications'
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### SNS Subscription
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
cloudformationResources: {
|
|
141
|
+
EmailSubscription: {
|
|
142
|
+
Type: 'AWS::SNS::Subscription',
|
|
143
|
+
Properties: {
|
|
144
|
+
TopicArn: '$CfResourceParam(\'AlertTopic\', \'TopicArn\')',
|
|
145
|
+
Protocol: 'email',
|
|
146
|
+
Endpoint: 'alerts@example.com'
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### IAM Role
|
|
153
|
+
|
|
154
|
+
```ts
|
|
155
|
+
cloudformationResources: {
|
|
156
|
+
CustomRole: {
|
|
157
|
+
Type: 'AWS::IAM::Role',
|
|
158
|
+
Properties: {
|
|
159
|
+
RoleName: 'custom-role',
|
|
160
|
+
AssumeRolePolicyDocument: {
|
|
161
|
+
Version: '2012-10-17',
|
|
162
|
+
Statement: [
|
|
163
|
+
{
|
|
164
|
+
Effect: 'Allow',
|
|
165
|
+
Principal: { Service: 'lambda.amazonaws.com' },
|
|
166
|
+
Action: 'sts:AssumeRole'
|
|
167
|
+
}
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
Policies: [
|
|
171
|
+
{
|
|
172
|
+
PolicyName: 'custom-policy',
|
|
173
|
+
PolicyDocument: {
|
|
174
|
+
Version: '2012-10-17',
|
|
175
|
+
Statement: [
|
|
176
|
+
{
|
|
177
|
+
Effect: 'Allow',
|
|
178
|
+
Action: ['s3:GetObject'],
|
|
179
|
+
Resource: '*'
|
|
180
|
+
}
|
|
181
|
+
]
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### CloudWatch Log Group
|
|
191
|
+
|
|
192
|
+
```ts
|
|
193
|
+
cloudformationResources: {
|
|
194
|
+
CustomLogGroup: {
|
|
195
|
+
Type: 'AWS::Logs::LogGroup',
|
|
196
|
+
Properties: {
|
|
197
|
+
LogGroupName: '/custom/logs',
|
|
198
|
+
RetentionInDays: 30
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
### Secrets Manager Secret
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
cloudformationResources: {
|
|
208
|
+
ApiSecret: {
|
|
209
|
+
Type: 'AWS::SecretsManager::Secret',
|
|
210
|
+
Properties: {
|
|
211
|
+
Name: 'api-credentials',
|
|
212
|
+
Description: 'API credentials for third-party service',
|
|
213
|
+
GenerateSecretString: {
|
|
214
|
+
SecretStringTemplate: '{"username": "admin"}',
|
|
215
|
+
GenerateStringKey: 'password',
|
|
216
|
+
PasswordLength: 32
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
## Connecting Stacktape and CloudFormation Resources
|
|
224
|
+
|
|
225
|
+
### Lambda Triggered by SNS
|
|
226
|
+
|
|
227
|
+
```ts
|
|
228
|
+
import { defineConfig } from 'stacktape';
|
|
229
|
+
|
|
230
|
+
export default defineConfig({
|
|
231
|
+
resources: {
|
|
232
|
+
alertHandler: {
|
|
233
|
+
type: 'function',
|
|
234
|
+
properties: {
|
|
235
|
+
packaging: {
|
|
236
|
+
type: 'stacktape-lambda-buildpack',
|
|
237
|
+
properties: { entryfilePath: 'src/alert-handler.ts' }
|
|
238
|
+
},
|
|
239
|
+
events: [
|
|
240
|
+
{
|
|
241
|
+
type: 'sns',
|
|
242
|
+
properties: {
|
|
243
|
+
topicArn: '$CfResourceParam(\'AlertTopic\', \'TopicArn\')'
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
]
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
cloudformationResources: {
|
|
252
|
+
AlertTopic: {
|
|
253
|
+
Type: 'AWS::SNS::Topic',
|
|
254
|
+
Properties: {
|
|
255
|
+
TopicName: 'alerts'
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
### Referencing Stacktape Resources in CloudFormation
|
|
264
|
+
|
|
265
|
+
Use `$ResourceParam()` to reference Stacktape resources from CloudFormation:
|
|
266
|
+
|
|
267
|
+
```ts
|
|
268
|
+
cloudformationResources: {
|
|
269
|
+
LambdaPermission: {
|
|
270
|
+
Type: 'AWS::Lambda::Permission',
|
|
271
|
+
Properties: {
|
|
272
|
+
FunctionName: '$ResourceParam(\'myFunction\', \'arn\')',
|
|
273
|
+
Action: 'lambda:InvokeFunction',
|
|
274
|
+
Principal: 'sns.amazonaws.com',
|
|
275
|
+
SourceArn: '$CfResourceParam(\'AlertTopic\', \'TopicArn\')'
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
## DependsOn
|
|
282
|
+
|
|
283
|
+
Control resource creation order:
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
cloudformationResources: {
|
|
287
|
+
TopicSubscription: {
|
|
288
|
+
Type: 'AWS::SNS::Subscription',
|
|
289
|
+
DependsOn: ['AlertTopic'],
|
|
290
|
+
Properties: {
|
|
291
|
+
TopicArn: '$CfResourceParam(\'AlertTopic\', \'TopicArn\')',
|
|
292
|
+
Protocol: 'email',
|
|
293
|
+
Endpoint: 'admin@example.com'
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Finding Resource Types
|
|
300
|
+
|
|
301
|
+
See the [AWS CloudFormation Resource Reference](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html) for all available resource types and their properties.
|
|
302
|
+
|
|
303
|
+
## Best Practices
|
|
304
|
+
|
|
305
|
+
1. **Use Stacktape resources when available** - They provide better defaults and integration
|
|
306
|
+
2. **Name resources consistently** - Include stack/stage in names to avoid conflicts
|
|
307
|
+
3. **Document custom resources** - Explain why CloudFormation was needed
|
|
308
|
+
4. **Test thoroughly** - CloudFormation errors can be cryptic
|
|
309
|
+
|
|
310
|
+
## Limitations
|
|
311
|
+
|
|
312
|
+
- CloudFormation resources don't benefit from Stacktape's simplified configuration
|
|
313
|
+
- IAM permissions must be managed manually
|
|
314
|
+
- No automatic `connectTo` support
|
|
315
|
+
- Updates may require more careful planning (some properties can't be updated in-place)
|