Skip to content

Add support for spot instances #5

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

Closed
wants to merge 9 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 11 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,27 +1,28 @@
AWS EC2 Instance Terraform module
AWS EC2 Spot Instance Request Terraform module
=================================

Terraform module which creates EC2 instance(s) on AWS.
Terraform module which creates EC2 Spot Request request(s) on AWS.

These types of resources are supported:

* [EC2 instance](https://www.terraform.io/docs/providers/aws/r/instance.html)
* [EC2 Spot Instance Request](https://www.terraform.io/docs/providers/aws/r/spot_instance_request.html)

Usage
-----

```hcl
module "ec2_cluster" {
source = "terraform-aws-modules/ec2-instance/aws"
module "ec2_spot_cluster" {
source = "johnypony3/ec2-spot-instance/aws"

name = "my-cluster"
count = 5

ami = "ami-ebd02392"
instance_type = "t2.micro"
key_name = "user1"
monitoring = true
vpc_security_group_ids = ["sg-12345678"]
spot_price = "0.03"

tags = {
Terraform = "true"
Expand All @@ -33,7 +34,7 @@ module "ec2_cluster" {
Examples
--------

* [Basic EC2 instance](https://github.com/terraform-aws-modules/terraform-aws-ec2-instance/tree/master/examples/basic)
* [Basic EC2 Spot instance](https://github.com/johnypony3/terraform-aws-ec2-spot-instance/tree/master/examples/spot)

Limitations
-----------
Expand All @@ -44,9 +45,9 @@ Limitations
Authors
-------

Module managed by [Anton Babenko](https://github.com/antonbabenko).

Module based on the work of [Anton Babenko](https://github.com/antonbabenko).
Written and managed by [johnypony3](https://github.com/johnypony3)
License
-------

Apache 2 Licensed. See LICENSE for full details.
Apache 2 Licensed. See LICENSE for full details.
4 changes: 2 additions & 2 deletions examples/basic/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Basic EC2 instance
Basic EC2 spot instance request
==================

Configuration in this directory creates single EC2 instance with minimum set of arguments: AMI ID and instance type.
Configuration in this directory creates single EC2 spot instance request with minimum set of arguments: AMI ID and instance type.

Unspecified arguments for security group id and subnet are inherited from the default VPC.

Expand Down
5 changes: 3 additions & 2 deletions examples/basic/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -37,20 +37,21 @@ module "security_group" {
source = "terraform-aws-modules/security-group/aws"

name = "example"
description = "Security group for example usage with EC2 instance"
description = "Security group"
vpc_id = "${data.aws_vpc.default.id}"

ingress_cidr_blocks = ["0.0.0.0/0"]
ingress_rules = ["http-80-tcp", "all-icmp"]
egress_rules = ["all-all"]
}

module "ec2" {
module "ec2_spot" {
source = "../../"

name = "example"
ami = "${data.aws_ami.amazon_linux.id}"
instance_type = "t2.micro"
vpc_security_group_ids = ["${module.security_group.this_security_group_id}"]
associate_public_ip_address = true
spot_price = "0.03"
}
38 changes: 29 additions & 9 deletions examples/basic/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
output "id" {
description = "List of IDs of instances"
value = ["${module.ec2.id}"]
value = ["${module.ec2_spot.id}"]
}

output "public_dns" {
description = "List of public DNS names assigned to the instances"
value = ["${module.ec2.public_dns}"]
description = "List of public DNS names assigned to the instances. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = ["${module.ec2_spot.public_dns}"]
}

output "instance_id" {
description = "EC2 instance ID"
value = "${module.ec2.id[0]}"
output "public_ip" {
description = "List of public IP addresses assigned to the instances, if applicable"
value = ["${module.ec2_spot.public_ip}"]
}

output "instance_public_dns" {
description = "Public DNS name assigned to the EC2 instance"
value = "${module.ec2.public_dns[0]}"
output "private_dns" {
description = "List of private DNS names assigned to the instances. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = ["${module.ec2_spot.private_dns}"]
}

output "private_ip" {
description = "List of private IP addresses assigned to the instances"
value = ["${module.ec2_spot.private_ip}"]
}

output "spot_bid_status" {
description = "The current bid status of the Spot Instance Request."
value = ["${module.ec2_spot.spot_bid_status}"]
}

output "spot_request_state" {
description = "The current request state of the Spot Instance Request."
value = ["${module.ec2_spot.spot_request_state}"]
}

output "spot_instance_id" {
description = "The Instance ID (if any) that is currently fulfilling the Spot Instance request."
value = ["${module.ec2_spot.spot_instance_id}"]
}
16 changes: 14 additions & 2 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
######
# EC2 instance
# EC2 spot instance
######
resource "aws_instance" "this" {
resource "aws_spot_instance_request" "this" {
count = "${var.count}"

ami = "${var.ami}"
Expand Down Expand Up @@ -31,6 +31,18 @@ resource "aws_instance" "this" {
placement_group = "${var.placement_group}"
tenancy = "${var.tenancy}"

spot_price = "${var.spot_price}"
wait_for_fulfillment = "${var.wait_for_fulfillment}"
spot_type = "${var.spot_type}"
instance_interruption_behaviour = "${var.instance_interruption_behaviour}"
launch_group = "${var.launch_group}"
block_duration_minutes = "${var.block_duration_minutes}"

timeouts {
create = "${var.create_timeout}"
delete = "${var.delete_timeout}"
}

# Note: network_interface can't be specified together with associate_public_ip_address
# network_interface = "${var.network_interface}"

Expand Down
53 changes: 14 additions & 39 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -1,64 +1,39 @@
output "id" {
description = "List of IDs of instances"
value = ["${aws_instance.this.*.id}"]
}

output "availability_zone" {
description = "List of availability zones of instances"
value = ["${aws_instance.this.*.availability_zone}"]
}

output "placement_group" {
description = "List of placement groups of instances"
value = ["${aws_instance.this.*.placement_group}"]
}

output "key_name" {
description = "List of key names of instances"
value = ["${aws_instance.this.*.key_name}"]
value = ["${aws_spot_instance_request.this.*.id}"]
}

output "public_dns" {
description = "List of public DNS names assigned to the instances. For EC2-VPC, this is only available if you've enabled DNS hostnames for your VPC"
value = ["${aws_instance.this.*.public_dns}"]
value = ["${aws_spot_instance_request.this.*.public_dns}"]
}

output "public_ip" {
description = "List of public IP addresses assigned to the instances, if applicable"
value = ["${aws_instance.this.*.public_ip}"]
}

output "network_interface_id" {
description = "List of IDs of the network interface of instances"
value = ["${aws_instance.this.*.network_interface_id}"]
}

output "primary_network_interface_id" {
description = "List of IDs of the primary network interface of instances"
value = ["${aws_instance.this.*.primary_network_interface_id}"]
value = ["${aws_spot_instance_request.this.*.public_ip}"]
}

output "private_dns" {
description = "List of private DNS names assigned to the instances. Can only be used inside the Amazon EC2, and only available if you've enabled DNS hostnames for your VPC"
value = ["${aws_instance.this.*.private_dns}"]
value = ["${aws_spot_instance_request.this.*.private_dns}"]
}

output "private_ip" {
description = "List of private IP addresses assigned to the instances"
value = ["${aws_instance.this.*.private_ip}"]
value = ["${aws_spot_instance_request.this.*.private_ip}"]
}

output "security_groups" {
description = "List of associated security groups of instances"
value = ["${aws_instance.this.*.security_groups}"]
output "spot_bid_status" {
description = "The current bid status of the Spot Instance Request."
value = ["${aws_spot_instance_request.this.*.spot_bid_status}"]
}

output "vpc_security_group_ids" {
description = "List of associated security groups of instances, if running in non-default VPC"
value = ["${aws_instance.this.*.vpc_security_group_ids}"]
output "spot_request_state" {
description = "The current request state of the Spot Instance Request."
value = ["${aws_spot_instance_request.this.*.spot_request_state}"]
}

output "subnet_id" {
description = "List of IDs of VPC subnets of instances"
value = ["${aws_instance.this.*.}"]
output "spot_instance_id" {
description = "The Instance ID (if any) that is currently fulfilling the Spot Instance request."
value = ["${aws_spot_instance_request.this.*.spot_instance_id}"]
}
44 changes: 44 additions & 0 deletions variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,47 @@ variable "network_interface" {
description = "Customize network interfaces to be attached at instance boot time"
default = []
}

variable "spot_price" {
type = "string"
description = "The maximum hourly price (bid) you are willing to pay for the instance, e.g. 0.10"
}

variable "wait_for_fulfillment" {
description = "(Optional; Default: false) If set, Terraform will wait for the Spot Request to be fulfilled, and will throw an error if the timeout of 10m is reached."
default = false
}

variable "launch_group" {
type = "string"
description = "Group name to assign the instances to so they can be started/stopped in unison, e.g. purple-plutonium"
default = ""
}

variable "instance_interruption_behaviour" {
type = "string"
description = "Whether a Spot instance stops or terminates when it is interrupted, can be stop or terminate"
default = "terminate"
}

variable "block_duration_minutes" {
type = "string"
description = "(Optional) The required duration for the Spot instances, in minutes. This value must be a multiple of 60 (60, 120, 180, 240, 300, or 360)."
default = "0"
}

variable "spot_type" {
type = "string"
description = "(Optional; Default: 'persistent') If set to 'one-time', after the instance is terminated, the spot request will be closed. Also, Terraform can't manage one-time spot requests, just launch them."
default = "persistent"
}

variable "create_timeout" {
description = "(Defaults to 10 mins) Used when requesting the spot instance (only valid if wait_for_fulfillment = true)"
default = "10m"
}

variable "delete_timeout" {
description = "(Defaults to 10 mins) Used when terminating all instances launched via the given spot instance request"
default = "10m"
}