diff --git a/cesnet-central/deploy.sh b/cesnet-central/deploy.sh
index d5606cf0ecccd6063851bdae182d936bea965425..764f9c63a3e45e60b080184d6bc56ca3221bfaab 100755
--- a/cesnet-central/deploy.sh
+++ b/cesnet-central/deploy.sh
@@ -27,3 +27,5 @@ ansible-playbook playbooks/cvmfs.yaml
 
 # wait for finish
 while ansible -m command -a 'kubectl get pods --all-namespaces' master | tail -n +3 | grep -v ' Running '; do sleep 5; done
+
+ansible-playbook playbooks/security-logs.yaml
diff --git a/cesnet-central/playbooks/security-logs.yaml b/cesnet-central/playbooks/security-logs.yaml
new file mode 120000
index 0000000000000000000000000000000000000000..0149b195ced3d8e9858c589d438a6947b105eb9b
--- /dev/null
+++ b/cesnet-central/playbooks/security-logs.yaml
@@ -0,0 +1 @@
+../../common/playbooks/security-logs.yaml
\ No newline at end of file
diff --git a/cesnet-central/playbooks/templates/fluent-bit-secrets.yaml.j2 b/cesnet-central/playbooks/templates/fluent-bit-secrets.yaml.j2
new file mode 120000
index 0000000000000000000000000000000000000000..c64dceeb78ad480b636eec9c342e7648ee4b6e3f
--- /dev/null
+++ b/cesnet-central/playbooks/templates/fluent-bit-secrets.yaml.j2
@@ -0,0 +1 @@
+../../../common/playbooks/templates/fluent-bit-secrets.yaml.j2
\ No newline at end of file
diff --git a/cesnet-central/playbooks/templates/fluent-bit.yaml.j2 b/cesnet-central/playbooks/templates/fluent-bit.yaml.j2
new file mode 120000
index 0000000000000000000000000000000000000000..4ccab1994206fa7d3eb20ebf59ee4a72872d7dd5
--- /dev/null
+++ b/cesnet-central/playbooks/templates/fluent-bit.yaml.j2
@@ -0,0 +1 @@
+../../../common/playbooks/templates/fluent-bit.yaml.j2
\ No newline at end of file
diff --git a/common/playbooks/security-logs.yaml b/common/playbooks/security-logs.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ee20f2e37eaca9f39b44b7d2cf74089c267f2ef8
--- /dev/null
+++ b/common/playbooks/security-logs.yaml
@@ -0,0 +1,91 @@
+---
+#
+# Secrets in "/{{ site_name }}":
+#
+# * fluent_es_host (optional): enable elasticsearch output
+# * fluent_es_index: Index option (when used, 'node-' or 'kube-' prefix is added)
+# * fluent_es_*: elasticsearch output additional options (tls, http_user, ...)
+#
+# * fluent_gelf_host (optional): enable graylog output
+# * fluent_gelf_mode (optional, "tls", "tcp", or "udp")
+# * fluent_gelf_*: graylog output additional options
+#
+# Secrets in "/{{ site_name }}" related to TLS:
+#
+# * fluent_secrets_ca (optional): propagated to /secrets/fluent.ca
+# * fluent_secrets_crt (optional): propagated to /secrets/fluent.crt
+# * fluent_secrets_key (optional): propagated to /secrets/fluent.key
+# * fluent_*_tls (optional): "On"
+# * fluent_*_tls.ca_file (optional): "/secrets/fluent.ca"
+# * fluent_*_tls.crt_file (optional): "/secrets/fluent.crt"
+# * fluent_*_tls.key_file (optional): "/secrets/fluent.key"
+# * fluent_*_tls.key_password (optional)
+# * fluent_*_tls.verify (optional)
+# * fluent_*_tls.verify_hostname (optional): "On"
+# * fluent_*_tls.vhost (optional)
+#
+# Self-sign certificate HOWTO (for TLS clients): [1]
+#
+# openssl req -x509 -newkey rsa:4096 -sha256 -nodes -keyout self_signed.key -out self_signed.crt -subj "/CN=test.host.net"
+#
+# [1] https://docs.fluentbit.io/manual/administration/transport-security#tips-and-tricks
+#
+# For GELF: add self_signed.crt to authorized client certificates directory.
+#
+- name: Fluent Bit Configuration
+  hosts: master
+  become: true
+  vars:
+    namespace: fluent-bit
+    version: "0.47.7" # app 3.1.6
+  tasks:
+    - name: Configure helm repo
+      shell: |-
+        helm repo add fluent https://fluent.github.io/helm-charts
+        helm repo update
+      when: "'fluent' not in ansible_local.helm_repos | map(attribute='name') | list"
+    - name: Get Secrets from Vault
+      set_fact:
+        secrets: "{{ lookup('community.hashi_vault.hashi_vault', vault_mount_point + '/site-' + site_name,
+          token_validate=false) }}"
+    - name: Debug Secrets
+      debug:
+        msg: "{{ item.key }} = {{ item.value }}"
+      loop: "{{ secrets | dict2items }}"
+    - name: Set Fluent TLS Fact From Secrets
+      set_fact:
+        fluent_has_tls: "{{ 'fluent_secrets_ca' in secrets or 'fluent_secrets_crt' in secrets or 'fluent_secrets_key' in  secrets }}"
+    - name: Create Fluent TLS Secrets File
+      template:
+        src: templates/fluent-bit-secrets.yaml.j2
+        dest: /tmp/fluent-bit-secrets.yaml
+        mode: 0600
+      when: fluent_has_tls
+    - name: Create Fluent TLS Secrets Object
+      command:
+        cmd: kubectl apply -f /tmp/fluent-bit-secrets.yaml
+      environment:
+        KUBECONFIG: /etc/kubernetes/admin.conf
+        PATH: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+      when: fluent_has_tls
+    - name: Fluent Bit Configuration
+      template:
+        src: templates/fluent-bit.yaml.j2
+        dest: /tmp/fluent-bit.yaml
+        mode: 0600
+    - name: Deploy/upgrade Fluent Bit
+      shell: |-
+        helm status --namespace {{ namespace }} fluent-bit
+        if [ $? -ne 0 ]; then
+            helm install --create-namespace --namespace {{ namespace }} \
+                -f /tmp/fluent-bit.yaml \
+                fluent-bit fluent/fluent-bit
+        else
+            helm upgrade --namespace {{ namespace }} \
+                -f /tmp/fluent-bit.yaml \
+                fluent-bit fluent/fluent-bit
+        fi
+      environment:
+        KUBECONFIG: /etc/kubernetes/admin.conf
+        PATH: /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
+      when: true
diff --git a/common/playbooks/templates/fluent-bit-secrets.yaml.j2 b/common/playbooks/templates/fluent-bit-secrets.yaml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..6c2dcba2ccc82c9f378652db34e1a0c8eb5aaaa6
--- /dev/null
+++ b/common/playbooks/templates/fluent-bit-secrets.yaml.j2
@@ -0,0 +1,19 @@
+---
+apiVersion: v1
+kind: Secret
+metadata:
+  name: fluent-output-tls
+  namespace: {{ namespace }}
+stringData:
+{% if 'fluent_secrets_ca' in secrets %}
+    ca.crt: |
+      {{ secrets['fluent_secrets_ca'] | indent(6) }}
+{%- endif %}
+{% if 'fluent_secrets_crt' in secrets %}
+    fluent.crt: |
+      {{ secrets['fluent_secrets_crt'] | indent(6) }}
+{%- endif %}
+{% if 'fluent_secrets_key' in secrets %}
+    fluent.key: |
+      {{ secrets['fluent_secrets_key'] | indent(6) }}
+{%- endif %}
diff --git a/common/playbooks/templates/fluent-bit.yaml.j2 b/common/playbooks/templates/fluent-bit.yaml.j2
new file mode 100644
index 0000000000000000000000000000000000000000..e16921d6c2490a64a54080740000f5037ce00a4e
--- /dev/null
+++ b/common/playbooks/templates/fluent-bit.yaml.j2
@@ -0,0 +1,115 @@
+---
+config:
+  inputs: |
+    [INPUT]
+        Name                     tail
+        Path                     /var/log/containers/*.log
+        DB                       /var/log/fluent-bit.db
+        multiline.parser         docker, cri
+        Tag                      kube.*
+        Mem_Buf_Limit            5MB
+        # Skip_Long_Lines On
+
+    [INPUT]
+        Name systemd
+        Tag host.*
+        Systemd_Filter _SYSTEMD_UNIT=kubelet.service
+        Read_From_Tail On
+
+  filters: |
+    [FILTER]
+        Name                    kubernetes
+        Match                   kube.*
+        Merge_Log_Key           log
+        Merge_Log               On
+        Keep_Log                Off
+        Annotations             Off
+        Labels                  Off
+        K8S-Logging.Parser      On
+        K8S-Logging.Exclude     On
+
+    [FILTER]
+        Name                    modify
+        Match                   *
+        Add                     cluster {{ site_name }}
+        Add                     tag eosc
+
+  outputs: |
+    # [OUTPUT]
+    #     Name                    stdout
+    #     Match                   host.*
+
+    # [OUTPUT]
+    #     Name                    stdout
+    #     Match                   kube.*
+
+{% if 'fluent_es_host' in secrets %}
+    [OUTPUT]
+        Name                    es
+        Match                   kube.*
+{% for key, value in secrets.items() %}
+{% if key | regex_search('^fluent_es_') %}
+{% if key == 'fluent_es_index' %}
+{% set value = ['kube', value | default(omit)] | join('-') %}
+{% endif %}
+        {{ '%-23s' | format(key | regex_replace('^fluent_es_', '') | title) }} {{ value }}
+{% endif %}
+{% endfor %}
+
+    [OUTPUT]
+        Name                    es
+        Match                   node.*
+{% for key, value in secrets.items() %}
+{% if key | regex_search('^fluent_es_') %}
+{% if key == 'fluent_es_index' %}
+{% set value = ['node', value | default(omit)] | join('-') %}
+{% endif %}
+        {{ '%-23s' | format(key | regex_replace('^fluent_es_', '') | title) }} {{ value }}
+{% endif %}
+{% endfor %}
+
+{% endif %}
+{% if 'fluent_gelf_host' in secrets %}
+    [OUTPUT]
+        Name                    gelf
+        Match                   kube.*
+        Gelf_Host_Key           host
+        Gelf_Short_Message_Key  log
+{% for key, value in secrets.items() %}
+{% if key | regex_search('^fluent_gelf_') %}
+        {{ '%-23s' | format(key | regex_replace('^fluent_gelf_', '')) | title }} {{ value }}
+{% endif %}
+{% endfor %}
+
+    [OUTPUT]
+        Name                    gelf
+        Match                   host.*
+        Gelf_Host_Key           _HOSTNAME
+        Gelf_Short_Message_Key  MESSAGE
+{% for key, value in secrets.items() %}
+{% if key | regex_search('^fluent_gelf_') %}
+        {{ '%-23s' | format(key | regex_replace('^fluent_gelf_', '')) | title }} {{ value }}
+{% endif %}
+{% endfor %}
+
+{% endif %}
+{% if fluent_has_tls %}
+extraVolumes:
+  - name: fluent-output-tls
+    secret:
+      secretName: fluent-output-tls
+
+extraVolumeMounts:
+  - name: fluent-output-tls
+    readOnly: true
+    mountPath: "/secrets"
+
+{% endif %}
+# daemonset runnable on control plane nodes
+tolerations:
+  - key: node-role.kubernetes.io/control-plane
+    operator: Exists
+    effect: NoSchedule
+  - key: node-role.kubernetes.io/master
+    operator: Exists
+    effect: NoSchedule
diff --git a/staging1/deploy.sh b/staging1/deploy.sh
index 68cffd8c70a88a1902f6b19c8a451f02a411ec9b..d509ed3f8ee0f20839400b7b6f99e502270b4bff 100755
--- a/staging1/deploy.sh
+++ b/staging1/deploy.sh
@@ -55,3 +55,4 @@ ansible-playbook playbooks/cvmfs.yaml
 while ansible -m command -a 'kubectl get pods --all-namespaces' master | tail -n +3 | grep -v ' Running '; do sleep 5; done
 
 ansible-playbook playbooks/security-assets.yaml
+ansible-playbook playbooks/security-logs.yaml
diff --git a/staging1/playbooks/security-logs.yaml b/staging1/playbooks/security-logs.yaml
new file mode 120000
index 0000000000000000000000000000000000000000..0149b195ced3d8e9858c589d438a6947b105eb9b
--- /dev/null
+++ b/staging1/playbooks/security-logs.yaml
@@ -0,0 +1 @@
+../../common/playbooks/security-logs.yaml
\ No newline at end of file
diff --git a/staging1/playbooks/templates/fluent-bit-secrets.yaml.j2 b/staging1/playbooks/templates/fluent-bit-secrets.yaml.j2
new file mode 120000
index 0000000000000000000000000000000000000000..86f2455ce688795a78ac156d0ec4b784da659ebe
--- /dev/null
+++ b/staging1/playbooks/templates/fluent-bit-secrets.yaml.j2
@@ -0,0 +1 @@
+/home/valtri/notebooks-operations.eosc/common/playbooks/templates/fluent-bit-secrets.yaml.j2
\ No newline at end of file
diff --git a/staging1/playbooks/templates/fluent-bit.yaml.j2 b/staging1/playbooks/templates/fluent-bit.yaml.j2
new file mode 120000
index 0000000000000000000000000000000000000000..4ccab1994206fa7d3eb20ebf59ee4a72872d7dd5
--- /dev/null
+++ b/staging1/playbooks/templates/fluent-bit.yaml.j2
@@ -0,0 +1 @@
+../../../common/playbooks/templates/fluent-bit.yaml.j2
\ No newline at end of file