I have done a lot of Terraform stuff on all three major clouds (AWS, Azure, GCP) for the past few months. If you need to build up a lot of resource on clooud, Terraform is the way to go. However, sometimes it seems easier to copy some part code from one place to another place. If you have a huge enterprise level environment, this kind of duplicated code is a nightmare for changes and maintenance. Tagging is the one that is very easy to have duplicated code everywhere. In this blog, I am going to discuss how to do tagging efficiently in Terraform.
Here is an example how tagging is done in Azure environment.
resource "azurerm_resource_group" "default" { name = "my-test-rg" location = "eastus" tags { environment = "Dev" project = "MyLab" owner = "weidong.zhou" } } resource "azurerm_virtual_network" "default" { name = "mytest-vnet1" address_space = ["10.1.0.0/16"] location = "${azurerm_resource_group.default.location}" resource_group_name = "${azurerm_resource_group.default.name}" tags { environment = "Dev" project = "MyLab" owner = "weidong.zhou" network = "vnet1" support = "IT operation" } }
You can see the tags section can be easily duplicated to almost every resource that needs to be tagged. It is going to be a nightmare to add or change tags in the future. I remembered I sawed some code as follows somewhere.
resource "aws_vpc" "this" { count = "${var.create_vpc ? 1 : 0}" cidr_block = "${var.cidr}" instance_tenancy = "${var.instance_tenancy}" enable_dns_hostnames = "${var.enable_dns_hostnames}" enable_dns_support = "${var.enable_dns_support}" assign_generated_ipv6_cidr_block = "${var.assign_generated_ipv6_cidr_block}" tags = "${merge(map("Name", format("%s", var.name)), var.tags, var.vpc_tags)}" }
Pay more attention to the last line. In one line, it does all the tagging it needs. This is the direction I am looking for. After some investigation, I figured out a similar way in the implementation. Here are the sample code:
locals { common_tags = { environment = "${var.environment}" project = "${var.project}" Owner = "${var.owner}" } extra_tags = { network = "${var.network1_name}" support = "${var.network_support_name}" } } resource "azurerm_resource_group" "default" { name = "my-test-rg" location = "eastus" tags = "${merge( local.common_tags, local.extra_tags)}" } resource "azurerm_virtual_network" "default" { name = "mytest-vnet1" address_space = ["10.1.0.0/16"] location = "${azurerm_resource_group.default.location}" resource_group_name = "${azurerm_resource_group.default.name}" tags = "${merge( local.common_tags, local.extra_tags)}" }
For a project with a lot of tags in every resource, this approach will help in the maintenance.
Pingback: Tagging with Terraform – David J Eddy
Great Post! How are you implementing in terraform 12? I’m getting IDENT error when i try to use variables or merge
Thanks for sharing, I will implement this today. one question, why do come tags in AWS like Owner here have cpitals? is Owner a special tag in some way?