storyshelf 0.3.2 → 0.5.3
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 +2 -1
- package/dist/client.js +20 -5
- package/dist/commands/build.js +31 -0
- package/dist/commands/connection.js +29 -0
- package/dist/commands/create.js +1 -1
- package/dist/commands/doctor.js +150 -0
- package/dist/commands/init.js +2 -2
- package/dist/commands/purge.js +1 -1
- package/dist/commands/retry.js +1 -1
- package/dist/commands/server/docker.js +76 -11
- package/dist/commands/server/init.js +495 -45
- package/dist/commands/server/prompts.js +410 -35
- package/dist/commands/server/serve.js +123 -0
- package/dist/commands/server/terraform-aws.js +458 -0
- package/dist/commands/server/terraform-azure.js +462 -0
- package/dist/commands/server/terraform-gcp.js +475 -0
- package/dist/commands/shared/detect-adapters.js +104 -0
- package/dist/commands/storybook-build.js +62 -0
- package/dist/commands/upload.js +106 -50
- package/dist/commands/whoami.js +22 -0
- package/dist/commands/worker/init.js +254 -0
- package/dist/commands/worker/serve.js +105 -0
- package/dist/config.js +396 -23
- package/dist/index.js +49 -17
- package/dist/output.js +10 -0
- package/package.json +21 -13
- package/schema/storyshelf-config.json +58 -0
|
@@ -0,0 +1,458 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import "node:path";
|
|
3
|
+
import "node:url";
|
|
4
|
+
import.meta.url;
|
|
5
|
+
//#region src/commands/server/terraform-aws.ts
|
|
6
|
+
/** Terraform CLI version floor for the generated modules. */
|
|
7
|
+
const TERRAFORM_REQUIRED_VERSION = ">= 1.9";
|
|
8
|
+
function header() {
|
|
9
|
+
return `# Generated by \`storyshelf server init --target aws\`. Do not edit by hand;\n# re-run the scaffold or edit the generator in @storyshelf/cli.\n\n`;
|
|
10
|
+
}
|
|
11
|
+
function generateAwsVersions() {
|
|
12
|
+
return `${header()}terraform {
|
|
13
|
+
required_version = "${TERRAFORM_REQUIRED_VERSION}"
|
|
14
|
+
|
|
15
|
+
required_providers {
|
|
16
|
+
aws = {
|
|
17
|
+
source = "hashicorp/aws"
|
|
18
|
+
version = ">= 5.60"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
`;
|
|
23
|
+
}
|
|
24
|
+
function generateAwsVariables() {
|
|
25
|
+
return `${header()}variable "project" {
|
|
26
|
+
description = "Project slug, used as a name prefix for all resources."
|
|
27
|
+
type = string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
variable "region" {
|
|
31
|
+
description = "AWS region for all resources."
|
|
32
|
+
type = string
|
|
33
|
+
default = "us-east-1"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
variable "vpc_id" {
|
|
37
|
+
description = "Existing VPC id. Empty creates a new VPC."
|
|
38
|
+
type = string
|
|
39
|
+
default = ""
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
variable "domain_name" {
|
|
43
|
+
description = "Public domain for the ALB (Route 53 + ACM). Empty leaves the ALB HTTP-only."
|
|
44
|
+
type = string
|
|
45
|
+
default = ""
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
variable "saml_metadata_url" {
|
|
49
|
+
description = "SAML metadata URL for Cognito federation (Entra/Okta). Empty skips federation."
|
|
50
|
+
type = string
|
|
51
|
+
default = ""
|
|
52
|
+
}
|
|
53
|
+
`;
|
|
54
|
+
}
|
|
55
|
+
function generateAwsVpc() {
|
|
56
|
+
return `${header()}# VPC: created unless var.vpc_id points at an existing one.
|
|
57
|
+
resource "aws_vpc" "main" {
|
|
58
|
+
count = var.vpc_id == "" ? 1 : 0
|
|
59
|
+
cidr_block = "10.0.0.0/16"
|
|
60
|
+
enable_dns_support = true
|
|
61
|
+
enable_dns_hostnames = true
|
|
62
|
+
|
|
63
|
+
tags = { Name = "\${var.project}-vpc" }
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
locals {
|
|
67
|
+
vpc_id = var.vpc_id != "" ? var.vpc_id : aws_vpc.main[0].id
|
|
68
|
+
}
|
|
69
|
+
`;
|
|
70
|
+
}
|
|
71
|
+
/** ALB + ECS security groups and private data-plane endpoints. */
|
|
72
|
+
function generateAwsSecurity() {
|
|
73
|
+
return `${header()}resource "aws_security_group" "alb" {
|
|
74
|
+
name = "\${var.project}-alb"
|
|
75
|
+
description = "ALB ingress"
|
|
76
|
+
vpc_id = local.vpc_id
|
|
77
|
+
|
|
78
|
+
ingress {
|
|
79
|
+
from_port = 443
|
|
80
|
+
to_port = 443
|
|
81
|
+
protocol = "tcp"
|
|
82
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
ingress {
|
|
86
|
+
from_port = 80
|
|
87
|
+
to_port = 80
|
|
88
|
+
protocol = "tcp"
|
|
89
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
egress {
|
|
93
|
+
from_port = 0
|
|
94
|
+
to_port = 0
|
|
95
|
+
protocol = "-1"
|
|
96
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
resource "aws_security_group" "ecs" {
|
|
101
|
+
name = "\${var.project}-ecs"
|
|
102
|
+
description = "ECS tasks: ALB ingress only"
|
|
103
|
+
vpc_id = local.vpc_id
|
|
104
|
+
|
|
105
|
+
ingress {
|
|
106
|
+
from_port = 3000
|
|
107
|
+
to_port = 3000
|
|
108
|
+
protocol = "tcp"
|
|
109
|
+
security_groups = [aws_security_group.alb.id]
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
egress {
|
|
113
|
+
from_port = 0
|
|
114
|
+
to_port = 0
|
|
115
|
+
protocol = "-1"
|
|
116
|
+
cidr_blocks = ["0.0.0.0/0"]
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
`;
|
|
120
|
+
}
|
|
121
|
+
/** Private data-plane endpoints (S3, SQS) off the public internet. */
|
|
122
|
+
function generateAwsEndpoints() {
|
|
123
|
+
return `${header()}# VPC endpoints keep data-plane traffic (S3, SQS) off the public internet.
|
|
124
|
+
resource "aws_vpc_endpoint" "s3" {
|
|
125
|
+
vpc_id = local.vpc_id
|
|
126
|
+
service_name = "com.amazonaws.\${var.region}.s3"
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
resource "aws_vpc_endpoint" "sqs" {
|
|
130
|
+
vpc_id = local.vpc_id
|
|
131
|
+
service_name = "com.amazonaws.\${var.region}.sqs"
|
|
132
|
+
security_group_ids = [aws_security_group.ecs.id]
|
|
133
|
+
}
|
|
134
|
+
`;
|
|
135
|
+
}
|
|
136
|
+
function generateAwsStorage() {
|
|
137
|
+
return `${header()}resource "aws_s3_bucket" "storybook" {
|
|
138
|
+
bucket = "\${var.project}-storybook"
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
resource "aws_s3_bucket_versioning" "storybook" {
|
|
142
|
+
bucket = aws_s3_bucket.storybook.id
|
|
143
|
+
|
|
144
|
+
versioning_configuration {
|
|
145
|
+
status = "Enabled"
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
resource "aws_s3_bucket_server_side_encryption_configuration" "storybook" {
|
|
150
|
+
bucket = aws_s3_bucket.storybook.id
|
|
151
|
+
|
|
152
|
+
rule {
|
|
153
|
+
apply_server_side_encryption_by_default {
|
|
154
|
+
sse_algorithm = "AES256"
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
resource "aws_s3_bucket_public_access_block" "storybook" {
|
|
160
|
+
bucket = aws_s3_bucket.storybook.id
|
|
161
|
+
block_public_acls = true
|
|
162
|
+
block_public_policy = true
|
|
163
|
+
ignore_public_acls = true
|
|
164
|
+
restrict_public_buckets = true
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
# Transient build bundles expire; baselines persist.
|
|
168
|
+
resource "aws_s3_bucket_lifecycle_configuration" "storybook" {
|
|
169
|
+
bucket = aws_s3_bucket.storybook.id
|
|
170
|
+
|
|
171
|
+
rule {
|
|
172
|
+
id = "expire-transient-builds"
|
|
173
|
+
status = "Enabled"
|
|
174
|
+
|
|
175
|
+
filter {
|
|
176
|
+
prefix = "builds/"
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
expiration {
|
|
180
|
+
days = 30
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
`;
|
|
185
|
+
}
|
|
186
|
+
function generateAwsQueue() {
|
|
187
|
+
return `${header()}resource "aws_sqs_queue" "capture_dlq" {
|
|
188
|
+
name = "\${var.project}-capture-dlq"
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
resource "aws_sqs_queue" "capture" {
|
|
192
|
+
name = "\${var.project}-capture"
|
|
193
|
+
visibility_timeout_seconds = 300
|
|
194
|
+
redrive_policy = jsonencode({
|
|
195
|
+
deadLetterTargetArn = aws_sqs_queue.capture_dlq.arn
|
|
196
|
+
maxReceiveCount = 3
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
`;
|
|
200
|
+
}
|
|
201
|
+
function generateAwsDatabase(dbEngine) {
|
|
202
|
+
if (dbEngine === "dsql") return `${header()}# Serverless Postgres. The server connects with
|
|
203
|
+
# createPostgresDatabase({ url: <cluster endpoint> }).
|
|
204
|
+
resource "aws_dsql_cluster" "main" {
|
|
205
|
+
deletion_protection_enabled = true
|
|
206
|
+
|
|
207
|
+
tags = { Name = "\${var.project}-db" }
|
|
208
|
+
}
|
|
209
|
+
`;
|
|
210
|
+
return `${header()}# VPC-isolated Postgres for regulated estates. The server connects with
|
|
211
|
+
# createPostgresDatabase({ url: <DATABASE_URL with sslmode=require> }).
|
|
212
|
+
resource "aws_db_subnet_group" "main" {
|
|
213
|
+
name = "\${var.project}-db"
|
|
214
|
+
subnet_ids = data.aws_subnets.private.ids
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
resource "aws_db_instance" "main" {
|
|
218
|
+
identifier = "\${var.project}-db"
|
|
219
|
+
engine = "postgres"
|
|
220
|
+
engine_version = "16"
|
|
221
|
+
instance_class = "db.t4g.micro"
|
|
222
|
+
allocated_storage = 20
|
|
223
|
+
db_subnet_group_name = aws_db_subnet_group.main.name
|
|
224
|
+
vpc_security_group_ids = [aws_security_group.ecs.id]
|
|
225
|
+
skip_final_snapshot = true
|
|
226
|
+
}
|
|
227
|
+
`;
|
|
228
|
+
}
|
|
229
|
+
function generateAwsIdentity() {
|
|
230
|
+
return `${header()}# Cognito User Pool: the enterprise identity front door. Federate a
|
|
231
|
+
# corporate IdP (Entra/Okta) via SAML by setting var.saml_metadata_url.
|
|
232
|
+
resource "aws_cognito_user_pool" "main" {
|
|
233
|
+
name = "\${var.project}-users"
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
resource "aws_cognito_user_pool_client" "shelf" {
|
|
237
|
+
name = "\${var.project}-shelf"
|
|
238
|
+
user_pool_id = aws_cognito_user_pool.main.id
|
|
239
|
+
generate_secret = true
|
|
240
|
+
|
|
241
|
+
allowed_oauth_flows = ["code"]
|
|
242
|
+
allowed_oauth_scopes = ["openid", "email", "profile"]
|
|
243
|
+
callback_urls = ["https://\${var.domain_name == "" ? aws_lb.main.dns_name : var.domain_name}/auth/callback"]
|
|
244
|
+
supported_identity_providers = ["COGNITO"]
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
resource "aws_cognito_user_group" "admins" {
|
|
248
|
+
name = "shelf-admins"
|
|
249
|
+
user_pool_id = aws_cognito_user_pool.main.id
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
resource "aws_cognito_identity_provider" "saml" {
|
|
253
|
+
count = var.saml_metadata_url == "" ? 0 : 1
|
|
254
|
+
user_pool_id = aws_cognito_user_pool.main.id
|
|
255
|
+
provider_name = "CorporateSAML"
|
|
256
|
+
provider_type = "SAML"
|
|
257
|
+
|
|
258
|
+
provider_details = {
|
|
259
|
+
MetadataURL = var.saml_metadata_url
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
`;
|
|
263
|
+
}
|
|
264
|
+
function generateAwsCompute() {
|
|
265
|
+
return `${header()}# ECS Fargate: long-lived app + worker services. Playwright/Chromium
|
|
266
|
+
# renders on Fargate — Lambda's 15-minute limit and /tmp caps rule it out.
|
|
267
|
+
resource "aws_lb" "main" {
|
|
268
|
+
name = "\${var.project}-alb"
|
|
269
|
+
load_balancer_type = "application"
|
|
270
|
+
security_groups = [aws_security_group.alb.id]
|
|
271
|
+
subnets = data.aws_subnets.public.ids
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
resource "aws_ecs_cluster" "main" {
|
|
275
|
+
name = "\${var.project}-cluster"
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
resource "aws_cloudwatch_log_group" "app" {
|
|
279
|
+
name = "/ecs/\${var.project}-app"
|
|
280
|
+
retention_in_days = 30
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
resource "aws_cloudwatch_log_group" "worker" {
|
|
284
|
+
name = "/ecs/\${var.project}-worker"
|
|
285
|
+
retention_in_days = 30
|
|
286
|
+
}
|
|
287
|
+
`;
|
|
288
|
+
}
|
|
289
|
+
function generateAwsSecrets() {
|
|
290
|
+
return `${header()}# Secrets Manager: session secret, OIDC secret, break-glass admin
|
|
291
|
+
# token. Task roles below may read exactly these ARNs.
|
|
292
|
+
resource "aws_secretsmanager_secret" "shelf_secret" {
|
|
293
|
+
name = "\${var.project}/SECRET"
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
resource "aws_secretsmanager_secret" "oidc_client_secret" {
|
|
297
|
+
name = "\${var.project}/OIDC_CLIENT_SECRET"
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
resource "aws_secretsmanager_secret" "admin_token" {
|
|
301
|
+
name = "\${var.project}/ADMIN_TOKEN"
|
|
302
|
+
}
|
|
303
|
+
`;
|
|
304
|
+
}
|
|
305
|
+
function generateAwsDns() {
|
|
306
|
+
return `${header()}# Route 53 + ACM. Skipped entirely when var.domain_name is empty
|
|
307
|
+
# (the ALB stays HTTP-only for dev).
|
|
308
|
+
resource "aws_acm_certificate" "main" {
|
|
309
|
+
count = var.domain_name == "" ? 0 : 1
|
|
310
|
+
domain_name = var.domain_name
|
|
311
|
+
validation_method = "DNS"
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
resource "aws_route53_zone" "main" {
|
|
315
|
+
count = var.domain_name == "" ? 0 : 1
|
|
316
|
+
name = var.domain_name
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
resource "aws_route53_record" "app" {
|
|
320
|
+
count = var.domain_name == "" ? 0 : 1
|
|
321
|
+
zone_id = aws_route53_zone.main[0].zone_id
|
|
322
|
+
name = var.domain_name
|
|
323
|
+
type = "A"
|
|
324
|
+
|
|
325
|
+
alias {
|
|
326
|
+
name = aws_lb.main.dns_name
|
|
327
|
+
zone_id = aws_lb.main.zone_id
|
|
328
|
+
evaluate_target_health = true
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
`;
|
|
332
|
+
}
|
|
333
|
+
function generateAwsOutputs(dbEngine) {
|
|
334
|
+
return `${header()}# Outputs feed directly into the scaffolded server's env.
|
|
335
|
+
# Keys are a stable contract parsed by CI — do not rename.
|
|
336
|
+
output "alb_dns_name" {
|
|
337
|
+
value = aws_lb.main.dns_name
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
output "s3_bucket" {
|
|
341
|
+
value = aws_s3_bucket.storybook.id
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
output "queue_url" {
|
|
345
|
+
value = aws_sqs_queue.capture.url
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
output "db_endpoint" {
|
|
349
|
+
value = ${generateAwsDbEndpoint(dbEngine)}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
output "user_pool_id" {
|
|
353
|
+
value = aws_cognito_user_pool.main.id
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
output "app_client_id" {
|
|
357
|
+
value = aws_cognito_user_pool_client.shelf.id
|
|
358
|
+
}
|
|
359
|
+
`;
|
|
360
|
+
}
|
|
361
|
+
/** Connection endpoint per Postgres engine (DSQL has no endpoint attribute). */
|
|
362
|
+
function generateAwsDbEndpoint(dbEngine) {
|
|
363
|
+
if (dbEngine === "dsql") return `"\${aws_dsql_cluster.main.identifier}.dsql.\${var.region}.on.aws"`;
|
|
364
|
+
return "aws_db_instance.main.endpoint";
|
|
365
|
+
}
|
|
366
|
+
function generateAwsCiProfile() {
|
|
367
|
+
return `## CI test profile
|
|
368
|
+
|
|
369
|
+
Smallest footprint, unique resources per run, documented destroy.
|
|
370
|
+
Prefer the serverless engine for CI (no instance to pay for idle):
|
|
371
|
+
|
|
372
|
+
\`\`\`sh
|
|
373
|
+
export PROJECT="shelf-ci-$GITHUB_RUN_ID" # unique prefix per run (all names derive from it)
|
|
374
|
+
terraform init
|
|
375
|
+
terraform plan -var "project=$PROJECT" -out=tfplan
|
|
376
|
+
terraform apply tfplan
|
|
377
|
+
terraform output -json # or: npm run infra:outputs
|
|
378
|
+
# ... run live tests against the outputs ...
|
|
379
|
+
terraform destroy -var "project=$PROJECT" -auto-approve
|
|
380
|
+
\`\`\`
|
|
381
|
+
|
|
382
|
+
Re-scaffold with the DSQL engine for the cheapest CI runs
|
|
383
|
+
(\`dbEngine: "dsql"\`); RDS uses the smallest burstable class
|
|
384
|
+
(\`db.t4g.micro\`) when you need a classic instance.
|
|
385
|
+
`;
|
|
386
|
+
}
|
|
387
|
+
function generateAwsReadme(project) {
|
|
388
|
+
return `# ${project} on AWS
|
|
389
|
+
|
|
390
|
+
Scaffolded by \`storyshelf server init --target aws\`.
|
|
391
|
+
|
|
392
|
+
## Next steps
|
|
393
|
+
|
|
394
|
+
\`\`\`sh
|
|
395
|
+
cd terraform
|
|
396
|
+
terraform init
|
|
397
|
+
terraform plan -out=tfplan # review before applying
|
|
398
|
+
terraform apply tfplan
|
|
399
|
+
\`\`\`
|
|
400
|
+
|
|
401
|
+
## Wire outputs into env
|
|
402
|
+
|
|
403
|
+
\`\`\`sh
|
|
404
|
+
terraform output -json # or: npm run infra:outputs
|
|
405
|
+
\`\`\`
|
|
406
|
+
|
|
407
|
+
| Output | Env var | Adapter |
|
|
408
|
+
|---|---|---|
|
|
409
|
+
| \`s3_bucket\` | \`S3_BUCKET\` (+ \`AWS_REGION\`) | \`storage-s3\` |
|
|
410
|
+
| \`queue_url\` | \`QUEUE_URL\` | \`queue-sqs\` |
|
|
411
|
+
| \`db_endpoint\` | \`DATABASE_URL\` (\`?sslmode=require\`) | \`db-postgres\` |
|
|
412
|
+
| \`user_pool_id\` / \`app_client_id\` | \`COGNITO_DOMAIN\` / \`COGNITO_REGION\` / \`COGNITO_USER_POOL_ID\` / \`OIDC_CLIENT_ID\` | \`auth\` (cognito social) |
|
|
413
|
+
| Secrets Manager | \`SECRET\` / \`OIDC_CLIENT_SECRET\` / \`ADMIN_TOKEN\` | sessions / OIDC / bootstrap |
|
|
414
|
+
|
|
415
|
+
\`\`\`sh
|
|
416
|
+
npm install
|
|
417
|
+
npm start
|
|
418
|
+
\`\`\`
|
|
419
|
+
|
|
420
|
+
Credentials come from IAM (ECS task roles) — never check access keys into env files.
|
|
421
|
+
|
|
422
|
+
${generateAwsCiProfile()}`;
|
|
423
|
+
}
|
|
424
|
+
function generateAwsTfvarsExample() {
|
|
425
|
+
return `# Copy to terraform.tfvars and fill in per environment.
|
|
426
|
+
# CI test profile: pass a unique project per run instead —
|
|
427
|
+
# terraform plan -var "project=shelf-ci-$GITHUB_RUN_ID"
|
|
428
|
+
# db_engine is baked at scaffold time (rds | dsql); prefer dsql for CI.
|
|
429
|
+
project = "my-storyshelf"
|
|
430
|
+
region = "us-east-1"
|
|
431
|
+
vpc_id = ""
|
|
432
|
+
domain_name = ""
|
|
433
|
+
saml_metadata_url = ""
|
|
434
|
+
`;
|
|
435
|
+
}
|
|
436
|
+
const AWS_FILES = [
|
|
437
|
+
["terraform/versions.tf", () => generateAwsVersions()],
|
|
438
|
+
["terraform/variables.tf", () => generateAwsVariables()],
|
|
439
|
+
["terraform/network.tf", () => `${generateAwsVpc()}${generateAwsSecurity()}${generateAwsEndpoints()}`],
|
|
440
|
+
["terraform/storage.tf", () => generateAwsStorage()],
|
|
441
|
+
["terraform/queue.tf", () => generateAwsQueue()],
|
|
442
|
+
["terraform/identity.tf", () => generateAwsIdentity()],
|
|
443
|
+
["terraform/compute.tf", () => generateAwsCompute()],
|
|
444
|
+
["terraform/secrets.tf", () => generateAwsSecrets()],
|
|
445
|
+
["terraform/dns.tf", () => generateAwsDns()],
|
|
446
|
+
["terraform/outputs.tf", (options) => generateAwsOutputs(options.dbEngine)],
|
|
447
|
+
["terraform/terraform.tfvars.example", () => generateAwsTfvarsExample()]
|
|
448
|
+
];
|
|
449
|
+
/** Generate every Terraform file for the AWS reference stack. */
|
|
450
|
+
function generateAwsTerraformFiles(options) {
|
|
451
|
+
const files = {};
|
|
452
|
+
for (const [path, generate] of AWS_FILES) files[path] = generate(options);
|
|
453
|
+
files["terraform/database.tf"] = generateAwsDatabase(options.dbEngine);
|
|
454
|
+
files["terraform/README.md"] = generateAwsReadme(options.project);
|
|
455
|
+
return files;
|
|
456
|
+
}
|
|
457
|
+
//#endregion
|
|
458
|
+
export { TERRAFORM_REQUIRED_VERSION, generateAwsCompute, generateAwsDatabase, generateAwsDns, generateAwsEndpoints, generateAwsIdentity, generateAwsOutputs, generateAwsQueue, generateAwsReadme, generateAwsSecrets, generateAwsSecurity, generateAwsStorage, generateAwsTerraformFiles, generateAwsTfvarsExample, generateAwsVariables, generateAwsVersions, generateAwsVpc };
|