Lovelidge
Lovelidge

Reputation: 1

Error: There are no 'Public' subnet groups in this VPC. Available types:

I'm creating a custom Vpc() (i.e a new Vpc() with NO subnetConfiguration)

    this.vpc = new Vpc(this, 'default', {
      vpcName: `${this.props.company.prefix}-vpc`,
      ipAddresses: IpAddresses.cidr('10.0.0.0/16'),
      natGateways: 0,
      createInternetGateway: false,
      enableDnsSupport: true,
      enableDnsHostnames: true,
      **subnetConfiguration**: [], // no subnets
      maxAzs: 3,
    });

...
    //
    // Create Route Tables
    //
    const publicRouteTable = this.createRouteTable("public");
    //
    // Create Public Subnets
    //
    this.createSubnet("public", "10.0.0.0/24", 0, publicRouteTable);

  //
  // create public route table
  //
  private createRouteTable(type: string): CfnRouteTable {
    //
    // Create Public Route Table
    //
    const routeTable = new CfnRouteTable(
      this,
      lnJoin(this.props.company.prefix, type, 'rt'),
      {
        vpcId: this.vpc.vpcId,
        tags: [
          {
            key: 'Name',
            value: lnJoin(this.props.company.prefix, type, 'rt'),
          },
        ],
      }
    );
    //
    // Create a Route
    //
    if (type === 'public') {
      new CfnRoute(
        this,
        lnJoin(this.props.company.prefix, type, 'rt', 'route'),
        {
          routeTableId: routeTable.ref,
          destinationCidrBlock: '0.0.0.0/0',
          gatewayId: this.igw.ref,
        }
      );
    }

    return routeTable;
  }

  //
  // Create Public Subnets
  //
  private createSubnet(
    type: string,
    cidrBlock: string,
    subnetIndex: number,
    routeTable: CfnRouteTable
  ): CfnSubnet {
    
    if (type !== 'public' && type !== 'private') {
      throw new Error('Invalid subnet type.');
    }

    let subnetType =
      type === 'public'
        ? SubnetType.PUBLIC
        : type === 'private'
          ? SubnetType.PRIVATE_WITH_EGRESS
          : SubnetType.PRIVATE_ISOLATED;

    const subnet = new CfnSubnet(
      this,
      lnJoin(
        this.props.company.prefix,
        type,
        'subnet',
        `(${this.vpc.availabilityZones[subnetIndex]})`
      ),
      {
        availabilityZone: this.vpc.availabilityZones[subnetIndex],
        vpcId: this.vpc.vpcId,
        cidrBlock: cidrBlock,
        mapPublicIpOnLaunch: type === 'public',
        tags: [
          {
            key: 'Name',
            value: lnJoin(
              this.props.company.prefix,
              type,
              'subnet',
              `(${this.vpc.availabilityZones[subnetIndex]})`
            ),
          },
          {
            key: this.SUBNETNAME_TAG,
            value: defaultSubnetName(subnetType),
          },
          {
            key: this.SUBNETTYPE_TAG,
            value: subnetTypeTagValue(subnetType),
          },
        ],
      }
    );

    new CfnSubnetRouteTableAssociation(
      this,
      lnJoin(
        this.props.company.prefix,
        type,
        'rt',
        'subnet',
        'assoc',
        `${subnetIndex}`
      ),
      {
        subnetId: subnet.ref,
        routeTableId: routeTable.ref,      
      },
    );

    return subnet;
  }

In subsequent Constructs I am attempting to interate through vpc.publicSubnets() this is when I get this error

"Error: There are no 'Public' subnet groups in this VPC. Available types:"

It's almost as though if I DON'T define subnetConfiguration[] the vpc doesn't see the subnets I created programatically...

I read somewhere that you have to use a specific Tag() when you create a public subnet.

  private SUBNETTYPE_TAG = 'aws-cdk:subnet-type';
  private SUBNETNAME_TAG = 'aws-cdk:subnet-name';

Even when I tag each subnet with the tags above

        tags: [
          {
            key: 'Name',
            value: lnJoin(
              this.props.company.prefix,
              type,
              'subnet',
              `(${this.vpc.availabilityZones[subnetIndex]})`
            ),
          },
**          {
            key: this.SUBNETNAME_TAG,
            value: defaultSubnetName(subnetType),
          },
          {
            key: this.SUBNETTYPE_TAG,
            value: subnetTypeTagValue(subnetType),
          },**
        ],

Can anyone tell me why I'm getting this error? Better yet, what I might do to resolve it?

Upvotes: -1

Views: 128

Answers (1)

gshpychka
gshpychka

Reputation: 11589

Your observation is correct - the Vpc L2 construct only populates the publicSubnets prop if you specify the appropriate subnetConfiguration.

If you create your subnets manually, then it will not be populated, regardless of what subnets you've added. The construct does not have any heuristics for determining whether a subnet is public or private - it only looks at the subnet type in subnetConfiguration when creating the VPC.

Here is the relevant code that populates the publicSubnets prop (this only happens during the creation of the Vpc construct): https://github.com/aws/aws-cdk/blob/0fc07f3762f3af821d742338c7839618a73ced50/packages/aws-cdk-lib/aws-ec2/lib/vpc.ts#L1868

Upvotes: 0

Related Questions