Boto EC2:使用标签创建实例
有没有办法通过boto这个Python库在创建实例的时候直接指定标签?我想避免先创建一个实例,然后再去获取它并添加标签。要是能在执行下面这个命令的时候,就直接设置好某些标签,那就简单多了:
ec2server.create_instance(
ec2_conn, ami_name, security_group, instance_type_name, key_pair_name, user_data
)
4 个回答
3
我使用的是boto 2.9.6版本,能够在收到run_instances的响应后,立刻给一个实例添加标签。像下面这样做就可以,不需要等待:
reservation = my_connection.run_instances(...)
for instance in reservation.instances:
instance.add_tag('Name', <whatever>)
我确认在成功添加标签后,这个实例仍然处于待处理状态。其实可以很简单地把这个逻辑封装成一个函数,就像原帖中请求的那样。
14
你可以在启动时、启动后,或者两者都可以给实例和EBS存储卷加标签。想了解更多信息,可以查看CreateTags和给你的亚马逊EC2资源加标签。
使用标签的AWS文档中有一张表,列出了支持加标签的资源,以及在创建时支持加标签的资源(从2017年5月1日起,实例和EBS存储卷都支持)。
下面是一个用Python在创建时给实例加标签的代码示例(其他SDK的参考可以在这个页面找到):
from pkg_resources import parse_version
import boto3
assert parse_version(boto3.__version__) >= parse_version('1.4.4'), \
"Older version of boto3 installed {} which doesn't support instance tagging on creation. Update with command 'pip install -U boto3>=1.4.4'".format(boto3.__version__)
import botocore
assert parse_version(botocore.__version__) >= parse_version('1.5.63'), \
"Older version of botocore installed {} which doesn't support instance tagging on creation. Update with command 'pip install -U botocore>=1.5.63'".format(botocore.__version__)
ec2 = boto3.resource('ec2')
tag_purpose_test = {"Key": "Purpose", "Value": "Test"}
instance = ec2.create_instances(
ImageId=EC2_IMAGE_ID,
MinCount=1,
MaxCount=1,
InstanceType=EC2_INSTANCE_TYPE,
KeyName=EC2_KEY_NAME,
SecurityGroupIds=[EC2_DEFAULT_SEC_GROUP],
SubnetId=EC2_SUBNET_ID,
TagSpecifications=[{'ResourceType': 'instance',
'Tags': [tag_purpose_test]}])[0]
我使用了
Python 2.7.13
boto3 (1.4.4)
botocore (1.5.63)
23
这个回答在写的时候是准确的,但现在已经过时了。现在,AWS的API和库(比如boto3)可以使用一个叫“TagSpecification”的参数,这样你在创建实例的时候就可以直接指定标签了。
在实例创建之前是不能添加标签的。虽然这个功能叫做create_instance,但实际上它是在预留一个实例。然后这个实例可能会被启动,也可能不会。(通常是会启动的,但有时候……)
所以,在实例启动之前,你是不能添加标签的。而且没有办法知道它是否已经启动,除非你不断地去检查。就像这样:
reservation = conn.run_instances( ... )
# NOTE: this isn't ideal, and assumes you're reserving one instance. Use a for loop, ideally.
instance = reservation.instances[0]
# Check up on its status every so often
status = instance.update()
while status == 'pending':
time.sleep(10)
status = instance.update()
if status == 'running':
instance.add_tag("Name","{{INSERT NAME}}")
else:
print('Instance status: ' + status)
return None
# Now that the status is running, it's not yet launched. The only way to tell if it's fully up is to try to SSH in.
if status == "running":
retry = True
while retry:
try:
# SSH into the box here. I personally use fabric
retry = False
except:
time.sleep(10)
# If we've reached this point, the instance is up and running, and we can SSH and do as we will with it. Or, there never was an instance to begin with.