diff --git a/cesnet-mcc/playbooks/cvmfs.yaml b/cesnet-mcc/playbooks/cvmfs.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..74d53ee0971e71ab97f88bb63e5771aaa955642d
--- /dev/null
+++ b/cesnet-mcc/playbooks/cvmfs.yaml
@@ -0,0 +1,77 @@
+---
+- name: CVMFS deployment
+  hosts: ingress, nfs, worker
+  vars:
+    # EGI repositories: gridpp.egi.eu eosc.egi.eu pheno.egi.eu mice.egi.eu ghost.egi.eu wenmr.egi.eu neugrid.egi.eu auger.egi.eu dirac.egi.eu galdyn.egi.eu seadatanet.egi.eu ligo.egi.eu supernemo.egi.eu pravda.egi.eu chipster.egi.eu hyperk.egi.eu snoplus.egi.eu km3net.egi.eu t2k.egi.eu na62.egi.eu biomed.egi.eu eiscat.egi.eu comet.egi.eu notebooks.egi.eu
+    cvmfs_repositories:
+      - cvmfs-config.cern.ch  # required
+      - atlas.cern.ch
+      - cms.cern.ch
+      - grid.cern.ch
+      - auger.egi.eu
+      - biomed.egi.eu
+      - dirac.egi.eu
+      - eiscat.egi.eu
+      - notebooks.egi.eu
+  become: true
+  tasks:
+    - name: Check cvmfs apt repository
+      command:
+        cmd: dpkg-query -W cvmfs-release
+      register: cvmfs_release_check_deb
+      failed_when: cvmfs_release_check_deb.rc > 1
+      changed_when: false
+    # Avoid occasional network failures (partially)
+    - name: Set cvmfs apt repository proxy cache
+      copy:
+        dest: /etc/apt/apt.conf.d/99cvmfs-proxy
+        mode: 0644
+        content: |
+          Acquire::http::Proxy {
+              cvmrepo.web.cern.ch "http://[{{ groups['ingress'][0] }}]:3128";
+          };
+    - name: Install and setup cvmfs apt repository
+      vars:
+        f: cvmfs-release-latest_all.deb
+      when: cvmfs_release_check_deb.rc | default(0) == 1
+      block:
+        - name: Download cvmfs-release latest package
+          get_url:
+            url: https://ecsft.cern.ch/dist/cvmfs/cvmfs-release/{{ f }}
+            dest: /tmp/{{ f }}
+            mode: 0644
+        - name: Install cvmfs-release latest package
+          apt:
+            deb: /tmp/{{ f }}
+        - name: Update apt cache with cvmfs apt repository
+          apt:
+            update_cache: true
+    - name: Install cvmfs
+      package:
+        name: cvmfs
+        state: present
+    - name: Config cvmfs
+      copy:
+        dest: /etc/cvmfs/default.local
+        mode: 0644
+        content: |
+          CVMFS_HTTP_PROXY=http://[{{ groups['ingress'][0] }}]:3128
+    - name: Setup and mount cvmfs repository {{ item }}
+      ansible.posix.mount:
+        path: /cvmfs/{{ item }}
+        src: "{{ item }}"
+        fstype: cvmfs
+        opts: defaults,_netdev,nodev,x-systemd.requires-mounts-for=/cvmfs/config-egi.egi.eu
+        state: mounted
+      with_items: "{{ cvmfs_repositories }}"
+    - name: Check updatedb.conf existence
+      stat:
+        path: /etc/updatedb.conf
+      register: register_updatedb
+    - name: Tune updatedb.conf - ensure /cvmfs in PRUNEPATHS
+      lineinfile:
+        path: /etc/updatedb.conf
+        backrefs: true
+        regex: '^(\s*PRUNEPATHS\s*=\s*)"(.*?)\s*(/cvmfs\s*)?"\s*$'
+        line: '\1"\2 /cvmfs"'
+      when: register_updatedb.stat.exists
diff --git a/cesnet-mcc/playbooks/squid.yaml b/cesnet-mcc/playbooks/squid.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..1a9c1af27de778e7d9f9b515a9701caade2f239c
--- /dev/null
+++ b/cesnet-mcc/playbooks/squid.yaml
@@ -0,0 +1,49 @@
+---
+- name: Gather facts on all nodes
+  hosts: allnodes
+  become: true
+  tasks:
+    - name: Gather facts on the node
+      debug:
+        msg: "IPv4: {{ansible_default_ipv4.address }}, IPv6: {{ansible_default_ipv6.address }}"
+- name: Squid proxy deployment
+  hosts: ingress[0]
+  become: true
+  tasks:
+    - name: Install squid
+      package:
+        name: squid
+      # full-fledge restart needed to build cache
+      notify: Restart squid
+    # https://cvmfs.readthedocs.io/en/stable/cpt-squid.html
+    - name: Configure squid
+      lineinfile:
+        regexp: '^\s*{{ item.key }}\s+.*'
+        line: "{{ item.key }} {{ item.value }}"
+        path: /etc/squid/squid.conf
+      loop: "{{ config | dict2items }}"
+      vars:
+        config:
+          collapsed_forwarding: "on"
+          minimum_expiry_time: 0
+          maximum_object_size: 1024 MB
+          cache_mem: 128 MB
+          maximum_object_size_in_memory: 128 KB
+          cache_dir: ufs /var/spool/squid 81920 16 256
+      notify: Reload squid
+    - name: Configure squid - ACL allcluster
+      template:
+        src: templates/etc/squid/conf.d/allcluster.conf
+        dest: /etc/squid/conf.d/allcluster.conf
+        mode: 0644
+      notify: Reload squid
+
+  handlers:
+    - name: Restart squid
+      service:
+        name: squid
+        state: restarted
+    - name: Reload squid
+      service:
+        name: squid
+        state: reloaded
diff --git a/cesnet-mcc/playbooks/templates/etc/squid/conf.d/allcluster.conf b/cesnet-mcc/playbooks/templates/etc/squid/conf.d/allcluster.conf
new file mode 100644
index 0000000000000000000000000000000000000000..1b525205427754a671717d14c2abfe4602a06522
--- /dev/null
+++ b/cesnet-mcc/playbooks/templates/etc/squid/conf.d/allcluster.conf
@@ -0,0 +1,7 @@
+{% for host in groups['ingress'] + groups['nfs'] + groups['worker'] -%}
+acl allcluster src {{ hostvars[host].ansible_default_ipv6.address }}
+{% endfor -%}
+{% for host in groups['ingress'] + groups['nfs'] + groups['worker'] -%}
+acl allcluster src {{ hostvars[host].ansible_default_ipv4.address }}
+{% endfor -%}
+http_access allow allcluster