Search code examples
typescriptamazon-web-servicesredisaws-cdkamazon-elasticache

SubnetIds are empty when creating an Elasticache cluster using CDK


When creating a VPC and a simple Elasticache (Redis) cluster using CDK, the stack creation fails with the following error: "The parameter SubnetIds must be provided."

My code creates a VPC, a cache subnetgroup (referencing the private subnet(s) from the VPC) and an Elasticache/Redis cluster. I expect the synthesised CloudFormation template to contain the subnet ID's, but instead it produces an empty array.

Below is my CDK Stack (based partly on this example):

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
            ]
        });
    }
}

If I look at the generated CloudFormation template, I see an empty array of subnet ID's for my Elasticache subnet group, while I would expect to see the VPC private subnet ID(s) there. This likely causes the error. Below is the generated subnet group:

"NetworkStacksubnetgroup": {
   "Type": "AWS::ElastiCache::SubnetGroup",
   "Properties": {
    "Description": "List of subnets used for redis cache NetworkStack",
    "SubnetIds": []
   },
   "Metadata": {
    "aws:cdk:path": "NetworkStack/NetworkStack-subnet-group"
   }
  }

Does anyone know how to fix this?


Solution

  • The privateSubnets prop contains subnets that have internet egress via NAT. Since you specified natGateways as 0, that property is empty - you do not have private subnets in your VPC.

    Instead, you have isolatedSubnets - with no egress/ingress. Iterate over that.

    Refer to Vpc.DEFAULT_SUBNETS_NO_NAT for a description of the default subnet configuration when natGateways is specified to be 0:

    1 Public and 1 Isolated Subnet per AZ evenly split

    P.S. FYI creating that connections object has no effect in the code you posted.