I’ve recently started as a DevOps Engineer at ACME Corporation
where all Terraformed resources are tagged using variables
defined on the command-line. Self-contained example:
provider "aws" {
region = "us-east-2"
}
variable "acme_owner" {
type = string
}
variable "acme_project" {
type = string
}
resource "aws_instance" "example" {
ami = "ami-07efac79022b86107" # ubuntu 20
instance_type = "t2.micro"
tags = {
Owner = var.acme_owner
Project = var.acme_project
}
}
There are actually over half a dozen tags for each AWS resource, and
they are almost all defined using input variables, except
Name which includes the resource name (e.g. acme-prod-webserver)
where “prod” is the environment name and “webserver” is the
resource name.
This “tags” block appears many times in the company code base, and it is identical nearly every time, except the Name varies.
I tried breaking out the tags into a template to reduce code duplication, like so:
tags.j2
:
{
Name = ${name}
Owner = var.acme_owner
Project = var.acme_project
}
main.tf
:
provider "aws" {
region = "us-east-2"
}
variable "acme_owner" {
type = string
}
variable "acme_project" {
type = string
}
resource "aws_instance" "webserver" {
ami = "ami-07efac79022b86107" # ubuntu 20
instance_type = "t2.micro"
tags = templatefile("${path.module}/tags.j2",
{ name = "acme-prod-webserver" })
}
But when I ran it with terraform plan -var acme_owner=foo -var acme_project=bar
I got an error:
Error: Incorrect attribute value type
on main.tf line 17, in resource "aws_instance" "webserver":
17: tags = templatefile("${path.module}/tags.j2",
18: { name = "acme-prod-webserver" })
|----------------
| path.module is "."
Inappropriate value for attribute "tags": map of string required.
Now, I’m confused. I know what a map is, and what a string is, but what is a map of string?