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

Feature request: Allow aws_instance resource to create and manage spot instances #1243

Closed
tomelliff opened this issue Jul 26, 2017 · 3 comments
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/ec2 Issues and PRs that pertain to the ec2 service. stale Old or inactive issues managed by automation, if no further action taken these will get closed.

Comments

@tomelliff
Copy link
Contributor

tomelliff commented Jul 26, 2017

I haven't taken a particularly long look at the code to see how much impact this would have but it would be nice if the aws_instance resource could be used to manage spot instances instead of having to explicitly use the aws_spot_instance_request resource.

This would simplify being able to switch between spot and on demand requests without duplicating code. As it is I have a module that creates EC2 instances and then a bunch of other dependent resources (Route53 records, Cloudwatch alarms etc) and I'm going to have to duplicate the aws_instance resource plus all the resources dependent on it to use the aws_spot_instance_request and also make them conditional on whether a spot price has been set.

So as a minimal example I'll have something like:

variable "instance_count" {
  default = 1
}

variable "spot_price" {
  default = ""
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_instance" "instance" {
  count         = "${var.spot_price == "" ? var.instance_count : 0}"
  ami           = "${data.aws_ami.ubuntu.id}"
  instance_type = "t2.micro"

  tags {
    Name = "${var.name}${var.instance_count > 1 ? format("-%v", count.index+1) : ""}.${var.domain}"
  }
}

resource "aws_spot_instance_request" "instance" {
  count         = "${var.spot_price != "" ? var.instance_count : 0}"
  ami           = "${data.aws_ami.ubuntu.id}"
  instance_type = "t2.micro"
  spot_price    = "${var.spot_price}"

  tags {
    Name = "${var.name}${var.instance_count > 1 ? format("-%v", count.index+1) : ""}.${var.domain}"
  }
}

data "aws_vpc" "vpc" {
  tags {
    Name = "myvpc"
  }
}

data "aws_route53_zone" "zone" {
  name   = "example.com"
  vpc_id = "${data.aws_vpc.selected.id}"
}

resource "aws_route53_record" "on_demand_record" {
  count   = "${var.spot_price == "" ? var.instance_count : 0}"
  zone_id = "${data.aws_route53_zone.zone.zone_id}"
  name    = "${var.name}${var.instance_count > 1 ? format("-%v", count.index+1) : ""}.example.com"
  type    = "A"
  ttl     = "60"

  records = ["${element(aws_instance.instance.*.private_ip, count.index)}"]
}

resource "aws_route53_record" "spot_record" {
  count   = "${var.spot_price != "" ? var.instance_count : 0}"
  zone_id = "${data.aws_route53_zone.zone.zone_id}"
  name    = "${var.name}${var.instance_count > 1 ? format("-%v", count.index+1) : ""}.example.com"
  type    = "A"
  ttl     = "60"

  records = ["${element(aws_spot_instance_request.instance.*.private_ip, count.index)}"]
}

But with a lot more duplicated configuration between the aws_instance and aws_spot_instance_request and also anything else that needs the instance id, private IP address or other computed attributes.

Instead I'd love to just do:

variable "instance_count" {
  default = 1
}

variable "spot_price" {
  default = ""
}

data "aws_ami" "ubuntu" {
  most_recent = true

  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-trusty-14.04-amd64-server-*"]
  }

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }

  owners = ["099720109477"] # Canonical
}

resource "aws_instance" "instance" {
  count         = "${var.instance_count}"
  ami           = "${data.aws_ami.ubuntu.id}"
  instance_type = "t2.micro"
  spot_price    = "${var.spot_price}"

  tags {
    Name = "${var.name}${var.instance_count > 1 ? format("-%v", count.index+1) : ""}.${var.domain}"
  }
}

data "aws_vpc" "vpc" {
  tags {
    Name = "myvpc"
  }
}

data "aws_route53_zone" "zone" {
  name   = "example.com"
  vpc_id = "${data.aws_vpc.selected.id}"
}

resource "aws_route53_record" "record" {
  count   = "${var.instance_count}"
  zone_id = "${data.aws_route53_zone.zone.zone_id}"
  name    = "${var.name}${var.instance_count > 1 ? format("-%v", count.index+1) : ""}.example.com"
  type    = "A"
  ttl     = "60"

  records = ["${element(aws_instance.instance.*.private_ip, count.index)}"]
}

Where the aws_instance resource takes an optional spot_price (plus other spot related config) and if it gets an empty string or isn't provided then it creates an on demand instance instead.

Would people be open to complicating the code in the aws_instance module to allow for this simpler interface? I'd guess it probably adds a fair bit more complexity to things in the code but I'm not sure if there's an specific steer away from that if it enables users (the vast majority of people) to more easily do something like this.

@grubernaut grubernaut added the enhancement Requests to existing resources that expand the functionality or scope. label Jul 26, 2017
@tomelliff
Copy link
Contributor Author

tomelliff commented Nov 29, 2017

Sounds like this should be much easier with this announcement today: https://aws.amazon.com/blogs/aws/amazon-ec2-update-streamlined-access-to-spot-capacity-smooth-price-changes-instance-hibernation/

Looks like the API docs/SDK haven't been updated just yet but checking the diffs on the SDK (https://github.com/aws/aws-sdk-go/pull/1666/files#diff-68798fbeff74277f6e5c5ab6f1cf92c6) it looks like things have been reworked a lot to expose a new LaunchTemplate structure.

@github-actions
Copy link

github-actions bot commented Jan 9, 2022

Marking this issue as stale due to inactivity. This helps our maintainers find and focus on the active issues. If this issue receives no comments in the next 30 days it will automatically be closed. Maintainers can also remove the stale label.

If this issue was automatically closed and you feel this issue should be reopened, we encourage creating a new issue linking back to this one for added context. Thank you!

@github-actions github-actions bot added the stale Old or inactive issues managed by automation, if no further action taken these will get closed. label Jan 9, 2022
@github-actions github-actions bot closed this as completed Feb 9, 2022
@github-actions
Copy link

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.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 16, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
enhancement Requests to existing resources that expand the functionality or scope. service/ec2 Issues and PRs that pertain to the ec2 service. stale Old or inactive issues managed by automation, if no further action taken these will get closed.
Projects
None yet
Development

No branches or pull requests

3 participants