DevOps Asked on December 9, 2021
I need to create a datadog synthetics monitors with the resource datadog_synthetics_test
I need to monitor multiples cluster, with multiple point of view :
# Clusters
variable "datadog_gke_clusters" {
default = [
# NPRD
{
name = "cluster01"
environment = "nprd"
url = {
private = "https://private.domain-priv.com"
public = "https://public.domain.com"
}
},
# PROD
{
name = "cluster02"
environment = "nprd"
url = {
private = "https://private.domain-priv.com"
public = "https://public.domain.com"
}
}
]
}
# Point of views
variable "gke_slo" {
description = "Response time threshold in ms to respond to a request."
default = [
{
zone = private
monitor_threshold = 50
},
{
zone = public
monitor_threshold = 100
},
]
}
for_each
need a map or a list of strings
resource "datadog_synthetics_test" "gke-monitoring" {
for_each = ... # cartesian product of lists
type = "api"
subtype = "http"
....
}
There is a function [setproduct(sets...)][1]
which produce a list which combine values of each list, but not a map.
I would need to produce a map which look like this :
{
"cluster01-private" = {
name = "cluster01"
environment = "nprd"
url = {
private = "https://private.cluster01.domain-priv.com"
public = "https://public.cluster01.domain.com"
}
zone = private
monitor_threshold = 50
},
"cluster01-public" = {
name = "cluster01"
environment = "nprd"
url = {
private = "https://private.cluster01.domain-priv.com"
public = "https://public.cluster01.domain.com"
}
zone = public
monitor_threshold = 100
},
# PROD
.... etc
}
How could I do that ?
Your loop is being nested.
Use this instead.
# Clusters
variable "datadog_gke_clusters" {
type = list(object({
name = string
environment = string
url = object({
private = string
public = string
})
}))
default = [
# NPRD
{
name = "cluster01"
environment = "nprd"
url = {
private = "https://private.domain-priv.com"
public = "https://public.domain.com"
}
},
# PROD
{
name = "cluster02"
environment = "nprd"
url = {
private = "https://private.domain-priv.com"
public = "https://public.domain.com"
}
}
]
}
# Point of views
variable "gke_slo" {
type = list(object({
zone = string
monitor_threshold = number
}))
description = "Response time threshold in ms to respond to a request."
default = [
{
zone = "private"
monitor_threshold = 50
},
{
zone = "public"
monitor_threshold = 100
},
]
}
locals {
result = {
for tuple in setproduct(var.datadog_gke_clusters, var.gke_slo): "${tuple[0].name}_${tuple[1].zone}" => {
name = tuple[0].name
environment = tuple[0].environment
url = tuple[0].url
zone = tuple[1].zone
monitor_threshold = tuple[1].monitor_threshold
}
}
}
output "result" {
value = local.result
}
Answered by Joseph on December 9, 2021
As in Terraform, a loop "products" a result (a map, a list, an object...), in this case, you have to avoid nested loop:
# Clusters
variable "datadog_gke_clusters" {
type = list(object({
name = string
environment = string
url = object({
private = string
public = string
})
}))
default = [
# NPRD
{
name = "cluster01"
environment = "nprd"
url = {
private = "https://private.domain-priv.com"
public = "https://public.domain.com"
}
},
# PROD
{
name = "cluster02"
environment = "nprd"
url = {
private = "https://private.domain-priv.com"
public = "https://public.domain.com"
}
}
]
}
# Point of views
variable "gke_slo" {
type = list(object({
zone = string
monitor_threshold = number
}))
description = "Response time threshold in ms to respond to a request."
default = [
{
zone = "private"
monitor_threshold = 50
},
{
zone = "public"
monitor_threshold = 100
},
]
}
locals {
result = {
for tuple in setproduct(var.datadog_gke_clusters, var.gke_slo): "${tuple[0].name}_${tuple[1].zone}" => {
name = tuple[0].name
environment = tuple[0].environment
url = tuple[0].url
zone = tuple[1].zone
monitor_threshold = tuple[1].monitor_threshold
}
}
}
output "result" {
value = local.result
}
Here we use setproduct
to produce a list(list(tuple(cluster,pov))
and then we can iterate on the first list to produce the expected result.
Answered by Sébastien Baillet on December 9, 2021
In 2 steps, you can first create your cartesian product in a variable:
locals {
datadog_gke_clusters_by_pov = flatten([
for cluster in var.datadog_gke_clusters : [
for pov in var.gke_slo_ : {
cluster = cluster
pov = pov
}
]
])
}
And then use this new variable in your resource block:
resource "datadog_synthetics_test" "gke-monitoring" {
for_each = {
for valuue in local.datadog_gke_clusters_by_pov : "${valuue.cluster.name}-${valuue.pov.zone_name}" => valuue
}
...
# here you can use each.value.cluster.* and each.value.pov.*
}
Have a good day!
Answered by Denouche on December 9, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP