I am building a module containing AWS resources. Most AWS resource have a tags
argument (e.g. Terraform Registry) and I want all resources to have tags owner
& environment
Is it possible to assert, using a terraform test, that all resources in my module which have a tags
argument do have a owner
& environment
tag?
I figure I need a way of looping over all the resources in the module but I’m not sure there are any hooks available that allow me to do that.
Does anyone know if there is a way of achieving this?
Yes, a few ways to do it.
You can assert that the tags are present, or you can do a json comparison
For example:
assert {
condition = length(google_secret_manager_secret.this.labels) == 2
error_message = "Incorrect number of labels found."
}
assert {
condition = google_secret_manager_secret.this.labels["foo"] == "bar"
error_message = "Expected label / value not found."
}
assert {
condition = google_secret_manager_secret.this.labels["baz"] == "qux"
error_message = "Expected label / value not found."
}
or something like
assert {
# This messy jsonencode is necessary for now; see:
# https://github.com/hashicorp/terraform/issues/34428
condition = jsonencode(google_secret_manager_secret.this.labels) == jsonencode({
"foo" = "asdfadsf",
"baz" = "qux",
})
error_message = "Expected members not found."
}
Also, with terraform 1.12, if the expectations don’t match, the output is finally actually useful:
│ Error: Test assertion failed
│
│ on tests/main.tftest.hcl line 90, in run "simple_example":
│ 90: condition = jsonencode(google_secret_manager_secret.this.labels) == jsonencode({
│ 91: "foo" = "asdfadsf",
│ 92: "baz" = "qux",
│ 93: })
│ ├────────────────
│ │ Diff:
│ │ --- actual
│ │ +++ expected
│ │ - "{\"baz\":\"qux\",\"foo\":\"bar\"}"
│ │ + "{\"baz\":\"qux\",\"foo\":\"asdfadsf\"}"
│
│
│ Expected members not found.
If the labels are created conditionally based on input vars, you can also test both cases (i.e., no labels when they’re not expected, and expected labels when they are).
thank you @wyardley . Unfortunately the solution you supplied relies upon knowing all the resource addresses. I want to put a test in place to ensure that all current and future resources have the tags.
Ahh, sorry, should have read your post more carefully.
Off the top of my head, I don’t think you can easily iterate through all current and future resources (without defining them in some kind of data structure), though if you could build a data structure of all the resources, I think you could then write a test that would assert each had the tags. But maybe someone will have an idea.
I get the idea; I’m not sure how many different resources / types of resources you’re likely to add, but IMO, with testing, sometimes it’s better to be explicit (add tests for the resource, including the labels, when you add the resource to the terraform code) vs. too magical.