You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 13:02:51