我有几个 EC2 Spot 请求,当价格合适时启动 EC2 实例。我希望生成的实例带有Name
andRole
标签,这样我的配置管理工具就知道它是什么类型的机器。
更新:
我采纳了 Hyper Anthony 的建议并实施了它——因为轮询容易出错并且耗费大量资源,所以我向我的 AMI 添加了启动脚本,该脚本会在实例启动时更新标签,以下是我采取的步骤:
确保 Boto 安装在您正在使用的 AMI 上
pip install boto
为 EC2 实例分配 IAM 角色
您启动的实例必须有某种方式来访问有关现货请求的信息。使用 IAM 角色或为您的实例提供访问密钥。我附加到我使用的 IAM 角色的策略是:
{
"Statement": [
{
"Action": [
"ec2:CreateTags",
"ec2:DescribeTags",
"ec2:DescribeInstances"
],
"Effect": "Allow",
"Resource": [
"*"
],
"Sid": "Stmt1432737176000"
}
],
"Version": "2012-10-17"
}
在启动时运行脚本来更新标签
def get_tags_from_spot_request():
instance_id = boto.utils.get_instance_identity()['document']['instanceId']
region = boto.utils.get_instance_identity()['document']['region']
conn = boto.ec2.connect_to_region(region)
inst = boto.ec2.instance.Instance(connection=conn)
inst.id = instance_id
inst.update()
spot_id = inst.spot_instance_request_id
tags = conn.get_all_tags(filters={'resource-type': 'spot-instances-request', 'resource-id': spot_id})
for tag in tags:
inst.add_tag(tag.name, tag.value)
答案1
Spot 实例请求是一种 EC2 资源。AWS 文档注意到这种类型的资源可以标记,但生成的标签不会被带到实际实例中:
您为 Spot 实例请求创建的标签仅适用于请求。这些标签不会自动添加到 Spot 服务为满足请求而启动的 Spot 实例中。您必须在创建 Spot 实例请求时或启动 Spot 实例后自行向 Spot 实例添加标签。
因此,您需要在实例启动后添加标签。您有以下几种选择:
- 创建的实例上的用户数据脚本:编写使用命令行工具和EC2 元数据服务允许实例发现其实例 ID 并为自己创建标签。您可以使用 AWS CLI创建标签标记任何 EC2 资源。或者,您可以将其作为启动脚本嵌入到 AMI 中,用于您打算使用的任何操作系统。无论哪种情况,实例都必须具有足够的权限为其自身创建 EC2 标签。
- 监控您的现货请求的外部实用程序:您可以使用其中一个 AWS SDK 来监控您的 Spot 请求并在实例创建后对其进行标记。AWS有关于此主题的教程在“如何标记您的 Spot 请求和实例”标题下。这里就不多说了,只需轮询即可描述 Spot 实例请求直到创建的实例 ID 可用,然后调用创建标签。
答案2
现在,您可以在创建 Spot 队列请求时向 SpotFleetLaunchSpecification 提供标签,这些标签将自动应用于该队列中的新实例。
http://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_SpotFleetLaunchSpecification.html
答案3
另一种可能性是使用 Ansible 作为配置管理工具。在 ec2 模块中,您可以启动现货和普通生命周期实例,您可以添加“instance_tags”属性来创建标签。一个简单的剧本是:
- name: Provision Spot Instance
hosts: localhost
connection: local
gather_facts: False
tasks:
- name: Launch the new Spot Instance
local_action:
module: ec2
spot_price: 0.02
group: testSG
instance_type: m3.medium
image: ami-12345
wait: true
instance_tags:
Name: TagValueForName
Foo: TagValueForFoo
region: us-east-1
keypair: mykeypair
有趣的是,我的抱怨是它只标记实例而不标记现场请求,这与您的问题相反。