使用Python AWS CDK部署含子网的VPC时出现CIDR冲突及EC2连接问题
问题排查与解决
1 CIDR块冲突报错原因
你第一版代码的问题根源是:CDK的ec2.Vpc高级构造默认会自动生成子网,默认配置为每个可用区创建1个公有子网、1个私有子网,你没有禁用默认子网生成逻辑,又手动声明了4个自定义子网,最终生成的CloudFormation模板中同时存在默认生成的子网和你手动声明的子网,就出现了CIDR重叠冲突。
如果需要完全自定义所有子网,只需要在创建ec2.Vpc时添加参数subnet_configuration=[],禁用默认子网生成即可。
2 简化代码后EC2无法连接的原因
第二版代码的子网配置逻辑本身没有问题,连接失败通常是以下几个可直接验证的原因:
- 密钥对不匹配:你指定的
KeyPairRandom必须和你部署堆栈的AWS区域中已存在的密钥对名称完全一致,否则你无法获取对应私钥完成SSH认证。 - 未分配公网IP:虽然公有子网默认开启公网IP分配,但建议在创建EC2实例时明确添加参数
associate_public_ip_address=True,确保实例分配到公网IP。 - 端口访问限制:首先确认你本地网络的运营商没有封禁22端口,其次如果部署在AWS中国区,需要确认你账号的网络ACL没有额外限制22端口的出入站。
另外你写的子网配置逻辑可以简化,不需要为每个同类型子网单独声明SubnetConfiguration,直接用count参数即可让CDK自动分配连续不冲突的CIDR,修正后的参考代码如下:
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-subnet", cidr_mask=26, subnet_type=ec2.SubnetType.PUBLIC, map_public_ip_on_launch=True, count=2 ), ec2.SubnetConfiguration( name="private-subnet", cidr_mask=26, subnet_type=ec2.SubnetType.PRIVATE_WITH_NAT, count=2 ) ] ) 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], associate_public_ip_address=True ) ec2_instance.connections.allow_from_any_ipv4( ec2.Port.tcp(22), 'Allow inbound SSH from anywhere')
你觉得CDK比Terraform难用,核心原因是CDK的高级构造封装了大量默认行为,如果你不了解这些隐藏逻辑很容易踩坑;如果需要和Terraform一致的完全手动控制的体验,可以直接使用CDK中Cfn开头的底层资源构造,所有参数都需要手动配置,没有隐藏逻辑。
内容的提问来源于stack exchange,提问作者Karma Cool
相关产品推荐
相关产品推荐

