Extracting Code Blocks as Variables in Terraform

Viewed 790

I currently have some terraform that looks like this:

resource "aws_autoscaling_group" "my_asg" {
  ...
  tag {
    key                 = "ManagedBy"
    value               = "Terraform"
    propagate_at_launch = true
  }
}

The problem is this code block is pretty huge, and lots of the tags are common across multiple ASGs, so to try and shrink it down to something more manageable and reduce duplication, I want to do something like this with the common tags:

resource "aws_autoscaling_group" "my_asg" {
  ...
  tag = "${var.managed_by_tag}"
}

variable "managed_by_tag" {
  type = "map"
  default = {
    key                 = "ManagedBy"
    value               = "Terraform"
    propagate_at_launch = true
  }
}

Unfortunately, when I run terraform apply on this I get the following error:

Error: Error loading C:\path\to\file.tf: Error reading config for aws_autoscaling_group[my_asg]: At 32:9: unknown slice type: *ast.LiteralType

From the error, it appears that the issue is that it's trying to put a thing of the wrong type - in this case a map - in a place where it doesn't belong. But where I'm getting confused is that the following works correctly, and implies (at least to me as a terraform noob) that a map should be okay here:

resource "aws_autoscaling_group" "my_asg" {
  ...
  tag = {
    key                 = "ManagedBy"
    value               = "Terraform"
    propagate_at_launch = true
  }
}

So my questions are:

  1. Is there a way of extracting these tags into variables?
  2. Why doesn't my approach above work?
2 Answers

Look closer at tag = "${var.managed_by_tag}": you're interpolating the map into a string, which you're then trying to use where Terraform wants a map.

Try this instead:

 resource "aws_autoscaling_group" "my_asg" {
   ...
   tag = var.managed_by_tag
 }

The variable you are using for common tags is declared correctly, it's just how your passing it to the tag code block. The way you are trying to interpolate passes tags the wrong type, if you use the merge function this will return it in the correct format. You can see this in the doc below,

Interpolation - merge

tags = "${merge(var.managed_by_tag)}"

Related