I have a Terraform locals.tf
file like the below snippet, which contains my environment definition.
locals {
environments = [
"dev",
"test",
"preprod",
"prod"
]
}
I am now looking to create an identical resource, an Azure monitor metric alert in this case, for each of the listed environments (except prod). I am attempting to do so using a For_Each
loop in the resource block of my main.tf
file, a snippet of which is shown below:
resource "azurerm_monitor_metric_alert" "main" {
for_each = {
[for s in toset(local.environments) : if s != "prod"]
}
name = "${each.key}-metric-alert"
resource_group_name = azurerm_resource_group.rg.name
scopes = [azurerm_storage_account.to_monitor[each.key].id]
[..........ADDITIONAL NON-PROD RESOURCE CONFIG...........]
For the prod environment though, the monitor alert requires a slightly different set of configuration from the others, and so what I’d like to do is filter out that environment from the locals.tf
file and then using another azurerm_monitor_metric_alert resource block, configure it along the lines of the below snippet:
resource "azurerm_monitor_metric_alert" "main" {
for_each = {
[for s in toset(local.environments) : if s == "prod"]
}
name = "${each.key}-metric-alert"
resource_group_name = azurerm_resource_group.rg.name
scopes = [azurerm_storage_account.to_monitor[each.key].id]
[..........ADDITIONAL PROD CONFIG...........]
I have the tried the above and various other implementations, but unfortunately I simply can’t get this to work. Would greatly appreciate some assistance here.
2
Answers
You didn’t specify what error you get but your
for
loops are missing one argument:And:
Also I`m not sure if you need this
toset
there. It might be required to put the wholefor
loop insidetoset
and notlocal.environments
.There are a few different problems with the following expression:
The
for
expression is missing its result clause after the colon. If you intend to just returns
directly then you can just specify that variable alone between the colon and theif
keyword:The braces
{
}
around this for expression are not valid. That syntax is for constructing an object-typed value, but for that to work you’d need to specify an attribute to assign the result of thefor
expression to.Since
var.environments
seems to be just a bunch of strings, I expect you probably want to construct a set of strings directly, without any wrapping map/object, like this:The inner
toset
you previously had forlocal.environments
is not really adding anything here because afor
expression effectively treats a set of strings like a list of those strings in lexical order. You can safely remove it like I did in my most recent example above, and that would be sufficient for this particular use of `local.environments.If you want to communicate that
local.environments
itself is semantically a set — which might be helpful for future maintainers of your module trying to understand what you intended — then you might choose to place thetoset
in the definition of the local value instead:Doing this would have no effect on the
for_each
expression this question is about though, so this would be a meaningful change only iflocal.environments
is used in other locations that should also treat it as a set, and that’s beyond the scope of this question.