Skip to content

Commit

Permalink
Add Support for List of Tag Maps (#18)
Browse files Browse the repository at this point in the history
* Updated to not used null_resource so that the null_resource provider isn't required

* Updated to unclude the null provider version.
Updated to allow for tagging of Autoscaling groups.
It was really damn hard guys, really hard to getthat stupid thing expanding as a dynamic list.

* updated formatting

* Fixed up readme. added better example. Added commends. Added contributor section. fixed copy paste error in table.

* Clarified and tested the usage of the tags

* Updated the path to the module in the example

* fixed formt

* made module generic

* made module generic

* Fixed up the autoscaling group example to be very clear with many comments.

* updated example in README

* fixed formatting

* changed example resource names from 'this' to 'default'

* remove provider

* Updated for consistency with other modules, fixed typoes

* Updated variable description
  • Loading branch information
Jamie-BitFlight authored and aknysh committed May 16, 2018
1 parent d58d787 commit 70a6ecf
Show file tree
Hide file tree
Showing 5 changed files with 264 additions and 32 deletions.
98 changes: 95 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,93 @@ resource "aws_instance" "eg_prod_bastion_xyz" {
vpc_security_group_ids = ["${aws_security_group.eg_prod_bastion_xyz.id}"]
}
```
### Advanced Example 2

Here is a more complex example with an autoscaling group that has a different tagging schema than other resources and requires its tags to be in this format, which this module can generate:
```hcl
tags = [
{
key = Name,
propagate_at_launch = 1,
value = namespace-stage-jamie
},
{
key = Namespace,
propagate_at_launch = 1,
value = namespace
},
{
key = Stage,
propagate_at_launch = 1,
value = stage
}
]
```

Autoscaling group using propagating tagging below (full example: examples/autoscalinggroup/main.tf)

```hcl
################################
# terraform-null-label example #
################################
module "label" {
source = "../../"
namespace = "cp"
stage = "prod"
name = "app"
tags = {
BusinessUnit = "Finance"
ManagedBy = "Terraform"
}
additional_tag_map = {
propagate_at_launch = "true"
}
}
#######################
# Launch template #
#######################
resource "aws_launch_template" "default" {
# terraform-null-label example used here: Set template name prefix
name_prefix = "${module.label.id}-"
image_id = "${data.aws_ami.amazon_linux.id}"
instance_type = "t2.micro"
instance_initiated_shutdown_behavior = "terminate"
vpc_security_group_ids = ["${data.aws_security_group.default.id}"]
monitoring {
enabled = false
}
# terraform-null-label example used here: Set tags on volumes
tag_specifications {
resource_type = "volume"
tags = "${module.label.tags}"
}
}
######################
# Autoscaling group #
######################
resource "aws_autoscaling_group" "default" {
# terraform-null-label example used here: Set ASG name prefix
name_prefix = "${module.label.id}-"
vpc_zone_identifier = ["${data.aws_subnet_ids.all.ids}"]
max_size = "1"
min_size = "1"
desired_capacity = "1"
launch_template = {
id = "${aws_launch_template.default.id}"
version = "$$Latest"
}
# terraform-null-label example used here: Set tags on ASG and EC2 Servers
tags = ["${module.label.tags_as_list_of_maps}"]
}
```

## Input

Expand All @@ -134,6 +221,7 @@ resource "aws_instance" "eg_prod_bastion_xyz" {
| namespace |__REQUIRED__ |Namespace, which could be your organization name, e.g. 'cp' or 'cloudposse'|
| stage |__REQUIRED__ |Stage, e.g. 'prod', 'staging', 'dev', or 'test'|
| tags |{} |Additional tags (e.g. `map('BusinessUnit`,`XYZ`)|
| additional_tag_map | {} | additional tags that get appended to each map in the list of maps, for the output `tags_as_list_of_maps` |

**WARNING** Any tags passed as an input to this module will *override* the tags generated by this module.

Expand All @@ -147,7 +235,8 @@ resource "aws_instance" "eg_prod_bastion_xyz" {
| name | Normalized name |
| namespace | Normalized namespace |
| stage | Normalized stage |
| tags | Merge input tags with our tags. Note: `Name` has a special meaning in AWS and we need to disamgiuate it by using the computed `id` |
| tags | Merged input tags with our tags. Note: `Name` has a special meaning in AWS and we need to disamgiuate it by using the computed `id` |
| tags_as_list_of_maps | Merged input tags and our tags output as list of maps that contain the tags for use on certain resource types. |

## Help

Expand Down Expand Up @@ -213,8 +302,8 @@ or [hire us][hire] to help build your next cloud-platform.

### Contributors

|[![Erik Osterman][erik_img]][erik_web]<br/>[Erik Osterman][erik_web] |[![Igor Rodionov][igor_img]][igor_web]<br/>[Igor Rodionov][igor_img] |[![Konstantin B][konstantin_img]][konstantin_web]<br/>[Konstantin B][konstantin_web] |[![Andriy Knysh][andriy_img]][andriy_web]<br/>[Andriy Knysh][andriy_web] |[![Sergey Vasilyev][sergey_img]][sergey_web]<br/>[Sergey Vasilyev][sergey_web] |
|---|---|---|---|---|
|[![Erik Osterman][erik_img]][erik_web]<br/>[Erik Osterman][erik_web] |[![Igor Rodionov][igor_img]][igor_web]<br/>[Igor Rodionov][igor_img] |[![Konstantin B][konstantin_img]][konstantin_web]<br/>[Konstantin B][konstantin_web] |[![Andriy Knysh][andriy_img]][andriy_web]<br/>[Andriy Knysh][andriy_web] |[![Sergey Vasilyev][sergey_img]][sergey_web]<br/>[Sergey Vasilyev][sergey_web] | [![Jamie Nelson][bitflight_img]][bitflight_web]<br/>[Jamie Nelson][bitflight_web] |
|---|---|---|---|---|---|

[andriy_img]: https://avatars0.githubusercontent.com/u/7356997?v=4&u=ed9ce1c9151d552d985bdf5546772e14ef7ab617&s=144
[andriy_web]: https://github.com/aknysh/
Expand All @@ -236,3 +325,6 @@ or [hire us][hire] to help build your next cloud-platform.

[vladimir_img]: https://avatars1.githubusercontent.com/u/26582191?v=4&u=ed9ce1c9151d552d985bdf5546772e14ef7ab617&s=144
[vladimir_web]: https://github.com/SweetOps/

[bitflight_img]: https://avatars0.githubusercontent.com/u/25075504?s=144&u=ac7e53bda3706cb9d51907808574b6d342703b3e&v=4
[bitflight_web]: https://github.com/Jamie-BitFlight
122 changes: 122 additions & 0 deletions examples/autoscalinggroup/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
################################
# terraform-null-label example #
################################
module "label" {
source = "../../"
namespace = "cp"
stage = "prod"
name = "app"

tags = {
BusinessUnit = "Finance"
ManagedBy = "Terraform"
}

additional_tag_map = {
propagate_at_launch = "true"
}
}

#######################
# Launch template #
#######################
resource "aws_launch_template" "default" {
# terraform-null-label example used here: Set template name prefix
name_prefix = "${module.label.id}-"
image_id = "${data.aws_ami.amazon_linux.id}"
instance_type = "t2.micro"
instance_initiated_shutdown_behavior = "terminate"

vpc_security_group_ids = ["${data.aws_security_group.default.id}"]

monitoring {
enabled = false
}

# terraform-null-label example used here: Set tags on volumes
tag_specifications {
resource_type = "volume"
tags = "${module.label.tags}"
}
}

######################
# Autoscaling group #
######################
resource "aws_autoscaling_group" "default" {
# terraform-null-label example used here: Set ASG name prefix
name_prefix = "${module.label.id}-"
vpc_zone_identifier = ["${data.aws_subnet_ids.all.ids}"]
max_size = "1"
min_size = "1"
desired_capacity = "1"

launch_template = {
id = "${aws_launch_template.default.id}"
version = "$$Latest"
}

# terraform-null-label example used here: Set tags on ASG and EC2 Servers
tags = ["${module.label.tags_as_list_of_maps}"]
}

# terraform-null-label example used here: Output list of tags applied in each format
output "tags_as_list_of_maps" {
value = ["${module.label.tags_as_list_of_maps}"]
}

output "tags" {
value = ["${module.label.tags}"]
}

################################
# Provider #
################################

provider "aws" {
region = "eu-west-1"
version = "~> 1.17"

# Make it faster by skipping unneeded checks here
skip_get_ec2_platforms = true
skip_metadata_api_check = true
skip_region_validation = true
skip_credentials_validation = true
skip_requesting_account_id = true
}

##############################################################
# Data sources to get VPC, subnets and security group details
##############################################################
data "aws_vpc" "default" {
default = true
}

data "aws_subnet_ids" "all" {
vpc_id = "${data.aws_vpc.default.id}"
}

data "aws_security_group" "default" {
vpc_id = "${data.aws_vpc.default.id}"
name = "default"
}

data "aws_ami" "amazon_linux" {
most_recent = true

filter {
name = "name"

values = [
"amzn-ami-hvm-*-x86_64-gp2",
]
}

filter {
name = "owner-alias"

values = [
"amazon",
]
}
}
43 changes: 29 additions & 14 deletions main.tf
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
resource "null_resource" "default" {
count = "${var.enabled == "true" ? 1 : 0}"

triggers = {
id = "${lower(join(var.delimiter, compact(concat(list(var.namespace, var.stage, var.name), var.attributes))))}"
name = "${lower(format("%v", var.name))}"
namespace = "${lower(format("%v", var.namespace))}"
stage = "${lower(format("%v", var.stage))}"
attributes = "${lower(format("%v", join(var.delimiter, compact(var.attributes))))}"
}

lifecycle {
create_before_destroy = true
}
locals {
enabled = "${var.enabled == "true" ? true : false }"
id = "${local.enabled ? lower(join(var.delimiter, compact(concat(list(var.namespace, var.stage, var.name), var.attributes)))) : ""}"
name = "${local.enabled ? lower(format("%v", var.name)) : ""}"
namespace = "${local.enabled ? lower(format("%v", var.namespace)) : ""}"
stage = "${local.enabled ? lower(format("%v", var.stage)) : ""}"
attributes = "${local.enabled ? lower(format("%v", join(var.delimiter, compact(var.attributes)))) : ""}"

tags = "${
merge(
map(
"Name", "${local.id}",
"Namespace", "${local.namespace}",
"Stage", "${local.stage}"
), var.tags
)
}"

tags_as_list_of_maps = ["${null_resource.tags_as_list_of_maps.*.triggers}"]
}

resource "null_resource" "tags_as_list_of_maps" {
count = "${length(keys(local.tags))}"

triggers = "${merge(map(
"key", "${element(keys(local.tags), count.index)}",
"value", "${element(values(local.tags), count.index)}"
),
var.additional_tag_map)}"
}
25 changes: 11 additions & 14 deletions outputs.tf
Original file line number Diff line number Diff line change
@@ -1,40 +1,37 @@
output "id" {
value = "${join("", null_resource.default.*.triggers.id)}"
value = "${local.id}"
description = "Disambiguated ID"
}

output "name" {
value = "${join("", null_resource.default.*.triggers.name)}"
value = "${local.name}"
description = "Normalized name"
}

output "namespace" {
value = "${join("", null_resource.default.*.triggers.namespace)}"
value = "${local.namespace}"
description = "Normalized namespace"
}

output "stage" {
value = "${join("", null_resource.default.*.triggers.stage)}"
value = "${local.stage}"
description = "Normalized stage"
}

output "attributes" {
value = "${join("", null_resource.default.*.triggers.attributes)}"
value = "${local.attributes}"
description = "Normalized attributes"
}

# Merge input tags with our tags.
# Note: `Name` has a special meaning in AWS and we need to disamgiuate it by using the computed `id`
output "tags" {
value = "${
merge(
map(
"Name", "${join("", null_resource.default.*.triggers.id)}",
"Namespace", "${join("", null_resource.default.*.triggers.namespace)}",
"Stage", "${join("", null_resource.default.*.triggers.stage)}"
), var.tags
)
}"
value = "${local.tags}"

description = "Normalized Tag map"
}

output "tags_as_list_of_maps" {
value = ["${local.tags_as_list_of_maps}"]
description = "Additional tags as a list of maps, which can be used in several AWS resources"
}
8 changes: 7 additions & 1 deletion variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,11 @@ variable "attributes" {
variable "tags" {
type = "map"
default = {}
description = "Additional tags (e.g. `map('BusinessUnit`,`XYZ`)"
description = "Additional tags (e.g. `map('BusinessUnit','XYZ')`"
}

variable "additional_tag_map" {
type = "map"
default = {}
description = "Additional tags for appending to each tag map."
}

0 comments on commit 70a6ecf

Please sign in to comment.