diff --git a/all.yml b/all.yml
index 0880c025e49dbf96cab0fc941a7eb10cc8af7168..87ea36586207a30700c241eab101c35761e7e9ac 100755
--- a/all.yml
+++ b/all.yml
@@ -14,6 +14,7 @@
 - import_playbook: plays/monitoring.yml
 
 # Services that only apply to a subset of server
+- import_playbook: plays/cas.yml
 - import_playbook: plays/dhcp.yml
 - import_playbook: plays/dns.yml
 - import_playbook: plays/etherpad.yml
diff --git a/group_vars/reverseproxy.yml b/group_vars/reverseproxy.yml
index fa185203f22c240f5ba2f4d8a7236364c3cce3fc..01abae8f1591b700810f825265309f4fc1c8d4ba 100644
--- a/group_vars/reverseproxy.yml
+++ b/group_vars/reverseproxy.yml
@@ -29,9 +29,6 @@ nginx:
     #    - {from: roundcube.crans.org, to: 10.231.136.105}
     #    - {from: phabricator.crans.org, to: 10.231.136.123}
     #    - {from: trackerusercontent.crans.org, to: 10.231.136.123}
-    #    - {from: cas.crans.org, to: 10.231.136.18}
-    #    - {from: auth.crans.org, to: 10.231.136.18}
-    #    - {from: login.crans.org, to: 10.231.136.18}
     #    - {from: webmail.crans.org, to: 10.231.136.107}
     #    - {from: horde.crans.org, to: 10.231.136.107}
     #    - {from: owncloud.crans.org, to: 10.231.136.26}
@@ -49,6 +46,9 @@ nginx:
     #    - {from: webirc.crans.org, to: "10.231.136.1:9000"}
     - {from: framadate.crans.org, to: 172.16.10.109}
     - {from: stream.crans.org, to: 172.16.10.118}
+    - {from: cas.crans.org, to: 172.16.10.120}
+    - {from: auth.crans.org, to: 172.16.10.120}
+    - {from: login.crans.org, to: 172.16.10.120}
     #    - {from: mailman.crans.org, to: 10.231.136.180}
     #
     #    # Zamok
diff --git a/hosts b/hosts
index 7757a23dbd7c4fc015c5cc11361fdb2fcd38294e..d2e4bbc393ef8886217440326f1aac15fd761f10 100644
--- a/hosts
+++ b/hosts
@@ -90,6 +90,8 @@ monitoring.adm.crans.org
 boeing.adm.crans.org
 fluxx.adm.crans.org
 unifi.adm.crans.org
+pastemoisa.adm.crans.org
+casouley.adm.crans.org
 
 [ovh_physical]
 sputnik.adm.crans.org
diff --git a/plays/cas.yml b/plays/cas.yml
new file mode 100755
index 0000000000000000000000000000000000000000..9fe922239ecbe709d4b9ad91adaaa953f107783c
--- /dev/null
+++ b/plays/cas.yml
@@ -0,0 +1,9 @@
+#!/usr/bin/env ansible-playbook
+---
+# Django CAS server
+
+- hosts: casouley.adm.crans.org
+  vars:
+    cas_secret_key: "{{ vault_cas_secret_key }}"
+    cas_ldap_password: "{{ vault_cas_ldap_password }}"
+  roles: ["django-cas"]
diff --git a/roles/django-cas/README.md b/roles/django-cas/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..6b9b47c5a55dbebdd4426148d054be4d4c511f3c
--- /dev/null
+++ b/roles/django-cas/README.md
@@ -0,0 +1,3 @@
+# Django CAS
+
+Une fois le rôle appliqué il faut aller dans `/var/local/django-cas` et faire un `./manage.py collectstatic`.
diff --git a/roles/django-cas/handlers/main.yml b/roles/django-cas/handlers/main.yml
new file mode 100644
index 0000000000000000000000000000000000000000..fe8fbf15fc08e4d27d8e6c85b561342d0749efa5
--- /dev/null
+++ b/roles/django-cas/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+- name: Restart nginx
+  service:
+    name: nginx
+    state: restarted
+
+- name: Restart uwsgi
+  service:
+    name: uwsgi
+    state: restarted
diff --git a/roles/django-cas/tasks/main.yml b/roles/django-cas/tasks/main.yml
index 803076206dfa6ffa29f040f36e9580dd67320aa7..6472c51592559c133f0e63190258335c8e3f952c 100644
--- a/roles/django-cas/tasks/main.yml
+++ b/roles/django-cas/tasks/main.yml
@@ -8,10 +8,62 @@
       - uwsgi-plugin-python3
       - python3-django
       - python3-django-cas-server
+      - python3-psycopg2
   register: apt_result
   retries: 3
   until: apt_result is succeeded
 
+- name: Upgrade to Bullseye Django CAS
+  apt:
+    deb: http://mirror.adm.crans.org/debian/pool/main/d/django-cas-server/python3-django-cas-server_1.1.0-2_all.deb
+  register: apt_result
+  retries: 3
+  until: apt_result is succeeded
+  when:
+    - ansible_lsb.codename == 'buster'
+
+- name: Clone Django CAS project repository
+  git:
+    repo: http://gitlab.adm.crans.org/nounous/django-cas.git
+    dest: /var/local/django-cas
+    version: master
+    umask: '002'
+
+- name: Configure Django CAS
+  template:
+    src: cas/settings_local.py.j2
+    dest: /var/local/django-cas/cas/settings_local.py
+    mode: 0600
+  notify: Restart uwsgi
+
+- name: Configure NGINX site
+  template:
+    src: nginx/sites-available/cas.j2
+    dest: /etc/nginx/sites-available/cas
+    mode: 0644
+  notify: Restart nginx
+
+- name: Enable nginx site
+  file:
+    src: /etc/nginx/sites-available/cas
+    dest: /etc/nginx/sites-enabled/cas
+    state: link
+  notify: Restart nginx
+
+- name: Configure UWSGI app
+  template:
+    src: uwsgi/apps-available/cas.ini.j2
+    dest: /etc/uwsgi/apps-available/cas.ini
+    mode: 0644
+  notify: Restart uwsgi
+
+- name: Enable uwsgi app
+  file:
+    src: /etc/uwsgi/apps-available/cas.ini
+    dest: /etc/uwsgi/apps-enabled/cas.ini
+    state: link
+  notify: Restart uwsgi
+
 - name: Install CAS crons
   template:
     src: cron.d/cas.j2
diff --git a/roles/django-cas/templates/cas/settings_local.py.j2 b/roles/django-cas/templates/cas/settings_local.py.j2
new file mode 100644
index 0000000000000000000000000000000000000000..aaaebe11076ed23d0a186999007ec5b7b1afbe25
--- /dev/null
+++ b/roles/django-cas/templates/cas/settings_local.py.j2
@@ -0,0 +1,9 @@
+{{ ansible_header | comment }}
+
+SECRET_KEY = '{{ cas_secret_key }}'
+
+# Settings for the CAS server
+CAS_LDAP_SERVER = "172.16.10.90"
+CAS_LDAP_USER = "cn=cas,ou=service-users,dc=crans,dc=org"
+CAS_LDAP_PASSWORD = "{{ cas_ldap_password }}"
+CAS_LDAP_BASE_DN = "cn=Utilisateurs,dc=crans,dc=org"
diff --git a/roles/django-cas/templates/cron.d/cas.j2 b/roles/django-cas/templates/cron.d/cas.j2
index ec29265e07c9e9f483e8681d2115b92995a74eb4..0fd4795d6532f8716531f58759e738f4cc1a4aef 100644
--- a/roles/django-cas/templates/cron.d/cas.j2
+++ b/roles/django-cas/templates/cron.d/cas.j2
@@ -1,4 +1,4 @@
 {{ ansible_header | comment }}
-0   0  * * * www-data /usr/local/django/cas/manage.py clearsessions
-*/5 *  * * * www-data /usr/local/django/cas/manage.py cas_clean_tickets
-5   0  * * * www-data /usr/local/django/cas/manage.py cas_clean_sessions
+0   0  * * * www-data /var/local/django-cas/manage.py clearsessions
+*/5 *  * * * www-data /var/local/django-cas/manage.py cas_clean_tickets
+5   0  * * * www-data /var/local/django-cas/manage.py cas_clean_sessions
diff --git a/roles/django-cas/templates/nginx/sites-available/cas.j2 b/roles/django-cas/templates/nginx/sites-available/cas.j2
new file mode 100644
index 0000000000000000000000000000000000000000..c243822e7c4092d0f60072b28f61ad7db200d53d
--- /dev/null
+++ b/roles/django-cas/templates/nginx/sites-available/cas.j2
@@ -0,0 +1,25 @@
+{{ ansible_header | comment }}
+
+server {
+     server_name cas.crans.org cas.adm.crans.org login.crans.org login.adm.crans.org auth.crans.org auth.adm.crans.org;
+     listen 80;
+     listen [::]:80;
+
+     location /cas {
+         rewrite ^/cas$ / redirect;
+         rewrite ^/cas/(.*)$ /$1 redirect;
+     }
+
+     location /static {
+         alias /var/local/django-cas/cas/local_static;
+     }
+
+     set_real_ip_from 10.231.136.0/24;
+     set_real_ip_from 2a0c:700:0:2::/64;
+     real_ip_header P-Real-Ip;
+
+     location / {
+         uwsgi_pass unix:///var/run/uwsgi/app/cas/socket;
+         include uwsgi_params;
+     }
+}
diff --git a/roles/django-cas/templates/update-motd.d/05-service.j2 b/roles/django-cas/templates/update-motd.d/05-service.j2
index 0a1da54c415a59b45e1d483cd985610f53ad7469..242bc2caf02799a49661c811768270e7e3117947 100755
--- a/roles/django-cas/templates/update-motd.d/05-service.j2
+++ b/roles/django-cas/templates/update-motd.d/05-service.j2
@@ -1,3 +1,3 @@
 #!/usr/bin/tail +14
 {{ ansible_header | comment }}
-> django-cas-server a été déployé sur cette machine. Voir /usr/local/django/cas/.
+> django-cas-server a été déployé sur cette machine. Voir /var/local/django-cas/.
diff --git a/roles/django-cas/templates/uwsgi/apps-available/cas.ini.j2 b/roles/django-cas/templates/uwsgi/apps-available/cas.ini.j2
new file mode 100644
index 0000000000000000000000000000000000000000..7ec928041916bf200963d03cf89aa2206523da44
--- /dev/null
+++ b/roles/django-cas/templates/uwsgi/apps-available/cas.ini.j2
@@ -0,0 +1,17 @@
+{{ ansible_header | comment }}
+
+[uwsgi]
+plugin = python3
+chdir = /var/local/django-cas/
+wsgi-file = /var/local/django-cas/cas/wsgi.py
+max-request=50
+cheaper = 1
+cheaper-initial = 1
+workers = 2
+die-on-term = true
+memory-report = true
+reload-on-rss = 75M
+evil-reload-on-rss = 200M
+limit-as = 450M
+reload-on-as = 350M
+evil-reload-on-as = 500M