diff --git a/README.md b/README.md
index e7aea7e5632180dad7540ac6cd98271927376410..4cf7777848da7df3b8336cd5823f1f2348b95eef 100644
--- a/README.md
+++ b/README.md
@@ -16,9 +16,8 @@ If database doesn't exists, role create schema and tables... if not, do nothing
 
 
 POSTGRESQL:
-The default authentication assumes that you are either logging in as or sudo’ing to the postgres account on the host.
-
 CREATE ROLE icinga2 WITH LOGIN PASSWORD 'icinga2' CREATEDB;
+CREATE ROLE icingaweb2 WITH LOGIN PASSWORD 'icingaweb2' CREATEDB;
 
 pg_hba.conf
 # Icinga
@@ -32,13 +31,16 @@ host    icingaweb2,postgres    icingaweb2          ::1/128      md5
 MYSQL:
 CREATE USER 'icinga2'@'%' IDENTIFIED BY 'icinga2';
 GRANT ALL PRIVILEGES ON icinga2.* TO 'icinga2'@'%';
-CREATE USER 'icinga2web'@'%' IDENTIFIED BY 'icinga2web';
-GRANT ALL PRIVILEGES ON icinga2web.* TO 'icinga2web'@'%';
+CREATE USER 'icingaweb2'@'%' IDENTIFIED BY 'icingaweb2';
+GRANT ALL PRIVILEGES ON icingaweb2.* TO 'icingaweb2'@'%';
+
+
 
 
+--------
 
 
---------You have to define a _group_ called `etcd-cluster` in your `/etc/ansible/hosts` inventary with all servers of the _etcd_ cluster (you can change the `etcd_inventory_group_name` variable if you want to use a different group name).
+You have to define a _group_ called `etcd-cluster` in your `/etc/ansible/hosts` inventary with all servers of the _etcd_ cluster (you can change the `etcd_inventory_group_name` variable if you want to use a different group name).
 
 After role execution, a file called `env-vars.sh` is stored in _etcd_ config dir (defined in `etcd_config_path` variable) of every cluster node to help you in the connection from the command line.
 
diff --git a/defaults/main.yml b/defaults/main.yml
index a73837f3e3e0764a57b966d0760885c836eeea4d..29239dfdfb2f77037910bf47f6e99f9b67148abf 100644
--- a/defaults/main.yml
+++ b/defaults/main.yml
@@ -1,37 +1,51 @@
 ---
 # Global config
 icinga_supported_distributions: [Debian]
+icinga_default_dist_codename: stretch
+icinga_template_header:
+  - "WARNING: This file is generated automatically with Ansible, do not edit directly!!"
+  - "https://code.vandalsweb.com/vandalsweb/ansible-playbooks"
+  - "---"
 
 # APT Icinga repository
 icinga_apt_repositories:
   - name: icinga
     gpg: "https://packages.icinga.com/icinga.key"
-    url: "[arch=amd64] http://packages.icinga.com/debian icinga-{{ ansible_lsb.codename | lower }} main"
+    url: "[arch=amd64] http://packages.icinga.com/debian icinga-{{ ansible_lsb.codename | default(icinga_default_dist_codename) | lower }} main"
 
 # Main config
-icinga_user: nagios
-icinga_group: nagios
+icinga_daemon_user: nagios
+icinga_daemon_group: nagios
 icinga_config_app_path: /etc/icinga2
 icinga_config_domain_path: "{{ icinga_config_app_path }}/conf.d"
 icinga_plugin_path: /usr/lib/nagios/plugins
 icinga_plugin_manubulon_path: "{{ icinga_plugin_path }}"
 icinga_plugin_contrib_path: "{{ icinga_plugin_path }}"
-icinga_template_header:
-  - "WARNING: This file is generated automatically with Ansible, do not edit directly!!"
-  - "https://code.vandalsweb.com/vandalsweb/ansible-playbooks"
-  - "---"
+icinga_domain: "{{ ansible_hostname }}"
+icinga_ssl_certs_path: /var/lib/icinga2/certs
+
+# SSL Certificates
+# icinga_ssl_provider: letsencrypt
+icinga_ssl_provider: openssl
+icinga_ssl_ca_country_name: ES
+icinga_ssl_ca_state_province: Madrid
+icinga_ssl_ca_locality: Madrid
+icinga_ssl_ca_organization_name: Icinga
+icinga_ssl_ca_organization_unit_name: Development Team
+icinga_ssl_ca_email: admin@vandalsweb.com
+icinga_ssl_letsencrypt_only_test_cert: false
+icinga_ssl_letsencrypt_webroot_path: /var/www/acme
+icinga_ssl_letsencrypt_logs_path: "/var/log/letsencrypt"
 
 # Database config
-# Select between mysql or postgresql
-#icinga_db_driver: mysql
+# icinga_db_driver:
 icinga_db_host: localhost
-icinga_db_postgresql_port: 5432
-icinga_db_mysql_port: 3306
+# icinga_db_port:
 icinga_db_dbname: icinga2
 # Database user/password (see README.md to see how to create this user, permissions, etc)
-#icinga_db_username:
-#icinga_db_password:
-# Init schema
+# icinga_db_username:
+# icinga_db_password:
+# Initial schema
 icinga_db_postgresql_schema_path: /usr/share/icinga2-ido-pgsql/schema/pgsql.sql
 icinga_db_mysql_schema_path: /usr/share/icinga2-ido-mysql/schema/mysql.sql
 
@@ -40,19 +54,29 @@ icinga_api_enabled: True
 
 # Icinga web
 icinga_web_enabled: True
-#icinga_web_url: https://monitor.vandalsweb.com/icingaweb2
+icinga_web_config_path: /etc/icingaweb2
+icinga_web_logs_path: /var/log/icinga2/web
+icinga_web_phpfpm_pool_name: www
+icinga_web_phpfpm_pass: "127.0.0.1:9000"
+
 # Icinga web database config
-# Select between mysql or postgresql
-#icinga_web_db_driver: mysql
+# icinga_web_db_driver:
 icinga_web_db_host: localhost
-icinga_web_db_postgresql_port: 5432
-icinga_web_db_mysql_port: 3306
-icinga_web_db_dbname: icinga2web
+# icinga_web_db_port:
+icinga_web_db_dbname: icingaweb2
+icinga_web_admin_user: bhean
 # Database user/password (see README.md to see how to create this user, permissions, etc)
-#icinga_web_db_username:
-#icinga_web_db_password:
+# icinga_web_db_username:
+# icinga_web_db_password:
 
 # Notifications
-icinga_notification_from_name: vandalsMonitor
-icinga_notification_from_email: admin@vandalsweb.com
+icinga_notification_from_name: "Icinga Admin"
+icinga_notification_from_email: "admin@{{ ansible_hostname }}"
+icinga_pushover_enabled: False
+icinga_pushover_notify_after_role_deploy: True
 icinga_pushover_endpoint: https://api.pushover.net/1/messages
+# icinga_pushover_userkey:
+# icinga_pushover_appkey:
+
+# Misc
+TEST_ENV: "{{ 'molecule_' in ansible_hostname }}"
diff --git a/handlers/main.yml b/handlers/main.yml
index 4ebd93321c733a6717e9b71e051c5690a712549a..8d6bacdfee67fa6f3d3610d8b1627468434b8914 100644
--- a/handlers/main.yml
+++ b/handlers/main.yml
@@ -1,12 +1,12 @@
 ---
-- name: Restarting Icinga server
+- name: "Restarting Icinga server"
   become: yes
   service:
     name: icinga2
     state: restarted
 
-- name: Restarting Apache2 server
+- name: "Restarting Nginx server"
   become: yes
   service:
-    name: apache2
+    name: nginx
     state: restarted
diff --git a/molecule/default/create.yml b/molecule/default/create.yml
index 5137782e4387f4bb6f375380800357601d031a88..f798834f3c40faa390d8446fe65ce0abacf66231 100644
--- a/molecule/default/create.yml
+++ b/molecule/default/create.yml
@@ -14,7 +14,7 @@
       template:
         src: "{{ molecule_scenario_directory }}/Dockerfile.j2"
         dest: "{{ molecule_ephemeral_directory }}/Dockerfile_{{ item.image | regex_replace('[^a-zA-Z0-9_]', '_') }}"
-      with_items: "{{ molecule_yml.platforms }}"
+      with_items: "{{ molecule_yml.platforms + molecule_yml.additional_instances }}"
       register: platforms
 
     - name: Discover local Docker images
@@ -37,7 +37,7 @@
       docker_network:
         name: "{{ item }}"
         state: present
-      with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}"
+      with_items: "{{ molecule_yml.platforms + molecule_yml.additional_instances | molecule_get_docker_networks }}"
 
     - name: Create molecule instance(s)
       docker_container:
@@ -54,10 +54,12 @@
         exposed_ports: "{{ item.exposed_ports | default(omit) }}"
         published_ports: "{{ item.published_ports | default(omit) }}"
         ulimits: "{{ item.ulimits | default(omit) }}"
+        network_mode: "{{ item.network_mode | default(omit) }}"
         networks: "{{ item.networks | default(omit) }}"
         dns_servers: "{{ item.dns_servers | default(omit) }}"
+        env: "{{ item.environment | default(omit) }}"
       register: server
-      with_items: "{{ molecule_yml.platforms }}"
+      with_items: "{{ molecule_yml.platforms + molecule_yml.additional_instances}}"
       async: 7200
       poll: 0
 
diff --git a/molecule/default/destroy.yml b/molecule/default/destroy.yml
index ec4da497e315324c358449fac4e9f53e10938e26..818bde3a13a33472859cebd080ff9d2ba6269e8e 100644
--- a/molecule/default/destroy.yml
+++ b/molecule/default/destroy.yml
@@ -14,7 +14,7 @@
         state: absent
         force_kill: "{{ item.force_kill | default(true) }}"
       register: server
-      with_items: "{{ molecule_yml.platforms }}"
+      with_items: "{{ molecule_yml.platforms + molecule_yml.additional_instances }}"
       async: 7200
       poll: 0
 
@@ -30,4 +30,4 @@
       docker_network:
         name: "{{ item }}"
         state: absent
-      with_items: "{{ molecule_yml.platforms | molecule_get_docker_networks }}"
+      with_items: "{{ molecule_yml.platforms + molecule_yml.additional_instances | molecule_get_docker_networks }}"
diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml
index a4cab2ab4e8e1e2f77356d1290c6facecb8235ff..80ebe122d6de950c0c1f6e5e50c1ddde123e3e5d 100644
--- a/molecule/default/molecule.yml
+++ b/molecule/default/molecule.yml
@@ -28,7 +28,7 @@ scenario:
     - converge
     - idempotence
     # - side_effect
-    # - verify
+    - verify
     - destroy
 
 dependency:
@@ -52,8 +52,33 @@ driver:
 platforms:
   # Debian 9 (STRETCH)
   - name: molecule_debian9
-    image: debian:9-slim
+    image: debian:9
     privileged: True
+    networks:
+      - name: molecule_icinga
+
+# Other instances required to run tests
+additional_instances:
+  - name: molecule_additional_mariadb
+    image: mariadb:5.5
+    privileged: True
+    networks:
+      - name: molecule_icinga
+    published_ports:
+      - 30306:3306
+    environment:
+      MYSQL_ROOT_PASSWORD: icingapass
+    command: "mysqld"
+  - name: molecule_additional_postgresql
+    image: postgres:9.6
+    privileged: True
+    networks:
+      - name: molecule_icinga
+    published_ports:
+      - 50432:5432
+    environment:
+      POSTGRES_PASSWORD: icingapass
+    command: "postgres"
 
 provisioner:
   name: ansible
diff --git a/molecule/default/playbook.yml b/molecule/default/playbook.yml
index e02f80c809b40181a0d103113430cab17c7aeab1..6ec33b4463bcd57423ec4eae7c7ff8c2f7951cb2 100644
--- a/molecule/default/playbook.yml
+++ b/molecule/default/playbook.yml
@@ -1,5 +1,38 @@
 ---
-- name: Converge
+- name: Converge (MySQL)
   hosts: all
+  vars:
+    icinga_ssl_provider: openssl
+    icinga_db_driver: mysql
+    icinga_db_host: molecule_additional_mariadb
+    icinga_db_port: 3306
+    icinga_db_username: root
+    icinga_db_password: icingapass
+    icinga_web_db_driver: "{{ icinga_db_driver }}"
+    icinga_web_db_host: "{{ icinga_db_host }}"
+    icinga_web_db_port: "{{ icinga_db_port }}"
+    icinga_web_db_username: root
+    icinga_web_db_password: icingapass
+    icinga_domain: monitor2.vandalsweb.com
+    icinga_pushover_notify_after_role_deploy: false
+  roles:
+    - role: icinga
+
+- name: Converge (PostgreSQL)
+  hosts: all
+  vars:
+    icinga_ssl_provider: openssl
+    icinga_db_driver: pgsql
+    icinga_db_host: molecule_additional_postgresql
+    icinga_db_port: 5432
+    icinga_db_username: postgres
+    icinga_db_password: icingapass
+    icinga_web_db_driver: "{{ icinga_db_driver }}"
+    icinga_web_db_host: "{{ icinga_db_host }}"
+    icinga_web_db_port: "{{ icinga_db_port }}"
+    icinga_web_db_username: postgres
+    icinga_web_db_password: icingapass
+    icinga_domain: monitor2.vandalsweb.com
+    icinga_pushover_notify_after_role_deploy: false
   roles:
     - role: icinga
diff --git a/molecule/default/tests/test_icinga.py b/molecule/default/tests/test_icinga.py
new file mode 100644
index 0000000000000000000000000000000000000000..c009ae0bc2bba751e52390b8df0d94bbeee94329
--- /dev/null
+++ b/molecule/default/tests/test_icinga.py
@@ -0,0 +1,9 @@
+def test_icinga2_is_installed(host):
+    package = host.package("icinga2")
+    assert package.is_installed
+
+
+def test_icinga2_running_and_enabled(host):
+    service = host.service("icinga2")
+    assert service.is_running
+    assert service.is_enabled
diff --git a/requirements.txt b/requirements.txt
index fd32c83ad8e02cdda7ad92ce97b85bb2940c43a9..c8ab69178f16359359e66311f2a39e717382d62c 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +1 @@
 ansible>=2.6
-
diff --git a/tasks/configure-db-mysql.yml b/tasks/configure-db-mysql.yml
index 34dadaaf42a7e82ab2e7c66a8b1250f29ad3ecb9..6feabef523baf4812971cad227ced1aa73a5296f 100644
--- a/tasks/configure-db-mysql.yml
+++ b/tasks/configure-db-mysql.yml
@@ -2,13 +2,9 @@
 - name: Installing Icinga database packages
   become: yes
   package:
-    name: "{{ item }}"
+    name: ['icinga2-ido-mysql', 'mysql-client', 'python-mysqldb']
     state: present
     update_cache: yes
-  with_items:
-    - icinga2-ido-mysql
-    - mysql-client
-    - python-mysqldb
 
 - name: Checking database
   mysql_db:
@@ -17,7 +13,7 @@
     login_user: "{{ icinga_db_username }}"
     login_password: "{{ icinga_db_password }}"
     login_host: "{{ icinga_db_host }}"
-    login_port: "{{ icinga_db_mysql_port }}"
+    login_port: "{{ icinga_db_port }}"
     db: "{{ icinga_db_dbname }}"
     state: present
   register: dbcreation
@@ -27,7 +23,7 @@
     login_user: "{{ icinga_db_username }}"
     login_password: "{{ icinga_db_password }}"
     login_host: "{{ icinga_db_host }}"
-    login_port: "{{ icinga_db_mysql_port }}"
+    login_port: "{{ icinga_db_port }}"
     db: "{{ icinga_db_dbname }}"
     state: import
     target: "{{ icinga_db_mysql_schema_path }}"
diff --git a/tasks/configure-db-postgresql.yml b/tasks/configure-db-pgsql.yml
similarity index 77%
rename from tasks/configure-db-postgresql.yml
rename to tasks/configure-db-pgsql.yml
index b1ffb413ad51f2d8def61a9a91c3edeb07434a50..e93ef007681728fa0eaee9b7bf4dfb2d933913b1 100644
--- a/tasks/configure-db-postgresql.yml
+++ b/tasks/configure-db-pgsql.yml
@@ -2,23 +2,19 @@
 - name: Installing Icinga database packages
   become: yes
   package:
-    name: "{{ item }}"
+    name: ['icinga2-ido-pgsql', 'postgresql-client', 'python-psycopg2']
     state: present
     update_cache: yes
-  with_items:
-    - icinga2-ido-pgsql
-    - postgresql-client
-    - python-psycopg2
 
 - name: Checking database
   postgresql_db:
-    encoding: "UTF8"
-    lc_collate: "en_US.UTF-8"
-    lc_ctype: "en_US.UTF-8"
+    encoding: "utf8"
+    lc_collate: "en_US.utf8"
+    lc_ctype: "en_US.utf8"
     login_user: "{{ icinga_db_username }}"
     login_password: "{{ icinga_db_password }}"
     login_host: "{{ icinga_db_host }}"
-    port: "{{ icinga_db_postgresql_port }}"
+    port: "{{ icinga_db_port }}"
     db: "{{ icinga_db_dbname }}"
     owner: "{{ icinga_db_username }}"
     state: present
@@ -29,7 +25,7 @@
     login_user: "{{ icinga_db_username }}"
     login_password: "{{ icinga_db_password }}"
     login_host: "{{ icinga_db_host }}"
-    port: "{{ icinga_db_postgresql_port }}"
+    port: "{{ icinga_db_port }}"
     db: "{{ icinga_db_dbname }}"
     state: restore
     target: "{{ icinga_db_postgresql_schema_path }}"
diff --git a/tasks/configure-db-web-mysql.yml b/tasks/configure-db-web-mysql.yml
index 1f29c7d6a9990d56f0c4a4972e9f43ba7ef2b254..7f21a9854c8f61734e619d47c303285545353fa9 100644
--- a/tasks/configure-db-web-mysql.yml
+++ b/tasks/configure-db-web-mysql.yml
@@ -2,11 +2,9 @@
 - name: Installing Icinga web database packages
   become: yes
   package:
-    name: "{{ item }}"
+    name: ['php-mysql']
     state: present
     update_cache: yes
-  with_items:
-    - php-mysql
 
 - name: Checking database
   mysql_db:
@@ -15,7 +13,33 @@
     login_user: "{{ icinga_web_db_username }}"
     login_password: "{{ icinga_web_db_password }}"
     login_host: "{{ icinga_web_db_host }}"
-    login_port: "{{ icinga_web_db_mysql_port }}"
+    login_port: "{{ icinga_web_db_port }}"
     db: "{{ icinga_web_db_dbname }}"
     state: present
-  register: dbcreation
+  register: dbwebcreation
+
+- name: Copying database template schema (if not exists)
+  become: yes
+  template:
+    src: "templates/icingaweb2_db/mysql.sql"
+    dest: "{{ icinga_web_config_path }}/mysql.sql"
+    owner: root
+    group: root
+    mode: "660"
+  when:
+    - dbwebcreation.changed
+
+- name: Creating database schema (if not exists)
+  become: yes
+  mysql_db:
+    login_user: "{{ icinga_web_db_username }}"
+    login_password: "{{ icinga_web_db_password }}"
+    login_host: "{{ icinga_web_db_host }}"
+    login_port: "{{ icinga_web_db_port }}"
+    db: "{{ icinga_web_db_dbname }}"
+    state: import
+    target: "{{ icinga_web_config_path }}/mysql.sql"
+  when:
+    - dbwebcreation.changed
+  notify:
+    - Restarting Icinga server
diff --git a/tasks/configure-db-web-pgsql.yml b/tasks/configure-db-web-pgsql.yml
new file mode 100644
index 0000000000000000000000000000000000000000..ee0b53b7fa80b16f0fd0ca207910c246abe8abab
--- /dev/null
+++ b/tasks/configure-db-web-pgsql.yml
@@ -0,0 +1,47 @@
+---
+- name: Installing Icinga web database packages
+  become: yes
+  package:
+    name: ['php-pgsql']
+    state: present
+    update_cache: yes
+
+- name: Checking database
+  postgresql_db:
+    encoding: "utf8"
+    lc_collate: "en_US.utf8"
+    lc_ctype: "en_US.utf8"
+    login_user: "{{ icinga_web_db_username }}"
+    login_password: "{{ icinga_web_db_password }}"
+    login_host: "{{ icinga_web_db_host }}"
+    port: "{{ icinga_web_db_port }}"
+    db: "{{ icinga_web_db_dbname }}"
+    owner: "{{ icinga_web_db_username }}"
+    state: present
+  register: dbwebcreation
+
+- name: Copying database template schema (if not exists)
+  become: yes
+  template:
+    src: "templates/icingaweb2_db/pgsql.sql"
+    dest: "{{ icinga_web_config_path }}/pgsql.sql"
+    owner: root
+    group: root
+    mode: "660"
+  when:
+    - dbwebcreation.changed
+
+- name: Creating database schema (if not exists)
+  become: yes
+  postgresql_db:
+    login_user: "{{ icinga_web_db_username }}"
+    login_password: "{{ icinga_web_db_password }}"
+    login_host: "{{ icinga_web_db_host }}"
+    port: "{{ icinga_web_db_port }}"
+    db: "{{ icinga_web_db_dbname }}"
+    state: restore
+    target: "{{ icinga_web_config_path }}/pgsql.sql"
+  when:
+    - dbwebcreation.changed
+  notify:
+    - Restarting Icinga server
diff --git a/tasks/configure-db-web-postgresql.yml b/tasks/configure-db-web-postgresql.yml
deleted file mode 100644
index 58fb381cc740af10aa6c401d1aef564c4eb7a87b..0000000000000000000000000000000000000000
--- a/tasks/configure-db-web-postgresql.yml
+++ /dev/null
@@ -1,23 +0,0 @@
----
-- name: Installing Icinga web database packages
-  become: yes
-  package:
-    name: "{{ item }}"
-    state: present
-    update_cache: yes
-  with_items:
-    - php-pgsql
-
-- name: Checking database
-  postgresql_db:
-    encoding: "UTF8"
-    lc_collate: "en_US.UTF-8"
-    lc_ctype: "en_US.UTF-8"
-    login_user: "{{ icinga_web_db_username }}"
-    login_password: "{{ icinga_web_db_password }}"
-    login_host: "{{ icinga_web_db_host }}"
-    port: "{{ icinga_web_db_postgresql_port }}"
-    db: "{{ icinga_web_db_web_dbname }}"
-    owner: "{{ icinga_web_db_username }}"
-    state: present
-  register: dbcreation
diff --git a/tasks/configure-db-web.yml b/tasks/configure-db-web.yml
new file mode 100644
index 0000000000000000000000000000000000000000..1b8b83b4befeb053d24df1569d14445b384cdf8c
--- /dev/null
+++ b/tasks/configure-db-web.yml
@@ -0,0 +1,9 @@
+---
+- name: "Generating initial data for Icinga web (part I - if not exists)"
+  set_fact:
+    icingaweb2_generated_password: "{{ 999999 | random }}"
+
+- name: "Generating initial data for Icinga web (part II - if not exists)"
+  set_fact:
+    icingaweb2_generated_password_encrypted: "{{ icingaweb2_generated_password | password_hash('sha512') }}"
+    icingaweb2_generated_datetime: "{{ ansible_date_time.date }} {{ ansible_date_time.time }}"
diff --git a/tasks/generate-ssl-certs-letsencrypt.yml b/tasks/generate-ssl-certs-letsencrypt.yml
new file mode 100644
index 0000000000000000000000000000000000000000..e15793ab6eb5a82a5a931c430a563d2dd27d992d
--- /dev/null
+++ b/tasks/generate-ssl-certs-letsencrypt.yml
@@ -0,0 +1,86 @@
+---
+- name: "Installing required packages"
+  become: yes
+  package:
+    name: ['certbot', 'nginx-full']
+    state: present
+    update_cache: yes
+
+- name: "Setting OpenSSL values"
+  set_fact:
+    icinga_ssl_ca_path: "/etc/letsencrypt/live/{{ icinga_domain }}/cert.pem"
+    icinga_ssl_csr_path: ""
+    icinga_ssl_cert_path: "/etc/letsencrypt/live/{{ icinga_domain }}/cert.pem"
+    icinga_ssl_key_path: "/etc/letsencrypt/live/{{ icinga_domain }}/privkey.pem"
+
+- name: "Check if Let's Encrypt certificates already exists"
+  become: yes
+  stat:
+    path: "{{ icinga_ssl_cert_path }}"
+  register: sslcerts
+
+- name: "Creating Let's Encrypt required directories"
+  become: yes
+  file:
+    path: "{{ item }}"
+    state: directory
+    owner: www-data
+    group: adm
+    mode: "0775"
+  with_items:
+    - "{{ icinga_ssl_letsencrypt_webroot_path }}"
+    - "{{ icinga_ssl_letsencrypt_logs_path }}"
+  when:
+    - sslcerts.stat.exists == False
+
+- name: "Copying basic Nginx config file for Let's Encrypt ACME Challenge"
+  become: yes
+  template:
+    src: "etc/nginx/sites-enabled/letsencrypt.conf"
+    dest: "/etc/nginx/sites-enabled/"
+    owner: "www-data"
+    group: "adm"
+    mode: "644"
+    validate: bash -c 'nginx -t -c /dev/stdin <<< "events {worker_connections 1;} http { include %s; }"'
+  notify:
+    - "Restarting Nginx server"
+  when:
+    - sslcerts.stat.exists == False
+
+- name: "Restarting Nginx server"
+  become: yes
+  service:
+    name: nginx
+    state: restarted
+  when:
+    - sslcerts.stat.exists == False
+
+- name: "Requesting SSL cert (Let's Encrypt ACME Challenge)"
+  become: yes
+  command: "certbot certonly
+    {% if icinga_ssl_letsencrypt_only_test_cert %}--test-cert{% endif %}
+    --non-interactive
+    --webroot
+    --webroot-path {{ icinga_ssl_letsencrypt_webroot_path }}
+    --agree-tos
+    --keep-until-expiring
+    --expand
+    --email {{ icinga_ssl_ca_email }}
+    --domain {{ icinga_domain }}
+    --logs-dir {{ icinga_ssl_letsencrypt_logs_path }}"
+  register: acme_challenge
+  when:
+    - sslcerts.stat.exists == False
+
+- name: "Debugging Let's Encrypt ACME Challenge"
+  debug:
+    msg: "{{ acme_challenge.stdout_lines }}"
+    verbosity: 2
+  when:
+    - sslcerts.stat.exists == False
+
+- name: "Deleting basic Nginx config file for Let's Encrypt ACME Challenge"
+  become: yes
+  file:
+    path: "/etc/nginx/sites-enabled/letsencrypt.conf"
+    state: absent
diff --git a/tasks/generate-ssl-certs-openssl.yml b/tasks/generate-ssl-certs-openssl.yml
new file mode 100644
index 0000000000000000000000000000000000000000..2010448151b97d1280311921aee3ca4adb6df410
--- /dev/null
+++ b/tasks/generate-ssl-certs-openssl.yml
@@ -0,0 +1,53 @@
+---
+- name: "Installing required packages"
+  become: yes
+  package:
+    name: ['openssl', 'python-openssl']
+    state: present
+    update_cache: yes
+
+- name: "Setting OpenSSL values"
+  set_fact:
+    icinga_ssl_ca_path: "/etc/ssl/certs/icinga-{{ icinga_domain }}.crt"
+    icinga_ssl_csr_path: "/etc/ssl/icinga-{{ icinga_domain }}.csr"
+    icinga_ssl_cert_path: "/etc/ssl/certs/icinga-{{ icinga_domain }}.crt"
+    icinga_ssl_key_path: "/etc/ssl/private/icinga-{{ icinga_domain }}.key"
+
+- name: "Generating OpenSSL private key"
+  become: yes
+  openssl_privatekey:
+    path: "{{ icinga_ssl_key_path }}"
+    owner: root
+    group: root
+    mode: "0640"
+    force: no
+
+- name: "Generating OpenSSL certificate signing request"
+  become: yes
+  openssl_csr:
+    path: "{{ icinga_ssl_csr_path }}"
+    privatekey_path: "{{ icinga_ssl_key_path }}"
+    country_name: "{{ icinga_ssl_ca_country_name }}"
+    state_or_province_name: "{{ icinga_ssl_ca_state_province }}"
+    locality_name: "{{ icinga_ssl_ca_locality }}"
+    organization_name: "{{ icinga_ssl_ca_organization_name }}"
+    organizational_unit_name: "{{ icinga_ssl_ca_organization_unit_name }}"
+    email_address: "{{ icinga_ssl_ca_email }}"
+    common_name: "{{ icinga_domain }}"
+    owner: root
+    group: root
+    mode: "0660"
+    force: no
+
+- name: "Generating OpenSSL self-signed certificate (\"valid\" for 20 years)"
+  become: yes
+  openssl_certificate:
+    path: "{{ icinga_ssl_cert_path }}"
+    privatekey_path: "{{ icinga_ssl_key_path }}"
+    csr_path: "{{ icinga_ssl_csr_path }}"
+    valid_in: 631139040
+    provider: selfsigned
+    owner: root
+    group: root
+    mode: "0644"
+    force: no
diff --git a/tasks/generate-ssl-certs.yml b/tasks/generate-ssl-certs.yml
deleted file mode 100644
index bf0d8fa9069886f8b2cff6b36aec156e25032483..0000000000000000000000000000000000000000
--- a/tasks/generate-ssl-certs.yml
+++ /dev/null
@@ -1,45 +0,0 @@
----
-- name: Checking if SSL certs already exists
-  become: yes
-  stat:
-    path: "/var/lib/icinga2/ca/ca.crt"
-  register: sslcertfile
-
-- name: Generating SSL CA cert (if doesn't exists)
-  become: yes
-  command: icinga2 pki new-ca
-  when:
-  - sslcertfile.stat.exists is defined
-  - not sslcertfile.stat.exists | bool
-  notify:
-  - Restarting Icinga server
-
-- name: Creating SSL certs directory
-  become: yes
-  file:
-    path: "/var/lib/icinga2/certs/"
-    state: directory
-    owner: "root"
-    group: "{{ icinga_group }}"
-    mode: "0770"
-  notify:
-  - Restarting Icinga server
-
-- name: Copying SSL CA cert to cert directory
-  become: yes
-  copy:
-    remote_src: true
-    src: "/var/lib/icinga2/ca/ca.crt"
-    dest: "/var/lib/icinga2/certs/"
-  notify:
-  - Restarting Icinga server
-
-- name: Generating SSL CSR/KEY certs (if doesn't exists)
-  become: yes
-  command: icinga2 pki new-cert \
-    --cn {{ ansible_hostname }} \
-    --key /var/lib/icinga2/certs/{{ ansible_hostname }}.key \
-    --csr /var/lib/icinga2/certs/{{ ansible_hostname }}.csr \
-    --cert /var/lib/icinga2/certs/{{ ansible_hostname }}.crt
-  notify:
-  - Restarting Icinga server
diff --git a/tasks/install-icinga-api.yml b/tasks/install-icinga-api.yml
index 5ab4334c29dcdb49828950cc62ed597d104aa76c..1b2e21f5405d5b89e05c0cb41e28f75646732a32 100644
--- a/tasks/install-icinga-api.yml
+++ b/tasks/install-icinga-api.yml
@@ -4,8 +4,8 @@
   template:
     src: etc/icinga2/conf.d/definition-apiusers.conf
     dest: "{{ icinga_config_domain_path }}"
-    owner: "{{ icinga_user }}"
-    group: "{{ icinga_group }}"
+    owner: "{{ icinga_daemon_user }}"
+    group: "{{ icinga_daemon_group }}"
     mode: "0644"
   notify:
     - Restarting Icinga server
diff --git a/tasks/install-icinga-web.yml b/tasks/install-icinga-web.yml
index 0704c3d5181302d215864e4acf80cc110a6b08f6..61ed694f6efebb0dc14f97ad881b84990fd7f90f 100644
--- a/tasks/install-icinga-web.yml
+++ b/tasks/install-icinga-web.yml
@@ -1,42 +1,68 @@
 ---
-- name: Installing Icinga web packages
+- name: "Installing Icinga web packages"
   become: yes
-  package:
-    name: "{{ item }}"
+  apt:
+    name: ['icingaweb2', 'nginx-full', 'icingacli', 'php-gd', 'php-fpm', 'php-ldap', 'php-mysql', 'php-pgsql', 'php-imagick', 'php-intl']
     state: present
     update_cache: yes
-  with_items:
-    - icingaweb2
-    - icingacli
-    - php-gd
+    install_recommends: no
   notify:
     - Restarting Icinga server
 
-#- name: Checking if web token already exists
-#  become: yes
-#  command:
+- name: "Copying Icinga web config files"
+  become: yes
+  template:
+    src: "etc/icingaweb2/{{ item }}"
+    dest: "{{ icinga_web_config_path }}"
+    owner: www-data
+    group: adm
+    mode: "0600"
+  with_items:
+    - authentication.ini
+    - config.ini
+    - groups.ini
+    - resources.ini
+    - roles.ini
 
-- name: Generating new web token
+- name: "Creating web log directory"
   become: yes
-  command: icingacli setup token create
-  register: icingawebtoken
+  file:
+    path: "{{ icinga_web_logs_path }}"
+    state: directory
+    owner: www-data
+    group: adm
+    mode: "0775"
 
-- name: Enabling Apache2 modules
+- name: "Copying PHP-FPM pool config file"
   become: yes
-  command: "a2enmod {{ item }}"
-  with_items:
-    - headers
-    - ssl
+  template:
+    src: "etc/php-fpm/pool.d/icinga.conf"
+    dest: "/etc/php/7.0/fpm/pool.d/{{ icinga_web_phpfpm_pool_name }}.conf"
+    owner: root
+    group: adm
+    mode: "644"
+    validate: php-fpm7.0 --test --fpm-config %s
 
-- name: Copying Apache2 config file
+- name: "Restarting PHP-FPM service"
+  become: yes
+  service:
+    name: php7.0-fpm
+    state: restarted
+
+- name: "Copying Nginx config file"
   become: yes
   template:
-    src: "etc/apache2/sites-enabled/icinga2web.conf"
-    dest: "/etc/apache2/sites-enabled/icinga2web.conf"
-    owner: "root"
-    group: "root"
+    src: "etc/nginx/sites-enabled/icingaweb2.conf"
+    dest: "/etc/nginx/sites-enabled/{{ icinga_domain }}.conf"
+    owner: www-data
+    group: adm
     mode: "644"
-    validate: apachectl configtest
+    validate: bash -c 'nginx -t -c /dev/stdin <<< "events {worker_connections 1;} http { include %s; }"'
   notify:
-    - Restarting Apache2 server
+    - "Restarting Nginx server"
 
+- name: "Restarting Nginx server"
+  become: yes
+  service:
+    name: nginx
+    state: restarted
diff --git a/tasks/install-icinga.yml b/tasks/install-icinga.yml
index 6dd7d2d08270dd8dfd4462c5fafca052f6cf9f28..f530e120be8529f0f928742be32584450c8e9a1a 100644
--- a/tasks/install-icinga.yml
+++ b/tasks/install-icinga.yml
@@ -1,5 +1,5 @@
 ---
-- name: Importing apt repository keys
+- name: "Importing apt repository keys"
   become: yes
   apt_key:
     url: "{{ item.gpg }}"
@@ -7,7 +7,7 @@
   with_items:
     - "{{ icinga_apt_repositories }}"
 
-- name: Adding apt repositories
+- name: "Adding apt repositories"
   become: yes
   apt_repository:
     repo: "deb {{ item.url }}"
@@ -16,37 +16,80 @@
   with_items:
     - "{{ icinga_apt_repositories }}"
 
-- name: Installing Icinga packages
+- name: "Installing Icinga packages"
   become: yes
   package:
-    name: "{{ item }}"
+    name: ['icinga2', 'monitoring-plugins', 'vim-icinga2']
     state: present
     update_cache: yes
-  with_items:
-    - icinga2
-    - monitoring-plugins
-    - vim-icinga2
   notify:
-    - Restarting Icinga server
+    - "Restarting Icinga server"
 
-- name: Creating domain config directory
+- name: "Creating domain config directory"
   become: yes
   file:
     path: "{{ icinga_config_domain_path }}"
     state: directory
     owner: "root"
-    group: "{{ icinga_group }}"
+    group: "{{ icinga_daemon_group }}"
     mode: "0750"
   notify:
     - Restarting Icinga server
 
-- name: Copying config files
+- name: "Creating SSL certificates directory"
+  become: yes
+  file:
+    path: "{{ icinga_ssl_certs_path }}"
+    state: directory
+    owner: "{{ icinga_daemon_user }}"
+    group: "{{ icinga_daemon_group }}"
+    mode: "0700"
+  notify:
+    - Restarting Icinga server
+
+- name: "Copying SSL certificates to Icinga directory"
+  become: yes
+  copy:
+    remote_src: yes
+    src: "{{ item.src }}"
+    dest: "{{ icinga_ssl_certs_path }}/{{ item.dest }}"
+    owner: "{{ icinga_daemon_user }}"
+    group: "{{ icinga_daemon_group }}"
+    mode: "0400"
+  with_items:
+    - src: "{{ icinga_ssl_cert_path }}"
+      dest: "ca.crt"
+    - src: "{{ icinga_ssl_cert_path }}"
+      dest: "{{ ansible_hostname }}.crt"
+    - src: "{{ icinga_ssl_key_path }}"
+      dest: "{{ ansible_hostname }}.key"
+  notify:
+    - Restarting Icinga server
+
+- name: "Deleting old config files (if exists)"
+  file:
+    path: "{{ icinga_config_domain_path }}/{{ item }}"
+    state: absent
+  with_items:
+    - app.conf
+    - apt.conf
+    - commands.conf
+    - downtimes.conf
+    - groups.conf
+    - hosts.conf
+    - notifications.conf
+    - services.conf
+    - templates.conf
+    - timeperiods.conf
+    - users.conf
+
+- name: "Copying config files"
   become: yes
   template:
     src: "{{ item.src }}"
     dest: "{{ item.dest }}"
     owner: "root"
-    group: "{{ icinga_group }}"
+    group: "{{ icinga_daemon_group }}"
     mode: "{{ item.mode | default('0640') }}"
   with_items:
     - src: "etc/icinga2/constants.conf"
@@ -85,4 +128,4 @@
     - src: "etc/icinga2/conf.d/use-timeperiods.conf"
       dest: "{{ icinga_config_domain_path }}"
   notify:
-    - Restarting Icinga server
+    - "Restarting Icinga server"
diff --git a/tasks/main.yml b/tasks/main.yml
index 604405316c35c38a2f3c45bf10329024dfc0fd48..78ee1284115c507e75c7b25ef7399af8a1f747f9 100644
--- a/tasks/main.yml
+++ b/tasks/main.yml
@@ -1,27 +1,38 @@
 ---
-# Tasks orchestrator
-# Don't add tasks here directly!
-
-- name: Validating parameters
+- name: Validating parameters4
   import_tasks: validate.yml
 
-#- name: Installing Icinga server
-#  import_tasks: install-icinga.yml
-
-#- name: Generating SSL certs
-#  import_tasks: generate-ssl-certs.yml
+- name: Generating SSL certs
+  import_tasks: "generate-ssl-certs-{{ icinga_ssl_provider | lower }}.yml"
 
-#- name: Installing Icinga database
-#  include_tasks: "configure-db-{{ icinga_db_driver | lower }}.yml"
+- name: Installing Icinga server
+  import_tasks: install-icinga.yml
 
-#- name: Installing Icinga REST API
-#  import_tasks: install-icinga-api.yml
-#  when: icinga_api_enabled | bool
+- name: Installing Icinga database
+  include_tasks: "configure-db-{{ icinga_db_driver | lower }}.yml"
 
-#- name: Installing Icinga web database
-#  include_tasks: "configure-db-web-{{ icinga_web_db_driver | lower }}.yml"
+- name: Installing Icinga REST API
+  import_tasks: install-icinga-api.yml
+  when: icinga_api_enabled | bool
 
 - name: Installing Icinga web
   import_tasks: install-icinga-web.yml
   when: icinga_web_enabled | bool
 
+- name: Preparing Icinga web database
+  include_tasks: "configure-db-web.yml"
+
+- name: Installing Icinga web database
+  include_tasks: "configure-db-web-{{ icinga_web_db_driver | lower }}.yml"
+
+- name: Sending deploy notifications
+  import_tasks: send-notifications.yml
+  when:
+  - not TEST_ENV
+  - icinga_pushover_notify_after_role_deploy
+
+- name: Flushing current role handlers before next role execution
+  meta: flush_handlers
+
+- name: Showing deploy summary
+  import_tasks: showing-deploy-summary.yml
diff --git a/tasks/send-notifications.yml b/tasks/send-notifications.yml
new file mode 100644
index 0000000000000000000000000000000000000000..cd75f107302b7e0bc69fe83e8bca7b7f7749f184
--- /dev/null
+++ b/tasks/send-notifications.yml
@@ -0,0 +1,8 @@
+---
+- name: "Sending notifications (to test alarms)"
+  run_once: true
+  local_action:
+    module: pushover
+    msg: "New version of the vandalsWeb Icinga service has been deployed!"
+    app_token: "{{ icinga_pushover_appkey }}"
+    user_key: "{{ icinga_pushover_userkey }}"
diff --git a/tasks/showing-deploy-summary.yml b/tasks/showing-deploy-summary.yml
new file mode 100644
index 0000000000000000000000000000000000000000..7e4c0019808446deaf0f01938ece6b4d5782db40
--- /dev/null
+++ b/tasks/showing-deploy-summary.yml
@@ -0,0 +1,10 @@
+---
+- name: "Ending role"
+  debug:
+    msg:
+      - "> First installation of Icinga packages is complete!"
+      - "> You can access Icinga Web in https://{{ icinga_domain }} using this login:"
+      - "> Username: {{ icinga_web_admin_user }}"
+      - "> Password: {{ icingaweb2_generated_password }}"
+  when:
+    - dbwebcreation.changed
diff --git a/tasks/validate.yml b/tasks/validate.yml
index fd3baf00391359660337b3b55a98fec08104ff0b..6373056e1d64d4b14a0b326d17d24fa05547a3c5 100644
--- a/tasks/validate.yml
+++ b/tasks/validate.yml
@@ -1,42 +1,66 @@
 ---
-- name: Checking server OS
-  fail:
-    msg: "The server OS is not supported: {{ ansible_distribution }}."
-  when:
-    - ansible_distribution not in icinga_supported_distributions
+- name: "Checking server OS"
+  assert:
+    that:
+      - ansible_distribution in icinga_supported_distributions
+    msg: "The server OS is not supported: {{ ansible_distribution }}"
 
-- name: "Checking required variables"
+- name: "Checking Icinga required variables"
   run_once: true
-  fail:
-    msg: "You have to configure {{ item }}_variable! See README.md."
-  when:
-    - item not in vars
-  with_items:
-    - icinga_db_username
-    - icinga_db_password
+  local_action:
+    module: assert
+    that:
+      - "icinga_db_username | default(false,true)"
+      - "icinga_db_password | default(false,true)"
+      - "icinga_db_port | default(false,true)"
+    msg: "You have to configure some required variables! See README.md"
 
-- name: "Checking Icinga web URL"
+- name: "Checking SSL provider"
   run_once: true
-  fail:
-    msg: "You have to configure {{ item }}_variable! See README.md."
-  when:
-    - item not in vars and icinga_web_enabled | bool
-  with_items:
-    - icinga_web_url
+  local_action:
+    module: assert
+    that:
+      - "(icinga_ssl_provider | lower == 'openssl') or (icinga_ssl_provider | lower == 'letsencrypt')"
+    msg: "Wrong value defined in icinga_ssl_provider variable. Must be \"openssl\" or \"letsencrypt\"."
 
-- name: "Checking Icinga database driver"
+- name: "Checking Icinga DB driver"
   run_once: true
-  fail:
-    msg: "Wrong database value in icinga_db_driver variable. Must be \"mysql\" or \"postgresql\"."
+  local_action:
+    module: assert
+    that:
+      - "icinga_api_enabled"
+    msg: "You need enable Icinca API to install Icinca Web! See README.md"
   when:
-    - icinga_db_driver | lower != 'mysql'
-    - icinga_db_driver | lower != 'postgresql'
+    - icinga_web_enabled | bool
 
-- name: "Checking Icinga web database driver"
+- name: "Checking Icinga web DB driver"
   run_once: true
-  fail:
-    msg: "Wrong database value in icinga_web_db_driver variable. Must be \"mysql\" or \"postgresql\"."
+  local_action:
+    module: assert
+    that:
+      - "(icinga_db_driver | lower == 'mysql') or (icinga_db_driver | lower == 'pgsql')"
+    msg: "Wrong value defined in icinga_db_driver variable. Must be \"mysql\" or \"pgsql\"."
+
+- name: "Checking Icinga web required variables"
+  run_once: true
+  local_action:
+    module: assert
+    that:
+      - "(icinga_web_db_driver | lower == 'mysql') or (icinga_web_db_driver | lower == 'pgsql')"
+      - "icinga_web_db_username | default(false,true)"
+      - "icinga_web_db_password | default(false,true)"
+      - "icinga_web_db_port | default(false,true)"
+    msg: "You have to configure some required variables! See README.md"
   when:
     - icinga_web_enabled | bool
-    - icinga_web_db_driver | lower != 'mysql'
-    - icinga_web_db_driver | lower != 'postgresql'
+
+- name: "Checking Pushover required variables"
+  run_once: true
+  local_action:
+    module: assert
+    that:
+      - "icinga_pushover_userkey | default(false,true)"
+      - "icinga_pushover_appkey | default(false,true)"
+    msg: "You have to configure some required variables! See README.md"
+  when:
+    - (icinga_pushover_enabled | bool) or (icinga_pushover_notify_after_role_deploy | bool)
diff --git a/templates/etc/apache2/sites-enabled/icinga2web.conf b/templates/etc/apache2/sites-enabled/icinga2web.conf
deleted file mode 100644
index 75ef83dc4e33f61bf6a86ad21803572fac820a97..0000000000000000000000000000000000000000
--- a/templates/etc/apache2/sites-enabled/icinga2web.conf
+++ /dev/null
@@ -1,49 +0,0 @@
-# http://monitor.vandalsweb.com
-<VirtualHost _default_:80>
-
-	ServerAdmin admin@vandalsweb.com
-	DocumentRoot /var/www/html
-
-	ServerName monitor.vandalsweb.com
-
-	RewriteEngine On
-	RewriteCond %{HTTPS} !=on
-	RewriteRule ^\/(.*)$ https://monitor.vandalsweb.com/icingaweb2/$1 [R=301,L]
-
-	ErrorLog /var/log/apache2/icinga2/error.log
-	CustomLog /var/log/apache2/icinga2/access.log combined
-
-</VirtualHost>
-
-# https://monitor.vandalsweb.com
-<VirtualHost _default_:443>
-
-	ServerAdmin admin@vandalsweb.com
-	DocumentRoot /var/www/html
-
-	ServerName monitor.vandalsweb.com
-
-	RewriteEngine On
-	RewriteCond %{REQUEST_URI} !^\/icingaweb2 [NC]
-	RewriteRule ^\/(.*)$ https://monitor.vandalsweb.com/icingaweb2/$1 [R=301,L]
-
-	ErrorLog /var/log/apache2/icinga2/error.log
-	CustomLog /var/log/apache2/icinga2/access.log combined
-
-	LogLevel warn
-
-	# Force browsers to use always SSL (Apache headers module required)
-	Header always add Strict-Transport-Security "max-age=15768000"
-
-	<Directory />
-		Options -Indexes
-	</Directory>
-
-	SSLEngine On
-	SSLProtocol All -SSLv2 -SSLv3
-	SSLCertificateFile /etc/letsencrypt/live/sandra.vandalsweb.com/fullchain.pem
-	SSLCertificateKeyFile /etc/letsencrypt/live/sandra.vandalsweb.com/privkey.pem
-
-	SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown downgrade-1.0 force-response-1.0
-
-</VirtualHost>
diff --git a/templates/etc/icinga2/conf.d/definition-commands.conf b/templates/etc/icinga2/conf.d/definition-commands.conf
index 4b893f9de9c849e6941416d3a83de73c42a4abfb..fa7971342b8a2fb6580062d0eba621c3453b7d36 100644
--- a/templates/etc/icinga2/conf.d/definition-commands.conf
+++ b/templates/etc/icinga2/conf.d/definition-commands.conf
@@ -132,6 +132,7 @@ object NotificationCommand "mail-service-notification" {
   }
 }
 
+{% if icinga_pushover_enabled | bool %}
 object NotificationCommand "pushover-host-notification" {
   import "plugin-notification-command"
 
@@ -157,3 +158,4 @@ object NotificationCommand "pushover-service-notification" {
     PUSHOVERMESSAGE = "$notification.type$ $host.display_name$ $service.display_name$ $service.state$ $icinga.long_date_time$"
   }
 }
+{% endif %}
diff --git a/templates/etc/icinga2/conf.d/definition-templates.conf b/templates/etc/icinga2/conf.d/definition-templates.conf
index 083276b4de525c692735f02cc9cacb011c0cae07..07a60693923ad8ac4003dc3ff235a6207a189279 100644
--- a/templates/etc/icinga2/conf.d/definition-templates.conf
+++ b/templates/etc/icinga2/conf.d/definition-templates.conf
@@ -82,6 +82,7 @@ template Notification "mail-service-notification" {
   }
 }
 
+{% if icinga_pushover_enabled | bool %}
 /**
  * Provices default settings for host notifications using
  * the Pushover push notification service.
@@ -94,7 +95,7 @@ template Notification "pushover-host-notification" {
   period = "24x7"
 
   vars += {
-    pushover_token = "a9tjx5zot31nvp9u6dygf95wymjips"
+    pushover_token = "{{ icinga_pushover_appkey }}"
   }
 }
 
@@ -113,3 +114,4 @@ template Notification "pushover-service-notification" {
     pushover_token = "a9tjx5zot31nvp9u6dygf95wymjips"
   }
 }
+{% endif %}
diff --git a/templates/etc/icinga2/conf.d/definition-users.conf b/templates/etc/icinga2/conf.d/definition-users.conf
index f16c2d2dc35d1b3ae595fc37534e19453c15a58d..8f6d24be5eae38b8d59cf6e292b3e59abd8118ab 100644
--- a/templates/etc/icinga2/conf.d/definition-users.conf
+++ b/templates/etc/icinga2/conf.d/definition-users.conf
@@ -15,6 +15,6 @@ object User "bhean" {
   period = "24x7"
 
   vars += {
-    pushover_user = "unoj1tqwh321wqwokp67pfzwbcfcm3"
+{% if icinga_pushover_enabled | bool %}pushover_user = "{{ icinga_pushover_userkey }}"{% endif %}
   }
 }
diff --git a/templates/etc/icinga2/conf.d/use-notifications.conf b/templates/etc/icinga2/conf.d/use-notifications.conf
index b4a37b2e94d63164bc51b551034af31f121544f7..105912b89c37d48e537b3719b51b8bdcac45c6ce 100644
--- a/templates/etc/icinga2/conf.d/use-notifications.conf
+++ b/templates/etc/icinga2/conf.d/use-notifications.conf
@@ -26,6 +26,7 @@ apply Notification "mail-notify" to Service {
   assign where host.vars.notification.mail
 }
 
+{% if icinga_pushover_enabled | bool %}
 apply Notification "pushover-notify" to Host {
   import "pushover-host-notification"
   user_groups = host.vars.notification.mail.groups
@@ -47,3 +48,4 @@ apply Notification "pushover-notify" to Service {
 
   assign where host.vars.notification.mail
 }
+{% endif %}
diff --git a/templates/etc/icinga2/constants.conf b/templates/etc/icinga2/constants.conf
index 039440273e81df8b923358812c431169980fcc41..f8d5c7e299a43f69bb8f54c4e8ebfefb3dbaf15c 100644
--- a/templates/etc/icinga2/constants.conf
+++ b/templates/etc/icinga2/constants.conf
@@ -26,7 +26,7 @@ const PluginContribDir = "{{ icinga_plugin_contrib_path }}"
 const TicketSalt = ""
 
 /* URL of the Icinga Web 2 */
-const IcingaWeb2Url = "{{ icinga_web_url }}"
+const IcingaWeb2Url = ""
 
 /* Email notification settings */
 const NotificationFromEmail = "{{ icinga_notification_from_email }}"
diff --git a/templates/etc/icinga2/zones.conf b/templates/etc/icinga2/zones.conf
index de2e7b9664483192455866a17b5d4a592c70b961..c81fe9a87bd48a57ca3f0bdf61bf9ab3749e50e3 100644
--- a/templates/etc/icinga2/zones.conf
+++ b/templates/etc/icinga2/zones.conf
@@ -10,12 +10,12 @@
  * constants.conf.
  */
 
-object Endpoint "{{ ansible_hostname }}" {
+object Endpoint "{{ icinga_domain }}" {
   host = "{{ ansible_hostname }}"
 }
 
 object Zone "{{ ansible_hostname }}" {
-  endpoints = [ "{{ ansible_hostname }}" ]
+  endpoints = [ "{{ icinga_domain }}" ]
 }
 
 /*
diff --git a/templates/etc/icingaweb2/authentication.ini b/templates/etc/icingaweb2/authentication.ini
new file mode 100644
index 0000000000000000000000000000000000000000..3ac8dca5908bd8aad0f6a3fe6d880988d8aa7d80
--- /dev/null
+++ b/templates/etc/icingaweb2/authentication.ini
@@ -0,0 +1,7 @@
+{% for headerline in icinga_template_header %}
+; {{ headerline }}
+{% endfor %}
+
+[icingaweb2]
+backend = "db"
+resource = "icingaweb_db"
\ No newline at end of file
diff --git a/templates/etc/icingaweb2/config.ini b/templates/etc/icingaweb2/config.ini
new file mode 100644
index 0000000000000000000000000000000000000000..e2a2c015a270bb1a6c5c4d1c2315ea65e6bbc1ea
--- /dev/null
+++ b/templates/etc/icingaweb2/config.ini
@@ -0,0 +1,15 @@
+{% for headerline in icinga_template_header %}
+; {{ headerline }}
+{% endfor %}
+
+[global]
+show_stacktraces = "1"
+show_application_state_messages = "1"
+config_backend = "db"
+config_resource = "icingaweb_db"
+
+[logging]
+log = "syslog"
+level = "ERROR"
+application = "icingaweb2"
+facility = "user"
diff --git a/templates/etc/icingaweb2/groups.ini b/templates/etc/icingaweb2/groups.ini
new file mode 100644
index 0000000000000000000000000000000000000000..b3495f66fa35f0ad987b6829ab5654893c5cfb3e
--- /dev/null
+++ b/templates/etc/icingaweb2/groups.ini
@@ -0,0 +1,7 @@
+{% for headerline in icinga_template_header %}
+; {{ headerline }}
+{% endfor %}
+
+[icingaweb2]
+backend = "db"
+resource = "icingaweb_db"
diff --git a/templates/etc/icingaweb2/resources.ini b/templates/etc/icingaweb2/resources.ini
new file mode 100644
index 0000000000000000000000000000000000000000..42108983d592cbfaffa4a9c92eb8d03d393c27fc
--- /dev/null
+++ b/templates/etc/icingaweb2/resources.ini
@@ -0,0 +1,25 @@
+{% for headerline in icinga_template_header %}
+; {{ headerline }}
+{% endfor %}
+
+[icingaweb_db]
+type = "db"
+db = "{{ icinga_web_db_driver }}"
+host = "{{ icinga_web_db_host }}"
+port = "{{ icinga_web_db_port }}"
+dbname = "{{ icinga_web_db_dbname }}"
+username = "{{ icinga_web_db_username }}"
+password = "{{ icinga_web_db_password }}"
+charset = "UTF8"
+use_ssl = "0"
+
+[icinga_ido]
+type = "db"
+db = "{{ icinga_web_db_driver }}"
+host = "{{ icinga_web_db_host }}"
+port = "{{ icinga_web_db_port }}"
+dbname = "{{ icinga_web_db_dbname }}"
+username = "{{ icinga_web_db_username }}"
+password = "{{ icinga_web_db_password }}"
+charset = "UTF8"
+use_ssl = "0"
\ No newline at end of file
diff --git a/templates/etc/icingaweb2/roles.ini b/templates/etc/icingaweb2/roles.ini
new file mode 100644
index 0000000000000000000000000000000000000000..b6ce5c1bd7db273a034886adf7d584f1b14fd318
--- /dev/null
+++ b/templates/etc/icingaweb2/roles.ini
@@ -0,0 +1,8 @@
+{% for headerline in icinga_template_header %}
+; {{ headerline }}
+{% endfor %}
+
+[Administrators]
+users = "{{ icinga_web_admin_user }}"
+permissions = "*"
+groups = "Administrators"
\ No newline at end of file
diff --git a/templates/etc/nginx/sites-enabled/icingaweb2.conf b/templates/etc/nginx/sites-enabled/icingaweb2.conf
new file mode 100644
index 0000000000000000000000000000000000000000..abe0701430c9a3e094d90a59955c104638c5b7ce
--- /dev/null
+++ b/templates/etc/nginx/sites-enabled/icingaweb2.conf
@@ -0,0 +1,55 @@
+{% for headerline in icinga_template_header %}
+# {{ headerline }}
+{% endfor %}
+
+server {
+	listen 80;
+	server_name {{ icinga_domain }};
+
+	return 301 https://$host$request_uri;
+}
+
+server {
+
+	listen 443 ssl http2;
+	server_name {{ icinga_domain }};
+
+	root /usr/share/icingaweb2/public;
+	index index.php index.html index.htm;
+
+	ssl_certificate {{ icinga_ssl_cert_path }};
+	ssl_certificate_key {{ icinga_ssl_key_path }};
+	ssl_protocols TLSv1.1 TLSv1.2;
+	ssl_ciphers HIGH:!aNULL:!MD5;
+
+	access_log {{ icinga_web_logs_path }}/access.log;
+	error_log {{ icinga_web_logs_path }}/error.log;
+
+{% if icinga_ssl_provider | lower == 'letsencrypt' %}
+	# Allow access to the ACME Challenge for domain verification
+	location ^~ /.well-known/acme-challenge {
+		allow all;
+		alias {{ icinga_ssl_letsencrypt_webroot_path }};
+
+		access_log {{ icinga_ssl_letsencrypt_logs_path }}/web-access.log;
+		error_log {{ icinga_ssl_letsencrypt_logs_path }}/web-error.log;
+	}
+
+{% endif %}
+	location ~ ^/index\.php(.*)$ {
+		#fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
+	    fastcgi_pass {{ icinga_web_phpfpm_pass }};
+	    fastcgi_index index.php;
+	    include /etc/nginx/fastcgi_params;
+	    fastcgi_param SCRIPT_FILENAME /usr/share/icingaweb2/public/index.php;
+	    fastcgi_param ICINGAWEB_CONFIGDIR {{ icinga_web_config_path }};
+	    fastcgi_param REMOTE_USER $remote_user;
+	  }
+
+	  location ~ ^/(.+)? {
+	    rewrite ^/$ /authentication/login;
+	    alias /usr/share/icingaweb2/public;
+	    index index.php;
+	    try_files $1 $uri $uri/ /index.php$is_args$args;
+	  }
+}
diff --git a/templates/etc/nginx/sites-enabled/letsencrypt.conf b/templates/etc/nginx/sites-enabled/letsencrypt.conf
new file mode 100644
index 0000000000000000000000000000000000000000..b0341b45006611f2e1e38b0c1f9444676391cc4a
--- /dev/null
+++ b/templates/etc/nginx/sites-enabled/letsencrypt.conf
@@ -0,0 +1,14 @@
+{% for headerline in icinga_template_header %}
+# {{ headerline }}
+{% endfor %}
+
+server {
+	listen 80;
+	server_name {{ icinga_domain }};
+
+	root {{ icinga_ssl_letsencrypt_webroot_path }};
+	index index.php index.html index.htm;
+
+	access_log {{ icinga_ssl_letsencrypt_logs_path }}/web-access.log;
+	error_log {{ icinga_ssl_letsencrypt_logs_path }}/web-error.log;
+}
diff --git a/templates/etc/php-fpm/pool.d/icinga.conf b/templates/etc/php-fpm/pool.d/icinga.conf
new file mode 100644
index 0000000000000000000000000000000000000000..591c3313d294c8f7819c4ba0e8c58d539341813f
--- /dev/null
+++ b/templates/etc/php-fpm/pool.d/icinga.conf
@@ -0,0 +1,419 @@
+{% for headerline in icinga_template_header %}
+; {{ headerline }}
+{% endfor %}
+
+; Start a new pool named '{{ icinga_web_phpfpm_pool_name }}'.
+; the variable $pool can be used in any directive and will be replaced by the
+; pool name ('{{ icinga_web_phpfpm_pool_name }}' here)
+["{{ icinga_web_phpfpm_pool_name }}"]
+
+; Per pool prefix
+; It only applies on the following directives:
+; - 'access.log'
+; - 'slowlog'
+; - 'listen' (unixsocket)
+; - 'chroot'
+; - 'chdir'
+; - 'php_values'
+; - 'php_admin_values'
+; When not set, the global prefix (or /usr) applies instead.
+; Note: This directive can also be relative to the global prefix.
+; Default Value: none
+;prefix = /path/to/pools/$pool
+
+; Unix user/group of processes
+; Note: The user is mandatory. If the group is not set, the default user's group
+;       will be used.
+user = www-data
+group = www-data
+
+; The address on which to accept FastCGI requests.
+; Valid syntaxes are:
+;   'ip.add.re.ss:port'    - to listen on a TCP socket to a specific IPv4 address on
+;                            a specific port;
+;   '[ip:6:addr:ess]:port' - to listen on a TCP socket to a specific IPv6 address on
+;                            a specific port;
+;   'port'                 - to listen on a TCP socket to all addresses
+;                            (IPv6 and IPv4-mapped) on a specific port;
+;   '/path/to/unix/socket' - to listen on a unix socket.
+; Note: This value is mandatory.
+;listen = /var/run/php5-fpm.sock
+listen = "{{ icinga_web_phpfpm_pass }}"
+
+; Set listen(2) backlog.
+; Default Value: 511 (-1 on FreeBSD and OpenBSD)
+;listen.backlog = 511
+
+; Set permissions for unix socket, if one is used. In Linux, read/write
+; permissions must be set in order to allow connections from a web server. Many
+; BSD-derived systems allow connections regardless of permissions.
+; Default Values: user and group are set as the running user
+;                 mode is set to 0660
+listen.owner = www-data
+listen.group = www-data
+;listen.mode = 0660
+; When POSIX Access Control Lists are supported you can set them using
+; these options, value is a comma separated list of user/group names.
+; When set, listen.owner and listen.group are ignored
+;listen.acl_users =
+;listen.acl_groups =
+
+; List of addresses (IPv4/IPv6) of FastCGI clients which are allowed to connect.
+; Equivalent to the FCGI_WEB_SERVER_ADDRS environment variable in the original
+; PHP FCGI (5.2.2+). Makes sense only with a tcp listening socket. Each address
+; must be separated by a comma. If this value is left blank, connections will be
+; accepted from any ip address.
+; Default Value: any
+;listen.allowed_clients = 127.0.0.1
+
+; Specify the nice(2) priority to apply to the pool processes (only if set)
+; The value can vary from -19 (highest priority) to 20 (lower priority)
+; Note: - It will only work if the FPM master process is launched as root
+;       - The pool processes will inherit the master process priority
+;         unless it specified otherwise
+; Default Value: no set
+; process.priority = -19
+
+; Set the process dumpable flag (PR_SET_DUMPABLE prctl) even if the process user
+; or group is differrent than the master process user. It allows to create process
+; core dump and ptrace the process for the pool user.
+; Default Value: no
+; process.dumpable = yes
+
+; Choose how the process manager will control the number of child processes.
+; Possible Values:
+;   static  - a fixed number (pm.max_children) of child processes;
+;   dynamic - the number of child processes are set dynamically based on the
+;             following directives. With this process management, there will be
+;             always at least 1 children.
+;             pm.max_children      - the maximum number of children that can
+;                                    be alive at the same time.
+;             pm.start_servers     - the number of children created on startup.
+;             pm.min_spare_servers - the minimum number of children in 'idle'
+;                                    state (waiting to process). If the number
+;                                    of 'idle' processes is less than this
+;                                    number then some children will be created.
+;             pm.max_spare_servers - the maximum number of children in 'idle'
+;                                    state (waiting to process). If the number
+;                                    of 'idle' processes is greater than this
+;                                    number then some children will be killed.
+;  ondemand - no children are created at startup. Children will be forked when
+;             new requests will connect. The following parameter are used:
+;             pm.max_children           - the maximum number of children that
+;                                         can be alive at the same time.
+;             pm.process_idle_timeout   - The number of seconds after which
+;                                         an idle process will be killed.
+; Note: This value is mandatory.
+pm = dynamic
+
+; The number of child processes to be created when pm is set to 'static' and the
+; maximum number of child processes when pm is set to 'dynamic' or 'ondemand'.
+; This value sets the limit on the number of simultaneous requests that will be
+; served. Equivalent to the ApacheMaxClients directive with mpm_prefork.
+; Equivalent to the PHP_FCGI_CHILDREN environment variable in the original PHP
+; CGI. The below defaults are based on a server without much resources. Don't
+; forget to tweak pm.* to fit your needs.
+; Note: Used when pm is set to 'static', 'dynamic' or 'ondemand'
+; Note: This value is mandatory.
+pm.max_children = 5
+
+; The number of child processes created on startup.
+; Note: Used only when pm is set to 'dynamic'
+; Default Value: min_spare_servers + (max_spare_servers - min_spare_servers) / 2
+pm.start_servers = 2
+
+; The desired minimum number of idle server processes.
+; Note: Used only when pm is set to 'dynamic'
+; Note: Mandatory when pm is set to 'dynamic'
+pm.min_spare_servers = 1
+
+; The desired maximum number of idle server processes.
+; Note: Used only when pm is set to 'dynamic'
+; Note: Mandatory when pm is set to 'dynamic'
+pm.max_spare_servers = 3
+
+; The number of seconds after which an idle process will be killed.
+; Note: Used only when pm is set to 'ondemand'
+; Default Value: 10s
+;pm.process_idle_timeout = 10s;
+
+; The number of requests each child process should execute before respawning.
+; This can be useful to work around memory leaks in 3rd party libraries. For
+; endless request processing specify '0'. Equivalent to PHP_FCGI_MAX_REQUESTS.
+; Default Value: 0
+;pm.max_requests = 500
+
+; The URI to view the FPM status page. If this value is not set, no URI will be
+; recognized as a status page. It shows the following informations:
+;   pool                 - the name of the pool;
+;   process manager      - static, dynamic or ondemand;
+;   start time           - the date and time FPM has started;
+;   start since          - number of seconds since FPM has started;
+;   accepted conn        - the number of request accepted by the pool;
+;   listen queue         - the number of request in the queue of pending
+;                          connections (see backlog in listen(2));
+;   max listen queue     - the maximum number of requests in the queue
+;                          of pending connections since FPM has started;
+;   listen queue len     - the size of the socket queue of pending connections;
+;   idle processes       - the number of idle processes;
+;   active processes     - the number of active processes;
+;   total processes      - the number of idle + active processes;
+;   max active processes - the maximum number of active processes since FPM
+;                          has started;
+;   max children reached - number of times, the process limit has been reached,
+;                          when pm tries to start more children (works only for
+;                          pm 'dynamic' and 'ondemand');
+; Value are updated in real time.
+; Example output:
+;   pool:                 www
+;   process manager:      static
+;   start time:           01/Jul/2011:17:53:49 +0200
+;   start since:          62636
+;   accepted conn:        190460
+;   listen queue:         0
+;   max listen queue:     1
+;   listen queue len:     42
+;   idle processes:       4
+;   active processes:     11
+;   total processes:      15
+;   max active processes: 12
+;   max children reached: 0
+;
+; By default the status page output is formatted as text/plain. Passing either
+; 'html', 'xml' or 'json' in the query string will return the corresponding
+; output syntax. Example:
+;   http://www.foo.bar/status
+;   http://www.foo.bar/status?json
+;   http://www.foo.bar/status?html
+;   http://www.foo.bar/status?xml
+;
+; By default the status page only outputs short status. Passing 'full' in the
+; query string will also return status for each pool process.
+; Example:
+;   http://www.foo.bar/status?full
+;   http://www.foo.bar/status?json&full
+;   http://www.foo.bar/status?html&full
+;   http://www.foo.bar/status?xml&full
+; The Full status returns for each process:
+;   pid                  - the PID of the process;
+;   state                - the state of the process (Idle, Running, ...);
+;   start time           - the date and time the process has started;
+;   start since          - the number of seconds since the process has started;
+;   requests             - the number of requests the process has served;
+;   request duration     - the duration in µs of the requests;
+;   request method       - the request method (GET, POST, ...);
+;   request URI          - the request URI with the query string;
+;   content length       - the content length of the request (only with POST);
+;   user                 - the user (PHP_AUTH_USER) (or '-' if not set);
+;   script               - the main script called (or '-' if not set);
+;   last request cpu     - the %cpu the last request consumed
+;                          it's always 0 if the process is not in Idle state
+;                          because CPU calculation is done when the request
+;                          processing has terminated;
+;   last request memory  - the max amount of memory the last request consumed
+;                          it's always 0 if the process is not in Idle state
+;                          because memory calculation is done when the request
+;                          processing has terminated;
+; If the process is in Idle state, then informations are related to the
+; last request the process has served. Otherwise informations are related to
+; the current request being served.
+; Example output:
+;   ************************
+;   pid:                  31330
+;   state:                Running
+;   start time:           01/Jul/2011:17:53:49 +0200
+;   start since:          63087
+;   requests:             12808
+;   request duration:     1250261
+;   request method:       GET
+;   request URI:          /test_mem.php?N=10000
+;   content length:       0
+;   user:                 -
+;   script:               /home/fat/web/docs/php/test_mem.php
+;   last request cpu:     0.00
+;   last request memory:  0
+;
+; Note: There is a real-time FPM status monitoring sample web page available
+;       It's available in: /usr/share/php/7.0/fpm/status.html
+;
+; Note: The value must start with a leading slash (/). The value can be
+;       anything, but it may not be a good idea to use the .php extension or it
+;       may conflict with a real PHP file.
+; Default Value: not set
+pm.status_path = /status
+
+; The ping URI to call the monitoring page of FPM. If this value is not set, no
+; URI will be recognized as a ping page. This could be used to test from outside
+; that FPM is alive and responding, or to
+; - create a graph of FPM availability (rrd or such);
+; - remove a server from a group if it is not responding (load balancing);
+; - trigger alerts for the operating team (24/7).
+; Note: The value must start with a leading slash (/). The value can be
+;       anything, but it may not be a good idea to use the .php extension or it
+;       may conflict with a real PHP file.
+; Default Value: not set
+;ping.path = /ping
+
+; This directive may be used to customize the response of a ping request. The
+; response is formatted as text/plain with a 200 response code.
+; Default Value: pong
+;ping.response = pong
+
+; The access log file
+; Default: not set
+access.log = "{{ icinga_web_logs_path }}/php-fpm-access.log"
+
+; The access log format.
+; The following syntax is allowed
+;  %%: the '%' character
+;  %C: %CPU used by the request
+;      it can accept the following format:
+;      - %{user}C for user CPU only
+;      - %{system}C for system CPU only
+;      - %{total}C  for user + system CPU (default)
+;  %d: time taken to serve the request
+;      it can accept the following format:
+;      - %{seconds}d (default)
+;      - %{miliseconds}d
+;      - %{mili}d
+;      - %{microseconds}d
+;      - %{micro}d
+;  %e: an environment variable (same as $_ENV or $_SERVER)
+;      it must be associated with embraces to specify the name of the env
+;      variable. Some exemples:
+;      - server specifics like: %{REQUEST_METHOD}e or %{SERVER_PROTOCOL}e
+;      - HTTP headers like: %{HTTP_HOST}e or %{HTTP_USER_AGENT}e
+;  %f: script filename
+;  %l: content-length of the request (for POST request only)
+;  %m: request method
+;  %M: peak of memory allocated by PHP
+;      it can accept the following format:
+;      - %{bytes}M (default)
+;      - %{kilobytes}M
+;      - %{kilo}M
+;      - %{megabytes}M
+;      - %{mega}M
+;  %n: pool name
+;  %o: output header
+;      it must be associated with embraces to specify the name of the header:
+;      - %{Content-Type}o
+;      - %{X-Powered-By}o
+;      - %{Transfert-Encoding}o
+;      - ....
+;  %p: PID of the child that serviced the request
+;  %P: PID of the parent of the child that serviced the request
+;  %q: the query string
+;  %Q: the '?' character if query string exists
+;  %r: the request URI (without the query string, see %q and %Q)
+;  %R: remote IP address
+;  %s: status (response code)
+;  %t: server time the request was received
+;  %T: time the log has been written (the request has finished)
+;      it can accept a strftime(3) format:
+;      %d/%b/%Y:%H:%M:%S %z (default)
+;  %u: remote user
+;
+; Default: "%R - %u %t \"%m %r\" %s"
+;access.format = "%R - %u %t \"%m %r%Q%q\" %s %f %{mili}d %{kilo}M %C%%"
+
+; The log file for slow requests
+; Default Value: not set
+; Note: slowlog is mandatory if request_slowlog_timeout is set
+slowlog = "{{ icinga_web_logs_path }}/php-fpm-slow.log"
+
+; The timeout for serving a single request after which a PHP backtrace will be
+; dumped to the 'slowlog' file. A value of '0s' means 'off'.
+; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
+; Default Value: 0
+;request_slowlog_timeout = 0
+
+; The timeout for serving a single request after which the worker process will
+; be killed. This option should be used when the 'max_execution_time' ini option
+; does not stop script execution for some reason. A value of '0' means 'off'.
+; Available units: s(econds)(default), m(inutes), h(ours), or d(ays)
+; Default Value: 0
+;request_terminate_timeout = 0
+
+; Set open file descriptor rlimit.
+; Default Value: system defined value
+;rlimit_files = 1024
+
+; Set max core size rlimit.
+; Possible Values: 'unlimited' or an integer greater or equal to 0
+; Default Value: system defined value
+;rlimit_core = 0
+
+; Chroot to this directory at the start. This value must be defined as an
+; absolute path. When this value is not set, chroot is not used.
+; Note: you can prefix with '$prefix' to chroot to the pool prefix or one
+; of its subdirectories. If the pool prefix is not set, the global prefix
+; will be used instead.
+; Note: chrooting is a great security feature and should be used whenever
+;       possible. However, all PHP paths will be relative to the chroot
+;       (error_log, sessions.save_path, ...).
+; Default Value: not set
+;chroot =
+
+; Chdir to this directory at the start.
+; Note: relative path can be used.
+; Default Value: current directory or / when chroot
+;chdir = /var/www
+
+; Redirect worker stdout and stderr into main error log. If not set, stdout and
+; stderr will be redirected to /dev/null according to FastCGI specs.
+; Note: on highloaded environement, this can cause some delay in the page
+; process time (several ms).
+; Default Value: no
+;catch_workers_output = yes
+
+; Clear environment in FPM workers
+; Prevents arbitrary environment variables from reaching FPM worker processes
+; by clearing the environment in workers before env vars specified in this
+; pool configuration are added.
+; Setting to "no" will make all environment variables available to PHP code
+; via getenv(), $_ENV and $_SERVER.
+; Default Value: yes
+;clear_env = no
+
+; Limits the extensions of the main script FPM will allow to parse. This can
+; prevent configuration mistakes on the web server side. You should only limit
+; FPM to .php extensions to prevent malicious users to use other extensions to
+; execute php code.
+; Note: set an empty value to allow all extensions.
+; Default Value: .php
+;security.limit_extensions = .php .php3 .php4 .php5 .php7
+
+; Pass environment variables like LD_LIBRARY_PATH. All $VARIABLEs are taken from
+; the current environment.
+; Default Value: clean env
+;env[HOSTNAME] = $HOSTNAME
+;env[PATH] = /usr/local/bin:/usr/bin:/bin
+;env[TMP] = /tmp
+;env[TMPDIR] = /tmp
+;env[TEMP] = /tmp
+
+; Additional php.ini defines, specific to this pool of workers. These settings
+; overwrite the values previously defined in the php.ini. The directives are the
+; same as the PHP SAPI:
+;   php_value/php_flag             - you can set classic ini defines which can
+;                                    be overwritten from PHP call 'ini_set'.
+;   php_admin_value/php_admin_flag - these directives won't be overwritten by
+;                                     PHP call 'ini_set'
+; For php_*flag, valid values are on, off, 1, 0, true, false, yes or no.
+
+; Defining 'extension' will load the corresponding shared extension from
+; extension_dir. Defining 'disable_functions' or 'disable_classes' will not
+; overwrite previously defined php.ini values, but will append the new value
+; instead.
+
+; Note: path INI options can be relative and will be expanded with the prefix
+; (pool, global or /usr)
+
+; Default Value: nothing is defined by default except the values in php.ini and
+;                specified at startup with the -d argument
+;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
+;php_flag[display_errors] = off
+;php_admin_value[error_log] = /var/log/fpm-php.www.log
+;php_admin_flag[log_errors] = on
+;php_admin_value[memory_limit] = 32M
+php_admin_value[date.timezone] = Europe/Madrid
diff --git a/templates/icingaweb2_db/mysql.sql b/templates/icingaweb2_db/mysql.sql
new file mode 100644
index 0000000000000000000000000000000000000000..ba4d29b84e7976dca3fd0386d32da34b7ce9af76
--- /dev/null
+++ b/templates/icingaweb2_db/mysql.sql
@@ -0,0 +1,61 @@
+-- icingaweb_group
+--
+CREATE TABLE IF NOT EXISTS `icingaweb_group` (
+	`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+	`name` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+	`parent` int(10) unsigned DEFAULT NULL,
+	`ctime` timestamp NULL DEFAULT NULL,
+	`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+PRIMARY KEY (`id`),
+UNIQUE KEY `idx_name` (`name`),
+KEY `fk_icingaweb_group_parent_id` (`parent`)
+) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
+
+ALTER TABLE `icingaweb_group`
+	ADD CONSTRAINT `fk_icingaweb_group_parent_id` FOREIGN KEY (`parent`) REFERENCES `icingaweb_group` (`id`);
+
+INSERT INTO `icingaweb_group` (`id`, `name`, `parent`, `ctime`, `mtime`)
+VALUES (1, 'Administrators', NULL, '{{ icingaweb2_generated_datetime }}', NULL);
+
+-- icingaweb_group_membership
+--
+CREATE TABLE IF NOT EXISTS `icingaweb_group_membership` (
+	`group_id` int(10) unsigned NOT NULL,
+	`username` varchar(254) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+	`ctime` timestamp NULL DEFAULT NULL,
+	`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+PRIMARY KEY (`group_id`,`username`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+ALTER TABLE `icingaweb_group_membership`
+	ADD CONSTRAINT `fk_icingaweb_group_membership_icingaweb_group` FOREIGN KEY (`group_id`) REFERENCES `icingaweb_group` (`id`);
+
+INSERT INTO `icingaweb_group_membership` (`group_id`, `username`, `ctime`, `mtime`)
+	VALUES (1, '{{ icinga_web_admin_user }}', '{{ icingaweb2_generated_datetime }}', NULL);
+
+-- icingaweb_user
+--
+CREATE TABLE IF NOT EXISTS `icingaweb_user` (
+	`name` varchar(254) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+	`active` tinyint(1) NOT NULL,
+	`password_hash` varbinary(255) NOT NULL,
+	`ctime` timestamp NULL DEFAULT NULL,
+	`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+PRIMARY KEY (`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+INSERT INTO `icingaweb_user` (`name`, `active`, `password_hash`, `ctime`, `mtime`)
+	VALUES ('{{ icinga_web_admin_user }}', 1, '{{ icingaweb2_generated_password_encrypted }}', '{{ icingaweb2_generated_datetime }}', NULL);
+
+-- icingaweb_user_preference
+--
+CREATE TABLE IF NOT EXISTS `icingaweb_user_preference` (
+	`username` varchar(254) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+	`section` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+	`name` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+	`value` varchar(255) NOT NULL,
+	`ctime` timestamp NULL DEFAULT NULL,
+	`mtime` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
+PRIMARY KEY (`username`,`section`,`name`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
diff --git a/templates/icingaweb2_db/pgsql.sql b/templates/icingaweb2_db/pgsql.sql
new file mode 100644
index 0000000000000000000000000000000000000000..a428d622b5ff8917794caedcacbd138abc73de8f
--- /dev/null
+++ b/templates/icingaweb2_db/pgsql.sql
@@ -0,0 +1,137 @@
+CREATE TABLE public.icingaweb_group (
+    id integer NOT NULL,
+    name character varying(64) NOT NULL,
+    parent integer,
+    ctime timestamp without time zone,
+    mtime timestamp without time zone
+);
+
+ALTER TABLE public.icingaweb_group OWNER TO icingaweb2;
+
+CREATE SEQUENCE public.icingaweb_group_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER TABLE public.icingaweb_group_id_seq OWNER TO icingaweb2;
+
+ALTER SEQUENCE public.icingaweb_group_id_seq OWNED BY public.icingaweb_group.id;
+
+CREATE TABLE public.icingaweb_group_membership (
+    group_id integer NOT NULL,
+    username character varying(254) NOT NULL,
+    ctime timestamp without time zone,
+    mtime timestamp without time zone
+);
+
+ALTER TABLE public.icingaweb_group_membership OWNER TO icingaweb2;
+
+CREATE TABLE public.icingaweb_user (
+    name character varying(254) NOT NULL,
+    active smallint NOT NULL,
+    password_hash bytea NOT NULL,
+    ctime timestamp without time zone,
+    mtime timestamp without time zone
+);
+
+ALTER TABLE public.icingaweb_user OWNER TO icingaweb2;
+
+CREATE TABLE public.icingaweb_user_preference (
+    username character varying(254) NOT NULL,
+    name character varying(64) NOT NULL,
+    section character varying(64) NOT NULL,
+    value character varying(255) NOT NULL,
+    ctime timestamp without time zone,
+    mtime timestamp without time zone
+);
+
+ALTER TABLE public.icingaweb_user_preference OWNER TO icingaweb2;
+
+CREATE TABLE public.test (
+    id integer NOT NULL,
+    name character varying(20) NOT NULL
+);
+
+ALTER TABLE public.test OWNER TO bhean;
+
+CREATE SEQUENCE public.test_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER TABLE public.test_id_seq OWNER TO icingaweb2;
+
+ALTER SEQUENCE public.test_id_seq OWNED BY public.test.id;
+
+CREATE TABLE public.users_banned (
+    id integer NOT NULL,
+    bot_name character varying(32),
+    user_id integer NOT NULL,
+    reason character varying(256) NOT NULL,
+    banned_by_user_id integer NOT NULL,
+    insert_date timestamp without time zone DEFAULT now() NOT NULL
+);
+
+ALTER TABLE public.users_banned OWNER TO icingaweb2;
+
+CREATE SEQUENCE public.users_banned_id_seq
+    START WITH 1
+    INCREMENT BY 1
+    NO MINVALUE
+    NO MAXVALUE
+    CACHE 1;
+
+ALTER TABLE public.users_banned_id_seq OWNER TO icingaweb2;
+
+ALTER SEQUENCE public.users_banned_id_seq OWNED BY public.users_banned.id;
+
+ALTER TABLE ONLY public.icingaweb_group ALTER COLUMN id SET DEFAULT nextval('public.icingaweb_group_id_seq'::regclass);
+
+ALTER TABLE ONLY public.test ALTER COLUMN id SET DEFAULT nextval('public.test_id_seq'::regclass);
+
+
+ALTER TABLE ONLY public.users_banned ALTER COLUMN id SET DEFAULT nextval('public.users_banned_id_seq'::regclass);
+
+INSERT INTO public.icingaweb_group (id, name, parent, ctime, mtime) VALUES (1, 'Administrators', NULL, '{{ icingaweb2_generated_datetime }}', NULL);
+
+
+SELECT pg_catalog.setval('public.icingaweb_group_id_seq', 1, true);
+
+INSERT INTO public.icingaweb_group_membership (group_id, username, ctime, mtime) VALUES (1, '{{ icinga_web_admin_user }}', '{{ icingaweb2_generated_datetime }}', NULL);
+
+INSERT INTO public.icingaweb_user (name, active, password_hash, ctime, mtime) VALUES ('{{ icinga_web_admin_user }}', 1, '{{ icingaweb2_generated_password_encrypted }}', '{{ icingaweb2_generated_datetime }}', NULL);
+
+SELECT pg_catalog.setval('public.test_id_seq', 1, false);
+
+SELECT pg_catalog.setval('public.users_banned_id_seq', 1, false);
+
+ALTER TABLE ONLY public.icingaweb_group
+    ADD CONSTRAINT pk_icingaweb_group PRIMARY KEY (id);
+
+ALTER TABLE ONLY public.icingaweb_user
+    ADD CONSTRAINT pk_icingaweb_user PRIMARY KEY (name);
+
+ALTER TABLE ONLY public.icingaweb_user_preference
+    ADD CONSTRAINT pk_icingaweb_user_preference PRIMARY KEY (username, section, name);
+
+ALTER TABLE ONLY public.test
+    ADD CONSTRAINT test_pkey PRIMARY KEY (id);
+
+ALTER TABLE ONLY public.users_banned
+    ADD CONSTRAINT users_banned_pkey PRIMARY KEY (id);
+
+CREATE UNIQUE INDEX idx_icingaweb_group ON public.icingaweb_group USING btree (lower((name)::text));
+CREATE UNIQUE INDEX idx_icingaweb_group_membership ON public.icingaweb_group_membership USING btree (group_id, lower((username)::text));
+CREATE UNIQUE INDEX idx_icingaweb_user ON public.icingaweb_user USING btree (lower((name)::text));
+CREATE UNIQUE INDEX idx_icingaweb_user_preference ON public.icingaweb_user_preference USING btree (lower((username)::text), lower((section)::text), lower((name)::text));
+CREATE INDEX users_banned_banner_by_user_id_idx ON public.users_banned USING btree (banned_by_user_id);
+CREATE INDEX users_banned_bot_name_idx ON public.users_banned USING btree (bot_name);
+CREATE INDEX users_banned_insert_date_idx ON public.users_banned USING btree (insert_date);
+CREATE UNIQUE INDEX users_banned_user_id_bot_name_uidx ON public.users_banned USING btree (user_id, bot_name);
+CREATE INDEX users_banned_user_id_idx ON public.users_banned USING btree (user_id);
+ALTER TABLE ONLY public.icingaweb_group ADD CONSTRAINT fk_icingaweb_group_parent_id FOREIGN KEY (parent) REFERENCES public.icingaweb_group(id);
+ALTER TABLE ONLY public.icingaweb_group_membership ADD CONSTRAINT pk_icingaweb_group_membership FOREIGN KEY (group_id) REFERENCES public.icingaweb_group(id);