Problémy Nasazení VPC s Podsítí s CDK a Python

0

Otázka

Snažím se vytvořit VPC s podsítí pro projekt, ale já jsem běží na problém, kdy CDK, zdá se, dva podsítí se stejnou CIDR blok při syntéze kódu do CloudFormation šablony, i když jsem použít pouze CIDR blok jednou za podsítě prohlášení. To způsobí, nasazení se nezdaří, protože CIDR bloky v rozporu s navzájem při vytváření podsítí. Zde je kód pro definování zásobníku:

from aws_cdk import core as cdk
from aws_cdk import aws_ec2 as ec2

class CdkWorkshop3Stack(cdk.Stack):

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

        # The code that defines your stack goes here

        # instantiate VPC with dns support and hostname enabled and cidr block at 10.0.0.0/24
        vpc = ec2.Vpc(self, "vpc-cf",
                      cidr="10.0.0.0/24",
                      enable_dns_support=True,
                      enable_dns_hostnames=True
                      )

        # instantiate internet gateway and attach VPC with internet gateway
        igw = ec2.CfnInternetGateway(self, "igw")
        igw_attach = ec2.CfnVPCGatewayAttachment(
            self, "igw_attach", vpc_id=vpc.vpc_id, internet_gateway_id=igw.attr_internet_gateway_id)

        # instantiate elastic IP with VPC domin
        eip = ec2.CfnEIP(self, "eip", domain="VPC")

        # instantiate public and private subnets and use first availability zone
        pub_subnetA = ec2.Subnet(
            self, "public-subnetA", availability_zone=super().availability_zones[0], cidr_block="10.0.0.0/26", vpc_id=vpc.vpc_id, map_public_ip_on_launch=True)
        pub_subnetB = ec2.Subnet(
            self, "public-subnetB", availability_zone=super().availability_zones[0], cidr_block="10.0.0.64/26", vpc_id=vpc.vpc_id, map_public_ip_on_launch=True)
        pri_subnetA = ec2.Subnet(
            self, "private-subnetA", availability_zone=super().availability_zones[0], cidr_block="10.0.0.128/26", vpc_id=vpc.vpc_id, map_public_ip_on_launch=False)
        pri_subnetB = ec2.Subnet(
            self, "private-subnetB", availability_zone=super().availability_zones[0], cidr_block="10.0.0.192/26", vpc_id=vpc.vpc_id, map_public_ip_on_launch=False)

        # instantiate NAT gateway
        nat_gateway = ec2.CfnNatGateway(
            self, "nat_gateway", allocation_id=eip.attr_allocation_id, subnet_id=pub_subnetA.subnet_vpc_id)

        # instantiate routing tables
        pub_route_table = ec2.CfnRouteTable(
            self, "pub_route_table", vpc_id=vpc.vpc_id)
        pri_route_table = ec2.CfnRouteTable(
            self, "pri_route_table", vpc_id=vpc.vpc_id)

        # instantiate public and private routes
        pub_route = ec2.CfnRoute(self, "pub_route", route_table_id=pub_route_table.attr_route_table_id,
                                 destination_cidr_block="0.0.0.0/0", gateway_id=igw.attr_internet_gateway_id)
        pri_route = ec2.CfnRoute(self, "pri_route", route_table_id=pri_route_table.attr_route_table_id,
                                 destination_cidr_block="0.0.0.0/0", nat_gateway_id=nat_gateway.ref)

        # instantiate subnet route table associations
        pub_subnetA_route_table_association = ec2.CfnSubnetRouteTableAssociation(
            self, "pub_subnetA_route_table_association", route_table_id=pub_route_table.attr_route_table_id, subnet_id=pub_subnetA.subnet_vpc_id)
        pub_subnetB_route_table_association = ec2.CfnSubnetRouteTableAssociation(
            self, "pub_subnetB_route_table_association", route_table_id=pub_route_table.attr_route_table_id, subnet_id=pub_subnetB.subnet_vpc_id)
        pri_subnetA_route_table_association = ec2.CfnSubnetRouteTableAssociation(
            self, "pri_subnetA_route_table_association", route_table_id=pri_route_table.attr_route_table_id, subnet_id=pri_subnetA.subnet_vpc_id)
        pri_subnetB_route_table_association = ec2.CfnSubnetRouteTableAssociation(
            self, "pri_subnetB_route_table_association", route_table_id=pri_route_table.attr_route_table_id, subnet_id=pri_subnetB.subnet_vpc_id)

        security_group = ec2.SecurityGroup(self, "security_group", vpc=vpc)
        security_group.add_ingress_rule(
            ec2.Peer.ipv4("0.0.0.0/0"), ec2.Port.tcp(22))

        ec2_instance = ec2.Instance(self, "EC2", instance_type=ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machine_image=ec2.MachineImage.latest_amazon_linux(),
                                    key_name="RandomKeyName", security_group=security_group, vpc=vpc, vpc_subnets=pri_subnetA)

Nevím, jak tento problém vyřešit, když je jasné, že je třeba používat pouze ty CIDR bloky jednou. Ale to neznamená.

EDIT: teď jsem včetně odkazu na CloudFormation šablona výstup v reakci na komentář. Všiml jsem si, že tento konflikt je problém, jen se zdá se vyskytují s public_subnetA a private_subnetA. Já pořád nechápu, proč se to děje.

EDIT 2: zkoušel jsem následující maafk návrh a snížené můj kód následující. Chci, aby 2 veřejné a soukromé konfigurace podsítě, ale teď se nemůžu připojit k instanci EC2 bez ohledu na to, co se snažím. Proč je něco, co lze snadno dosáhnout v Terraform tak zbytečně těžké udělat v AWS CDK, natož v Pythonu?

from aws_cdk import core as cdk
from aws_cdk import aws_ec2 as ec2

class HelloCdkStack(cdk.Stack):

    def __init__(self, scope: cdk.Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        vpc = ec2.Vpc(self, "vpc-cf",
                      cidr="10.0.0.0/24",
                      enable_dns_support=True,
                      enable_dns_hostnames=True,
                      nat_gateways=1,
                      max_azs=1,
                      subnet_configuration=[ec2.SubnetConfiguration(
                          name="public-subnetA",
                          cidr_mask=26,
                          subnet_type=ec2.SubnetType.PUBLIC
                      ), ec2.SubnetConfiguration(
                          name="public-subnetB",
                          cidr_mask=26,
                          subnet_type=ec2.SubnetType.PUBLIC
                      ), ec2.SubnetConfiguration(
                          name="private-subnetA",
                          cidr_mask=26,
                          subnet_type=ec2.SubnetType.PRIVATE
                      ), ec2.SubnetConfiguration(
                          name="private-subnetB",
                          cidr_mask=26,
                          subnet_type=ec2.SubnetType.PRIVATE)]
                      )

        ec2_instance = ec2.Instance(self, "EC2", instance_type=ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machine_image=ec2.MachineImage.latest_amazon_linux(
        ), key_name="KeyPairRandom", vpc=vpc, vpc_subnets=vpc.select_subnets(subnet_type=ec2.SubnetType.PUBLIC).subnets[0])

        ec2_instance.connections.allow_from_any_ipv4(
            ec2.Port.tcp(22), 'Allow inbound SSH from anywhere')
1

Nejlepší odpověď

1

Přidáváte mnohem více kódu, než je nutné.

Vytvoření VPC s CDK již postará o většinu z toho za vás

Od docs

Výchozí konfigurace VPC bude vytvořit veřejných a soukromých podsítí

Zde je více "CDK nativní způsob, jak" to napsat.

from aws_cdk import core as cdk
from aws_cdk import aws_ec2 as ec2

class CdkWorkshop3Stack(cdk.Stack):

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

        vpc = ec2.Vpc(self, "vpc-cf",
            cidr="10.0.0.0/24",
            # dns hostnames and support enabled by default
        )

        ec2_instance = ec2.Instance(self, "EC2", 
            instance_type=ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO), machine_image=ec2.MachineImage.latest_amazon_linux(),
            key_name="RandomKeyName", 
            vpc=vpc,
            # PRIVATE subnets are chosen by default
        )
        # Not a great security practice to open ssh to the world, but can do it this way
        ec2_instance.connections.allow_from_any_ipv4(ec2.Port.tcp(22), 'Allow inbound SSH from anywhere')

Mnohem méně kódu, a pomocí "rozumné hodnoty", které přicházejí s CDK

2021-11-20 12:31:11

Jak to mám udělat, aby si vybrat veřejné podsítě. Myslím, že soukromé podsítě výchozí opouští mě nemůže připojit k instance pomocí SSH.
Karma Cool

Podívejte se na dokumentaci o Vpc postavit.
gshpychka

Nejlepší volba pro SSH je použít SSM Session manager (ve výchozím nastavení nainstalován na Amazon Linux), nebo použít bastion host ve veřejné podsítě. Pokud jste absolutně musí vytvořit instanci ve veřejné podsítě, můžete přidat vpc_subnets=vpc.SubnetSelection(subnet_type=ec2.SubnetType.PUBLIC) k ec2.Instance parametry
maafk

V jiných jazycích

Tato stránka je v jiných jazycích

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................