chore: add basic keycloak service

This commit is contained in:
Bert-Jan Fikse 2025-11-07 14:16:31 +01:00
parent 137075ee6f
commit 24b4f291a3
Signed by: bert-jan
GPG key ID: C1E0AB516AC16D1A
9 changed files with 246 additions and 0 deletions

65
roles/keycloak/README.md Normal file
View file

@ -0,0 +1,65 @@
Keycloak
=========
Ansible role to deploy Keycloak with PostgreSQL database using Docker Compose.
Requirements
------------
- Docker and Docker Compose installed on the target host
- Ansible collection: `community.docker`
- Traefik reverse proxy (for external access)
Role Variables
--------------
Key variables defined in `defaults/main.yml`:
**Base Configuration:**
- `docker_compose_base_dir`: Base directory for Docker Compose files (default: `/etc/docker/compose`)
- `docker_volume_base_dir`: Base directory for Docker volumes (default: `/srv/data`)
**Keycloak Configuration:**
- `keycloak_service_name`: Service name (default: `keycloak`)
- `keycloak_domain`: Domain name for Keycloak (default: `auth.digitalboard.ch`)
- `keycloak_image`: Keycloak Docker image (default: `quay.io/keycloak/keycloak:24.0.1`)
- `keycloak_port`: Internal Keycloak port (default: `8080`)
- `keycloak_admin_user`: Admin username (default: `admin`)
- `keycloak_admin_password`: Admin password (default: `changeme`)
- `keycloak_log_level`: Log level (default: `INFO`)
- `keycloak_proxy_mode`: Proxy mode (default: `edge`)
**PostgreSQL Configuration:**
- `keycloak_postgres_image`: PostgreSQL Docker image (default: `postgres:15`)
- `keycloak_postgres_db`: Database name (default: `keycloak`)
- `keycloak_postgres_user`: Database user (default: `keycloak`)
- `keycloak_postgres_password`: Database password (default: `changeme`)
**Traefik Configuration:**
- `keycloak_traefik_network`: Traefik network name (default: `proxy`)
- `keycloak_backend_network`: Backend network name (default: `backend`)
- `keycloak_use_ssl`: Enable SSL (default: `true`)
- `keycloak_cert_resolver`: Certificate resolver name (default: `dns`)
Dependencies
------------
This role requires the Traefik reverse proxy to be configured and the `proxy` network to be created.
Example Playbook
----------------
```yaml
- hosts: backend_servers
roles:
- role: keycloak
vars:
keycloak_domain: "auth.example.com"
keycloak_admin_password: "secure_password"
keycloak_postgres_password: "secure_db_password"
```
License
-------
MIT-0

View file

@ -0,0 +1,35 @@
#SPDX-License-Identifier: MIT-0
---
# defaults file for keycloak
# Base directory configuration (inherited from base role or defined here)
docker_compose_base_dir: /etc/docker/compose
docker_volume_base_dir: /srv/data
# Keycloak-specific configuration
keycloak_service_name: keycloak
keycloak_docker_compose_dir: "{{ docker_compose_base_dir }}/{{ keycloak_service_name }}"
keycloak_docker_volume_dir: "{{ docker_volume_base_dir }}/{{ keycloak_service_name }}"
# Keycloak service configuration
keycloak_domain: "keycloak.local.test"
keycloak_image: "quay.io/keycloak/keycloak:24.0.1"
keycloak_port: 8080
keycloak_admin_user: admin
keycloak_admin_password: "changeme"
# PostgreSQL configuration
keycloak_postgres_image: "postgres:15"
keycloak_postgres_db: keycloak
keycloak_postgres_user: keycloak
keycloak_postgres_password: "changeme"
# Traefik configuration
keycloak_traefik_network: "proxy"
keycloak_backend_network: "backend"
keycloak_use_ssl: true
# Keycloak environment variables
keycloak_log_level: "INFO"
keycloak_proxy_mode: "edge"
keycloak_gzip_enabled: false # Disable GZIP encoding to avoid MIME type issues

View file

@ -0,0 +1,3 @@
#SPDX-License-Identifier: MIT-0
---
# handlers file for keycloak

View file

@ -0,0 +1,35 @@
#SPDX-License-Identifier: MIT-0
galaxy_info:
author: your name
description: your role description
company: your company (optional)
# If the issue tracker for your role is not on github, uncomment the
# next line and provide a value
# issue_tracker_url: http://example.com/issue/tracker
# Choose a valid license ID from https://spdx.org - some suggested licenses:
# - BSD-3-Clause (default)
# - MIT
# - GPL-2.0-or-later
# - GPL-3.0-only
# - Apache-2.0
# - CC-BY-4.0
license: license (GPL-2.0-or-later, MIT, etc)
min_ansible_version: 2.1
# If this a Container Enabled role, provide the minimum Ansible Container version.
# min_ansible_container_version:
galaxy_tags: []
# List tags for your role here, one per line. A tag is a keyword that describes
# and categorizes the role. Users find roles by searching for tags. Be sure to
# remove the '[]' above, if you add tags to this list.
#
# NOTE: A tag is limited to a single word comprised of alphanumeric characters.
# Maximum 20 tags per role.
dependencies: []
# List your role dependencies here, one per line. Be sure to remove the '[]' above,
# if you add dependencies to this list.

View file

@ -0,0 +1,32 @@
#SPDX-License-Identifier: MIT-0
---
# tasks file for keycloak
- name: Create docker compose directory
file:
path: "{{ keycloak_docker_compose_dir }}"
state: directory
mode: '0755'
- name: Create keycloak data directory
file:
path: "{{ keycloak_docker_volume_dir }}/data"
state: directory
mode: '0755'
- name: Create postgres data directory
file:
path: "{{ keycloak_docker_volume_dir }}/postgresql"
state: directory
mode: '0755'
- name: Create docker-compose file for keycloak
template:
src: docker-compose.yml.j2
dest: "{{ keycloak_docker_compose_dir }}/docker-compose.yml"
mode: '0644'
- name: Start keycloak container
community.docker.docker_compose_v2:
project_src: "{{ keycloak_docker_compose_dir }}"
state: present

View file

@ -0,0 +1,64 @@
services:
postgres:
image: {{ keycloak_postgres_image }}
restart: unless-stopped
environment:
POSTGRES_DB: {{ keycloak_postgres_db }}
POSTGRES_USER: {{ keycloak_postgres_user }}
POSTGRES_PASSWORD: {{ keycloak_postgres_password }}
volumes:
- {{ keycloak_docker_volume_dir }}/postgresql:/var/lib/postgresql/data
networks:
- {{ keycloak_backend_network }}
{{ keycloak_service_name }}:
image: {{ keycloak_image }}
restart: unless-stopped
entrypoint: /bin/sh
command:
- -c
- >
/opt/keycloak/bin/kc.sh build &&
/opt/keycloak/bin/kc.sh start --optimized
environment:
KC_DB: postgres
KC_DB_URL: jdbc:postgresql://postgres:5432/{{ keycloak_postgres_db }}
KC_DB_USERNAME: {{ keycloak_postgres_user }}
KC_DB_PASSWORD: {{ keycloak_postgres_password }}
KEYCLOAK_ADMIN: {{ keycloak_admin_user }}
KEYCLOAK_ADMIN_PASSWORD: {{ keycloak_admin_password }}
KC_LOG_LEVEL: {{ keycloak_log_level }}
KC_SPI_RESOURCE_ENCODING_GZIP_ENABLED: {{ keycloak_gzip_enabled | lower }}
KC_SPI_RESOURCE_ENCODING_GZIP_CACHE_DIR: /opt/keycloak/data/gzip-cache
KC_PROXY: {{ keycloak_proxy_mode }}
KC_HOSTNAME: {{ keycloak_domain }}
depends_on:
- postgres
volumes:
- {{ keycloak_docker_volume_dir }}/data:/opt/keycloak/data
networks:
- {{ keycloak_backend_network }}
- {{ keycloak_traefik_network }}
tmpfs:
- /opt/keycloak/data/tmp:size=1024m
labels:
- traefik.enable=true
- traefik.docker.network={{ keycloak_traefik_network }}
- traefik.http.routers.{{ keycloak_service_name }}.rule=Host(`{{ keycloak_domain }}`)
{% if keycloak_use_ssl %}
- traefik.http.routers.{{ keycloak_service_name }}.entrypoints=websecure
- traefik.http.routers.{{ keycloak_service_name }}.tls=true
{% else %}
- traefik.http.routers.{{ keycloak_service_name }}.entrypoints=web
{% endif %}
- traefik.http.services.{{ keycloak_service_name }}.loadbalancer.server.port={{ keycloak_port }}
# Middleware: Keycloak proxy headers
- traefik.http.routers.{{ keycloak_service_name }}.middlewares={{ keycloak_service_name }}-headers
- traefik.http.middlewares.{{ keycloak_service_name }}-headers.headers.customrequestheaders.X-Forwarded-Proto=https
- traefik.http.middlewares.{{ keycloak_service_name }}-headers.headers.customrequestheaders.X-Forwarded-Host={{ keycloak_domain }}
- traefik.http.middlewares.{{ keycloak_service_name }}-headers.headers.customrequestheaders.X-Forwarded-Port=443
networks:
{{ keycloak_backend_network }}:
{{ keycloak_traefik_network }}:
external: true

View file

@ -0,0 +1,3 @@
#SPDX-License-Identifier: MIT-0
localhost

View file

@ -0,0 +1,6 @@
#SPDX-License-Identifier: MIT-0
---
- hosts: localhost
remote_user: root
roles:
- keycloak

View file

@ -0,0 +1,3 @@
#SPDX-License-Identifier: MIT-0
---
# vars file for keycloak