diff --git a/README.md b/README.md index e0b46241..8c039727 100644 --- a/README.md +++ b/README.md @@ -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" @@ -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 ----------- @@ -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. \ No newline at end of file +Apache 2 Licensed. See LICENSE for full details. diff --git a/examples/basic/README.md b/examples/basic/README.md index 27a1f5f5..1462b598 100644 --- a/examples/basic/README.md +++ b/examples/basic/README.md @@ -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. diff --git a/examples/basic/main.tf b/examples/basic/main.tf index 31ef309a..4dd43d72 100644 --- a/examples/basic/main.tf +++ b/examples/basic/main.tf @@ -37,7 +37,7 @@ 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"] @@ -45,7 +45,7 @@ module "security_group" { egress_rules = ["all-all"] } -module "ec2" { +module "ec2_spot" { source = "../../" name = "example" @@ -53,4 +53,5 @@ module "ec2" { instance_type = "t2.micro" vpc_security_group_ids = ["${module.security_group.this_security_group_id}"] associate_public_ip_address = true + spot_price = "0.03" } diff --git a/examples/basic/outputs.tf b/examples/basic/outputs.tf index e87e2d8b..b72e6492 100644 --- a/examples/basic/outputs.tf +++ b/examples/basic/outputs.tf @@ -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}"] } diff --git a/main.tf b/main.tf index cda3c35e..6ceb5edc 100644 --- a/main.tf +++ b/main.tf @@ -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}" @@ -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}" diff --git a/outputs.tf b/outputs.tf index 8a76b3bc..bd955163 100644 --- a/outputs.tf +++ b/outputs.tf @@ -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}"] } diff --git a/variables.tf b/variables.tf index 90851a61..0632eb56 100644 --- a/variables.tf +++ b/variables.tf @@ -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" +}