Dynamically generate two services from the same data (got error "An object with type 'Service' already exists")

Hello,

we store, in the custom vars section of a host, information about its web sites and want to dynamically apply Service checks with this data.

In this example with wordpress sites, I have the following in the host definition


object Host "wp-srv" {
  wordpress = {
    site1 = {
       http_vhost = "wp.example.tld"
       http_port = "443"
    },
   site2 = {
      http_vhost = "wp2.example.tld"
      http_port = "8080"
  },
 },
},

I want to apply two Service checks to each of site1/site2. In my case those checks are one HTTP to verify that the application is running correctly, and one to verify for TLS certificate expiration date. (yes even if those specific checks could be combined in one we want to have them separated)

I tried to do it like this

apply Service for (site => config in host.vars.sites.wordpress) {
  display_name    = "HTTP_" + site

  check_command   = "http"
  vars.http_ssl   = true
  vars.http_port  = config.http_port
  vars.http_vhost = config.http_vhost

  import "generic-service"

  assign where host.address
  ignore where host.vars.monitored == false
}

apply Service for (site => config in host.vars.sites.wordpress) {
  display_name    = "HTTP SSL Certificate_" + site

  check_command   = "http"
  vars.http_ssl   = true
  vars.http_port  = config.http_port
  vars.http_vhost = config.http_vhost
  vars.http_certificate = 30

  import "generic-service"

  assign where host.address
  ignore where host.vars.monitored == false
}

But Icinga don’t like it and throws this error

$ > icinga2 daemon -C
[2022-10-18 17:26:39 +0200] critical/config: Error: An object with type 'Service' and name 'wp-srv!site1' already exists (in /etc/icinga2/zones.d/global-templates/services/wordpress.conf: 4:1-4:63), new declaration: in /etc/icinga2/zones.d/global-templates/services/wordpress.conf: 20:1-20:63
Location: in /etc/icinga2/zones.d/global-templates/services/wordpress.conf: 20:1-20:63
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(18): }
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(19): 
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(20): apply Service for (site => config in host.vars.sites.wordpress) {
                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(21):   display_name    = "HTTP SSL Certificate_" + site
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(22): 
[2022-10-18 17:26:39 +0200] critical/config: Error: An object with type 'Service' and name 'wp-srv!site2' already exists (in /etc/icinga2/zones.d/global-templates/services/wordpress.conf: 4:1-4:63), new declaration: in /etc/icinga2/zones.d/global-templates/services/wordpress.conf: 20:1-20:63
Location: in /etc/icinga2/zones.d/global-templates/services/wordpress.conf: 20:1-20:63
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(18): }
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(19): 
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(20): apply Service for (site => config in host.vars.sites.wordpress) {
                                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(21):   display_name    = "HTTP SSL Certificate_" + site
/etc/icinga2/zones.d/global-templates/services/wordpress.conf(22): 

It seems that this creates the same internal object of type ‘Service’ and name ‘wp-srv!site1’ because of the two ‘for’ loops.

I also tried to encapsulate both Service checks in a single for loop, but then the problem is that the host variable does not exist. (out of scope variable)

Is there any solution to this problem?
I could always generate two different dictionaries inside vars to store the same values and use each one for each Service, but it would also mean that the day I want a third check I need a third dictionary… doesn’t seems practical.

by the way I have seen other posts asking for similar problems but not exactly the same. I also found one where someone tells that the better way to get information about this is asking here :slight_smile: (that what I understand at least)


  • Version used (icinga2 --version)

Copyright (c) 2012-2022 Icinga GmbH (https://icinga.com/)
License GPLv2+: GNU GPL version 2 or later <https://gnu.org/licenses/gpl2.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

System information:
  Platform: Debian GNU/Linux
  Platform version: 11 (bullseye)
  Kernel: Linux
  Kernel version: 5.10.0-18-amd64
  Architecture: x86_64

Build information:
  Compiler: GNU 10.2.1
  Build host: runner-hh8q3bz2-project-298-concurrent-0
  OpenSSL version: OpenSSL 1.1.1n  15 Mar 2022

Application information:

General paths:
  Config directory: /etc/icinga2
  Data directory: /var/lib/icinga2
  Log directory: /var/log/icinga2
  Cache directory: /var/cache/icinga2
  Spool directory: /var/spool/icinga2
  Run directory: /run/icinga2

Old paths (deprecated):
  Installation root: /usr
  Sysconf directory: /etc
  Run directory (base): /run
  Local state directory: /var

Internal paths:
  Package data directory: /usr/share/icinga2
  State path: /var/lib/icinga2/icinga2.state
  Modified attributes path: /var/lib/icinga2/modified-attributes.conf
  Objects path: /var/cache/icinga2/icinga2.debug
  Vars path: /var/cache/icinga2/icinga2.vars
  PID path: /run/icinga2/icinga2.pid
  • Operating System and version: Debian Bullseye
  • Enabled features (icinga2 feature list): api checker command ido-mysql mainlog notification

Hii, you can just prefix the service names generated by the apply rules. See also Language Reference - Icinga 2

apply Service "http-" for (site => config in host.vars.sites.wordpress) ...
apply Service "https-" for (site => config in host.vars.sites.wordpress) ...

This solved my problem, thanks for your help