When using Terraform to batch create log data sources, some data source types are ElasticSearch while others are Opensearch. So how do you conditionally create resources based on a specific field (e.g., es_type)?
locals { # Convert the JSON file to an object user_data = jsondecode(file("${path.module}/env-details.json")) # Construct a map # key is env_name # value is another map, where key is grafana datasource type and value is url envs = { for env in local.user_data : env.env_name => { prometheus = env.prom_url # Use ${} to construct a new url jaeger = "${env.jaeger_url}/trace/" es = env.es_url es_type = env.es_type } } }
resource "grafana_data_source" "elasticsearch" { for_each = { for env_name, env_info in local.envs : env_name => env_info if env_info.es_type == "elasticsearch" }
type = "elasticsearch" name = "${each.key}_es" uid = "${each.key}_es" url = each.value.es database_name = "[example.*-]YYYY.MM.DD"
Don’t let the length of this code intimidate you — most of it isn’t directly relevant to the topic at hand. The key to the implementation lies in this code snippet:
1 2 3 4
for_each = { for env_name, env_info in local.envs : env_name => env_info if env_info.es_type == "elasticsearch" }
It’s quite straightforward and self-explanatory. If es_type is elasticsearch, then the object gets included in the map.
After that, different DataSource types will have different parameters, as shown above:
Opensearch has a different type from ES, and Opensearch has authentication enabled
Opensearch uses the database field instead of database_name
Opensearch additionally has the flavor and pplEnabled fields.
Alternative Solution
If your raw data or the constructed locals is a list rather than a map, you can use count + the condition ? true_val : false_val conditional expression to achieve the same result.
Here’s an example:
The decision is based on whether var.cloudflare is true or false.
1 2 3 4 5 6 7 8 9
resource "cloudflare_record" "record" { count = var.cloudflare ? 1 : 0 zone_id = "${data.cloudflare_zones.domain.zones[0].id}" name = "${var.subdomain}" value = "${var.origin_server}" type = "CNAME" ttl = 1 proxied = true }
The key point is the conditional expression: count = var.cloudflare ? 1 : 0