terraform-community-modules / tf_aws_vpc

[DEPRECATED] Use https://github.com/terraform-aws-modules/terraform-aws-vpc
Other
210 stars 203 forks source link

Add the ability to set subnet-type specific tags. #49

Closed ashb closed 7 years ago

ashb commented 7 years ago

Example use case is to take all private subnets with type:private for use with AWSnycast (from the tf_aws_nat module).

dyindude commented 7 years ago

This would be useful in cases where app specific subnets are being created:

  private_subnets = ["${cidrsubnet(var.vpc_cidr,6,0)}",  //logstash-a
                     "${cidrsubnet(var.vpc_cidr,6,4)}",  //logstash-b
                     "${cidrsubnet(var.vpc_cidr,6,8)}",  //logstash-c
                     "${cidrsubnet(var.vpc_cidr,6,1)}",  //kafka-a
                     "${cidrsubnet(var.vpc_cidr,6,5)}",  //kafka-b
                     "${cidrsubnet(var.vpc_cidr,6,9)}",  //kafka-c
                     "${cidrsubnet(var.vpc_cidr,6,2)}",  //ES-a
                     "${cidrsubnet(var.vpc_cidr,6,6)}",  //ES-b
                     "${cidrsubnet(var.vpc_cidr,6,10)}", //ES-c
                     "${cidrsubnet(var.vpc_cidr,6,3)}",  //kibana-a
                     "${cidrsubnet(var.vpc_cidr,6,7)}",  //kibana-b
                     "${cidrsubnet(var.vpc_cidr,6,11)}"] //kibana-c

It becomes difficult to distinguish which subnets are associated with other resources when looking in the AWS console without a way to identify them.

ashb commented 7 years ago

That would be useful, but right this PR as it is right just applies one set of tags to all of the private subnets.

Anyone know if it's possible to have a variable that is a list of dicts? (From everything I've seen so far I suspect it is not.)

antonbabenko commented 7 years ago

This is not possible @ashb .

antonbabenko commented 7 years ago

This PR looks good to me. @dyindude what do you think?

dyindude commented 7 years ago

@ashb After looking at it again, you're right. I suppose it would still be the same problem for my use case as is with the current Name tags.

It is possible to create a list of maps, which you could then merge based on count.index

With some creative use of data.template_file I was able to whip up an example that pulls one value out of these simple maps:

variable "subnet_tags" {
    type = "list"
    default = [{ App = "logstash" },{ App = "es" },{ App = "kibana" }]
}

data "template_file" "subnet_tags" {
 template =  "$${subnet_tags}"
 count = 3
 vars {
  subnet_tags = "${lookup(var.subnet_tags[count.index],"App")}"
 }
}

output "subnet_tags" {
  value = ["${data.template_file.subnet_tags.*.rendered}"]
}

apply:

terraform apply
data.template_file.subnet_tags.0: Refreshing state...
data.template_file.subnet_tags.1: Refreshing state...
data.template_file.subnet_tags.2: Refreshing state...

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

subnet_tags = [
    logstash,
    es,
    kibana
]

Looking at your code, I believe by declaring the tags as a list of maps, you should be able to use something like this:

//line 44
"${merge(var.private_subnet_tags[count.index], merge(var.tags, map("Name", format("%s-subnet-private-%s", var.name, element(var.azs, count.index)))))}"

The only downside I foresee is that if you wanted different tags for each subnet, your list of maps would ideally be the same length as the number of subnets. If it was a list with length 1, the same map would be merged into all subnets.

@antonbabenko I haven't had a chance to test this yet, but it looks like a simple change. I would personally like something that allows better documentation of individual subnets, but it sounds like @ashb's commit will provide some compatibility with other TF module(s).

ashb commented 7 years ago

My usecase is probably covered by #50.