Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

aws_spot_instance_request tags won't apply to instance #3263

Closed
caarlos0 opened this issue Sep 17, 2015 · 19 comments
Closed

aws_spot_instance_request tags won't apply to instance #3263

caarlos0 opened this issue Sep 17, 2015 · 19 comments

Comments

@caarlos0
Copy link
Contributor

I have an aws_spot_instance_request like this:

resource "aws_spot_instance_request" "seleniumgrid" {
    ami = "${var.amiPuppet}"
    key_name = "${var.key}"
    instance_type = "c3.4xlarge"
    subnet_id = "${var.subnet}"
    vpc_security_group_ids = [ "${var.securityGroup}" ]
    user_data = "${template_file.userdata.rendered}"
    wait_for_fulfillment = true
    spot_price = "${var.price}"
    availability_zone = "${var.zone}"
    instance_initiated_shutdown_behavior = "terminate"
    root_block_device {
      volume_size = 100
      volume_type = "gp2"
    }
    tags {
      Name = "${var.name}.${var.domain}"
      Provider = "Terraform"
      CA_TEAM = "${var.team}"
      CA_ROLE = "${var.role}"
      CA_SERVICE = "${var.service}"
    }
}

The tags are being applied only to the spot request itself, not to the underlying instance. Is this an expected behavior? How can I change this?

Thanks!

@jmreicha
Copy link

I just ran in to this issue as well.

@seanb4t
Copy link

seanb4t commented Dec 2, 2015

Definitely an issue, also in 0.6.8. Need a way to apply those tags to the new instance, or allow for an aws_instance_tag resource that will allow arbitrary tags to be set on ec2 instances.

@caarlos0
Copy link
Contributor Author

caarlos0 commented Dec 2, 2015

Agreed!

@stolinzeev
Copy link

Present in 0.6.8 as well

@catsby
Copy link
Contributor

catsby commented Dec 7, 2015

There is no AWS API that will do this via the Spot Instance request itself. We would need to trap the InstanceId (which we do) and then call out to set the tags on that. I don't see a straightforward easy way to do this, but it shouldn't be too hard. I don't know that I'll get to this anytime soon however, but maybe someone in the community will pick it up.

@cbarbour
Copy link

This is the expected behavior as per AWS documentation, unfortunately.

http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-requests.html#concepts-spot-instances-request-tags

I did find a solution. I created an IAM role with a policy that grants CreateTag permissions. I added an instance_profile to the role, and a ruleset allowing it to be assigned to the instances.

Using cloud init, I have a script that looks up the instances metadata, and using the result, tags itself based on arguments passed to the script.

There are a few moving parts, unfortunately. It helps if you're already familiar with cloud-init.

@cbarbour
Copy link

Another option: Use autoscaling groups. Tags applied to the launch_configuration will be passed on to the resulting spot instance.

@rehmanzile
Copy link

This issue seems to be open for a year now. Any luck with the fix.

@jalkjaer
Copy link

jalkjaer commented Mar 6, 2017

Until there is explicit support, we are getting by with the following user-data snippet to clone the spot-request tags to the instance.
Its somewhat simplistic and lacks error handling, but it does the job for us. It requires that aws cli / curl is available and that the instance has the proper IAM permission of course

#!/bin/bash

REGION=us-east-1
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
SPOT_REQ_ID=$(aws --region $REGION ec2 describe-instances --instance-ids "$INSTANCE_ID"  --query 'Reservations[0].Instances[0].SpotInstanceRequestId' --output text)
if [ "$SPOT_REQ_ID" != "None" ] ; then
  TAGS=$(aws --region $REGION ec2 describe-spot-instance-requests --spot-instance-request-ids "$SPOT_REQ_ID" --query 'SpotInstanceRequests[0].Tags')
  aws --region $REGION ec2 create-tags --resources "$INSTANCE_ID" --tags "$TAGS"
fi

@AlexTawse
Copy link

Issue still seems to be present in 0.9.4. Causing problems - will attempt the workaround solutions posted here

@kostyrev
Copy link

Workarounds are good but not always applicable.
Please consider adding explicit support.

@DanielMarquard
Copy link

Still a problem in 0.11.3. No errors, but tags seem to just be being disregarded.

@drorata
Copy link

drorata commented Feb 22, 2018

@DanielMarquard did you the workaround above: #3263 (comment)

@DanielMarquard
Copy link

@drorata I haven't, but it seems like it would work. I'll have Terraform execute that command in the CI script. Thanks.

@raackley
Copy link

Still an issue on 0.11.7, but the workaround posted above works well.

@DanielMarquard
Copy link

DanielMarquard commented Jun 12, 2018

Here's my workaround. I use environment variables, but your use case might not require them.

resource "aws_spot_instance_request" "instance" {
  wait_for_fulfillment = true

  provisioner "local-exec" {
    command = "aws ec2 create-tags --resources ${aws_spot_instance_request.instance.spot_instance_id} --tags Key=Name,Value=ec2-resource-name"

    environment {
      AWS_ACCESS_KEY_ID = "${var.aws_access_key}"
      AWS_SECRET_ACCESS_KEY = "${var.aws_secret_key}"
      AWS_DEFAULT_REGION = "${var.region}"
    }
  }
}

@fa-farafa
Copy link

fa-farafa commented Sep 24, 2018

Hi, adopted above workaround for count >=1
Region is important if instances aren't in your default region.

  provisioner "local-exec" {
    command = "aws ec2 create-tags --resources ${self.spot_instance_id} --tags Key=Name,Value=ec2-name-${count.index} --region ${var.region}"

@joeabbey
Copy link

joeabbey commented Mar 1, 2019

If you also want tags applied to your volumes:

  provisioner "local-exec" {
    command = "${join("", formatlist("aws ec2 create-tags --resources ${self.spot_instance_id} --tags Key=\"%s\",Value=\"%s\" --region=${var.region}; ", keys(self.tags), values(self.tags)))}"
    environment {
      AWS_ACCESS_KEY_ID = "${var.aws_access_key}"
      AWS_SECRET_ACCESS_KEY = "${var.aws_secret_key}"
      AWS_DEFAULT_REGION = "${var.region}"
    }
  }

  provisioner "local-exec" {
    command = "for eachVolume in `aws ec2 describe-volumes --region ${var.region} --filters Name=attachment.instance-id,Values=${self.spot_instance_id} | jq -r .Volumes[].VolumeId`; do ${join("", formatlist("aws ec2 create-tags --resources $eachVolume --tags          Key=\"%s\",Value=\"%s\" --region=${var.region}; ", keys(self.tags), values(self.tags)))} done;"
    environment {
      AWS_ACCESS_KEY_ID = "${var.aws_access_key}"
      AWS_SECRET_ACCESS_KEY = "${var.aws_secret_key}"
      AWS_DEFAULT_REGION = "${var.region}"
    }
  }

Note: the above uses jq

@ghost
Copy link

ghost commented Mar 29, 2020

I'm going to lock this issue because it has been closed for 30 days ⏳. This helps our maintainers find and focus on the active issues.

If you have found a problem that seems similar to this, please open a new issue and complete the issue template so we can capture all the details necessary to investigate further.

@ghost ghost locked and limited conversation to collaborators Mar 29, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet