使用AWS CDK创建ElastiCache集群时SubnetIds为空报错求助
解决AWS CDK创建ElastiCache Redis集群时SubnetIds为空的问题
问题现象
使用AWS CDK创建VPC与ElastiCache(Redis)集群时,栈创建失败,报错:
The parameter SubnetIds must be provided.
生成的CloudFormation模板中,ElastiCache子网组的SubnetIds为空数组,而非预期的私有子网ID:
"NetworkStacksubnetgroup": { "Type": "AWS::ElastiCache::SubnetGroup", "Properties": { "Description": "List of subnets used for redis cache NetworkStack", "SubnetIds": [] }, "Metadata": { "aws:cdk:path": "NetworkStack/NetworkStack-subnet-group" } }
对应的CDK代码片段:
import { Stack, StackProps } from "aws-cdk-lib"; import { Construct } from "constructs"; import { aws_ec2 as ec2, aws_elasticache as elasticache } from "aws-cdk-lib"; export class NetworkStack extends Stack { public vpc: ec2.Vpc; public redisCluster: elasticache.CfnCacheCluster; constructor(scope: Construct, id: string, props?: StackProps) { super(scope, id, props); this.vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 2, natGateways: 0, }); const subnetGroup = new elasticache.CfnSubnetGroup(this, `${id}-subnet-group`, { description: `List of subnets used for redis cache ${id}`, subnetIds: this.vpc.privateSubnets.map(function (subnet) { return subnet.subnetId; }) }); const securityGroup = new ec2.SecurityGroup(this, `${id}-security-group`, { vpc: this.vpc }); this.redisCluster = new elasticache.CfnCacheCluster(this, `${id}-cluster`, { cacheNodeType: 'cache.t2.micro', engine: 'redis', numCacheNodes: 1, autoMinorVersionUpgrade: true, cacheSubnetGroupName: subnetGroup.ref, vpcSecurityGroupIds: [ securityGroup.securityGroupId ] }); } }
原因分析
当VPC配置中natGateways: 0时,CDK默认不会创建带NAT网关的私有子网(PRIVATE_WITH_NAT),也不会自动生成隔离子网(PRIVATE_ISOLATED),此时this.vpc.privateSubnets为空数组,直接导致子网组的SubnetIds没有有效值。
解决方案
根据你的网络需求选择以下两种方案之一:
方案1:使用隔离子网(无需公网访问)
如果Redis集群不需要访问公网,显式配置VPC创建隔离子网,并在子网组中引用这些子网:
this.vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 2, natGateways: 0, subnetConfiguration: [ { cidrMask: 24, name: 'IsolatedSubnet', subnetType: ec2.SubnetType.PRIVATE_ISOLATED, // 配置隔离子网 } ] }); // 子网组引用隔离子网 const subnetGroup = new elasticache.CfnSubnetGroup(this, `${id}-subnet-group`, { description: `List of subnets used for redis cache ${id}`, subnetIds: this.vpc.isolatedSubnets.map(subnet => subnet.subnetId) });
方案2:启用NAT网关,使用带公网访问的私有子网
如果Redis集群需要访问公网(如下载补丁、连接外部服务),将natGateways设为至少1,CDK会自动创建带NAT网关的私有子网,此时this.vpc.privateSubnets会包含有效值:
this.vpc = new ec2.Vpc(this, 'Vpc', { maxAzs: 2, natGateways: 1, // 启用NAT网关 });
此时原有的子网组代码无需修改,this.vpc.privateSubnets.map(...)会正确获取私有子网ID。
验证
修改代码后,重新执行cdk synth生成CloudFormation模板,检查子网组的SubnetIds是否已填充正确的子网ID,再执行cdk deploy即可完成栈的创建。
内容的提问来源于stack exchange,提问作者Ejnar
相关产品推荐
相关产品推荐

