Boto3 create_image用于AMI创建-仅保存根卷

emm*_*dee 6 python amazon-ec2 amazon-web-services boto3

我正在编写一个脚本来创建实例的AMI图像。

我的目标是仅保存根卷。

我正在使用boto3。

我的测试实例附加了2个EBS卷。我只想用AMI保存根卷。

这是我的代码的工作方式:

  1. 收集实例列表
  2. 分析每个实例以仅标识根设备,收集其映射数据
  3. 执行boto3的instance.create_image,以触发,并通过唯一BlockDeviceMappings根设备。

预期结果: AMI只有我在create_image呼叫中定义的块设备。

实际结果是: AMI具有连接至该源实例,所有的块的装置,而不管所述显式的BlockDeviceMappings期间定义create_image

在下面的代码中,我编写了一个函数,该函数将已收集的源实例数据带到其他位置。我仅定义根卷信息,BlockDeviceMappings没有声明附加到源卷的任何其他设备。

def create_image(inst, instance, inst_dict):
    nowtime = datetime.datetime.now().strftime('%Y-%m-%d')
    try:
        image = instance.create_image(
            BlockDeviceMappings=[
                {
                    'DeviceName': inst_dict[inst]['root_dev_name'],
                    'Ebs': {
                        'Encrypted': inst_dict[inst]['vol_encr'],
                        'DeleteOnTermination': inst_dict[inst]['vol_del_rule'],
                        'VolumeSize': inst_dict[inst]['vol_size'],
                        'VolumeType': inst_dict[inst]['root_dev_type']
                    },
                },
            ],
            Description=inst_dict[inst]['inst_name'] + " " + str(nowtime),
            DryRun=False,
            Name=inst_dict[inst]['inst_name'] + " " + str(nowtime),
            NoReboot=True
        )
    except Exception, e:
        logging.error("Failed to create image! Instance: " + inst_dict[inst]['inst_name'])
        return 1
Run Code Online (Sandbox Code Playgroud)

我确实看到boto3具有'NoDevice': 'string'可以添加到BlockDeviceMapping对象的参数。但是它附加在映射本身上,这使我感到困惑,为什么要声明一个块设备映射,而只是“排除”它。我不确定如何或为什么使用此NoDevice值。

另外:一个具体问题:

  • 如果boto3 create_image会创建所有块设备,而不管放入了什么BlockDeviceMappings,那么BlockDeviceMappings,如果仅复制源实例块设备,那为什么还没有偶数呢?

谢谢您的帮助。

编辑/更新:

我尝试声明不需要的卷的设备映射。然后使用NoDevice参数:

    BlockDeviceMappings=[
        {
            'DeviceName': inst_dict[inst]['root_dev_name'],
            'Ebs': {
                'Encrypted': inst_dict[inst]['vol_encr'],
                'DeleteOnTermination': inst_dict[inst]['vol_del_rule'],
                'VolumeSize': inst_dict[inst]['vol_size'],
                'VolumeType': inst_dict[inst]['root_dev_type']
            },
        },
        {
            'DeviceName': '/dev/sdf',
            'Ebs': {
                'Encrypted': True,
                'DeleteOnTermination': False,
                'VolumeSize': 24,
                'VolumeType': 'gp2'
            },
            'NoDevice': '',
        },
    ],
Run Code Online (Sandbox Code Playgroud)

我唯一看到的是为该NoDevice值设置一个空字符串。将其设置为布尔值或其他任何值都会出错。我试着 'NoDevice': 'true''NoDevice': 'false''NoDevice': True'NoDevice': False'NoDevice': '/dev/sdf'和他们的所有错误。唯一接受的是'NoDevice': ''结果仍然相同,两个设备都连接到AMI。

emm*_*dee 6

好,知道了。

诀窍是,如果要使用省略,则不要在映射中定义DeviceName以外的任何内容。 NoDevice

现在可以正常工作,向映射添加任何更多信息将使该NoDevice虚空并被忽略。

希望将来能帮助其他人:

{
    'DeviceName': '/dev/sdf',
    'NoDevice': ''
},
Run Code Online (Sandbox Code Playgroud)