From e93f2354f71a6bcd160629a5bc9cd05eb840a059 Mon Sep 17 00:00:00 2001
From: Thomas Schneider <tschneider@asta.rwth-aachen.de>
Date: Sun, 24 Oct 2021 23:15:29 +0200
Subject: [PATCH] Add keycloak role

---
 keycloak/defaults/main.yml         |  14 +++
 keycloak/files/keycloak.service    |  14 +++
 keycloak/files/postgres-module.xml |  10 ++
 keycloak/handlers/main.yml         |  10 ++
 keycloak/tasks/main.yml            | 193 +++++++++++++++++++++++++++++
 keycloak/tasks/postgres.yml        |  99 +++++++++++++++
 6 files changed, 340 insertions(+)
 create mode 100644 keycloak/defaults/main.yml
 create mode 100644 keycloak/files/keycloak.service
 create mode 100644 keycloak/files/postgres-module.xml
 create mode 100644 keycloak/handlers/main.yml
 create mode 100644 keycloak/tasks/main.yml
 create mode 100644 keycloak/tasks/postgres.yml

diff --git a/keycloak/defaults/main.yml b/keycloak/defaults/main.yml
new file mode 100644
index 0000000..bfd2a65
--- /dev/null
+++ b/keycloak/defaults/main.yml
@@ -0,0 +1,14 @@
+---
+
+keycloak_version: "15.0.2"
+keycloak_db:
+  type: h2
+
+# keycloak_db:
+#   type: postgres
+#   user: keycloak
+#   password: hunter2
+#   host: db.example.org
+#   name: keycloak
+
+keycloak_manage_local_postgres: true
diff --git a/keycloak/files/keycloak.service b/keycloak/files/keycloak.service
new file mode 100644
index 0000000..2659c25
--- /dev/null
+++ b/keycloak/files/keycloak.service
@@ -0,0 +1,14 @@
+[Unit]
+Description=Keycloak Identity and Access Management
+After=network-online.target postgresql.service
+Wants=network-online.target
+
+[Service]
+ExecStart=/opt/keycloak/bin/standalone.sh
+User=keycloak
+Environment=JBOSS_BASE_DIR=/var/lib/keycloak/standalone
+Environment=JBOSS_LOG_DIR=/var/log/keycloak
+LimitNOFILE=102642
+
+[Install]
+WantedBy=multi-user.target
diff --git a/keycloak/files/postgres-module.xml b/keycloak/files/postgres-module.xml
new file mode 100644
index 0000000..928ac7b
--- /dev/null
+++ b/keycloak/files/postgres-module.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<module xmlns="urn:jboss:module:1.3" name="org.postgresql">
+  <resources>
+    <resource-root path="postgresql.jar"/>
+  </resources>
+  <dependencies>
+    <module name="javax.api"/>
+    <module name="javax.transaction.api"/>
+  </dependencies>
+</module>
diff --git a/keycloak/handlers/main.yml b/keycloak/handlers/main.yml
new file mode 100644
index 0000000..9daa46f
--- /dev/null
+++ b/keycloak/handlers/main.yml
@@ -0,0 +1,10 @@
+---
+
+- name: Reload systemd
+  systemd:
+    daemon_reload: true
+
+- name: Restart keycloak
+  systemd:
+    name: keycloak.service
+    state: restarted
diff --git a/keycloak/tasks/main.yml b/keycloak/tasks/main.yml
new file mode 100644
index 0000000..7c365de
--- /dev/null
+++ b/keycloak/tasks/main.yml
@@ -0,0 +1,193 @@
+---
+
+- name: Install JRE and other required packages
+  apt:
+    name:
+      - default-jre-headless
+      - python3-lxml
+    state: present
+
+- name: Create keycloak group
+  group:
+    name: keycloak
+    system: true
+
+- name: Create keycloak user
+  user:
+    name: keycloak
+    system: true
+    home: /var/lib/keycloak
+    group: keycloak
+
+- name: Configure keycloak home directory
+  file:
+    path: /var/lib/keycloak
+    state: directory
+    owner: keycloak
+    group: keycloak
+    mode: '0700'
+
+- name: Configure log directory
+  file:
+    path: /var/log/keycloak
+    state: directory
+    owner: keycloak
+    group: keycloak
+    mode: '0750'
+
+- name: Get installed version
+  slurp:
+    src: /opt/keycloak/version.txt
+  register: keycloak_version_txt
+  ignore_errors: true
+
+- name: Extract version from string
+  set_fact:
+    keycloak_installed_version: >-
+      {{ keycloak_version_txt.content | b64decode
+         | regex_search('Version ([\d.]+)', '\1') | first }}
+  when:
+    not keycloak_version_txt.failed
+
+- when: >-
+    keycloak_version_txt.failed or
+    keycloak_installed_version != keycloak_version
+  notify:
+    - Restart keycloak
+  block:
+    - name: Create temporary directory
+      tempfile:
+        state: directory
+      register: tempdir
+
+    - name: Fetch and extract keycloak
+      unarchive:
+        # yamllint disable-line rule:line-length
+        src: "https://github.com/keycloak/keycloak/releases/download/{{ keycloak_version }}/keycloak-{{ keycloak_version }}.tar.gz"
+        dest: "{{ tempdir.path }}"
+        remote_src: true
+
+    - name: Ensure the target directory is absent
+      file:
+        path: /opt/keycloak-{{ keycloak_version }}
+        state: absent
+
+    - name: Move keycloak to target directory
+      copy:
+        src: "{{ tempdir.path }}/keycloak-{{ keycloak_version }}"
+        dest: /opt/
+        remote_src: true
+        owner: root
+        group: root
+        mode: preserve
+
+    - name: Fix file owner
+      file:
+        path: /opt/keycloak-{{ keycloak_version }}
+        owner: root
+        group: root
+        recurse: true
+
+    - name: Get old installation path
+      stat:
+        path: /opt/keycloak
+      register: installation_path
+
+    - name: Set installation symlink
+      file:
+        src: /opt/keycloak-{{ keycloak_version }}
+        dest: /opt/keycloak
+        state: link
+        follow: false
+        force: true
+
+    - name: Remove old version
+      file:
+        path: "{{ installation_path.stat.lnk_source }}"
+        state: absent
+      when: >-
+        installation_path.stat.islnk is defined and installation_path.stat.islnk
+
+    - name: Remove temporary directory
+      file:
+        path: "{{ tempdir.path }}"
+        state: absent
+
+- name: Check whether configuration/data directory already exists
+  stat:
+    path: /var/lib/keycloak/standalone
+  register: config_directory
+
+- name: Initialise configuration/data directory
+  when: not config_directory.stat.exists
+  copy:
+    src: /opt/keycloak/standalone
+    dest: /var/lib/keycloak/
+    remote_src: true
+    owner: keycloak
+    group: keycloak
+    mode: preserve
+
+- name: Ensure log directory points to correct path
+  file:
+    path: /var/lib/keycloak/standalone/log
+    src: /var/log/keycloak
+    state: link
+    force: true
+
+- name: Ensure correct configuration/data directory permissions
+  file:
+    path: /var/lib/keycloak/standalone
+    owner: keycloak
+    group: keycloak
+    recurse: true
+
+- import_tasks: postgres.yml
+  when: keycloak_db.type == "postgres"
+
+- name: Configure H2 datasource
+  when: keycloak_db.type == "h2"
+  xml:
+    path: /var/lib/keycloak/standalone/configuration/standalone.xml
+    namespaces:
+      ds: urn:jboss:domain:datasources:6.0
+    xpath: >-
+      //ds:subsystem/ds:datasources/ds:datasource[@jndi-name="java:jboss/datasources/KeycloakDS"]
+    input_type: xml
+    set_children:
+      - <connection-url>jdbc:h2:${jboss.server.data.dir}/keycloak;AUTO_SERVER=TRUE</connection-url>
+      - <driver>h2</driver>
+      - >-
+        <security>
+          <user-name>sa</user-name>
+          <password>sa</password>
+        </security>
+  notify:
+    - Restart keycloak
+
+- name: Configure keycloak for reverse proxy usage
+  xml:
+    path: /var/lib/keycloak/standalone/configuration/standalone.xml
+    namespaces:
+      ut: urn:jboss:domain:undertow:12.0
+    xpath: >-
+      //ut:subsystem/ut:server[@name="default-server"]/ut:http-listener[@name="default"]
+    attribute: proxy-address-forwarding
+    value: "true"
+
+- name: Install systemd service
+  copy:
+    src: keycloak.service
+    dest: /etc/systemd/system/keycloak.service
+    owner: root
+    group: root
+    mode: '0644'
+  notify:
+    - Reload systemd
+    - Restart keycloak
+
+- name: Enable and start keycloak
+  systemd:
+    name: keycloak.service
+    state: started
+    enabled: true
diff --git a/keycloak/tasks/postgres.yml b/keycloak/tasks/postgres.yml
new file mode 100644
index 0000000..09785fe
--- /dev/null
+++ b/keycloak/tasks/postgres.yml
@@ -0,0 +1,99 @@
+---
+
+- when: keycloak_manage_local_postgres
+  become: true
+  become_user: postgres
+  block:
+    - name: Create postgres user
+      postgresql_user:
+        name: "{{ keycloak_db.user }}"
+        password: "{{ keycloak_db.password }}"
+        state: present
+    - name: Create postgres database
+      postgresql_db:
+        name: "{{ keycloak_db.name }}"
+        owner: "{{ keycloak_db.user }}"
+        state: present
+
+- name: Install JDBC postgres driver
+  apt:
+    name: libpostgresql-jdbc-java
+    state: present
+
+- name: Create postgres driver module directory
+  file:
+    path: /opt/keycloak/modules/system/layers/keycloak/org/postgresql/main
+    state: directory
+    owner: root
+    group: root
+    mode: '0755'
+
+- name: Link postgres driver
+  file:
+    src: /usr/share/java/postgresql.jar
+    dest: >-
+      /opt/keycloak/modules/system/layers/keycloak/org/postgresql/main/postgresql.jar
+    state: link
+  notify:
+    - Restart keycloak
+
+- name: Register postgres driver module
+  copy:
+    src: postgres-module.xml
+    dest: >-
+      /opt/keycloak/modules/system/layers/keycloak/org/postgresql/main/module.xml
+    owner: root
+    group: root
+    mode: '0644'
+  notify:
+    - Restart keycloak
+
+- name: Check whether postgres datasource driver is registered
+  xml:
+    path: /var/lib/keycloak/standalone/configuration/standalone.xml
+    namespaces:
+      ds: urn:jboss:domain:datasources:6.0
+    xpath: >-
+      //ds:subsystem/ds:datasources/ds:drivers/ds:driver[@name="postgresql"]
+    count: true
+  register: postgres_datasource
+
+- name: Register postgres datasource driver
+  xml:
+    path: /var/lib/keycloak/standalone/configuration/standalone.xml
+    namespaces:
+      ds: urn:jboss:domain:datasources:6.0
+    xpath: //ds:subsystem/ds:datasources/ds:drivers
+    input_type: xml
+    add_children:
+      - >-
+        <driver name="postgresql" module="org.postgresql">
+          <xa-datasource-class>org.postgresql.xa.PGXADataSource</xa-datasource-class>
+        </driver>
+  when: postgres_datasource.count == 0
+  notify:
+    - Restart keycloak
+
+- name: Configure postgres datasource
+  xml:
+    path: /var/lib/keycloak/standalone/configuration/standalone.xml
+    namespaces:
+      ds: urn:jboss:domain:datasources:6.0
+    xpath: >-
+      //ds:subsystem/ds:datasources/ds:datasource[@jndi-name="java:jboss/datasources/KeycloakDS"]
+    input_type: xml
+    set_children:
+      # yamllint disable-line rule:line-length
+      - <connection-url>jdbc:postgresql://{{ keycloak_db.host }}/{{ keycloak_db.name }}</connection-url>
+      - <driver>postgresql</driver>
+      - >-
+        <pool>
+          <max-pool-size>20</max-pool-size>
+        </pool>
+      - >-
+        <security>
+          <user-name>{{ keycloak_db.user }}</user-name>
+          <password>{{ keycloak_db.password }}</password>
+        </security>
+  notify:
+    - Restart keycloak
-- 
GitLab