如何使用 Boto 启动 EC2 实例,指定 EBS 的大小?

Posted

技术标签:

【中文标题】如何使用 Boto 启动 EC2 实例,指定 EBS 的大小?【英文标题】:How to launch EC2 instance with Boto, specifying size of EBS? 【发布时间】:2012-11-15 04:04:39 【问题描述】:

我正在使用 boto/python 启动一个从 EBS 卷启动的新 EC2 实例。在我启动实例时,我想覆盖引导 EBS 卷的默认大小。

我没有找到适合我的启动代码的 boto 方法或参数:

ec2 = boto.connect_ec2( ACCESS_KEY, SECRET_KEY, region=region )

reservation = ec2.run_instances( image_id=AMI_ID, 
                                 key_name=EC2_KEY_HANDLE, 
                                 instance_type=INSTANCE_TYPE,
                                 security_groups = [ SECGROUP_HANDLE, ] )

This web page 展示了如何使用命令行工具增加正在运行的 EC2 实例的 EBS 卷的大小,但我想在指定 EC2 实例时使用 boto:

【问题讨论】:

【参考方案1】:

这是使用 boto3“一切都是资源”方法的代码版本。另请注意如何避免硬编码磁盘名称:

import boto3

ec2 = boto3.resource('ec2')


def ec2_one_by_key_and_value(collection: str, key: str, value: str):
    handler = getattr(ec2, collection)
    return list(handler.filter(Filters=['Name': key, 'Values': [value]]))[0]


image = ec2_one_by_key_and_value('images', 'name', 'ubuntu/images/hvm-ssd/...')
root_disk = None
for block_device in image.block_device_mappings:
    if block_device['DeviceName'] == image.root_device_name:
        root_disk = block_device
        assert root_disk['Ebs']
        root_disk['Ebs']['VolumeSize'] = 16 # New disk 
        break
assert root_disk
instances = ec2.create_instances(MinCount=1, ..., ImageId=image.id,
                                 BlockDeviceMappings=image.block_device_mappings)

【讨论】:

【参考方案2】:

您必须先创建块储存设备映射:

dev_sda1 = boto.ec2.blockdevicemapping.EBSBlockDeviceType()
dev_sda1.size = 50 # size in Gigabytes
bdm = boto.ec2.blockdevicemapping.BlockDeviceMapping()
bdm['/dev/sda1'] = dev_sda1 

之后,您可以在run_instances 调用中提供块设备映射:

reservation = ec2.run_instances( image_id=AMI_ID, 
                                 key_name=EC2_KEY_HANDLE, 
                                 instance_type=INSTANCE_TYPE,
                                 security_groups = [ SECGROUP_HANDLE, ],
                                 block_device_mappings = [bdm])

不幸的是,这是not really well documented,但示例为can be found in the source code。

【讨论】:

这行得通!谢谢!对像我这样的其他菜鸟的一个警告:我认为我会很聪明,将/dev/sda1 更改为/dev/xvda1,因为在我运行的 Ubuntu 实例上,根据df -h 命令,这是引导卷的名称。无论出于何种原因,失败并显示错误消息:“无效的设备名称/dev/xvda1”所以我将其改回/dev/sda1,一切顺利。 默认的 amazon linux 8GB ami 不会还有一个 8GB 大小的分区表,第一次启动后必须扩展它吗? 迟到的评论,但也许有用。您可以使用来自 boto.ec2.image.Image 对象的 'block_device_mapping' 的值,对其进行修改,然后将其直接用作 boto.ec2.image.Image.run()block_device_map 参数/跨度> 重要提示:在 Boto 中,默认为 delete_on_termination=False。但是,在 Web 控制台中,默认情况下会选中“终止时删除”复选框。 在较新版本的 Boto 中,run_instances() 方法中的参数 block_device_mappings 已重命名为 block_device_map,并且应该是 BlockDeviceMapping 类型,而不是这样的数组。【参考方案3】:

您还可以使用CloudFormation,它用于记录和自动化您的环境。 您可以在以下位置查看 ESB 定义的模板:https://s3.amazonaws.com/cloudformation-templates-us-east-1/EC2WithEBSSample.template

 "Resources" : 
    "Ec2Instance" : 
      "Type" : "AWS::EC2::Instance",
      "Properties" : 
        "AvailabilityZone" :  "Fn::FindInMap" : [ "RegionMap",  "Ref" : "AWS::Region" , "TestAz" ],
        "SecurityGroups" : [  "Ref" : "InstanceSecurityGroup"  ],
        "KeyName" :  "Ref" : "KeyName" ,
        "ImageId" :  "Fn::FindInMap" : [ "RegionMap",  "Ref" : "AWS::Region" , "AMI" ],
        "Volumes" : [ 
           "VolumeId" :  "Ref" : "NewVolume" ,
            "Device" : "/dev/sdk"
          
        ]
      
    ,

    ...

    "NewVolume" : 
      "Type" : "AWS::EC2::Volume",
      "Properties" : 
        "Size" : "100",
        "AvailabilityZone" :  "Fn::FindInMap" : [ "RegionMap",  "Ref" : "AWS::Region" , "TestAz" ]
      
    

然后您可以使用Boto CloudFormation API 来部署您的环境。

【讨论】:

谢谢你。 cloudformation 看起来很有趣,最后会仔细研究一下

以上是关于如何使用 Boto 启动 EC2 实例,指定 EBS 的大小?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 boto3 指定 core-os ec2 实例的根卷大小?

AWS lambda 使用启动模板和 boto3 创建 ec2 实例,仅使用所需的权限

Boto 在 ec2 实例上执行 shell 命令

使用 Boto 3 显示 EC2 实例名称

我们如何使用 python boto3 获取挂载到 EC2 实例的所有文件系统(EFS)的列表?

如何在Python AWS boto API中获取EC2实例ID的容器实例列表