From e3a99fec9cc83858b577bd0f6d5872dbbb1cb217 Mon Sep 17 00:00:00 2001 From: Shaun Cutts Date: Thu, 13 Feb 2020 15:56:48 -0500 Subject: [PATCH] adds mixed instance policy configuration (#19) * adds mixed instance policy configuration * updates README, formats terraform * Updated README.md * Executed 'terraform fmt' Co-authored-by: actions-bot <58130806+actions-bot@users.noreply.github.com> --- ...res-mixed-instance-policy.us-east-2.tfvars | 36 ++++++++++ examples/complete/main.tf | 4 +- examples/complete/variables.tf | 37 ++++++++++ main.tf | 69 +++++++++++++++++-- variables.tf | 20 ++++++ 5 files changed, 161 insertions(+), 5 deletions(-) create mode 100644 examples/complete/fixtures-mixed-instance-policy.us-east-2.tfvars diff --git a/examples/complete/fixtures-mixed-instance-policy.us-east-2.tfvars b/examples/complete/fixtures-mixed-instance-policy.us-east-2.tfvars new file mode 100644 index 0000000..ad57625 --- /dev/null +++ b/examples/complete/fixtures-mixed-instance-policy.us-east-2.tfvars @@ -0,0 +1,36 @@ +region = "us-east-2" + +availability_zones = ["us-east-2a", "us-east-2b"] + +namespace = "eg" + +stage = "test" + +name = "ec2-autoscale-group" + +image_id = "ami-00c03f7f7f2ec15c3" + +instance_type = "t2.small" + +health_check_type = "EC2" + +wait_for_capacity_timeout = "10m" + +max_size = 3 + +min_size = 2 + +cpu_utilization_high_threshold_percent = 80 + +cpu_utilization_low_threshold_percent = 20 + +mixed_instances_policy = { + instances_distribution = null + override = [{ + instance_type = "t3.small" + weighted_capacity = null + }, { + instance_type = "t3a.small" + weighted_capacity = null + }] +} \ No newline at end of file diff --git a/examples/complete/main.tf b/examples/complete/main.tf index aef5221..efe47bb 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -11,7 +11,7 @@ module "vpc" { } module "subnets" { - source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.16.0" + source = "git::https://github.com/cloudposse/terraform-aws-dynamic-subnets.git?ref=tags/0.18.1" availability_zones = var.availability_zones namespace = var.namespace stage = var.stage @@ -32,6 +32,8 @@ module "autoscale_group" { image_id = var.image_id instance_type = var.instance_type + instance_market_options = var.instance_market_options + mixed_instances_policy = var.mixed_instances_policy subnet_ids = module.subnets.public_subnet_ids health_check_type = var.health_check_type min_size = var.min_size diff --git a/examples/complete/variables.tf b/examples/complete/variables.tf index 92c2516..80a895f 100644 --- a/examples/complete/variables.tf +++ b/examples/complete/variables.tf @@ -62,3 +62,40 @@ variable "cpu_utilization_low_threshold_percent" { type = number description = "CPU utilization low threshold" } + +variable "instance_market_options" { + description = "The market (purchasing) option for the instances" + + type = object({ + market_type = string + spot_options = object({ + block_duration_minutes = number + instance_interruption_behavior = string + max_price = number + spot_instance_type = string + valid_until = string + }) + }) + + default = null +} + +variable mixed_instances_policy { + description = "policy to used mixed group of on demand/spot of differing types. Launch template is automatically generated. https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html#mixed_instances_policy-1" + + type = object({ + instances_distribution = object({ + on_demand_allocation_strategy = string + on_demand_base_capacity = number + on_demand_percentage_above_base_capacity = number + spot_allocation_strategy = string + spot_instance_pools = number + spot_max_price = string + }) + override = list(object({ + instance_type = string + weighted_capacity = number + })) + }) + default = null +} diff --git a/main.tf b/main.tf index bc38a82..3f65dcf 100644 --- a/main.tf +++ b/main.tf @@ -62,7 +62,8 @@ resource "aws_launch_template" "default" { market_type = lookup(instance_market_options.value, "market_type", null) dynamic "spot_options" { - for_each = flatten(list(lookup(instance_market_options.value, "spot_options", []))) + for_each = (instance_market_options.value.spot_options != null ? + [instance_market_options.value.spot_options] : []) content { block_duration_minutes = lookup(spot_options.value, "block_duration_minutes", null) instance_interruption_behavior = lookup(spot_options.value, "instance_interruption_behavior", null) @@ -124,6 +125,22 @@ resource "aws_launch_template" "default" { } } +locals { + launch_template_block = { + id = join("", aws_launch_template.default.*.id) + version = var.launch_template_version != "" ? var.launch_template_version : join("", aws_launch_template.default.*.latest_version) + } + launch_template = ( + var.mixed_instances_policy == null ? local.launch_template_block + : null) + mixed_instances_policy = ( + var.mixed_instances_policy == null ? null : { + instances_distribution = var.mixed_instances_policy.instances_distribution + launch_template = local.launch_template_block + override = var.mixed_instances_policy.override + }) +} + resource "aws_autoscaling_group" "default" { count = var.enabled ? 1 : 0 @@ -148,9 +165,53 @@ resource "aws_autoscaling_group" "default" { protect_from_scale_in = var.protect_from_scale_in service_linked_role_arn = var.service_linked_role_arn - launch_template { - id = join("", aws_launch_template.default.*.id) - version = var.launch_template_version != "" ? var.launch_template_version : join("", aws_launch_template.default.*.latest_version) + dynamic "launch_template" { + for_each = (local.launch_template != null ? + [local.launch_template] : []) + content { + id = local.launch_template_block.id + version = local.launch_template_block.version + } + } + + dynamic "mixed_instances_policy" { + for_each = (local.mixed_instances_policy != null ? + [local.mixed_instances_policy] : []) + content { + dynamic "instances_distribution" { + for_each = ( + mixed_instances_policy.value.instances_distribution != null ? + [mixed_instances_policy.value.instances_distribution] : []) + content { + on_demand_allocation_strategy = lookup( + instances_distribution.value, "on_demand_allocation_strategy", null) + on_demand_base_capacity = lookup( + instances_distribution.value, "on_demand_base_capacity", null) + on_demand_percentage_above_base_capacity = lookup( + instances_distribution.value, "on_demand_percentage_above_base_capacity", null) + spot_allocation_strategy = lookup( + instances_distribution.value, "spot_allocation_strategy", null) + spot_instance_pools = lookup( + instances_distribution.value, "spot_instance_pools", null) + spot_max_price = lookup( + instances_distribution.value, "spot_max_price", null) + } + } + launch_template { + launch_template_specification { + launch_template_id = mixed_instances_policy.value.launch_template.id + version = mixed_instances_policy.value.launch_template.version + } + dynamic "override" { + for_each = (mixed_instances_policy.value.override != null ? + mixed_instances_policy.value.override : []) + content { + instance_type = lookup(override.value, "instance_type", null) + weighted_capacity = lookup(override.value, "weighted_capacity", null) + } + } + } + } } tags = flatten([ diff --git a/variables.tf b/variables.tf index 4fdcdf8..8113a37 100644 --- a/variables.tf +++ b/variables.tf @@ -143,6 +143,26 @@ variable "instance_market_options" { default = null } +variable mixed_instances_policy { + description = "policy to used mixed group of on demand/spot of differing types. Launch template is automatically generated. https://www.terraform.io/docs/providers/aws/r/autoscaling_group.html#mixed_instances_policy-1" + + type = object({ + instances_distribution = object({ + on_demand_allocation_strategy = string + on_demand_base_capacity = number + on_demand_percentage_above_base_capacity = number + spot_allocation_strategy = string + spot_instance_pools = number + spot_max_price = string + }) + override = list(object({ + instance_type = string + weighted_capacity = number + })) + }) + default = null +} + variable "placement" { description = "The placement specifications of the instances"