如何在Python中创建无JSII的AWS CDK自定义EC2构造库
创建自定义AWS CDK EC2构造库(Python,无需JSII)
没问题,我来帮你搞定这个自定义EC2构造库!既然不需要JSII,咱们直接基于Python的CDK原生构造来封装就好,完全不用折腾跨语言的那套流程。下面是完整的实现方案:
第一步:依赖准备
首先确保你已经安装了必要的CDK依赖包:
pip install aws-cdk-lib constructs
第二步:实现自定义构造类
我们会创建一个继承自constructs.Construct的类,把VPC和EC2实例的创建逻辑封装进去,同时接收你需要的所有参数。这里我还做了一些参数映射处理,让字符串参数能正确对应到CDK的枚举类型:
from constructs import Construct import aws_cdk as cdk from aws_cdk import aws_ec2 as ec2 from aws_cdk import aws_iam as iam class CustomEc2Instance(Construct): def __init__(self, scope: Construct, construct_id: str, instance_name: str, instance_type: str, machine_image: str, subnet_type: str, key_name: str = "demo-key", role: iam.IRole = None, vpc: ec2.IVpc = None, **kwargs): super().__init__(scope, construct_id, **kwargs) # 处理VPC:如果没传入就创建一个默认VPC self.vpc = vpc or ec2.Vpc(self, f"{instance_name}-VPC", max_azs=2, subnet_configuration=[ ec2.SubnetConfiguration( name="Public", subnet_type=ec2.SubnetType.PUBLIC, cidr_mask=24 ), ec2.SubnetConfiguration( name="Private", subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS, cidr_mask=24 ) ]) # 处理子网类型字符串转CDK枚举 subnet_type_map = { "PUBLIC": ec2.SubnetType.PUBLIC, "PRIVATE": ec2.SubnetType.PRIVATE_WITH_EGRESS, "ISOLATED": ec2.SubnetType.PRIVATE_ISOLATED } selected_subnet_type = subnet_type_map.get(subnet_type.upper()) if not selected_subnet_type: raise ValueError(f"不支持的子网类型:{subnet_type},可选值:PUBLIC/PRIVATE/ISOLATED") # 处理机器镜像:这里先支持Amazon Linux,你可以扩展其他镜像类型 if machine_image.upper() == "AMAZON_LINUX": img = ec2.AmazonLinuxImage( generation=ec2.AmazonLinuxGeneration.AMAZON_LINUX, edition=ec2.AmazonLinuxEdition.STANDARD, virtualization=ec2.AmazonLinuxVirt.HVM, storage=ec2.AmazonLinuxStorage.GENERAL_PURPOSE ) # 可以在这里添加更多镜像支持,比如Ubuntu、Windows等 elif machine_image.upper() == "UBUNTU_22_04": img = ec2.MachineImage.generic_linux({ "us-east-1": "ami-0c55b159cbfafe1f0" # 替换成你区域对应的Ubuntu 22.04 AMI }) else: raise ValueError(f"不支持的镜像类型:{machine_image},当前支持AMAZON_LINUX/UBUNTU_22_04") # 处理IAM角色:如果没传入就创建一个基础角色 self.ec2_role = role or iam.Role(self, f"{instance_name}-Role", assumed_by=iam.ServicePrincipal("ec2.amazonaws.com"), managed_policies=[ iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSSMManagedInstanceCore") ]) # 创建EC2实例 self.ec2_instance = ec2.Instance(self, instance_name, vpc=self.vpc, instance_type=ec2.InstanceType(instance_type), machine_image=img, key_name=key_name, vpc_subnets=ec2.SubnetSelection(subnet_type=selected_subnet_type), role=self.ec2_role)
第三步:使用自定义构造类
现在你可以在自己的CDK栈里直接调用这个构造类,传入需要的参数就行:
class MyCdkStack(cdk.Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # 创建自定义EC2实例(自带VPC) dummy_ec2 = CustomEc2Instance(self, "DummyEC2", instance_name="MyTestInstance", instance_type="t2.micro", machine_image="AMAZON_LINUX", subnet_type="PUBLIC", key_name="demo-key") # 如果要使用已有VPC,也可以传入: # existing_vpc = ec2.Vpc.from_lookup(self, "ExistingVPC", vpc_id="vpc-xxxxxx") # dummy_ec2 = CustomEc2Instance(self, "DummyEC2", # instance_name="MyTestInstance", # instance_type="t2.micro", # machine_image="AMAZON_LINUX", # subnet_type="PRIVATE", # key_name="demo-key", # vpc=existing_vpc) app = cdk.App() MyCdkStack(app, "MyCdkStack") app.synth()
关键细节说明
- 参数灵活性:我加入了可选参数,比如允许传入已有VPC或IAM角色,默认则自动创建,这样适配更多场景
- 错误处理:对不支持的子网类型和镜像类型做了异常抛出,避免运行时出错
- IAM角色:默认添加了
AmazonSSMManagedInstanceCore托管策略,方便你用SSM会话管理器连接实例,不用开SSH端口
这样封装后,你可以在任何CDK项目里复用这个构造类,不用每次重复写VPC和EC2的创建代码啦!
内容的提问来源于stack exchange,提问作者Amit Kanderi
相关产品推荐
相关产品推荐

