skip to Main Content

I am using the AWS CDK in Python to spin up infrastructure. However whenever I add the CDK code to create an EC2 instance resource I get the following error when running cdk deploy:

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

And the stack trace points to the code that creates the EC2 instance resource. I’ve definitely created public subnets in the vpc. Here is my code. The first file creates the EC2 resource and the second one creates the new VPC and subnet resources that it belongs to. How do I resolve this error?

Stack Code to create the EC2 resource:
animal_cdk/ec2.py

from constructs import Construct
from aws_cdk import (
    Stack,
    aws_ec2 as ec2,
    Tags,
    CfnTag
)
import aws_cdk.aws_elasticloadbalancingv2 as elbv2

class Ec2Stack(Stack):

    def __init__(self, scope: Construct, construct_id: str, vpc_stack, stage, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        shark_ec2 = ec2.Instance(self, "SharkEc2Instance",
            vpc=vpc_stack.vpc,
            instance_type=ec2.InstanceType.of(ec2.InstanceClass.C5, ec2.InstanceSize.XLARGE9),
            machine_image=ec2.MachineImage.latest_amazon_linux(
                generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2
            ),
        )

Stack Code to create VPC and subnets, that gets imported by EC2 above:
animal_cdk/vpc.py

# Code to create the VPC and subnets

from constructs import Construct
from aws_cdk import (
    Stack,
    aws_ec2 as ec2,
    Tags,
    CfnTag
)

class VpcStack(Stack):

    def __init__(self, scope: Construct, construct_id: str, stage, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        self.vpc = ec2.Vpc(self, "AnimalVpc",
            ip_addresses=ec2.IpAddresses.cidr("10.0.0.0/16"),
            vpc_name="animal-vpc",
            subnet_configuration= []
        )

        self.shark_public_subnet = ec2.PublicSubnet(self, "SharkPublicSubnet",
            availability_zone="us-west-2c",
            cidr_block="10.0.0.0/28",
            vpc_id=self.vpc.vpc_id,
            map_public_ip_on_launch=True,
        )
        Tags.of(self.shark_public_subnet).add("Name", "shark-public-subnet")

How VPC gets passed to EC2 Stack:
animal_cdk/application_infrastucture.py

from constructs import Construct
from aws_cdk import (
    Stack,
)

from animal_cdk.vpc import VpcStack
from animal_cdk.ec2 import Ec2Stack

class ApplicationInfrastructure(Stack):

    def __init__(self, scope: Construct, **kwargs) -> None:
        super().__init__(scope, **kwargs)

        vpcStack = VpcStack(self, "Animal-VPC-Stack", stage="beta")
        ec2Stack = Ec2Stack(self, "Animal-EC2-Stack", vpc_stack=vpcStack, stage="beta")

Anyone know how I can resolve this error or why I’m getting it? I’ve looked through the docs and tried a bunch of things but no luck so far.

2

Answers


  1. The error message you’re seeing indicates that there are no ‘Public’ subnet groups in the VPC you’re using when creating the EC2 instance resource. Looking at your code, it seems that you’re not passing the public subnet to the EC2 stack correctly.

    You need to do 2 things to resolve this issue:

    First Update the Ec2Stack class in animal_cdk/ec2.py to accept the shark_public_subnet as a parameter: `class Ec2Stack(Stack):
    def init(self, scope: Construct, construct_id: str, vpc_stack, public_subnet, stage, **kwargs) -> None:
    super().init(scope, construct_id, **kwargs)

        shark_ec2 = ec2.Instance(self, "SharkEc2Instance",
            vpc=vpc_stack.vpc,
            vpc_subnets=ec2.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC, subnet_name=public_subnet.ref),
            instance_type=ec2.InstanceType.of(ec2.InstanceClass.C5, ec2.InstanceSize.XLARGE9),
            machine_image=ec2.MachineImage.latest_amazon_linux(generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX_2),
        )
    

    `

    Then you have to Update the ApplicationInfrastructure class in animal_cdk/application_infrastucture.py to pass the shark_public_subnet to the Ec2Stack:9

    class ApplicationInfrastructure(Stack):
    def __init__(self, scope: Construct, **kwargs) -> None:
        super().__init__(scope, **kwargs)
    
        vpc_stack = VpcStack(self, "Animal-VPC-Stack", stage="beta")
        ec2_stack = Ec2Stack(self, "Animal-EC2-Stack", vpc_stack=vpc_stack, public_subnet=vpc_stack.shark_public_subnet, stage="beta")
    

    Make sure to redeploy your CDK stacks using cdk deploy after making these changes.

    I hope this helps.

    Have a nice day!

    Login or Signup to reply.
  2. The subnet you added outside the VPC constructor in VpcStack the subnet will be added to the CloudFormation template as expected, but apparently is not visible in the VPC construct itself. You can confirm this with a call to print(vpc.public_subnets) within VpStack. It outputs [].

    You will get the expected behaviour if you define your subnet in the VPC constructor:

    self.vpc = ec2.Vpc(
        self,
        "AnimalVpc",
        ip_addresses=ec2.IpAddresses.cidr("10.0.0.0/16"),
        vpc_name="animal-vpc",
        subnet_configuration=[
            ec2.SubnetConfiguration(
                name="SharkPublicSubnet",
                subnet_type=ec2.SubnetType.PUBLIC,
                cidr_mask=28,
                map_public_ip_on_launch=True,
            )
        ],
    )
    
    Tags.of(self.vpc.public_subnets[0]).add("Name", "shark-public-subnet")
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search