I had the same problem which @dnsmichi solved for me about two years ago, this is the anonymized version of his code.
object Host "mssql-server" {
check_command = "dummy"
vars.mssql.instances = {
"instance1" = {
databases = [ "database1-1" ]
connected_users = {
warning = "1800"
critical = "2500"
}
}
"instance2" = {
databases = [ "database2-1", "database2-2", "database2-3", "database2-4" ]
}
"instance3" = {
databases = [ "database3-1" ]
connected_users = {
warning = "200"
critical = "500"
}
}
"instance4" = {
databases = [ "database4-1" ]
}
}
}
globals.get_database_details = function(host, instances) {
//an algorithm is required which flattens and reverses the dictonary, so we get a unique key in format "instance-database"
if (instances && typeof(instances) != Dictionary) {
log(LogWarning, "config", "'instances' is not a Dictionary for '" + host.name + "'.")
return {} //and log an error
}
var res = {}
for (instance_name => instance_details in instances) {
//instance_details is a dictionary with 'databases' and so on as keys
if (instance_details.contains("databases")) {
for (db_name in instance_details.databases) {
var key = instance_name + "-" + db_name
var val = {
"instance_name" = instance_name
"db_name" = db_name
}
res[key] = val
}
}
}
//print for debugging
log(LogInformation, "config/host/" + host.name, Json.encode(res))
//could be easier if we can assume instance_name and db_name do not contain dashes, then the key could be returned as array and split in the apply with String#split
return res
}
//send 'host' to the Funktion for better debugging
apply Service "mssql-" for (instance_db => db_details in get_database_details(host, host.vars.mssql.instances)) {
check_command = "dummy"
//structur see above
var database_name = db_details.db_name
var instance_name = db_details.instance_name
display_name = "mssql-" + instance_name + "-" + database_name
vars.mssql_health_server = instance_name
vars.mssql_health_database = database_name
}
It needed several hours for him to write it, another one for me to understand and another to explain to and implement at my customer. So just give it a try, with the debug output it is understandable, but of course it is not so easy.