{"id":15013954,"url":"https://github.com/voxpupuli/puppet-icinga2","last_synced_at":"2025-12-18T06:04:31.918Z","repository":{"id":39380244,"uuid":"67499430","full_name":"voxpupuli/puppet-icinga2","owner":"voxpupuli","description":"Puppet module to manage Icinga 2","archived":false,"fork":false,"pushed_at":"2024-10-18T13:45:00.000Z","size":2674,"stargazers_count":62,"open_issues_count":6,"forks_count":94,"subscribers_count":54,"default_branch":"main","last_synced_at":"2024-10-29T14:22:36.783Z","etag":null,"topics":["icinga","monitoring","puppet"],"latest_commit_sha":null,"homepage":"https://forge.puppet.com/icinga/icinga2","language":"Puppet","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/voxpupuli.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"vox-pupuli","github":"voxpupuli"}},"created_at":"2016-09-06T10:49:47.000Z","updated_at":"2024-10-18T13:34:23.000Z","dependencies_parsed_at":"2023-12-16T16:05:21.870Z","dependency_job_id":"ca26a0e6-2518-420e-b860-c107c69c5c6e","html_url":"https://github.com/voxpupuli/puppet-icinga2","commit_stats":{"total_commits":1185,"total_committers":61,"mean_commits":19.42622950819672,"dds":"0.46329113924050636","last_synced_commit":"eaaca5b4d84059be75ff5447fd80e6b00051a31b"},"previous_names":["voxpupuli/puppet-icinga2","icinga/puppet-icinga2"],"tags_count":71,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-icinga2","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-icinga2/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-icinga2/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/voxpupuli%2Fpuppet-icinga2/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/voxpupuli","download_url":"https://codeload.github.com/voxpupuli/puppet-icinga2/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246026111,"owners_count":20711580,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["icinga","monitoring","puppet"],"created_at":"2024-09-24T19:44:59.750Z","updated_at":"2025-12-18T06:04:31.911Z","avatar_url":"https://github.com/voxpupuli.png","language":"Puppet","funding_links":["https://opencollective.com/vox-pupuli","https://github.com/sponsors/voxpupuli"],"categories":[],"sub_categories":[],"readme":"# Icinga 2 Puppet Module\n\n[![Build Status](https://github.com/voxpupuli/puppet-icinga2/workflows/CI/badge.svg)](https://github.com/voxpupuli/puppet-icinga2/actions?query=workflow%3ACI)\n[![Release](https://github.com/voxpupuli/puppet-icinga2/actions/workflows/release.yml/badge.svg)](https://github.com/voxpupuli/puppet-icinga2/actions/workflows/release.yml)\n[![Puppet Forge](https://img.shields.io/puppetforge/v/puppet/icinga2.svg)](https://forge.puppet.com/modules/puppet/icinga)\n[![puppet integration](http://www.puppetmodule.info/images/badge.png)](https://icinga.com/products/integrations/puppet)\n[![Apache-2.0 License](https://img.shields.io/github/license/voxpupuli/puppet-icinga2.svg)](LICENSE)\n[![Donated by Icinga](https://img.shields.io/badge/donated%20by-Icinga-fb7047.svg)](#transfer-notice)\n[![Sponsored by NETWAYS](https://img.shields.io/badge/Sponsored%20by-NETWAYS%20GmbH-blue.svg)](https://www.netways.de)\n\n[Icinga Logo](https://www.icinga.com/wp-content/uploads/2014/06/icinga_logo.png)\n\n#### Table of Contents\n\n1. [Overview](#overview)\n2. [Module Description - What the module does and why it is useful](#module-description)\n3. [Setup - The basics of getting started with icinga2](#setup)\n4. [Usage - Configuration options and additional functionality](#usage)\n    * [Installing Icinga](#installing-icinga)\n    * [Clustering Icinga](#clustering-icinga)\n    * [Config Objects](#config-objects)\n    * [Reading objects from hiera](#Reading-objects-from-hiera)\n    * [Apply Rules](#apply-rules)\n    * [Custom configuration](#custom-configuration)\n5. [How Configuration is parsed](#how-configuration-is-parsed)\n6. [Reference](#reference)\n7. [Release Notes](#release-notes)\n\n## Overview\n\nIcinga 2 is a widely used open source monitoring software. This Puppet module helps with installing and managing\nconfiguration of Icinga 2 on multiple operating systems.\n\n### What's new in version 4.0.0\n\nNew version 4.0.0 means we have a breaking change. However, this change only affects the `export` parameter in the individual object defined resources introduced in v3.6.0. We replaced the `icinga2::object` exported resources with the type of `icinga2::config::fragment` to do the config rendering thru runs on the single Icinga agent to get an static configuration on the destination, generally the Icinga config server.\n\nIf you are using the `export` parameter in connection with the class `icinga2::query_objects`, it is recommended to suspend the puppet runs on the icinga servers and satellites (or everwhere you declare `icinga2::query_objects`) after updating this module until all agents have been processed by Puppet at least once.\n\nAlso, the anchors have been replaced by contains, this may cause problems if you set dependency to the icinga2 class.\n\n### What's new in version 3.6.0\n\nEach Icinga object has been given the new parameter `export` that specifies one (ordinary objects for the config server) or more nodes (e.g. zones and endpoints for HA servers from workers aka satellites) as targets where the objects are then created using the class `query_objects`. This has been implemented to avoid collecting export resources in large environments.\n\n## Module Description\n\nThis module installs and configures Icinga 2 on your Linux or Windows hosts.\n\nBy default it uses packages provided by your distribution's repository or\n[Chocolatey] on Windows.\n\nThe module can also be configured to use [packages.icinga.com] as the primary repository, which enables you to install\nIcinga 2 versions that are newer than the ones provided by your distribution's vendor. All features and objects\navailable in Icinga 2 can be enabled and configured with this module.\n\n## Setup\n\n### What the Icinga 2 Puppet module supports\n\n* Installation of packages\n* Configuration of features\n* Configuration of objects (also apply rules)\n* Service\n* MySQL / PostgreSQL Database Schema Import\n* Repository Management\n* Certification Authority\n\n### Dependencies\n\nThis module supports:\n\n* [puppet] \u003e= 7.0.0 \u003c 9.0.0\n\nAnd depends on:\n\n* [puppetlabs/stdlib] \u003e= 6.6.0 \u003c 10.0.0\n* [puppetlabs/concat] \u003e= 6.4.0 \u003c 10.0.0\n* [icinga/icinga] \u003e= 1.0.0 \u003c 8.0.0\n    * needed if `manage_repos` is set to `true`\n* [puppetlabs/chocolatey] \u003e= 5.2.0 \u003c 9.0.0\n    * needed if agent os is windows and if `manage_packages` is set to `true`\n\n### Limitations\n\nThe use of Icinga's own CA is recommended. If you still want to use the Puppet certificates, please note that Puppet 7 uses an intermediate CA by default and Icinga cannot handle its CA certificate, see [Icinga Issue](https://github.com/Icinga/icinga2/pull/8859).\n\nThis module has been tested on:\n\n* Debian 10, 11, 12\n* Ubuntu 20.04, 22.04\n* CentOS/RHEL 7, 8, 9\n* AlmaLinux/Rocky 8, 9\n* Fedora 32\n* Windows Server 2019\n\nOther operating systems or versions may work but have not been tested.\n\n## Usage\n\n### Installing Icinga\n\nThe default class `icinga2` installs and configures a basic installation of Icinga 2. The features `checker`, `mainlog`\nand `notification` are enabled by default.\n\nBy default, your distribution's packages are used to install Icinga 2. On Windows systems we use the [Chocolatey]\npackage manager.\n\nUse the `manage_repos` parameter to configure repositories by default the official and stable [packages.icinga.com]. To configure your own\nrepositories, or use the official testing or nightly snapshot stage, see https://github.com/icinga/puppet-icinga.\n\n``` puppet\nclass { 'icinga2':\n  manage_repos =\u003e true,\n}\n```\n\nIf you want to manage the version of Icinga 2, you have to disable the package management of this module and handle\npackages in your own Puppet code. The attribute `manage_repos` is disabled by default and you have to manage\na repository within icinga in front of the package resource. You can combine this one with the section before about repositories.\n\n``` puppet\n# class of extra module icinga/icinga\ninclude ::icinga::repos\n\npackage { 'icinga2':\n  ensure =\u003e latest,\n  notify =\u003e Class['icinga2'],\n}\n\nclass { 'icinga2':\n  manage_packages =\u003e false,\n}\n```\n\nNote: Be careful with this option: Setting `manage_packages` to false means that this module will not install any package at\nall, including IDO packages!\n\n\n### Clustering Icinga\n\nIcinga 2 can run in three different roles:\n\n* in a master zone which is on top of the hierarchy\n* in a satellite zone which is a child of a satellite or master zone\n* a standalone client node/zone which works as an agent connected to master and/or satellite zones\n\nTo learn more about Icinga 2 Clustering, follow the official docs on [distributed monitoring]. The following examples show\nhow these roles can be configured using this Puppet module.\n\n#### Master\n\nA Master zone has no parent and is usually also the place where you enable the IDO and notification features. A master\nsends configurations over the Icinga 2 protocol to satellites and/or clients.\n\nMore detailed examples can be found in the [examples] directory.\n\nThis example creates the configuration for a master that has one satellite connected. A global zone is created for\ntemplates, and all features of a typical master are enabled.\n\n``` puppet\nclass { 'icinga2':\n  confd     =\u003e false,\n  constants =\u003e {\n    'ZoneName'   =\u003e 'master',\n    'TicketSalt' =\u003e '5a3d695b8aef8f18452fc494593056a4',\n  },\n}\n\nclass { 'icinga2::feature::api':\n  pki             =\u003e 'none',\n  accept_commands =\u003e true,\n  # when having multiple masters, you have to enable:\n  accept_config =\u003e true,\n  endpoints       =\u003e {\n    'master.example.org'    =\u003e {},\n    'satellite.example.org' =\u003e {\n      'host' =\u003e '172.16.2.11'\n    },\n  },\n  zones           =\u003e {\n    'master' =\u003e {\n      'endpoints' =\u003e ['master.example.org'],\n    },\n    'dmz'    =\u003e {\n      'endpoints' =\u003e ['satellite.example.org'],\n      'parent'    =\u003e 'master',\n    },\n  }\n}\n\n# to enable a CA on this instance you have to declare. Only one instance is allowed to be a CA:\ninclude icinga2::pki::ca\n\nicinga2::object::zone { 'global-templates':\n  global =\u003e true,\n}\n```\n\n#### Satellite\n\nA satellite has a parent zone and one or multiple child zones. Satellites are usually created to distribute the\nmonitoring load or to reach delimited zones in the network. A satellite either executes checks itself or delegates them\nto a client.\n\nThe satellite has fewer features enabled, but executes checks similar to a master. It connects to a master zone, and to\na satellite or client below in the hierarchy. As parent acts either the master zone, or another satellite zone.\n\n``` puppet\nclass { 'icinga2':\n  confd     =\u003e false,\n  # setting dedicated feature list to disable notification\n  features  =\u003e ['checker','mainlog'],\n  constants =\u003e {\n    'ZoneName' =\u003e 'dmz',\n  },\n}\n\nclass { 'icinga2::feature::api':\n  accept_config   =\u003e true,\n  accept_commands =\u003e true,\n  ca_host         =\u003e '172.16.1.11',\n  ticket_salt     =\u003e '5a3d695b8aef8f18452fc494593056a4',\n  # to increase your security set fingerprint to validate the certificate of ca_host\n  # fingerprint     =\u003e 'D8:98:82:1B:14:8A:6A:89:4B:7A:40:32:50:68:01:D8:98:82:1B:14:8A:6A:89:4B:7A:40:32:99:3D:96:72:72',\n  endpoints       =\u003e {\n    'satellite.example.org' =\u003e {},\n    'master.example.org'    =\u003e {\n      'host' =\u003e '172.16.1.11',\n    },\n  },\n  zones           =\u003e {\n    'master' =\u003e {\n      'endpoints' =\u003e ['master.example.org'],\n    },\n    'dmz'    =\u003e {\n      'endpoints' =\u003e ['satellite.example.org'],\n      'parent'    =\u003e 'master',\n    },\n  }\n}\n\nicinga2::object::zone { 'global-templates':\n  global =\u003e true,\n}\n```\n\n#### Agent\n\nIcinga 2 runs as a client usually on each of your servers. It receives config or commands from a satellite or master\nzones and runs the checks that have to be executed locally.\n\nThe client is connected to the satellite, which is the direct parent zone.\n\n``` puppet\nclass { 'icinga2':\n  confd     =\u003e false,\n  features  =\u003e ['mainlog'],\n}\n\nclass { 'icinga2::feature::api':\n  accept_config   =\u003e true,\n  accept_commands =\u003e true,\n  ticket_salt     =\u003e '5a3d695b8aef8f18452fc494593056a4',\n  # to increase your security set fingerprint to validate the certificate of ca_host\n  # fingerprint     =\u003e 'D8:98:82:1B:14:8A:6A:89:4B:7A:40:32:50:68:01:D8:98:82:1B:14:8A:6A:89:4B:7A:40:32:99:3D:96:72:72',\n  endpoints       =\u003e {\n    'NodeName'              =\u003e {},\n    'satellite.example.org' =\u003e {\n      'host' =\u003e '172.16.2.11',\n    },\n  },\n  zones           =\u003e {\n    'ZoneName' =\u003e {\n      'endpoints' =\u003e ['NodeName'],\n      'parent'    =\u003e 'dmz',\n    },\n    'dmz'      =\u003e {\n      'endpoints' =\u003e ['satellite.example.org'],\n    },\n  }\n}\n\nicinga2::object::zone { 'global-templates':\n  global =\u003e true,\n}\n```\n\nThe parameter `fingerprint` is optional and new since v2.1.0. It's used to validate the certificate of the CA host.\nYou can get the fingerprint via `openssl x509 -noout -fingerprint -sha256 -inform pem -in master.crt` on the master host. (Icinga2 versions before 2.12.0 require '-sha1' as digest algorithm.)\n\n\n### Config Objects\n\nWith this module you can create almost every object that Icinga 2 knows about. When creating objects some parameters are\nrequired. This module sets the same requirements as Icinga 2 does. When creating an object you must set a target for the\nconfiguration.\n\nHere are some examples for some object types:\n\n#### Host\n``` puppet\nicinga2::object::host { 'srv-web1.fqdn.com':\n  display_name  =\u003e 'srv-web1.fqdn.com',\n  address       =\u003e '127.0.0.1',\n  address6      =\u003e '::1',\n  check_command =\u003e 'hostalive',\n  target        =\u003e '/etc/icinga2/conf.d/srv-web1.fqdn.com.conf',\n}\n```\n\n#### Service\n``` puppet\nicinga2::object::service { 'uptime':\n  host_name      =\u003e 'srv-web1.fqdn.com',\n  display_name   =\u003e 'Uptime',\n  check_command  =\u003e 'check_uptime',\n  check_interval =\u003e '600m',\n  groups         =\u003e ['uptime', 'linux'],\n  target         =\u003e '/etc/icinga2/conf.d/uptime.conf',\n}\n```\n\n#### Hostgroup\n``` puppet\nicinga2::object::hostgroup { 'monitoring-hosts':\n  display_name =\u003e 'Linux Servers',\n  groups       =\u003e [ 'linux-servers' ],\n  target       =\u003e '/etc/icinga2/conf.d/groups2.conf',\n  assign       =\u003e [ 'host.vars.os == linux' ],\n}\n```\n\n### Reading objects from hiera\n\nThe following example shows how icinga2 objects can be read from\na hiera datastore. See also examples/objects_from_hiera.pp.\n\n```\nclass { 'icinga2':\n  manage_repos =\u003e true,\n}\n\n$defaults = lookup('monitoring::defaults', undef, undef, {})\n\nlookup('monitoring::objects').each |String $object_type, Hash $content| {\n  $content.each |String $object_name, Hash $object_config| {\n    ensure_resource(\n      $object_type,\n      $object_name,\n      deep_merge($defaults[$object_type], $object_config))\n  }\n}\n```\n\nThe datastore could be like:\n\n```\n---\nmonitoring::objects:\n  'icinga2::object::host':\n    centos7.localdomain:\n      address: 127.0.0.1\n      vars:\n        os: Linux\n  'icinga2::object::service':\n    ping4:\n      check_command: ping4\n      apply: true\n      assign:\n        - host.address\n    ssh:\n      check_command: ssh\n      apply: true\n      assign:\n        - host.address \u0026\u0026 host.vars.os == Linux\n\nmonitoring::defaults:\n  'icinga2::object::host':\n    import:\n      - generic-host\n    target: /etc/icinga2/conf.d/hosts.conf\n  'icinga2::object::service':\n    import:\n      - generic-service\n    target: /etc/icinga2/conf.d/services.conf\n```\n\n\n### Apply Rules\n\nSome objects can be applied to other objects. To create a simple apply rule you\nmust set the `apply` parameter to `true`. If this parameter is set to a string,\nthis string will be used to build an `apply for` loop. A service object always\ntargets a host object. All other objects need to explicitly set an\n`apply_target`\n\nApply a SSH service to all Linux hosts:\n\n```\nicinga2::object::service { 'SSH':\n  target        =\u003e '/etc/icinga2/conf.d/test.conf',\n  apply         =\u003e true,\n  assign        =\u003e [ 'host.vars.os == Linux' ],\n  ignore        =\u003e [ 'host.vars.os == Windows' ],\n  display_name  =\u003e 'Test Service',\n  check_command =\u003e 'ssh',\n}\n```\n\nApply notifications to services:\n\n```\nicinga2::object::notification { 'testnotification':\n  target       =\u003e '/etc/icinga2/conf.d/test.conf',\n  apply        =\u003e true,\n  apply_target =\u003e 'Service',\n  assign       =\u003e [ 'host.vars.os == Linux' ],\n  ignore       =\u003e [ 'host.vars.os == Windows' ],\n  user_groups  =\u003e ['icingaadmins']\n}\n```\n\nAssign all Linux hosts to a hostgroup:\n```\nicinga2::object::hostgroup { 'monitoring-hosts':\n  display_name =\u003e 'Linux Servers',\n  groups       =\u003e [ 'linux-servers' ],\n  target       =\u003e '/etc/icinga2/conf.d/groups2.conf',\n  assign       =\u003e [ 'host.vars.os == linux' ],\n}\n```\n\nA loop to create HTTP services for all vHosts of a host object:\n```\nicinga2::object::service { 'HTTP':\n  target        =\u003e '/etc/icinga2/conf.d/http.conf',\n  apply         =\u003e 'http_vhost =\u003e config in host.vars_http_vhost',\n  assign        =\u003e [ 'host.vars.os == Linux' ],\n  display_name  =\u003e 'HTTP Service',\n  check_command =\u003e 'http',\n}\n```\n\n### Custom Configuration\n\nSometimes it's necessary to cover very special configurations, that you cannot handle with this module. In this case you can use the `icinga2::config::file` tag on your file resource. The module collects all file resource types with this tag and triggers a reload of Icinga 2 on a file change.\n\n```\ninclude icinga2\n\nfile { '/etc/icinga2/conf.d/for-loop.conf':\n  ensure =\u003e file,\n  source =\u003e '...',\n  tag    =\u003e 'icinga2::config::file',\n}\n```\n\n## How Configuration is parsed\n\nTo generate a valid Icinga 2 configuration all object attributes are parsed. This simple parsing algorithm takes a\ndecision for each attribute, whether part of the string is to be quoted or not, and how an array or dictionary is to be\nformatted.\n\nParsing of a single attribute can be disabled by tagging it with -: at the front of the string.\n```\n   attr =\u003e '-:\"unparsed string with quotes\"'\n```\nAn array, a hash or a string can be assigned to an object attribute. True and false are also valid values.\n\nHashes and arrays are created recursively, and all parts – such as single items of an array, keys and its values\nare parsed separately as strings.\n\nStrings are parsed in chunks, by splitting the original string into separate substrings at specific keywords (operators)\nsuch as `+`, `-`, `in`, `\u0026\u0026`, `||`, etc.\n\n**NOTICE**: This splitting only works for keywords that are surrounded by whitespace, e.g.:\n```\n   attr =\u003e 'string1 + string2 - string3'\n```\n\nThe algorithm will loop over the parameter and start by splitting it into 'string1' and 'string2 - string3'.\n'string1' will be passed to the sub function 'value_types' and then the algorithm will continue parsing the rest of the\nstring ('string2 - string3'), splitting it, passing it to value_types, etc.\n\nBrackets are parsed for expressions:\n```\n  attr =\u003e '3 * (value1 - value2) / 2'\n```\n\nThe parser also detects function calls and will parse all parameters separately.\n```\n  attr =\u003e 'function(param1, param2, ...)'\n```\n\nTrue and false can be used as either booleans or strings.\n```\n  attrs =\u003e true or  attr =\u003e 'true'\n```\n\nIn Icinga you can write your own lambda functions with {{ ... }}. For Puppet use:\n```\n  attrs =\u003e '{{ ... }}'\n```\n\nThe parser analyzes which parts of the string have to be quoted and which do not.\n\nAs a general rule, all fragments are quoted except for the following:\n\n* Boolean: `true`, `false`\n* Numbers: `3` or `2.5`\n* Time Intervals: `3m` or `2.5h`  (s = seconds, m = minutes, h = hours, d = days)\n* Functions: `{{ ... }}` or function `()` `{}`\n* All constants, which are declared in the constants parameter in main class `icinga2`\n    * `NodeName`\n* Names of attributes that belong to the same type of object:\n    * e.g. `name` and `check_command` for a host object\n* All attributes or variables (custom attributes) from the host, service or user contexts:\n    * `host.name`, `service.check_command`, `user.groups`, ...\n\nAssignment with += and -=:\n\nNow it's possible to build an Icinga DSL code snippet like\n```\n  vars += config\n```\nsimply use a string with the prefix '+ ', e.g.\n```\n  vars =\u003e '+ config',\n```\nThe blank between + and the proper string 'config' is imported for the parser because numbers\n```\n  attr =\u003e '+ -14',\n```\nare also possible now. For numbers -= can be built, too:\n```\n  attr =\u003e '- -14',\n```\nArrays can also be marked to merge with '+' or reduce by '-' as the first item of the array:\n```\n  attr =\u003e [ '+', item1, item2, ... ]\n```\nResult: attr += [ item1, item2, ... ]\n```\n  attr =\u003e [ '-', item1, item2, ... ]\n```\nResult: attr -= [ item1, item2, ... ]\n\nThat all works for attributes and custom attributes!\n\nFinally dictionaries can be merged when a key '+' is set:\n```\n  attr =\u003e {\n    '+'    =\u003e true,\n    'key1' =\u003e 'val1',\n  }\n```\nResult:\n```\n  attr += {\n    \"key1\" = \"val1\"\n  }\n```\nIf 'attr' is a custom attribute this just works since level 3 of the dictionary:\n```\n  vars =\u003e {\n    'level1' =\u003e {\n      'level2' =\u003e {\n        'level3' =\u003e {\n          '+' =\u003e true,\n          ...\n        },\n      },\n    },\n  },\n```\nParsed to:\n```\n  vars.level1[\"level2\"] += level3\n```\nNow it's also possible to add multiple custom attributes:\n```\n  vars =\u003e [\n    {\n      'a' =\u003e '1',\n      'b' =\u003e '2',\n    },\n    'config',\n    {\n      'c' =\u003e {\n        'd' =\u003e {\n          '+' =\u003e true,\n          'e' =\u003e '5',\n        },\n      },\n    },\n  ],\n```\nAnd you'll get:\n```\n  vars.a = \"1\"\n  vars.b = \"2\"\n  vars += config\n  vars.c[\"d\"] += {\n    \"e\" = \"5\"\n  }\n```\nNote: Using an Array always means merge '+=' all items to vars.\n\n##### What isn't supported?\n\nIt's not currently possible to use dictionaries in a string WITH nested array or hash, like\n```\n  attr1 =\u003e 'hash1 + { item1 =\u003e value1, item2 =\u003e [ value1, value2 ], ... ]'\n  attr2 =\u003e 'hash2 + { item1 =\u003e value1, item2 =\u003e { ... },... }'\n```\n\n## Reference\n\nSee [REFERENCE.md](https://github.com/Icinga/puppet-icinga2/blob/master/REFERENCE.md)\n\n## Known Issues\n\n### Environment Bleed\n\nDue to a long known bug in puppet known as environment bleed, upgrading this module from versions \u003c3.2.0 to a version \u003e=3.2.0 may present some issues. The handling of new datatypes introduced in the 3.2.0 update of this module may result in configuration file contents with the following line:\n```\npassword = \"Sensitive [value redacted]\"\n```\nThis may affect configuration files which are influenced by the following puppet code pieces:\n- icinga2::feature::api::ticket\\_salt\n- icinga2::feature::api::ticket\\_id\n- icinga2::feature::elasticsearch::password\n- icinga2::feature::icingadb::password\n- icinga2::feature::idomysql::password\n- icinga2::feature::idopgsql::password\n- icinga2::feature::influxdb::password\n- icinga2::feature::influxdb::basic\\_auth['password']\n- icinga2::feature::influxdb2::auth\\_token\n- icinga2::object::apiuser::password\n\nThis may be fixed by doing the following steps in order:\n1. Update all environments containing this module to the latest version\n2. Regenerate all resource types in case you are using environment isolation\n\t- 2.1 Delete old resource types for each environment\n\t\t```\n\t\trm -rf /etc/puppetlabs/code/environment/xxx/.resource\\_types/\n\t\t```\n\t- 2.2 Generate new resource types for each environment\n\t\t```\n\t\tpuppet generate types --environment xxx\n\t\t```\n3. Restart the puppetserver service\n\n## Release Notes\n\nWhen releasing new versions we refer to [SemVer 1.0.0] for version numbers.\n[SemVer 1.0.0]: http://semver.org/spec/v1.0.0.html\n\nSee also [CHANGELOG.md](https://github.com/Icinga/puppet-icinga2/blob/master/CHANGELOG.md)\n\n[distributed monitoring]: http://docs.icinga.com/icinga2/latest/doc/module/icinga2/chapter/distributed-monitoring\n[puppetlabs/stdlib]: https://github.com/puppetlabs/puppetlabs-stdlib\n[puppetlabs/concat]: https://github.com/puppetlabs/puppetlabs-concat\n[puppetlabs/apt]: https://github.com/puppetlabs/puppetlabs-apt\n[puppetlabs/chocolatey]: https://github.com/puppetlabs/puppetlabs-chocolatey\n[puppet/zypprepo]: https://forge.puppet.com/puppet/zypprepo\n[puppetlabs/mysql]: https://github.com/puppetlabs/puppetlabs-mysql\n[puppetlabs/puppetlabs-postgresql]: https://github.com/puppetlabs/puppetlabs-postgresql\n[puppet-icinga2]: https://github.com/voxpupuli/puppet-icinga2\n[packages.icinga.com]: https://packages.icinga.com\n[Chocolatey]: https://chocolatey.org\n\n## Transfer Notice\n\nThis plugin was originally authored by [Icinga](http://www.icinga.com).\nThe maintainer preferred that Vox Pupuli take ownership of the module for future improvement and maintenance.\nExisting pull requests and issues were transferred over, please fork and continue to contribute here instead of Icinga.\n\nPreviously: https://github.com/icinga/puppet-icinga2\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpupuli%2Fpuppet-icinga2","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvoxpupuli%2Fpuppet-icinga2","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvoxpupuli%2Fpuppet-icinga2/lists"}