@stacksjs/cloud 0.58.49 → 0.58.50
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/dist/index.js +144 -60
- package/package.json +32 -32
- package/src/cloud/aws-sdk-layer/nodejs/package-lock.json +6 -6
- package/src/cloud/aws-sdk-layer/nodejs/package.json +2 -2
- package/src/cloud/cdn.ts +5 -5
- package/src/cloud/compute.ts +150 -28
- package/src/cloud/index.ts +13 -9
- package/src/cloud/network.ts +4 -24
- package/src/cloud/package/package.json +1 -1
- package/src/cloud/router-layer/nodejs/package.json +2 -2
- package/src/cloud/stacksjs-router-0.58.48.tgz +0 -0
package/dist/index.js
CHANGED
|
@@ -406,6 +406,7 @@ var appEnv = config2.app.env === "local" ? "dev" : config2.app.env;
|
|
|
406
406
|
var cloudName = `stacks-cloud-${appEnv}`;
|
|
407
407
|
// src/cloud/index.ts
|
|
408
408
|
import {Stack as Stack2} from "aws-cdk-lib";
|
|
409
|
+
import {config as config20} from "@stacksjs/config";
|
|
409
410
|
|
|
410
411
|
// src/cloud/ai.ts
|
|
411
412
|
import {Duration, CfnOutput as Output, aws_iam as iam, aws_lambda as lambda} from "aws-cdk-lib";
|
|
@@ -1347,7 +1348,7 @@ class CdnStack {
|
|
|
1347
1348
|
}
|
|
1348
1349
|
}
|
|
1349
1350
|
shouldDeployApi() {
|
|
1350
|
-
return config6.cloud.api;
|
|
1351
|
+
return config6.cloud.api?.deploy;
|
|
1351
1352
|
}
|
|
1352
1353
|
apiBehaviorOptions(scope, props) {
|
|
1353
1354
|
const hostname = Fn.select(2, Fn.split("/", props.webServerUrl.url));
|
|
@@ -1472,7 +1473,6 @@ class CdnStack {
|
|
|
1472
1473
|
if (this.shouldDeployApi()) {
|
|
1473
1474
|
const keysToRemove = ["_HANDLER", "_X_AMZN_TRACE_ID", "AWS_REGION", "AWS_EXECUTION_ENV", "AWS_LAMBDA_FUNCTION_NAME", "AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "AWS_LAMBDA_FUNCTION_VERSION", "AWS_LAMBDA_INITIALIZATION_TYPE", "AWS_LAMBDA_LOG_GROUP_NAME", "AWS_LAMBDA_LOG_STREAM_NAME", "AWS_ACCESS_KEY", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_LAMBDA_RUNTIME_API", "LAMBDA_TASK_ROOT", "LAMBDA_RUNTIME_DIR", "_"];
|
|
1474
1475
|
keysToRemove.forEach((key) => delete env2[key]);
|
|
1475
|
-
behaviorOptions = this.apiBehaviorOptions(scope, props);
|
|
1476
1476
|
}
|
|
1477
1477
|
if (this.shouldDeployDocs() && !config6.app.docMode) {
|
|
1478
1478
|
behaviorOptions = {
|
|
@@ -1960,34 +1960,14 @@ class NetworkStack {
|
|
|
1960
1960
|
natGateways: 0,
|
|
1961
1961
|
subnetConfiguration: [
|
|
1962
1962
|
{
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1963
|
+
name: "public-subnet-1",
|
|
1964
|
+
subnetType: ec22.SubnetType.PUBLIC,
|
|
1965
|
+
cidrMask: 24
|
|
1966
1966
|
},
|
|
1967
1967
|
{
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
},
|
|
1972
|
-
{
|
|
1973
|
-
cidrMask: 21,
|
|
1974
|
-
name: `${props.slug}-${props.appEnv}-public-subnet-3`,
|
|
1975
|
-
subnetType: ec22.SubnetType.PUBLIC
|
|
1976
|
-
},
|
|
1977
|
-
{
|
|
1978
|
-
cidrMask: 21,
|
|
1979
|
-
name: `${props.slug}-${props.appEnv}-private-subnet-1`,
|
|
1980
|
-
subnetType: ec22.SubnetType.PRIVATE_ISOLATED
|
|
1981
|
-
},
|
|
1982
|
-
{
|
|
1983
|
-
cidrMask: 21,
|
|
1984
|
-
name: `${props.slug}-${props.appEnv}-private-subnet-2`,
|
|
1985
|
-
subnetType: ec22.SubnetType.PRIVATE_ISOLATED
|
|
1986
|
-
},
|
|
1987
|
-
{
|
|
1988
|
-
cidrMask: 21,
|
|
1989
|
-
name: `${props.slug}-${props.appEnv}-private-subnet-3`,
|
|
1990
|
-
subnetType: ec22.SubnetType.PRIVATE_ISOLATED
|
|
1968
|
+
name: "private-subnet-1",
|
|
1969
|
+
subnetType: ec22.SubnetType.PRIVATE_ISOLATED,
|
|
1970
|
+
cidrMask: 28
|
|
1991
1971
|
}
|
|
1992
1972
|
]
|
|
1993
1973
|
});
|
|
@@ -2337,11 +2317,14 @@ class PermissionsStack {
|
|
|
2337
2317
|
}
|
|
2338
2318
|
|
|
2339
2319
|
// src/cloud/compute.ts
|
|
2340
|
-
import {Duration as Duration6, CfnOutput as Output6,
|
|
2320
|
+
import {Duration as Duration6, CfnOutput as Output6, RemovalPolicy as RemovalPolicy8, aws_ec2 as ec23, aws_ecs as ecs, aws_secretsmanager as secretsmanager} from "aws-cdk-lib";
|
|
2341
2321
|
import {path as p6} from "@stacksjs/path";
|
|
2342
2322
|
import {env as env6} from "@stacksjs/env";
|
|
2323
|
+
import {LogGroup} from "aws-cdk-lib/aws-logs";
|
|
2324
|
+
import * as elbv2 from "aws-cdk-lib/aws-elasticloadbalancingv2";
|
|
2343
2325
|
|
|
2344
2326
|
class ComputeStack {
|
|
2327
|
+
lb;
|
|
2345
2328
|
apiServer;
|
|
2346
2329
|
apiServerUrl;
|
|
2347
2330
|
constructor(scope, props) {
|
|
@@ -2349,17 +2332,122 @@ class ComputeStack {
|
|
|
2349
2332
|
const fileSystem = props.fileSystem;
|
|
2350
2333
|
if (!fileSystem)
|
|
2351
2334
|
throw new Error("The file system is missing. Please make sure it was created properly.");
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2335
|
+
const cluster = new ecs.Cluster(scope, "StacksCluster", {
|
|
2336
|
+
clusterName: `${props.slug}-${props.appEnv}-web-server-cluster`,
|
|
2337
|
+
vpc
|
|
2338
|
+
});
|
|
2339
|
+
const taskDefinition = new ecs.FargateTaskDefinition(scope, "TaskDefinition", {
|
|
2340
|
+
family: `${props.appName}-${props.appEnv}-api`,
|
|
2341
|
+
memoryLimitMiB: 512,
|
|
2342
|
+
cpu: 256,
|
|
2343
|
+
runtimePlatform: {
|
|
2344
|
+
cpuArchitecture: ecs.CpuArchitecture.ARM64
|
|
2345
|
+
}
|
|
2346
|
+
});
|
|
2347
|
+
const container = taskDefinition.addContainer("WebServerContainer", {
|
|
2348
|
+
containerName: `${props.appName}-${props.appEnv}-api`,
|
|
2349
|
+
image: ecs.ContainerImage.fromAsset(p6.frameworkPath("server")),
|
|
2350
|
+
logging: new ecs.AwsLogDriver({
|
|
2351
|
+
streamPrefix: `${props.appName}-${props.appEnv}-web`,
|
|
2352
|
+
logGroup: new LogGroup(scope, "StacksApiLogs", {
|
|
2353
|
+
logGroupName: "/ecs/stacks-api",
|
|
2354
|
+
removalPolicy: RemovalPolicy8.DESTROY
|
|
2355
|
+
})
|
|
2356
|
+
}),
|
|
2357
|
+
healthCheck: {
|
|
2358
|
+
command: ["CMD-SHELL", "curl -f http://localhost:3000/health || exit 1"],
|
|
2359
|
+
interval: Duration6.seconds(10),
|
|
2360
|
+
timeout: Duration6.seconds(5),
|
|
2361
|
+
retries: 3,
|
|
2362
|
+
startPeriod: Duration6.seconds(10)
|
|
2363
|
+
}
|
|
2364
|
+
});
|
|
2365
|
+
container.addPortMappings({
|
|
2366
|
+
containerPort: 3000,
|
|
2367
|
+
hostPort: 3000
|
|
2368
|
+
});
|
|
2369
|
+
const serviceSecurityGroup = new ec23.SecurityGroup(scope, "ServiceSecurityGroup", {
|
|
2370
|
+
securityGroupName: `${props.appName}-${props.appEnv}-api-service-sg`,
|
|
2358
2371
|
vpc,
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2372
|
+
description: "Stacks Security Group for API Service"
|
|
2373
|
+
});
|
|
2374
|
+
const publicLoadBalancerSG = new ec23.SecurityGroup(scope, "PublicLoadBalancerSG", {
|
|
2375
|
+
securityGroupName: `${props.appName}-${props.appEnv}-public-load-balancer-sg`,
|
|
2376
|
+
vpc,
|
|
2377
|
+
description: "Access to the public facing load balancer"
|
|
2378
|
+
});
|
|
2379
|
+
serviceSecurityGroup.addIngressRule(publicLoadBalancerSG, ec23.Port.allTraffic(), "Ingress from the public ALB");
|
|
2380
|
+
serviceSecurityGroup.addIngressRule(publicLoadBalancerSG, ec23.Port.allTraffic(), "Ingress from the public ALB");
|
|
2381
|
+
this.lb = new elbv2.ApplicationLoadBalancer(scope, "ApplicationLoadBalancer", {
|
|
2382
|
+
loadBalancerName: `${props.appName}-${props.appEnv}-alb`,
|
|
2383
|
+
vpc,
|
|
2384
|
+
vpcSubnets: {
|
|
2385
|
+
subnets: vpc.selectSubnets({
|
|
2386
|
+
subnetType: ec23.SubnetType.PUBLIC,
|
|
2387
|
+
onePerAz: true
|
|
2388
|
+
}).subnets
|
|
2389
|
+
},
|
|
2390
|
+
internetFacing: true,
|
|
2391
|
+
idleTimeout: Duration6.seconds(30),
|
|
2392
|
+
securityGroup: publicLoadBalancerSG
|
|
2393
|
+
});
|
|
2394
|
+
const serviceTargetGroup = new elbv2.ApplicationTargetGroup(scope, "ServiceTargetGroup", {
|
|
2395
|
+
vpc,
|
|
2396
|
+
targetType: elbv2.TargetType.IP,
|
|
2397
|
+
protocol: elbv2.ApplicationProtocol.HTTP,
|
|
2398
|
+
port: 3000,
|
|
2399
|
+
healthCheck: {
|
|
2400
|
+
interval: Duration6.seconds(6),
|
|
2401
|
+
path: "/",
|
|
2402
|
+
protocol: elbv2.Protocol.HTTP,
|
|
2403
|
+
timeout: Duration6.seconds(5),
|
|
2404
|
+
healthyThresholdCount: 2,
|
|
2405
|
+
unhealthyThresholdCount: 10
|
|
2406
|
+
}
|
|
2407
|
+
});
|
|
2408
|
+
const service = new ecs.FargateService(scope, "StacksApiService", {
|
|
2409
|
+
serviceName: `${props.appName}-${props.appEnv}-api-service`,
|
|
2410
|
+
cluster,
|
|
2411
|
+
taskDefinition,
|
|
2412
|
+
desiredCount: 2,
|
|
2413
|
+
assignPublicIp: true,
|
|
2414
|
+
maxHealthyPercent: 200,
|
|
2415
|
+
vpcSubnets: vpc.selectSubnets({
|
|
2416
|
+
subnetType: ec23.SubnetType.PUBLIC,
|
|
2417
|
+
onePerAz: true
|
|
2418
|
+
}),
|
|
2419
|
+
minHealthyPercent: 75,
|
|
2420
|
+
securityGroups: [serviceSecurityGroup]
|
|
2421
|
+
});
|
|
2422
|
+
service.attachToApplicationTargetGroup(serviceTargetGroup);
|
|
2423
|
+
publicLoadBalancerSG.addIngressRule(ec23.Peer.anyIpv4(), ec23.Port.allTraffic());
|
|
2424
|
+
this.lb.addListener("HttpListener", {
|
|
2425
|
+
port: 80,
|
|
2426
|
+
defaultAction: elbv2.ListenerAction.forward([serviceTargetGroup])
|
|
2427
|
+
});
|
|
2428
|
+
props.fileSystem.connections.allowFromAnyIpv4(ec23.Port.tcp(2049));
|
|
2429
|
+
const volumeName = `${props.slug}-${props.appEnv}-efs`;
|
|
2430
|
+
taskDefinition.addVolume({
|
|
2431
|
+
name: volumeName,
|
|
2432
|
+
efsVolumeConfiguration: {
|
|
2433
|
+
fileSystemId: props.fileSystem.fileSystemId
|
|
2434
|
+
}
|
|
2435
|
+
});
|
|
2436
|
+
container.addMountPoints({
|
|
2437
|
+
sourceVolume: volumeName,
|
|
2438
|
+
containerPath: "/mnt/efs",
|
|
2439
|
+
readOnly: false
|
|
2440
|
+
});
|
|
2441
|
+
const scaling = service.autoScaleTaskCount({ maxCapacity: 2 });
|
|
2442
|
+
scaling.scaleOnCpuUtilization("CpuScaling", {
|
|
2443
|
+
targetUtilizationPercent: 50,
|
|
2444
|
+
scaleInCooldown: Duration6.seconds(60),
|
|
2445
|
+
scaleOutCooldown: Duration6.seconds(60)
|
|
2446
|
+
});
|
|
2447
|
+
scaling.scaleOnMemoryUtilization("MemoryScaling", {
|
|
2448
|
+
targetUtilizationPercent: 60,
|
|
2449
|
+
scaleInCooldown: Duration6.seconds(60),
|
|
2450
|
+
scaleOutCooldown: Duration6.seconds(60)
|
|
2363
2451
|
});
|
|
2364
2452
|
const keysToRemove = ["_HANDLER", "_X_AMZN_TRACE_ID", "AWS_REGION", "AWS_EXECUTION_ENV", "AWS_LAMBDA_FUNCTION_NAME", "AWS_LAMBDA_FUNCTION_MEMORY_SIZE", "AWS_LAMBDA_FUNCTION_VERSION", "AWS_LAMBDA_INITIALIZATION_TYPE", "AWS_LAMBDA_LOG_GROUP_NAME", "AWS_LAMBDA_LOG_STREAM_NAME", "AWS_ACCESS_KEY", "AWS_ACCESS_KEY_ID", "AWS_SECRET_ACCESS_KEY", "AWS_SESSION_TOKEN", "AWS_LAMBDA_RUNTIME_API", "LAMBDA_TASK_ROOT", "LAMBDA_RUNTIME_DIR", "_"];
|
|
2365
2453
|
keysToRemove.forEach((key) => delete env6[key]);
|
|
@@ -2371,23 +2459,16 @@ class ComputeStack {
|
|
|
2371
2459
|
generateStringKey: Object.keys(env6).join(",").length.toString()
|
|
2372
2460
|
}
|
|
2373
2461
|
});
|
|
2374
|
-
secrets.grantRead(
|
|
2375
|
-
|
|
2376
|
-
this.apiServerUrl = new lambda5.FunctionUrl(scope, "StacksServerUrl", {
|
|
2377
|
-
function: this.apiServer,
|
|
2378
|
-
authType: lambda5.FunctionUrlAuthType.NONE,
|
|
2379
|
-
cors: {
|
|
2380
|
-
allowedOrigins: ["*"]
|
|
2381
|
-
}
|
|
2382
|
-
});
|
|
2462
|
+
secrets.grantRead(service.taskDefinition.executionRole);
|
|
2463
|
+
container.addEnvironment("SECRETS_ARN", secrets.secretArn);
|
|
2383
2464
|
const apiPrefix = "api";
|
|
2384
2465
|
new Output6(scope, "ApiUrl", {
|
|
2385
2466
|
value: `https://${props.domain}/${apiPrefix}`,
|
|
2386
2467
|
description: "The URL of the deployed application"
|
|
2387
2468
|
});
|
|
2388
2469
|
new Output6(scope, "ApiVanityUrl", {
|
|
2389
|
-
value: this.
|
|
2390
|
-
description: "The Vanity URL of the
|
|
2470
|
+
value: `http://${this.lb.loadBalancerDnsName}`,
|
|
2471
|
+
description: "The Vanity URL / DNS name of the load balancer"
|
|
2391
2472
|
});
|
|
2392
2473
|
}
|
|
2393
2474
|
}
|
|
@@ -2422,13 +2503,16 @@ class Cloud extends Stack2 {
|
|
|
2422
2503
|
});
|
|
2423
2504
|
new RedirectsStack(this, props);
|
|
2424
2505
|
new PermissionsStack(this);
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2506
|
+
let api;
|
|
2507
|
+
if (config20.cloud.api?.deploy) {
|
|
2508
|
+
api = new ComputeStack(this, {
|
|
2509
|
+
...props,
|
|
2510
|
+
vpc: network2.vpc,
|
|
2511
|
+
fileSystem: fileSystem.fileSystem,
|
|
2512
|
+
zone: dns2.zone,
|
|
2513
|
+
certificate: security2.certificate
|
|
2514
|
+
});
|
|
2515
|
+
}
|
|
2432
2516
|
const ai2 = new AiStack(this, props);
|
|
2433
2517
|
const cli4 = new CliStack(this, props);
|
|
2434
2518
|
const cdn2 = new CdnStack(this, {
|
|
@@ -2439,11 +2523,11 @@ class Cloud extends Stack2 {
|
|
|
2439
2523
|
firewall: security2.firewall,
|
|
2440
2524
|
originRequestFunction: docs2.originRequestFunction,
|
|
2441
2525
|
zone: dns2.zone,
|
|
2442
|
-
webServer: api.apiServer,
|
|
2443
|
-
webServerUrl: api.apiServerUrl,
|
|
2444
2526
|
cliSetupUrl: cli4.cliSetupUrl,
|
|
2445
2527
|
askAiUrl: ai2.askAiUrl,
|
|
2446
|
-
summarizeAiUrl: ai2.summarizeAiUrl
|
|
2528
|
+
summarizeAiUrl: ai2.summarizeAiUrl,
|
|
2529
|
+
webServer: api?.apiServer,
|
|
2530
|
+
webServerUrl: api?.apiServerUrl
|
|
2447
2531
|
});
|
|
2448
2532
|
new DeploymentStack(this, {
|
|
2449
2533
|
...props,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stacksjs/cloud",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.58.
|
|
4
|
+
"version": "0.58.50",
|
|
5
5
|
"description": "The Stacks cloud/serverless integration & implementation.",
|
|
6
6
|
"author": "Chris Breuer",
|
|
7
7
|
"license": "MIT",
|
|
@@ -55,20 +55,20 @@
|
|
|
55
55
|
"prepublishOnly": "bun run build"
|
|
56
56
|
},
|
|
57
57
|
"peerDependencies": {
|
|
58
|
-
"@aws-sdk/client-bedrock": "^3.
|
|
59
|
-
"@aws-sdk/client-cloudformation": "^3.
|
|
60
|
-
"@aws-sdk/client-cloudfront": "^3.
|
|
61
|
-
"@aws-sdk/client-cloudwatch-logs": "^3.
|
|
62
|
-
"@aws-sdk/client-ec2": "^3.
|
|
63
|
-
"@aws-sdk/client-efs": "^3.
|
|
64
|
-
"@aws-sdk/client-iam": "^3.
|
|
65
|
-
"@aws-sdk/client-lambda": "^3.
|
|
66
|
-
"@aws-sdk/client-route-53-domains": "^3.
|
|
67
|
-
"@aws-sdk/client-s3": "^3.
|
|
68
|
-
"@aws-sdk/client-ses": "^3.
|
|
69
|
-
"@aws-sdk/client-sesv2": "^3.
|
|
70
|
-
"@aws-sdk/client-ssm": "^3.
|
|
71
|
-
"@aws-sdk/lib-dynamodb": "^3.
|
|
58
|
+
"@aws-sdk/client-bedrock": "^3.504.0",
|
|
59
|
+
"@aws-sdk/client-cloudformation": "^3.504.0",
|
|
60
|
+
"@aws-sdk/client-cloudfront": "^3.504.0",
|
|
61
|
+
"@aws-sdk/client-cloudwatch-logs": "^3.504.0",
|
|
62
|
+
"@aws-sdk/client-ec2": "^3.504.0",
|
|
63
|
+
"@aws-sdk/client-efs": "^3.504.0",
|
|
64
|
+
"@aws-sdk/client-iam": "^3.504.0",
|
|
65
|
+
"@aws-sdk/client-lambda": "^3.504.0",
|
|
66
|
+
"@aws-sdk/client-route-53-domains": "^3.504.0",
|
|
67
|
+
"@aws-sdk/client-s3": "^3.504.0",
|
|
68
|
+
"@aws-sdk/client-ses": "^3.504.0",
|
|
69
|
+
"@aws-sdk/client-sesv2": "^3.504.0",
|
|
70
|
+
"@aws-sdk/client-ssm": "^3.504.0",
|
|
71
|
+
"@aws-sdk/lib-dynamodb": "^3.506.0",
|
|
72
72
|
"@stacksjs/config": "latest",
|
|
73
73
|
"@stacksjs/env": "latest",
|
|
74
74
|
"@stacksjs/logging": "latest",
|
|
@@ -80,20 +80,20 @@
|
|
|
80
80
|
"@stacksjs/validation": "latest"
|
|
81
81
|
},
|
|
82
82
|
"dependencies": {
|
|
83
|
-
"@aws-sdk/client-bedrock": "^3.
|
|
84
|
-
"@aws-sdk/client-cloudformation": "^3.
|
|
85
|
-
"@aws-sdk/client-cloudfront": "^3.
|
|
86
|
-
"@aws-sdk/client-cloudwatch-logs": "^3.
|
|
87
|
-
"@aws-sdk/client-dynamodb": "3.
|
|
88
|
-
"@aws-sdk/client-ec2": "^3.
|
|
89
|
-
"@aws-sdk/client-efs": "^3.
|
|
90
|
-
"@aws-sdk/client-iam": "^3.
|
|
91
|
-
"@aws-sdk/client-lambda": "^3.
|
|
92
|
-
"@aws-sdk/client-route-53-domains": "^3.
|
|
93
|
-
"@aws-sdk/client-s3": "^3.
|
|
94
|
-
"@aws-sdk/client-ses": "^3.
|
|
95
|
-
"@aws-sdk/client-sesv2": "^3.
|
|
96
|
-
"@aws-sdk/client-ssm": "^3.
|
|
83
|
+
"@aws-sdk/client-bedrock": "^3.504.0",
|
|
84
|
+
"@aws-sdk/client-cloudformation": "^3.504.0",
|
|
85
|
+
"@aws-sdk/client-cloudfront": "^3.504.0",
|
|
86
|
+
"@aws-sdk/client-cloudwatch-logs": "^3.504.0",
|
|
87
|
+
"@aws-sdk/client-dynamodb": "3.506.0",
|
|
88
|
+
"@aws-sdk/client-ec2": "^3.504.0",
|
|
89
|
+
"@aws-sdk/client-efs": "^3.504.0",
|
|
90
|
+
"@aws-sdk/client-iam": "^3.504.0",
|
|
91
|
+
"@aws-sdk/client-lambda": "^3.504.0",
|
|
92
|
+
"@aws-sdk/client-route-53-domains": "^3.504.0",
|
|
93
|
+
"@aws-sdk/client-s3": "^3.504.0",
|
|
94
|
+
"@aws-sdk/client-ses": "^3.504.0",
|
|
95
|
+
"@aws-sdk/client-sesv2": "^3.504.0",
|
|
96
|
+
"@aws-sdk/client-ssm": "^3.504.0",
|
|
97
97
|
"@stacksjs/config": "latest",
|
|
98
98
|
"@stacksjs/dns": "latest",
|
|
99
99
|
"@stacksjs/env": "latest",
|
|
@@ -103,13 +103,13 @@
|
|
|
103
103
|
"@stacksjs/storage": "latest",
|
|
104
104
|
"@stacksjs/utils": "latest",
|
|
105
105
|
"@stacksjs/validation": "latest",
|
|
106
|
-
"aws-cdk": "^2.
|
|
107
|
-
"aws-cdk-lib": "^2.
|
|
106
|
+
"aws-cdk": "^2.126.0",
|
|
107
|
+
"aws-cdk-lib": "^2.126.0",
|
|
108
108
|
"aws4fetch": "^1.0.17",
|
|
109
109
|
"constructs": "^10.3.0"
|
|
110
110
|
},
|
|
111
111
|
"devDependencies": {
|
|
112
|
-
"@oclif/plugin-plugins": "^4.1
|
|
112
|
+
"@oclif/plugin-plugins": "^4.2.1",
|
|
113
113
|
"@stacksjs/cli": "latest",
|
|
114
114
|
"@stacksjs/development": "latest",
|
|
115
115
|
"@stacksjs/env": "latest",
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aws-sdk-layer",
|
|
3
|
-
"version": "0.58.
|
|
3
|
+
"version": "0.58.49",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "aws-sdk-layer",
|
|
9
|
-
"version": "0.58.
|
|
9
|
+
"version": "0.58.49",
|
|
10
10
|
"license": "ISC",
|
|
11
11
|
"dependencies": {
|
|
12
|
-
"aws-sdk": "^2.
|
|
12
|
+
"aws-sdk": "^2.1550.0"
|
|
13
13
|
}
|
|
14
14
|
},
|
|
15
15
|
"node_modules/available-typed-arrays": {
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
}
|
|
25
25
|
},
|
|
26
26
|
"node_modules/aws-sdk": {
|
|
27
|
-
"version": "2.
|
|
28
|
-
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.
|
|
29
|
-
"integrity": "sha512-
|
|
27
|
+
"version": "2.1550.0",
|
|
28
|
+
"resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1550.0.tgz",
|
|
29
|
+
"integrity": "sha512-abkbOeaL7iV085UqO8Y7/Ep7VYONK32chhKejhMbPYSqTp2YgNeqOSQfSaVZWeWCwqJxujEyoXFGTNgTt46D0g==",
|
|
30
30
|
"dependencies": {
|
|
31
31
|
"buffer": "4.9.2",
|
|
32
32
|
"events": "1.1.1",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aws-sdk-layer",
|
|
3
|
-
"version": "0.58.
|
|
3
|
+
"version": "0.58.50",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "ISC",
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"aws-sdk": "^2.
|
|
13
|
+
"aws-sdk": "^2.1550.0"
|
|
14
14
|
}
|
|
15
15
|
}
|
package/src/cloud/cdn.ts
CHANGED
|
@@ -16,8 +16,8 @@ export interface CdnStackProps extends NestedCloudProps {
|
|
|
16
16
|
firewall: wafv2.CfnWebACL
|
|
17
17
|
originRequestFunction: lambda.Function
|
|
18
18
|
zone: route53.IHostedZone
|
|
19
|
-
webServer
|
|
20
|
-
webServerUrl
|
|
19
|
+
webServer?: lambda.Function
|
|
20
|
+
webServerUrl?: lambda.FunctionUrl
|
|
21
21
|
cliSetupUrl: lambda.FunctionUrl
|
|
22
22
|
askAiUrl: lambda.FunctionUrl
|
|
23
23
|
summarizeAiUrl: lambda.FunctionUrl
|
|
@@ -184,11 +184,11 @@ export class CdnStack {
|
|
|
184
184
|
}
|
|
185
185
|
|
|
186
186
|
shouldDeployApi() {
|
|
187
|
-
return config.cloud.api
|
|
187
|
+
return config.cloud.api?.deploy
|
|
188
188
|
}
|
|
189
189
|
|
|
190
190
|
apiBehaviorOptions(scope: Construct, props: CdnStackProps): Record<string, cloudfront.BehaviorOptions> {
|
|
191
|
-
const hostname = Fn.select(2, Fn.split('/', props.webServerUrl
|
|
191
|
+
const hostname = Fn.select(2, Fn.split('/', props.webServerUrl!.url))
|
|
192
192
|
const origin = (path: '/api' | '/api/*' = '/api') => {
|
|
193
193
|
return new origins.HttpOrigin(hostname, {
|
|
194
194
|
originPath: path,
|
|
@@ -326,7 +326,7 @@ export class CdnStack {
|
|
|
326
326
|
const keysToRemove = ['_HANDLER', '_X_AMZN_TRACE_ID', 'AWS_REGION', 'AWS_EXECUTION_ENV', 'AWS_LAMBDA_FUNCTION_NAME', 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE', 'AWS_LAMBDA_FUNCTION_VERSION', 'AWS_LAMBDA_INITIALIZATION_TYPE', 'AWS_LAMBDA_LOG_GROUP_NAME', 'AWS_LAMBDA_LOG_STREAM_NAME', 'AWS_ACCESS_KEY', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_SESSION_TOKEN', 'AWS_LAMBDA_RUNTIME_API', 'LAMBDA_TASK_ROOT', 'LAMBDA_RUNTIME_DIR', '_']
|
|
327
327
|
keysToRemove.forEach(key => delete env[key as EnvKey])
|
|
328
328
|
|
|
329
|
-
behaviorOptions = this.apiBehaviorOptions(scope, props)
|
|
329
|
+
// behaviorOptions = this.apiBehaviorOptions(scope, props)
|
|
330
330
|
}
|
|
331
331
|
|
|
332
332
|
// if docMode is used, we don't need to add a behavior for the docs
|
package/src/cloud/compute.ts
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/* eslint-disable no-new */
|
|
2
|
-
import type { aws_certificatemanager as acm,
|
|
3
|
-
import { Duration, CfnOutput as Output,
|
|
2
|
+
import type { aws_certificatemanager as acm, aws_efs as efs, aws_lambda as lambda, aws_route53 as route53 } from 'aws-cdk-lib'
|
|
3
|
+
import { Duration, CfnOutput as Output, RemovalPolicy, aws_ec2 as ec2, aws_ecs as ecs, aws_secretsmanager as secretsmanager } from 'aws-cdk-lib'
|
|
4
4
|
import type { Construct } from 'constructs'
|
|
5
5
|
import { path as p } from '@stacksjs/path'
|
|
6
6
|
import { env } from '@stacksjs/env'
|
|
7
|
+
import { LogGroup } from 'aws-cdk-lib/aws-logs'
|
|
8
|
+
import * as elbv2 from 'aws-cdk-lib/aws-elasticloadbalancingv2'
|
|
7
9
|
import type { NestedCloudProps } from '../types'
|
|
8
10
|
import type { EnvKey } from '../../../../env'
|
|
9
11
|
|
|
@@ -15,6 +17,7 @@ export interface ComputeStackProps extends NestedCloudProps {
|
|
|
15
17
|
}
|
|
16
18
|
|
|
17
19
|
export class ComputeStack {
|
|
20
|
+
lb: elbv2.ApplicationLoadBalancer
|
|
18
21
|
apiServer: lambda.Function
|
|
19
22
|
apiServerUrl: lambda.FunctionUrl
|
|
20
23
|
|
|
@@ -25,22 +28,149 @@ export class ComputeStack {
|
|
|
25
28
|
if (!fileSystem)
|
|
26
29
|
throw new Error('The file system is missing. Please make sure it was created properly.')
|
|
27
30
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
+
const cluster = new ecs.Cluster(scope, 'StacksCluster', {
|
|
32
|
+
clusterName: `${props.slug}-${props.appEnv}-web-server-cluster`,
|
|
33
|
+
vpc,
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
const taskDefinition = new ecs.FargateTaskDefinition(scope, 'TaskDefinition', {
|
|
37
|
+
family: `${props.appName}-${props.appEnv}-api`,
|
|
38
|
+
memoryLimitMiB: 512, // Match your Lambda memory size
|
|
39
|
+
cpu: 256, // Choose an appropriate value
|
|
40
|
+
runtimePlatform: {
|
|
41
|
+
cpuArchitecture: ecs.CpuArchitecture.ARM64,
|
|
42
|
+
},
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const container = taskDefinition.addContainer('WebServerContainer', {
|
|
46
|
+
containerName: `${props.appName}-${props.appEnv}-api`,
|
|
47
|
+
image: ecs.ContainerImage.fromAsset(p.frameworkPath('server')),
|
|
48
|
+
logging: new ecs.AwsLogDriver({
|
|
49
|
+
streamPrefix: `${props.appName}-${props.appEnv}-web`,
|
|
50
|
+
logGroup: new LogGroup(scope, 'StacksApiLogs', {
|
|
51
|
+
logGroupName: '/ecs/stacks-api',
|
|
52
|
+
removalPolicy: RemovalPolicy.DESTROY, // Automatically remove logs on stack deletion
|
|
53
|
+
}),
|
|
54
|
+
}),
|
|
55
|
+
healthCheck: {
|
|
56
|
+
command: ['CMD-SHELL', 'curl -f http://localhost:3000/health || exit 1'],
|
|
57
|
+
interval: Duration.seconds(10),
|
|
58
|
+
timeout: Duration.seconds(5),
|
|
59
|
+
retries: 3,
|
|
60
|
+
startPeriod: Duration.seconds(10),
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
container.addPortMappings({
|
|
65
|
+
containerPort: 3000,
|
|
66
|
+
hostPort: 3000,
|
|
67
|
+
})
|
|
68
|
+
|
|
69
|
+
const serviceSecurityGroup = new ec2.SecurityGroup(scope, 'ServiceSecurityGroup', {
|
|
70
|
+
securityGroupName: `${props.appName}-${props.appEnv}-api-service-sg`,
|
|
71
|
+
vpc,
|
|
72
|
+
description: 'Stacks Security Group for API Service',
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const publicLoadBalancerSG = new ec2.SecurityGroup(scope, 'PublicLoadBalancerSG', {
|
|
76
|
+
securityGroupName: `${props.appName}-${props.appEnv}-public-load-balancer-sg`,
|
|
77
|
+
vpc,
|
|
78
|
+
description: 'Access to the public facing load balancer',
|
|
79
|
+
})
|
|
80
|
+
|
|
81
|
+
// Assuming serviceSecurityGroup and publicLoadBalancerSG are already defined
|
|
82
|
+
serviceSecurityGroup.addIngressRule(
|
|
83
|
+
publicLoadBalancerSG,
|
|
84
|
+
ec2.Port.allTraffic(),
|
|
85
|
+
'Ingress from the public ALB',
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
// Assuming serviceSecurityGroup and publicLoadBalancerSG are already defined
|
|
89
|
+
serviceSecurityGroup.addIngressRule(publicLoadBalancerSG, ec2.Port.allTraffic(), 'Ingress from the public ALB')
|
|
90
|
+
|
|
91
|
+
this.lb = new elbv2.ApplicationLoadBalancer(scope, 'ApplicationLoadBalancer', {
|
|
92
|
+
loadBalancerName: `${props.appName}-${props.appEnv}-alb`,
|
|
93
|
+
vpc,
|
|
94
|
+
vpcSubnets: {
|
|
95
|
+
subnets: vpc.selectSubnets({
|
|
96
|
+
subnetType: ec2.SubnetType.PUBLIC,
|
|
97
|
+
onePerAz: true,
|
|
98
|
+
}).subnets,
|
|
99
|
+
},
|
|
100
|
+
internetFacing: true,
|
|
101
|
+
idleTimeout: Duration.seconds(30),
|
|
102
|
+
securityGroup: publicLoadBalancerSG,
|
|
103
|
+
})
|
|
31
104
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
description: 'The web server for the Stacks application',
|
|
35
|
-
code: lambda.Code.fromAssetImage(p.frameworkPath('server')),
|
|
36
|
-
handler: lambda.Handler.FROM_IMAGE,
|
|
37
|
-
runtime: lambda.Runtime.FROM_IMAGE,
|
|
105
|
+
const serviceTargetGroup = new elbv2.ApplicationTargetGroup(scope, 'ServiceTargetGroup', {
|
|
106
|
+
// targetGroupName: `${props.appName}-${props.appEnv}-service-tg`,
|
|
38
107
|
vpc,
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
108
|
+
targetType: elbv2.TargetType.IP,
|
|
109
|
+
protocol: elbv2.ApplicationProtocol.HTTP,
|
|
110
|
+
port: 3000,
|
|
111
|
+
healthCheck: {
|
|
112
|
+
interval: Duration.seconds(6),
|
|
113
|
+
path: '/',
|
|
114
|
+
protocol: elbv2.Protocol.HTTP,
|
|
115
|
+
timeout: Duration.seconds(5),
|
|
116
|
+
healthyThresholdCount: 2,
|
|
117
|
+
unhealthyThresholdCount: 10,
|
|
118
|
+
},
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
const service = new ecs.FargateService(scope, 'StacksApiService', {
|
|
122
|
+
serviceName: `${props.appName}-${props.appEnv}-api-service`,
|
|
123
|
+
cluster,
|
|
124
|
+
taskDefinition,
|
|
125
|
+
desiredCount: 2,
|
|
126
|
+
assignPublicIp: true,
|
|
127
|
+
maxHealthyPercent: 200,
|
|
128
|
+
vpcSubnets: vpc.selectSubnets({
|
|
129
|
+
subnetType: ec2.SubnetType.PUBLIC,
|
|
130
|
+
onePerAz: true,
|
|
131
|
+
}),
|
|
132
|
+
minHealthyPercent: 75,
|
|
133
|
+
securityGroups: [serviceSecurityGroup],
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
service.attachToApplicationTargetGroup(serviceTargetGroup)
|
|
137
|
+
publicLoadBalancerSG.addIngressRule(ec2.Peer.anyIpv4(), ec2.Port.allTraffic())
|
|
138
|
+
|
|
139
|
+
this.lb.addListener('HttpListener', {
|
|
140
|
+
port: 80,
|
|
141
|
+
defaultAction: elbv2.ListenerAction.forward([serviceTargetGroup]),
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
props.fileSystem.connections.allowFromAnyIpv4(ec2.Port.tcp(2049)) // port 2049 (NFS) for EFS
|
|
145
|
+
|
|
146
|
+
const volumeName = `${props.slug}-${props.appEnv}-efs`
|
|
147
|
+
taskDefinition.addVolume({
|
|
148
|
+
name: volumeName,
|
|
149
|
+
efsVolumeConfiguration: {
|
|
150
|
+
fileSystemId: props.fileSystem.fileSystemId,
|
|
151
|
+
},
|
|
152
|
+
})
|
|
153
|
+
|
|
154
|
+
container.addMountPoints({
|
|
155
|
+
sourceVolume: volumeName,
|
|
156
|
+
containerPath: '/mnt/efs',
|
|
157
|
+
readOnly: false,
|
|
158
|
+
})
|
|
159
|
+
|
|
160
|
+
// Setup AutoScaling policy
|
|
161
|
+
// TODO: make this configurable in cloud.compute
|
|
162
|
+
const scaling = service.autoScaleTaskCount({ maxCapacity: 2 })
|
|
163
|
+
|
|
164
|
+
scaling.scaleOnCpuUtilization('CpuScaling', {
|
|
165
|
+
targetUtilizationPercent: 50,
|
|
166
|
+
scaleInCooldown: Duration.seconds(60),
|
|
167
|
+
scaleOutCooldown: Duration.seconds(60),
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
scaling.scaleOnMemoryUtilization('MemoryScaling', {
|
|
171
|
+
targetUtilizationPercent: 60,
|
|
172
|
+
scaleInCooldown: Duration.seconds(60),
|
|
173
|
+
scaleOutCooldown: Duration.seconds(60),
|
|
44
174
|
})
|
|
45
175
|
|
|
46
176
|
const keysToRemove = ['_HANDLER', '_X_AMZN_TRACE_ID', 'AWS_REGION', 'AWS_EXECUTION_ENV', 'AWS_LAMBDA_FUNCTION_NAME', 'AWS_LAMBDA_FUNCTION_MEMORY_SIZE', 'AWS_LAMBDA_FUNCTION_VERSION', 'AWS_LAMBDA_INITIALIZATION_TYPE', 'AWS_LAMBDA_LOG_GROUP_NAME', 'AWS_LAMBDA_LOG_STREAM_NAME', 'AWS_ACCESS_KEY', 'AWS_ACCESS_KEY_ID', 'AWS_SECRET_ACCESS_KEY', 'AWS_SESSION_TOKEN', 'AWS_LAMBDA_RUNTIME_API', 'LAMBDA_TASK_ROOT', 'LAMBDA_RUNTIME_DIR', '_']
|
|
@@ -55,16 +185,8 @@ export class ComputeStack {
|
|
|
55
185
|
},
|
|
56
186
|
})
|
|
57
187
|
|
|
58
|
-
secrets.grantRead(
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
this.apiServerUrl = new lambda.FunctionUrl(scope, 'StacksServerUrl', {
|
|
62
|
-
function: this.apiServer,
|
|
63
|
-
authType: lambda.FunctionUrlAuthType.NONE, // becomes a public API
|
|
64
|
-
cors: {
|
|
65
|
-
allowedOrigins: ['*'],
|
|
66
|
-
},
|
|
67
|
-
})
|
|
188
|
+
secrets.grantRead(service.taskDefinition.executionRole!)
|
|
189
|
+
container.addEnvironment('SECRETS_ARN', secrets.secretArn)
|
|
68
190
|
|
|
69
191
|
const apiPrefix = 'api'
|
|
70
192
|
new Output(scope, 'ApiUrl', {
|
|
@@ -73,8 +195,8 @@ export class ComputeStack {
|
|
|
73
195
|
})
|
|
74
196
|
|
|
75
197
|
new Output(scope, 'ApiVanityUrl', {
|
|
76
|
-
value: this.
|
|
77
|
-
description: 'The Vanity URL of the
|
|
198
|
+
value: `http://${this.lb.loadBalancerDnsName}`,
|
|
199
|
+
description: 'The Vanity URL / DNS name of the load balancer',
|
|
78
200
|
})
|
|
79
201
|
}
|
|
80
202
|
}
|
package/src/cloud/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/* eslint-disable no-new */
|
|
2
2
|
import { Stack } from 'aws-cdk-lib'
|
|
3
3
|
import type { Construct } from 'constructs'
|
|
4
|
+
import { config } from '@stacksjs/config'
|
|
4
5
|
import type { CloudOptions } from '../types'
|
|
5
6
|
import { AiStack } from './ai'
|
|
6
7
|
import { CdnStack } from './cdn'
|
|
@@ -62,13 +63,16 @@ export class Cloud extends Stack {
|
|
|
62
63
|
|
|
63
64
|
// new DashboardStack(this)
|
|
64
65
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
66
|
+
let api
|
|
67
|
+
if (config.cloud.api?.deploy) {
|
|
68
|
+
api = new ComputeStack(this, {
|
|
69
|
+
...props,
|
|
70
|
+
vpc: network.vpc,
|
|
71
|
+
fileSystem: fileSystem.fileSystem,
|
|
72
|
+
zone: dns.zone,
|
|
73
|
+
certificate: security.certificate,
|
|
74
|
+
})
|
|
75
|
+
}
|
|
72
76
|
|
|
73
77
|
const ai = new AiStack(this, props)
|
|
74
78
|
|
|
@@ -82,11 +86,11 @@ export class Cloud extends Stack {
|
|
|
82
86
|
firewall: security.firewall,
|
|
83
87
|
originRequestFunction: docs.originRequestFunction,
|
|
84
88
|
zone: dns.zone,
|
|
85
|
-
webServer: api.apiServer,
|
|
86
|
-
webServerUrl: api.apiServerUrl,
|
|
87
89
|
cliSetupUrl: cli.cliSetupUrl,
|
|
88
90
|
askAiUrl: ai.askAiUrl,
|
|
89
91
|
summarizeAiUrl: ai.summarizeAiUrl,
|
|
92
|
+
webServer: api?.apiServer,
|
|
93
|
+
webServerUrl: api?.apiServerUrl,
|
|
90
94
|
})
|
|
91
95
|
|
|
92
96
|
new DeploymentStack(this, {
|
package/src/cloud/network.ts
CHANGED
|
@@ -17,34 +17,14 @@ export class NetworkStack {
|
|
|
17
17
|
natGateways: 0,
|
|
18
18
|
subnetConfiguration: [
|
|
19
19
|
{
|
|
20
|
-
|
|
21
|
-
name: `${props.slug}-${props.appEnv}-public-subnet-1`,
|
|
20
|
+
name: 'public-subnet-1',
|
|
22
21
|
subnetType: ec2.SubnetType.PUBLIC,
|
|
22
|
+
cidrMask: 24,
|
|
23
23
|
},
|
|
24
24
|
{
|
|
25
|
-
|
|
26
|
-
name: `${props.slug}-${props.appEnv}-public-subnet-2`,
|
|
27
|
-
subnetType: ec2.SubnetType.PUBLIC,
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
cidrMask: 21,
|
|
31
|
-
name: `${props.slug}-${props.appEnv}-public-subnet-3`,
|
|
32
|
-
subnetType: ec2.SubnetType.PUBLIC,
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
cidrMask: 21,
|
|
36
|
-
name: `${props.slug}-${props.appEnv}-private-subnet-1`,
|
|
37
|
-
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
cidrMask: 21,
|
|
41
|
-
name: `${props.slug}-${props.appEnv}-private-subnet-2`,
|
|
42
|
-
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
cidrMask: 21,
|
|
46
|
-
name: `${props.slug}-${props.appEnv}-private-subnet-3`,
|
|
25
|
+
name: 'private-subnet-1',
|
|
47
26
|
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
|
|
27
|
+
cidrMask: 28,
|
|
48
28
|
},
|
|
49
29
|
],
|
|
50
30
|
})
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stacks-router-layer",
|
|
3
|
-
"version": "0.58.
|
|
3
|
+
"version": "0.58.50",
|
|
4
4
|
"description": "",
|
|
5
5
|
"author": "",
|
|
6
6
|
"license": "MIT",
|
|
@@ -10,6 +10,6 @@
|
|
|
10
10
|
"test": "echo \"Error: no test specified\" && exit 1"
|
|
11
11
|
},
|
|
12
12
|
"dependencies": {
|
|
13
|
-
"@stacksjs/router": "^0.58.
|
|
13
|
+
"@stacksjs/router": "^0.58.49"
|
|
14
14
|
}
|
|
15
15
|
}
|
|
Binary file
|