使用Python AWS CDK创建启动模板时EC2 EBS加密配置失效问题
问题排查与解决方案
问题原因
你遇到的CloudFormation模板中BlockDeviceMappings为空的问题,大概率是因为直接将boto3返回的原始字典结构传入CDK的LaunchTemplate,而非转换为CDK要求的ec2.BlockDevice对象。CDK无法正确序列化原始字典,导致生成的模板中该字段为空。
正确解决方案(使用ec2.LaunchTemplate)
以下是通过CDK 2.66.0(Python 3.9)创建带加密EBS卷的启动模板的完整代码:
import boto3 from aws_cdk import aws_ec2 as ec2 from aws_cdk import Stack from constructs import Construct class EncryptedLaunchTemplateStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # 替换为你的未加密AMI ID TARGET_AMI_ID = "ami-xxxxxxxxxxxxxxxxx" # 1. 通过boto3获取AMI的块设备映射(合成阶段执行) ec2_client = boto3.client("ec2", region_name=self.region) ami_details = ec2_client.describe_images(ImageIds=[TARGET_AMI_ID])["Images"][0] ami_block_mappings = ami_details["BlockDeviceMappings"] # 2. 将boto3返回的映射转换为CDK BlockDevice对象 cdk_block_devices = [] for mapping in ami_block_mappings: # 仅处理EBS卷(实例存储卷无法加密) if "Ebs" in mapping: ebs_config = mapping["Ebs"] cdk_block_devices.append( ec2.BlockDevice( device_name=mapping["DeviceName"], ebs=ec2.EbsDeviceOptions( encrypted=True, # 启用加密 # 保留AMI原有的卷属性(按需调整) volume_size=ebs_config["VolumeSize"], volume_type=ec2.EbsDeviceVolumeType(ebs_config["VolumeType"]), delete_on_termination=ebs_config.get("DeleteOnTermination", True) ) ) ) # 3. 创建启动模板 ec2.LaunchTemplate( self, "EncryptedLT", launch_template_name="Encrypted-Launch-Template", machine_image=ec2.MachineImage.lookup(image_id=TARGET_AMI_ID), block_devices=cdk_block_devices )
关键注意事项
- 保留原AMI属性:转换块设备映射时,要保留原AMI的卷大小、类型、终止时删除等属性,仅修改
encrypted为True,避免启动实例时出现配置不匹配。 - 实例存储卷处理:如果AMI包含实例存储卷(无
Ebs字段的映射),这些卷无法加密,直接跳过即可。 - 区域一致性:确保boto3客户端使用的区域与CDK栈的区域一致,避免跨区域查询AMI失败。
内容的提问来源于stack exchange,提问作者Rafiq
相关产品推荐
相关产品推荐

