How to tag and name the EC2 Instance that was launched by an EC2 Spot Request

amazon ec2amazon-web-services

I have a couple of EC2 Spot Requests that launch EC2 Instances when the price is right. I'd like the resulting instances to get tagged with a Name and Role tag so my configuration management tool knows what type of machine it is.

UPDATE:

I took Hyper Anthony's advice and implemented it — because polling was going to be error-prone and resource-intensive I added a startup script to my AMI which updates the tags when an instance launches, these are the steps I took:

Ensure Boto is installed on whatever AMI you're using

pip install boto

Assign an IAM Role to the EC2 Instance

The instance you're launching must have some way to access information about the spot request. Use an IAM role or alternatively make access keys available to your instance. The policy that I attached to the IAM role that I used is:

{
    "Statement": [
        {
            "Action": [
                "ec2:CreateTags",
                "ec2:DescribeTags",
                "ec2:DescribeInstances"
            ],
            "Effect": "Allow",
            "Resource": [
                "*"
            ],
            "Sid": "Stmt1432737176000"
        }
    ],
    "Version": "2012-10-17"
}

Run a script on startup to update the tags

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)

Best Answer

Spot instances requests are a type of EC2 resource. The AWS documentation notes that this type of resource can be tagged, but the resulting tags are not carried over to the actual instances:

The tags that you create for your Spot Instance requests only apply to the requests. These tags are not added automatically to the Spot Instance that the Spot service launches to fulfill the request. You must add tags to a Spot Instance yourself when you create the Spot Instance request or after the Spot Instance is launched.

So you'll need to add the tags after the instances have launched. You have some options here:

  • User Data Script on the created instance: Write a user data script that uses command line tools and the EC2 meta data service to allow the instance to discover its instance Id and create tags for itself. You can use the AWS CLI create-tags to tag any of your EC2 resources. Alternatively, you could bake this into the AMI as a startup script for whatever OS you intend to use. In either situation, the instance will have to have sufficient permissions to create EC2 tags for itself.
  • External Utility that monitors your spot request: You can use one of the AWS SDKs to monitor your spot request and tag the instances once they have been created. AWS has a tutorial on this very topic under the "How to Tag Your Spot Requests and Instances" header. Without getting too verbose, this simply involves polling Describe Spot Instance Requests until a created Instance Id is available, and then calling Create Tags.