【问题标题】:Boto3 create_image for AMI creation - Save ONLY the root volumeBoto3 create_image 用于 AMI 创建 - 仅保存根卷
【发布时间】:2018-04-09 08:42:52
【问题描述】:

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

我的目标是只保存根卷。

我正在使用 boto3。

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

我的代码是这样工作的:

  1. 收集实例列表
  2. 分析每个实例以仅识别根设备,收集其映射数据
  3. 执行boto3 的instance.create_image 来触发,并ONLY为根设备传递BlockDeviceMappings

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

实际结果: AMI 具有附加到源实例的所有块储存设备,无论在 create_image 期间定义的显式 BlockDeviceMappings 是什么

在下面的代码中,我编写了一个函数,该函数将已经收集的源实例数据带到别处。我只定义根卷信息,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

我确实看到 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': '',
        },
    ],

我唯一能看到的是为NoDevice 值设置一个空字符串。将其设置为布尔值或其他任何值都会产生错误。 我试过了 'NoDevice': 'true''NoDevice': 'false''NoDevice': True'NoDevice': False'NoDevice': '/dev/sdf' 并且它们都给出错误。唯一接受的是'NoDevice': '',但结果是一样的,两个设备都连接到 AMI。

【问题讨论】:

    标签: python amazon-web-services amazon-ec2 boto3


    【解决方案1】:

    好的,想通了。

    如果您想使用 NoDevice 省略它,则诀窍是不要在映射中定义除 DeviceName 之外的任何其他内容

    这正在工作,向映射添加任何更多信息将使NoDevice 无效并被忽略。

    希望将来能帮助别人:

    {
        'DeviceName': '/dev/sdf',
        'NoDevice': ''
    },
    

    【讨论】:

    • 你能把你用来创建与boto3连接的代码吗? @emmdee
    • @emmdee 它不起作用,它只采用附加卷的 AMI,而不是根卷,尽管我将根卷 ID 作为 DeviceName 传递,但如果我传递错误的 DeviceName,那么实例 AMI 的所有卷都被采用.
    【解决方案2】:

    我能够使用以下语法使其正常工作:

    createImage = client.create_image(
        BlockDeviceMappings=[
            {
                'DeviceName': '/dev/sda1',
                'Ebs': {
                    'DeleteOnTermination': True,
                    'VolumeSize': 20,
                    'VolumeType': 'gp2',
                    'Encrypted': False
                },
            'DeviceName': '/dev/xvdf',
                'Ebs':{},
            'NoDevice': '', 
            },
        ],
        Description='AMI created by me',
        InstanceId='i-xxxxxxxxxxxxxxxx',
        Name='Insert the AMI name here',
        NoReboot=False,
        DryRun=False,
    )
    

    【讨论】:

      【解决方案3】:

      请使用以下 Snippet 仅获取根设备的图像,并通过添加其他设备排除其余设备,如下所示:

      createImage = client.create_image(
          BlockDeviceMappings=[
              {
                  'DeviceName': '/dev/sda1',
                  'Ebs': {
                      'DeleteOnTermination': True,
                      'VolumeSize': 20,
                      'VolumeType': 'gp2',
                      'Encrypted': True
                  },
      
              },
              {
                  'DeviceName': '/dev/sdg',
                  'Ebs': {},
                  'NoDevice': '',
      
              },
              {
                  'DeviceName': '/dev/sdf',
                  'Ebs': {},
                  'NoDevice': '',
              }
          ],
          Description="Created from Source <InstanceID>"
          InstanceId=i-XXXXXXXXXXX,
          Name="Backup Image"
          NoReboot=True,
          DryRun=False,
      )`
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        • 1970-01-01
        • 2011-04-21
        • 2020-02-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多