Fix ALB listener default action, auto-import numberOfAzs, and correct docs
- Fix HTTP listener in spicy-alb.ts missing default action when no certificate is provided, which would cause CDK synth to fail - Auto-import numberOfAzs from VPC stack exports (NumberOfAZs) in cluster, service, and ALB stacks when not provided via context - Fix CDK_SYNTH_EXAMPLES.md ALB examples using raw vpcId/subnetIds that don't match the actual fromContext() implementation (requires clusterName) - Fix docs overstating "only clusterName required" to list actual required params - Remove package-lock.json and add to .gitignore (project uses pnpm) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -8,3 +8,6 @@ node_modules
|
|||||||
cdk.out
|
cdk.out
|
||||||
OLD_STUFF/
|
OLD_STUFF/
|
||||||
OLDER_STUFF/
|
OLDER_STUFF/
|
||||||
|
|
||||||
|
# Use pnpm only
|
||||||
|
package-lock.json
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ pnpm exec cdk synth \
|
|||||||
|
|
||||||
### Minimal Cluster (No Load Balancers) - Using CloudFormation Imports
|
### Minimal Cluster (No Load Balancers) - Using CloudFormation Imports
|
||||||
|
|
||||||
**Minimal props approach:** Only `vpcStackName` required. All VPC details auto-import from VPC stack exports.
|
**Minimal required props:** `vpcStackName` and tags (`ownerTag`, `productTag`). All VPC details auto-import from VPC stack exports, including `numberOfAzs`.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm exec cdk synth \
|
pnpm exec cdk synth \
|
||||||
@@ -128,7 +128,7 @@ pnpm exec cdk synth \
|
|||||||
|
|
||||||
- VPC ID from `${vpcStackName}-VPCID`
|
- VPC ID from `${vpcStackName}-VPCID`
|
||||||
- VPC CIDR from `${vpcStackName}-VPCCIDR`
|
- VPC CIDR from `${vpcStackName}-VPCCIDR`
|
||||||
- Number of AZs from `${vpcStackName}-NumberOfAZs`
|
- Number of AZs from `${vpcStackName}-NumberOfAZs` (or override with `-c numberOfAzs=N`)
|
||||||
- Private subnet IDs from `${vpcStackName}-PrivateSubnetA1ID`, `${vpcStackName}-PrivateSubnetB1ID`, etc.
|
- Private subnet IDs from `${vpcStackName}-PrivateSubnetA1ID`, `${vpcStackName}-PrivateSubnetB1ID`, etc.
|
||||||
- Public subnet IDs from `${vpcStackName}-PublicSubnetAID`, `${vpcStackName}-PublicSubnetBID`, etc. (if `createExternalLoadBalancer=true`)
|
- Public subnet IDs from `${vpcStackName}-PublicSubnetAID`, `${vpcStackName}-PublicSubnetBID`, etc. (if `createExternalLoadBalancer=true`)
|
||||||
- Availability zones auto-derived from region and number of AZs
|
- Availability zones auto-derived from region and number of AZs
|
||||||
@@ -216,14 +216,13 @@ The ALB stack creates a persistent Application Load Balancer that can be shared
|
|||||||
|
|
||||||
### Internet-Facing ALB
|
### Internet-Facing ALB
|
||||||
|
|
||||||
|
**Uses CloudFormation imports:** Only `clusterName` (or `clusterStackName`) and `numberOfAzs` required. VPC details and subnets are auto-imported from cluster/VPC stack exports. `numberOfAzs` is also auto-imported from the VPC stack if not provided.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm exec cdk synth \
|
pnpm exec cdk synth \
|
||||||
-c stackType=alb \
|
-c stackType=alb \
|
||||||
-c stackName=my-service-alb \
|
-c stackName=my-service-alb \
|
||||||
-c vpcId=vpc-12345678 \
|
-c clusterName=my-cluster \
|
||||||
-c vpcCidrBlock=10.0.0.0/16 \
|
|
||||||
-c availabilityZones=ca-central-1a,ca-central-1b \
|
|
||||||
-c subnetIds=subnet-xxx,subnet-yyy \
|
|
||||||
-c scheme=internet-facing \
|
-c scheme=internet-facing \
|
||||||
-c certificateArn=arn:aws:acm:ca-central-1:123456789:certificate/xxx \
|
-c certificateArn=arn:aws:acm:ca-central-1:123456789:certificate/xxx \
|
||||||
-c logsBucketName=my-cluster-logs \
|
-c logsBucketName=my-cluster-logs \
|
||||||
@@ -233,13 +232,21 @@ pnpm exec cdk synth \
|
|||||||
-c environment=dev
|
-c environment=dev
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**What auto-imports:**
|
||||||
|
|
||||||
|
- VPC stack name from `${clusterStackName}-VPCStackName` (cluster stack export)
|
||||||
|
- VPC ID from `${clusterStackName}-VPC` (cluster stack export)
|
||||||
|
- VPC CIDR from `${vpcStackName}-VPCCIDR` (VPC stack export)
|
||||||
|
- Number of AZs from `${vpcStackName}-NumberOfAZs` (VPC stack export)
|
||||||
|
- Public subnet IDs from `${vpcStackName}-PublicSubnetAID`, etc. (for internet-facing)
|
||||||
|
- Private subnet IDs from `${vpcStackName}-PrivateSubnetA1ID`, etc. (for internal)
|
||||||
|
|
||||||
**Creates:**
|
**Creates:**
|
||||||
|
|
||||||
- Application Load Balancer (internet-facing)
|
- Application Load Balancer (internet-facing)
|
||||||
- Security Group for ALB
|
- Security Group for ALB
|
||||||
- HTTP Listener (port 80)
|
- HTTP Listener (port 80) with HTTP→HTTPS redirect
|
||||||
- HTTPS Listener (port 443) with SSL certificate
|
- HTTPS Listener (port 443) with SSL certificate
|
||||||
- HTTP→HTTPS redirect rule
|
|
||||||
- ALB access logs to S3 (if logsBucketName provided)
|
- ALB access logs to S3 (if logsBucketName provided)
|
||||||
|
|
||||||
### Internal ALB
|
### Internal ALB
|
||||||
@@ -248,10 +255,7 @@ pnpm exec cdk synth \
|
|||||||
pnpm exec cdk synth \
|
pnpm exec cdk synth \
|
||||||
-c stackType=alb \
|
-c stackType=alb \
|
||||||
-c stackName=my-service-alb \
|
-c stackName=my-service-alb \
|
||||||
-c vpcId=vpc-12345678 \
|
-c clusterName=my-cluster \
|
||||||
-c vpcCidrBlock=10.0.0.0/16 \
|
|
||||||
-c availabilityZones=ca-central-1a,ca-central-1b \
|
|
||||||
-c subnetIds=subnet-aaa,subnet-bbb \
|
|
||||||
-c scheme=internal \
|
-c scheme=internal \
|
||||||
-c certificateArn=arn:aws:acm:ca-central-1:123456789:certificate/xxx \
|
-c certificateArn=arn:aws:acm:ca-central-1:123456789:certificate/xxx \
|
||||||
-c logsBucketName=my-cluster-logs \
|
-c logsBucketName=my-cluster-logs \
|
||||||
@@ -267,10 +271,7 @@ pnpm exec cdk synth \
|
|||||||
pnpm exec cdk synth \
|
pnpm exec cdk synth \
|
||||||
-c stackType=alb \
|
-c stackType=alb \
|
||||||
-c stackName=my-service-alb \
|
-c stackName=my-service-alb \
|
||||||
-c vpcId=vpc-12345678 \
|
-c clusterName=my-cluster \
|
||||||
-c vpcCidrBlock=10.0.0.0/16 \
|
|
||||||
-c availabilityZones=ca-central-1a,ca-central-1b \
|
|
||||||
-c subnetIds=subnet-xxx,subnet-yyy \
|
|
||||||
-c scheme=internet-facing \
|
-c scheme=internet-facing \
|
||||||
-c certificateArn=arn:aws:acm:ca-central-1:123456789:certificate/xxx \
|
-c certificateArn=arn:aws:acm:ca-central-1:123456789:certificate/xxx \
|
||||||
-c logsBucketName=my-cluster-logs \
|
-c logsBucketName=my-cluster-logs \
|
||||||
@@ -295,7 +296,7 @@ pnpm exec cdk synth \
|
|||||||
|
|
||||||
### Minimal Service (No Load Balancer) - Using CloudFormation Imports
|
### Minimal Service (No Load Balancer) - Using CloudFormation Imports
|
||||||
|
|
||||||
**Minimal props approach:** Only `clusterName` is required. VPC info auto-imports from cluster stack exports.
|
**Minimal required props:** `clusterName`, `serviceName`, `image`, `containerPort`, and tags (`ownerTag`, `productTag`). All VPC info auto-imports from cluster/VPC stack exports.
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm exec cdk synth \
|
pnpm exec cdk synth \
|
||||||
@@ -316,11 +317,11 @@ pnpm exec cdk synth \
|
|||||||
- VPC stack name from `${clusterStackName}-VPCStackName` (cluster stack export)
|
- VPC stack name from `${clusterStackName}-VPCStackName` (cluster stack export)
|
||||||
- VPC ID from `${clusterStackName}-VPC` (cluster stack export)
|
- VPC ID from `${clusterStackName}-VPC` (cluster stack export)
|
||||||
- VPC CIDR from `${vpcStackName}-VPCCIDR` (VPC stack export, using imported VPC stack name)
|
- VPC CIDR from `${vpcStackName}-VPCCIDR` (VPC stack export, using imported VPC stack name)
|
||||||
- Private subnets from `${vpcStackName}-PrivateSubnetA1ID`, etc. (VPC stack exports)
|
|
||||||
- Number of AZs from `${vpcStackName}-NumberOfAZs` (VPC stack export)
|
- Number of AZs from `${vpcStackName}-NumberOfAZs` (VPC stack export)
|
||||||
|
- Private subnets from `${vpcStackName}-PrivateSubnetA1ID`, etc. (VPC stack exports)
|
||||||
- Logs bucket from `${clusterStackName}-logs-s3-bucket` (cluster stack export)
|
- Logs bucket from `${clusterStackName}-logs-s3-bucket` (cluster stack export)
|
||||||
|
|
||||||
**Note:** The service stack imports the VPC stack name from the cluster stack export `${clusterStackName}-VPCStackName`, then uses that to import all VPC details (CIDR, subnets, AZs) from the VPC stack exports.
|
**Note:** The service stack imports the VPC stack name from the cluster stack export `${clusterStackName}-VPCStackName`, then uses that to import all VPC details (CIDR, subnets, AZs) from the VPC stack exports. `numberOfAzs` can be provided explicitly via `-c numberOfAzs=N` but will auto-import from the VPC stack if omitted.
|
||||||
|
|
||||||
### Service with Cluster ALB - Using CloudFormation Imports
|
### Service with Cluster ALB - Using CloudFormation Imports
|
||||||
|
|
||||||
@@ -784,7 +785,7 @@ pnpm exec cdk synth \
|
|||||||
| `vpcCidrBlock` | - | VPC CIDR (required, or auto-imported from `${vpcStackName}-VPCCIDR` using imported VPC stack name) |
|
| `vpcCidrBlock` | - | VPC CIDR (required, or auto-imported from `${vpcStackName}-VPCCIDR` using imported VPC stack name) |
|
||||||
| `availabilityZones` | - | Comma-separated AZs (required, or auto-derived from VPC stack imports with `numberOfAzs`) |
|
| `availabilityZones` | - | Comma-separated AZs (required, or auto-derived from VPC stack imports with `numberOfAzs`) |
|
||||||
| `privateSubnetIds` | - | Private subnet IDs (required, or auto-imported from `${vpcStackName}-PrivateSubnetA1ID`, etc.) |
|
| `privateSubnetIds` | - | Private subnet IDs (required, or auto-imported from `${vpcStackName}-PrivateSubnetA1ID`, etc.) |
|
||||||
| `numberOfAzs` | - | Number of AZs (required when importing subnets from VPC stack) |
|
| `numberOfAzs` | auto | Number of AZs (auto-imported from VPC stack, or override explicitly) |
|
||||||
| `publicSubnetIds` | - | Public subnet IDs (for individual ALB) |
|
| `publicSubnetIds` | - | Public subnet IDs (for individual ALB) |
|
||||||
| `serviceName` | - | Service name (required) |
|
| `serviceName` | - | Service name (required) |
|
||||||
| `image` | - | Docker image URI (required) |
|
| `image` | - | Docker image URI (required) |
|
||||||
@@ -918,8 +919,8 @@ pnpm exec cdk synth -c stackType=vpc -c stackName=test -c ownerTag=T -c productT
|
|||||||
pnpm exec cdk synth -c stackType=ecs-cluster -c stackName=test -c vpcStackName=test-vpc -c ownerTag=T -c productTag=t -c componentTag=c -c environment=d
|
pnpm exec cdk synth -c stackType=ecs-cluster -c stackName=test -c vpcStackName=test-vpc -c ownerTag=T -c productTag=t -c componentTag=c -c environment=d
|
||||||
```
|
```
|
||||||
|
|
||||||
**Service:**
|
**Service (using CloudFormation imports):**
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm exec cdk synth -c stackType=ecs-service -c stackName=test -c clusterName=test -c vpcId=vpc-123 -c vpcCidrBlock=10.0.0.0/16 -c availabilityZones=ca-central-1a -c privateSubnetIds=subnet-123 -c serviceName=test -c image=nginx:latest -c containerPort=80 -c ownerTag=T -c productTag=t -c componentTag=s -c environment=d
|
pnpm exec cdk synth -c stackType=ecs-service -c stackName=test -c clusterName=test -c serviceName=test -c image=nginx:latest -c containerPort=80 -c ownerTag=T -c productTag=t -c componentTag=s -c environment=d
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ Deploy ECS services with mixed capacity provider strategies for EC2 + Fargate bu
|
|||||||
|
|
||||||
### Minimal Jenkinsfile (EC2 Only) - Using CloudFormation Imports
|
### Minimal Jenkinsfile (EC2 Only) - Using CloudFormation Imports
|
||||||
|
|
||||||
**Minimal props:** Only `clusterName` required. VPC info auto-imports from cluster stack exports.
|
**Minimal required props:** `clusterName`, `numberOfAzs`, `serviceName`, `image`, `containerPort`, and tags (`ownerTag`, `productTag`). VPC info auto-imports from cluster/VPC stack exports.
|
||||||
|
|
||||||
```groovy
|
```groovy
|
||||||
@Library(["spicy-automation@main"]) _
|
@Library(["spicy-automation@main"]) _
|
||||||
@@ -49,11 +49,11 @@ spicyECSService(
|
|||||||
- VPC stack name from `${clusterStackName}-VPCStackName` (cluster stack export)
|
- VPC stack name from `${clusterStackName}-VPCStackName` (cluster stack export)
|
||||||
- VPC ID from `${clusterStackName}-VPC` (cluster stack export)
|
- VPC ID from `${clusterStackName}-VPC` (cluster stack export)
|
||||||
- VPC CIDR from `${vpcStackName}-VPCCIDR` (VPC stack export, using imported VPC stack name)
|
- VPC CIDR from `${vpcStackName}-VPCCIDR` (VPC stack export, using imported VPC stack name)
|
||||||
|
- Number of AZs from `${vpcStackName}-NumberOfAZs` (VPC stack export, or override with `numberOfAzs` parameter)
|
||||||
- Private subnets from `${vpcStackName}-PrivateSubnetA1ID`, etc. (VPC stack exports)
|
- Private subnets from `${vpcStackName}-PrivateSubnetA1ID`, etc. (VPC stack exports)
|
||||||
- Number of AZs from `${vpcStackName}-NumberOfAZs` (VPC stack export)
|
|
||||||
- Logs bucket from `${clusterStackName}-logs-s3-bucket` (cluster stack export)
|
- Logs bucket from `${clusterStackName}-logs-s3-bucket` (cluster stack export)
|
||||||
|
|
||||||
**Note:** The service stack imports the VPC stack name from the cluster stack export `${clusterStackName}-VPCStackName`, then uses that to import all VPC details (CIDR, subnets, AZs) from the VPC stack exports.
|
**Note:** The service stack imports the VPC stack name from the cluster stack export `${clusterStackName}-VPCStackName`, then uses that to import all VPC details (CIDR, subnets, AZs) from the VPC stack exports. `numberOfAzs` is required by the Jenkins pipeline but auto-imports from VPC stack exports when using CDK directly.
|
||||||
|
|
||||||
### Mixed Capacity Strategy (EC2 + Fargate Burst)
|
### Mixed Capacity Strategy (EC2 + Fargate Burst)
|
||||||
|
|
||||||
|
|||||||
@@ -161,12 +161,6 @@ export class SpicyAlb extends Construct {
|
|||||||
this.loadBalancer.logAccessLogs(props.logsBucket, prefix);
|
this.loadBalancer.logAccessLogs(props.logsBucket, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTTP Listener
|
|
||||||
this.httpListener = this.loadBalancer.addListener('HTTPListener', {
|
|
||||||
port: 80,
|
|
||||||
protocol: elbv2.ApplicationProtocol.HTTP,
|
|
||||||
});
|
|
||||||
|
|
||||||
// HTTPS Listener (if certificate provided)
|
// HTTPS Listener (if certificate provided)
|
||||||
if (props.certificateArn) {
|
if (props.certificateArn) {
|
||||||
this.httpsListener = this.loadBalancer.addListener('HTTPSListener', {
|
this.httpsListener = this.loadBalancer.addListener('HTTPSListener', {
|
||||||
@@ -178,17 +172,28 @@ export class SpicyAlb extends Construct {
|
|||||||
messageBody: 'No target groups configured',
|
messageBody: 'No target groups configured',
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// HTTP→HTTPS redirect (if enabled, default true)
|
// HTTP Listener - redirect to HTTPS if certificate provided, otherwise serve as primary
|
||||||
if (props.redirectHttpToHttps !== false) {
|
if (props.certificateArn && props.redirectHttpToHttps !== false) {
|
||||||
this.httpListener.addAction('RedirectToHTTPS', {
|
this.httpListener = this.loadBalancer.addListener('HTTPListener', {
|
||||||
action: elbv2.ListenerAction.redirect({
|
port: 80,
|
||||||
protocol: 'HTTPS',
|
protocol: elbv2.ApplicationProtocol.HTTP,
|
||||||
port: '443',
|
defaultAction: elbv2.ListenerAction.redirect({
|
||||||
permanent: true,
|
protocol: 'HTTPS',
|
||||||
}),
|
port: '443',
|
||||||
});
|
permanent: true,
|
||||||
}
|
}),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.httpListener = this.loadBalancer.addListener('HTTPListener', {
|
||||||
|
port: 80,
|
||||||
|
protocol: elbv2.ApplicationProtocol.HTTP,
|
||||||
|
defaultAction: elbv2.ListenerAction.fixedResponse(404, {
|
||||||
|
contentType: 'text/plain',
|
||||||
|
messageBody: 'No target groups configured',
|
||||||
|
}),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Blue/Green DNS configuration
|
// Blue/Green DNS configuration
|
||||||
|
|||||||
@@ -129,10 +129,18 @@ export class SpicyAlbStack extends cdk.Stack {
|
|||||||
|
|
||||||
// Import all VPC details from VPC stack exports
|
// Import all VPC details from VPC stack exports
|
||||||
const vpcCidrBlock = cdk.Fn.importValue(`${vpcStackName}-VPCCIDR`).toString();
|
const vpcCidrBlock = cdk.Fn.importValue(`${vpcStackName}-VPCCIDR`).toString();
|
||||||
|
|
||||||
|
// numberOfAzs: use context value if provided, otherwise auto-import from VPC stack export
|
||||||
const numberOfAzsRaw = app.node.tryGetContext('numberOfAzs');
|
const numberOfAzsRaw = app.node.tryGetContext('numberOfAzs');
|
||||||
const numberOfAzs = numberOfAzsRaw ? parseInt(numberOfAzsRaw, 10) : NaN;
|
let numberOfAzs: number;
|
||||||
|
if (numberOfAzsRaw) {
|
||||||
|
numberOfAzs = parseInt(numberOfAzsRaw, 10);
|
||||||
|
} else {
|
||||||
|
const imported = cdk.Fn.importValue(`${vpcStackName}-NumberOfAZs`).toString();
|
||||||
|
numberOfAzs = parseInt(imported, 10);
|
||||||
|
}
|
||||||
if (!numberOfAzs || Number.isNaN(numberOfAzs)) {
|
if (!numberOfAzs || Number.isNaN(numberOfAzs)) {
|
||||||
throw new Error('numberOfAzs is required in context (2-4) to import VPC subnets for ALB.');
|
throw new Error('numberOfAzs is required (2-4). Provide via context or ensure VPC stack exports NumberOfAZs.');
|
||||||
}
|
}
|
||||||
const azs = ['A', 'B', 'C', 'D'].slice(0, Math.min(Math.max(numberOfAzs, 1), 4));
|
const azs = ['A', 'B', 'C', 'D'].slice(0, Math.min(Math.max(numberOfAzs, 1), 4));
|
||||||
|
|
||||||
|
|||||||
@@ -243,10 +243,18 @@ export class SpicyEcsClusterStack extends cdk.Stack {
|
|||||||
'vpcStackName is required. Provide vpcStackName to import all VPC details from VPC stack exports.'
|
'vpcStackName is required. Provide vpcStackName to import all VPC details from VPC stack exports.'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// numberOfAzs: use context value if provided, otherwise auto-import from VPC stack export
|
||||||
const numberOfAzsRaw = app.node.tryGetContext('numberOfAzs');
|
const numberOfAzsRaw = app.node.tryGetContext('numberOfAzs');
|
||||||
const numberOfAzs = numberOfAzsRaw ? parseInt(numberOfAzsRaw, 10) : NaN;
|
let numberOfAzs: number;
|
||||||
|
if (numberOfAzsRaw) {
|
||||||
|
numberOfAzs = parseInt(numberOfAzsRaw, 10);
|
||||||
|
} else {
|
||||||
|
// Auto-import from VPC stack export
|
||||||
|
const imported = cdk.Fn.importValue(`${vpcStackName}-NumberOfAZs`).toString();
|
||||||
|
numberOfAzs = parseInt(imported, 10);
|
||||||
|
}
|
||||||
if (!numberOfAzs || Number.isNaN(numberOfAzs)) {
|
if (!numberOfAzs || Number.isNaN(numberOfAzs)) {
|
||||||
throw new Error('numberOfAzs is required in context (2-4) to import subnets from the VPC stack.');
|
throw new Error('numberOfAzs is required (2-4). Provide via context or ensure VPC stack exports NumberOfAZs.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tags
|
// Tags
|
||||||
|
|||||||
@@ -187,10 +187,18 @@ export class SpicyEcsServiceStack extends cdk.Stack {
|
|||||||
|
|
||||||
// Import all VPC details from VPC stack exports
|
// Import all VPC details from VPC stack exports
|
||||||
const vpcCidrBlock = cdk.Fn.importValue(`${vpcStackName}-VPCCIDR`).toString();
|
const vpcCidrBlock = cdk.Fn.importValue(`${vpcStackName}-VPCCIDR`).toString();
|
||||||
|
|
||||||
|
// numberOfAzs: use context value if provided, otherwise auto-import from VPC stack export
|
||||||
const numberOfAzsRaw = app.node.tryGetContext('numberOfAzs');
|
const numberOfAzsRaw = app.node.tryGetContext('numberOfAzs');
|
||||||
const numberOfAzs = numberOfAzsRaw ? parseInt(numberOfAzsRaw, 10) : NaN;
|
let numberOfAzs: number;
|
||||||
|
if (numberOfAzsRaw) {
|
||||||
|
numberOfAzs = parseInt(numberOfAzsRaw, 10);
|
||||||
|
} else {
|
||||||
|
const imported = cdk.Fn.importValue(`${vpcStackName}-NumberOfAZs`).toString();
|
||||||
|
numberOfAzs = parseInt(imported, 10);
|
||||||
|
}
|
||||||
if (!numberOfAzs || Number.isNaN(numberOfAzs)) {
|
if (!numberOfAzs || Number.isNaN(numberOfAzs)) {
|
||||||
throw new Error('numberOfAzs is required in context (2-4) to import VPC subnets.');
|
throw new Error('numberOfAzs is required (2-4). Provide via context or ensure VPC stack exports NumberOfAZs.');
|
||||||
}
|
}
|
||||||
const azs = ['A', 'B', 'C', 'D'].slice(0, Math.min(Math.max(numberOfAzs, 1), 4));
|
const azs = ['A', 'B', 'C', 'D'].slice(0, Math.min(Math.max(numberOfAzs, 1), 4));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user