From 2c2a8a9bc255b49dc63f587d090b6b5a7d8b7c94 Mon Sep 17 00:00:00 2001 From: Bryant Biggs Date: Mon, 14 Feb 2022 05:57:12 -0500 Subject: [PATCH] feat!: Update autoscaling group `tags` -> `tag` to support v4 of AWS provider (#179) BREAKING CHANGES: * `var.propagate_name` has been removed * `var.tags_as_map` has been moved into `var.tags` and now `var.tags` just takes the standard `map(string)` map of key-value pairs for tags. The tags provided are propagated to instances launched through the dynamic tag block * Users will need to ensure that the value they are passing to `var.tags` is the standard map of key=value pairs (map(string)) --- .pre-commit-config.yaml | 2 +- README.md | 4 +- examples/complete/main.tf | 97 ++++++++++++++------------------------- main.tf | 48 ++++++++----------- variables.tf | 14 +----- 5 files changed, 56 insertions(+), 109 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 093121e..8a010fd 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,6 +1,6 @@ repos: - repo: https://github.com/antonbabenko/pre-commit-terraform - rev: v1.62.3 + rev: v1.64.0 hooks: - id: terraform_fmt - id: terraform_validate diff --git a/README.md b/README.md index b5721b7..02005f7 100644 --- a/README.md +++ b/README.md @@ -363,7 +363,6 @@ No modules. | [placement](#input\_placement) | (LT) The placement of the instance | `map(string)` | `null` | no | | [placement\_group](#input\_placement\_group) | The name of the placement group into which you'll launch your instances, if any | `string` | `null` | no | | [placement\_tenancy](#input\_placement\_tenancy) | (LC) The tenancy of the instance. Valid values are `default` or `dedicated` | `string` | `null` | no | -| [propagate\_name](#input\_propagate\_name) | Determines whether to propagate the `var.instance_name`/`var.name` tag to launch instances | `bool` | `true` | no | | [protect\_from\_scale\_in](#input\_protect\_from\_scale\_in) | Allows setting instance protection. The autoscaling group will not select instances with this setting for termination during scale in events. | `bool` | `false` | no | | [ram\_disk\_id](#input\_ram\_disk\_id) | (LT) The ID of the ram disk | `string` | `null` | no | | [root\_block\_device](#input\_root\_block\_device) | (LC) Customize details about the root block device of the instance | `list(map(string))` | `[]` | no | @@ -374,8 +373,7 @@ No modules. | [spot\_price](#input\_spot\_price) | (LC) The maximum price to use for reserving spot instances (defaults to on-demand price) | `string` | `null` | no | | [suspended\_processes](#input\_suspended\_processes) | A list of processes to suspend for the Auto Scaling Group. The allowed values are `Launch`, `Terminate`, `HealthCheck`, `ReplaceUnhealthy`, `AZRebalance`, `AlarmNotification`, `ScheduledActions`, `AddToLoadBalancer`. Note that if you suspend either the `Launch` or `Terminate` process types, it can prevent your Auto Scaling Group from functioning properly | `list(string)` | `null` | no | | [tag\_specifications](#input\_tag\_specifications) | (LT) The tags to apply to the resources during launch | `list(any)` | `[]` | no | -| [tags](#input\_tags) | A list of tag blocks. Each element should have keys named key, value, and propagate\_at\_launch | `list(map(string))` | `[]` | no | -| [tags\_as\_map](#input\_tags\_as\_map) | A map of tags and values in the same format as other resources accept. This will be converted into the non-standard format that the aws\_autoscaling\_group requires. | `map(string)` | `{}` | no | +| [tags](#input\_tags) | A map of tags to assign to resources | `map(string)` | `{}` | no | | [target\_group\_arns](#input\_target\_group\_arns) | A set of `aws_alb_target_group` ARNs, for use with Application or Network Load Balancing | `list(string)` | `[]` | no | | [termination\_policies](#input\_termination\_policies) | A list of policies to decide how the instances in the Auto Scaling Group should be terminated. The allowed values are `OldestInstance`, `NewestInstance`, `OldestLaunchConfiguration`, `ClosestToNextInstanceHour`, `OldestLaunchTemplate`, `AllocationStrategy`, `Default` | `list(string)` | `null` | no | | [update\_default\_version](#input\_update\_default\_version) | (LT) Whether to update Default Version each update. Conflicts with `default_version` | `string` | `null` | no | diff --git a/examples/complete/main.tf b/examples/complete/main.tf index ef889b9..c883269 100644 --- a/examples/complete/main.tf +++ b/examples/complete/main.tf @@ -16,23 +16,9 @@ provider "aws" { } locals { - name = "example-asg" + name = "ex-asg-complete" region = "eu-west-1" - - tags = [ - { - key = "Project" - value = "megasecret" - propagate_at_launch = true - }, - { - key = "foo" - value = "something" - propagate_at_launch = true - }, - ] - - tags_as_map = { + tags = { Owner = "user" Environment = "dev" } @@ -61,7 +47,7 @@ module "vpc" { enable_dns_hostnames = true enable_dns_support = true - tags = local.tags_as_map + tags = local.tags } module "asg_sg" { @@ -82,7 +68,7 @@ module "asg_sg" { egress_rules = ["all-all"] - tags = local.tags_as_map + tags = local.tags } data "aws_ami" "amazon_linux" { @@ -112,28 +98,26 @@ resource "aws_iam_service_linked_role" "autoscaling" { resource "aws_iam_instance_profile" "ssm" { name = "complete-${local.name}" role = aws_iam_role.ssm.name - tags = local.tags_as_map + tags = local.tags } resource "aws_iam_role" "ssm" { name = "complete-${local.name}" - tags = local.tags_as_map + tags = local.tags - assume_role_policy = <<-EOT - { - "Version": "2012-10-17", - "Statement": [ + assume_role_policy = jsonencode({ + Version = "2012-10-17", + Statement = [ { - "Action": "sts:AssumeRole", - "Principal": { - "Service": "ec2.amazonaws.com" + Action = "sts:AssumeRole", + Principal = { + Service = "ec2.amazonaws.com" }, - "Effect": "Allow", - "Sid": "" + Effect = "Allow", + Sid = "" } ] - } - EOT + }) } module "alb_http_sg" { @@ -146,7 +130,7 @@ module "alb_http_sg" { ingress_cidr_blocks = ["0.0.0.0/0"] - tags = local.tags_as_map + tags = local.tags } module "alb" { @@ -176,7 +160,7 @@ module "alb" { }, ] - tags = local.tags_as_map + tags = local.tags } ################################################################################ @@ -213,8 +197,7 @@ module "lt_only" { image_id = data.aws_ami.amazon_linux.id instance_type = "t3.micro" - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } module "lc_only" { @@ -234,8 +217,7 @@ module "lc_only" { image_id = data.aws_ami.amazon_linux.id instance_type = "t3.micro" - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } ################################################################################ @@ -261,8 +243,7 @@ module "default_lt" { image_id = data.aws_ami.amazon_linux.id instance_type = "t3.micro" - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } # Launch configuration @@ -284,8 +265,7 @@ module "default_lc" { image_id = data.aws_ami.amazon_linux.id instance_type = "t3.micro" - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } ################################################################################ @@ -318,8 +298,7 @@ module "external_lt" { use_lt = true launch_template = aws_launch_template.this.name - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } # Launch configuration @@ -348,8 +327,7 @@ module "external_lc" { use_lc = true launch_configuration = aws_launch_configuration.this.name - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } ################################################################################ @@ -469,9 +447,6 @@ module "complete_lt" { instance_market_options = { market_type = "spot" - spot_options = { - block_duration_minutes = 60 - } } metadata_options = { @@ -507,16 +482,15 @@ module "complete_lt" { }, { resource_type = "volume" - tags = merge({ WhatAmI = "Volume" }, local.tags_as_map) + tags = merge({ WhatAmI = "Volume" }) }, { resource_type = "spot-instances-request" - tags = merge({ WhatAmI = "SpotInstanceRequest" }, local.tags_as_map) + tags = merge({ WhatAmI = "SpotInstanceRequest" }) } ] - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags # Autoscaling Schedule schedules = { @@ -557,7 +531,11 @@ module "complete_lt" { }, predictive-scaling = { policy_type = "PredictiveScaling" - predictive_scaling_config = { + predictive_scaling_configuration = { + mode = "ForecastAndScale" + scheduling_buffer_time = 10 + max_capacity_breach_behavior = "IncreaseMaxCapacity" + max_capacity_buffer = 10 metric_specification = { target_value = 32 predefined_scaling_metric_specification = { @@ -569,10 +547,6 @@ module "complete_lt" { resource_label = "testLabel" } } - mode = "ForecastAndScale" - scheduling_buffer_time = 10 - max_capacity_breach_behavior = "IncreaseMaxCapacity" - max_capacity_buffer = 10 } } } @@ -668,8 +642,7 @@ module "complete_lc" { http_put_response_hop_limit = 32 } - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } ################################################################################ @@ -746,8 +719,7 @@ module "mixed_instance" { ] } - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } ################################################################################ @@ -778,6 +750,5 @@ module "warmed_lt" { max_group_prepared_capacity = 2 } - tags = local.tags - tags_as_map = local.tags_as_map + tags = local.tags } diff --git a/main.tf b/main.tf index ad612d7..0746a0b 100644 --- a/main.tf +++ b/main.tf @@ -8,29 +8,11 @@ locals { launch_template = var.create_lt ? aws_launch_template.this[0].name : var.launch_template launch_template_version = var.create_lt && var.lt_version == null ? aws_launch_template.this[0].latest_version : var.lt_version - tags = distinct(concat( - [for k, v in data.aws_default_tags.current.tags : - { key = k - value = v - propagate_at_launch = true - } - ], - [ - { - key = "Name" - value = coalesce(var.instance_name, var.name) - propagate_at_launch = var.propagate_name - }, - ], + asg_tags = merge( + data.aws_default_tags.current.tags, var.tags, - [for k, v in var.tags_as_map : - { - key = k - value = v - propagate_at_launch = true - } - ] - )) + { "Name" = coalesce(var.instance_name, var.name) }, + ) } ################################################################################ @@ -303,7 +285,7 @@ resource "aws_launch_template" "this" { for_each = var.tag_specifications content { resource_type = tag_specifications.value.resource_type - tags = tag_specifications.value.tags + tags = merge(var.tags, tag_specifications.value.tags) } } @@ -311,7 +293,7 @@ resource "aws_launch_template" "this" { create_before_destroy = true } - tags = var.tags_as_map + tags = var.tags } ################################################################################ @@ -446,7 +428,14 @@ resource "aws_autoscaling_group" "this" { delete = var.delete_timeout } - tags = local.tags + dynamic "tag" { + for_each = local.asg_tags + content { + key = tag.key + value = tag.value + propagate_at_launch = true + } + } lifecycle { create_before_destroy = true @@ -477,6 +466,7 @@ resource "aws_autoscaling_schedule" "this" { ################################################################################ # Autoscaling Policy ################################################################################ + resource "aws_autoscaling_policy" "this" { for_each = { for k, v in var.scaling_policies : k => v if var.create_asg && var.create_scaling_policy } @@ -542,12 +532,12 @@ resource "aws_autoscaling_policy" "this" { scheduling_buffer_time = lookup(predictive_scaling_configuration.value, "scheduling_buffer_time", null) dynamic "metric_specification" { - for_each = lookup(predictive_scaling_configuration.value, "metric_specification", []) + for_each = can(predictive_scaling_configuration.value.metric_specification.target_value) ? [predictive_scaling_configuration.value.metric_specification] : [] content { target_value = metric_specification.value.target_value dynamic "predefined_load_metric_specification" { - for_each = lookup(metric_specification.value, "predefined_load_metric_specification", null) != null ? [metric_specification.value.predefined_load_metric_specification] : [] + for_each = can(metric_specification.value.predefined_load_metric_specification.predefined_metric_type) ? [metric_specification.value.predefined_load_metric_specification] : [] content { predefined_metric_type = predefined_load_metric_specification.value.predefined_metric_type resource_label = predefined_load_metric_specification.value.resource_label @@ -555,7 +545,7 @@ resource "aws_autoscaling_policy" "this" { } dynamic "predefined_metric_pair_specification" { - for_each = lookup(metric_specification.value, "predefined_metric_pair_specification", null) != null ? [metric_specification.value.predefined_metric_pair_specification] : [] + for_each = can(metric_specification.value.predefined_metric_pair_specification.predefined_metric_type) ? [metric_specification.value.predefined_metric_pair_specification] : [] content { predefined_metric_type = predefined_metric_pair_specification.value.predefined_metric_type resource_label = predefined_metric_pair_specification.value.resource_label @@ -563,7 +553,7 @@ resource "aws_autoscaling_policy" "this" { } dynamic "predefined_scaling_metric_specification" { - for_each = lookup(metric_specification.value, "predefined_scaling_metric_specification", null) != null ? [metric_specification.value.predefined_scaling_metric_specification] : [] + for_each = can(metric_specification.value.predefined_scaling_metric_specification.predefined_metric_type) ? [metric_specification.value.predefined_scaling_metric_specification] : [] content { predefined_metric_type = predefined_scaling_metric_specification.value.predefined_metric_type resource_label = predefined_scaling_metric_specification.value.resource_label diff --git a/variables.tf b/variables.tf index 572a61e..ce93cd1 100644 --- a/variables.tf +++ b/variables.tf @@ -212,23 +212,11 @@ variable "delete_timeout" { } variable "tags" { - description = "A list of tag blocks. Each element should have keys named key, value, and propagate_at_launch" - type = list(map(string)) - default = [] -} - -variable "tags_as_map" { - description = "A map of tags and values in the same format as other resources accept. This will be converted into the non-standard format that the aws_autoscaling_group requires." + description = "A map of tags to assign to resources" type = map(string) default = {} } -variable "propagate_name" { - description = "Determines whether to propagate the `var.instance_name`/`var.name` tag to launch instances" - type = bool - default = true -} - variable "warm_pool" { description = "If this block is configured, add a Warm Pool to the specified Auto Scaling group" type = any