Keycloak works, add example yml
This commit is contained in:
parent
2523515243
commit
a29efe00e0
|
@ -0,0 +1 @@
|
||||||
|
*.secret.yml
|
|
@ -0,0 +1,6 @@
|
||||||
|
global_ssh_keys:
|
||||||
|
- albert_rsa
|
||||||
|
- ignisf
|
||||||
|
- zeridon
|
||||||
|
- shteryana
|
||||||
|
- dexxter00
|
|
@ -0,0 +1,23 @@
|
||||||
|
keycloak_config:
|
||||||
|
hostname: auth.openfest.org
|
||||||
|
db:
|
||||||
|
host: host.containers.internal
|
||||||
|
user: keycloak
|
||||||
|
database: keycloak
|
||||||
|
password: slojnaparola
|
||||||
|
access_host: all
|
||||||
|
ansible_host: infrahost
|
||||||
|
podman:
|
||||||
|
user: auth
|
||||||
|
home: /home/auth
|
||||||
|
datadir: /home/auth/keycloak
|
||||||
|
listen_address: 127.0.0.1:9091
|
||||||
|
reverse_proxy:
|
||||||
|
external_url: auth.openfest.org
|
||||||
|
proxy_url: 127.0.0.1:9091
|
||||||
|
ansible_host: infrahost
|
||||||
|
tls:
|
||||||
|
type: internal
|
||||||
|
admin:
|
||||||
|
user: admin
|
||||||
|
password: slojnaparola
|
|
@ -0,0 +1,2 @@
|
||||||
|
postgresql:
|
||||||
|
listen_addresses: "*"
|
|
@ -3,46 +3,62 @@
|
||||||
- name: Check parameters
|
- name: Check parameters
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- keycloak_podman_user_name is defined
|
- keycloak.podman.user is defined
|
||||||
- keycloak_db_password is defined
|
- keycloak.db.password is defined
|
||||||
|
|
||||||
- name: Create PostgreSQL database
|
- name: Create PostgreSQL database
|
||||||
include_tasks: create_postgres_db.yml
|
ansible.builtin.include_tasks: create_postgres_db.yml
|
||||||
vars:
|
vars:
|
||||||
postgres_username: keycloak
|
user: "{{ keycloak.db.user }}"
|
||||||
postgres_database: keycloak
|
database: "{{ keycloak.db.database }}"
|
||||||
postgres_password: "{{ keycloak_db_password }}" #TODO: change for a password manager
|
password: "{{ keycloak.db.password }}"
|
||||||
|
access_host: "{{ keycloak.db.access_host | default(omit) }}"
|
||||||
args:
|
args:
|
||||||
apply:
|
apply:
|
||||||
delegate_to: "{{ keycloak_db_ansible_host | default(omit) }}"
|
delegate_to: "{{ keycloak.db.ansible_host | default(omit) }}"
|
||||||
|
|
||||||
- name: Set up container user
|
- name: Set up container user
|
||||||
include_role:
|
ansible.builtin.include_role:
|
||||||
name: container-user
|
name: container-user
|
||||||
vars:
|
vars:
|
||||||
podman_user: "{{ keycloak_podman_user_name }}"
|
user: "{{ keycloak.podman.user }}"
|
||||||
podman_home: "{{ keycloak_podman_user_home | default(omit) }}"
|
home: "{{ keycloak.podman.home | default(omit) }}"
|
||||||
podman_uid: "{{ keycloak_podman_user_uid | default(omit) }}"
|
uid: "{{ keycloak.podman.uid | default(omit) }}"
|
||||||
|
|
||||||
#- name: Create secrets
|
|
||||||
# containers.podman.podman_secret:
|
|
||||||
# become: true
|
|
||||||
# become_user: "{{ keycloak_podman_user_name }}"
|
|
||||||
|
|
||||||
- name: Create data directories
|
- name: Create data directories
|
||||||
ansible.builtin.file:
|
ansible.builtin.file:
|
||||||
state: directory
|
state: directory
|
||||||
path: "{{ item }}"
|
path: "{{ item }}"
|
||||||
with_items:
|
with_items:
|
||||||
- "{{ keycloak_data_dir }}/keystore/"
|
- "{{ keycloak.datadir }}/keystore/"
|
||||||
|
|
||||||
- name: Upload unit files
|
- name: Upload unit files
|
||||||
ansible.builtin.template:
|
ansible.builtin.template:
|
||||||
src: units/sso-keycloak.container.j2
|
src: units/sso-keycloak.container.j2
|
||||||
dest: ~/.config/containers/systemd/sso-keycloak.container
|
dest: ~/.config/containers/systemd/sso-keycloak.container
|
||||||
become: true
|
become: true
|
||||||
become_user: "{{ keycloak_podman_user_name }}"
|
become_user: "{{ keycloak.podman.user }}"
|
||||||
|
|
||||||
|
- name: Set up podman secrets
|
||||||
|
containers.podman.podman_secret:
|
||||||
|
name: "{{ item.key }}"
|
||||||
|
data: "{{ item.value }}"
|
||||||
|
state: present
|
||||||
|
skip_existing: false
|
||||||
|
force: true
|
||||||
|
vars:
|
||||||
|
secrets:
|
||||||
|
keycloak-admin-user: "{{ keycloak.admin.user }}"
|
||||||
|
keycloak-admin-password: "{{ keycloak.admin.password }}"
|
||||||
|
keycloak-db-host: "{{ keycloak.db.host }}"
|
||||||
|
keycloak-db-name: "{{ keycloak.db.database }}"
|
||||||
|
keycloak-db-user: "{{ keycloak.db.user }}"
|
||||||
|
keycloak-db-password: "{{ keycloak.db.password }}"
|
||||||
|
with_dict: "{{ secrets }}"
|
||||||
|
no_log: true # Secret values
|
||||||
|
|
||||||
|
become: true
|
||||||
|
become_user: "{{ keycloak.podman.user }}"
|
||||||
|
|
||||||
# Note: enabled in the unit file
|
# Note: enabled in the unit file
|
||||||
- name: Start Keycloak
|
- name: Start Keycloak
|
||||||
|
@ -52,4 +68,15 @@
|
||||||
daemon_reload: true
|
daemon_reload: true
|
||||||
state: started
|
state: started
|
||||||
become: true
|
become: true
|
||||||
become_user: "{{ keycloak_podman_user_name }}"
|
become_user: "{{ keycloak.podman.user }}"
|
||||||
|
|
||||||
|
- name: Set up reverse proxy
|
||||||
|
ansible.builtin.include_tasks: create_vhost.yml
|
||||||
|
vars:
|
||||||
|
external_url: "{{ keycloak.reverse_proxy.external_url }}"
|
||||||
|
proxy_url: "{{ keycloak.reverse_proxy.proxy_url }}"
|
||||||
|
app_name: "{{ keycloak.reverse_proxy.app_name | default('keycloak') }}"
|
||||||
|
tls: "{{ keycloak.reverse_proxy.tls | default(omit) }}"
|
||||||
|
args:
|
||||||
|
apply:
|
||||||
|
delegate_to: "{{ keycloak.reverse_proxy.ansible_host | default(omit) }}"
|
||||||
|
|
|
@ -6,6 +6,4 @@
|
||||||
- name: Set up Keycloak
|
- name: Set up Keycloak
|
||||||
include_tasks: keycloak.yml
|
include_tasks: keycloak.yml
|
||||||
vars:
|
vars:
|
||||||
podman_user_name: "{{ keycloak_podman_user_name }}"
|
keycloak: "{{ keycloak_config }}"
|
||||||
podman_user_home: "{{ keycloak_podman_user_home | default(omit) }}"
|
|
||||||
podman_user_uid: "{{ keycloak_podman_user_uid | default(omit) }}"
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ ContainerName=sso-keycloak
|
||||||
Image=quay.io/keycloak/keycloak:latest
|
Image=quay.io/keycloak/keycloak:latest
|
||||||
|
|
||||||
Environment=JAVA_OPTS="-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseG1GC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=80 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512"
|
Environment=JAVA_OPTS="-Xms64m -Xmx512m -XX:MetaspaceSize=96M -XX:MaxMetaspaceSize=256m -Dfile.encoding=UTF-8 -Dsun.stdout.encoding=UTF-8 -Dsun.err.encoding=UTF-8 -Dstdout.encoding=UTF-8 -Dstderr.encoding=UTF-8 -XX:+ExitOnOutOfMemoryError -Djava.security.egd=file:/dev/urandom -XX:+UseG1GC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=80 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:FlightRecorderOptions=stackdepth=512"
|
||||||
Volume={{ keycloak_data_dir }}/keystore/:/keystore/
|
Volume={{ keycloak.datadir }}/keystore/:/keystore/
|
||||||
|
|
||||||
Secret=keycloak-admin-user,type=env,target=KEYCLOAK_ADMIN
|
Secret=keycloak-admin-user,type=env,target=KEYCLOAK_ADMIN
|
||||||
Secret=keycloak-admin-password,type=env,target=KEYCLOAK_ADMIN_PASSWORD
|
Secret=keycloak-admin-password,type=env,target=KEYCLOAK_ADMIN_PASSWORD
|
||||||
|
@ -18,9 +18,9 @@ Secret=keycloak-db-password,type=env,target=KC_DB_PASSWORD
|
||||||
Environment=KC_DB=postgres
|
Environment=KC_DB=postgres
|
||||||
Environment=KC_HEALTH_ENABLED=true
|
Environment=KC_HEALTH_ENABLED=true
|
||||||
|
|
||||||
Exec=start --features=preview --hostname {{ keycloak_hostname }} --proxy edge
|
Exec=start --features=preview --hostname {{ keycloak.hostname }} --proxy edge
|
||||||
|
|
||||||
PublishPort={{ keycloak_listen_address }}:8080
|
PublishPort={{ keycloak.listen_address }}:8080
|
||||||
AutoUpdate=registry
|
AutoUpdate=registry
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=default.target
|
WantedBy=default.target
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
- name: Check if required parameters are set
|
- name: Check if required parameters are set
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- podman_user_name is defined
|
- user is defined
|
||||||
|
|
||||||
- name: Set up as container host
|
- name: Set up as container host
|
||||||
ansible.builtin.include_role:
|
ansible.builtin.include_role:
|
||||||
|
@ -11,17 +11,17 @@
|
||||||
|
|
||||||
- name: Create user
|
- name: Create user
|
||||||
ansible.builtin.user:
|
ansible.builtin.user:
|
||||||
name: "{{ podman_user_name }}"
|
name: "{{ user }}"
|
||||||
home: "{{ podman_user_home | default(omit) }}"
|
home: "{{ home | default(omit) }}"
|
||||||
uid: "{{ podman_user_uid | default(omit) }}"
|
uid: "{{ uid | default(omit) }}"
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
- name: Add public keys for user '{{ podman_user_name }}'
|
- name: Add public keys for user '{{ podman_user_name }}'
|
||||||
ansible.posix.authorized_key:
|
ansible.posix.authorized_key:
|
||||||
user: "{{ podman_user_name }}"
|
user: "{{ user }}"
|
||||||
key: "{{ lookup('file', '../../access/keys/' + item + '.pub') }}"
|
key: "{{ lookup('file', '../../access/keys/' + item + '.pub') }}"
|
||||||
state: present # Note: we don't remove other/existing keys
|
state: present # Note: we don't remove other/existing keys
|
||||||
with_items: "{{ global_ssh_keys + (ssh_keys[podman_user_name] | default([])) + (ssh_keys['*'] | default([])) }}"
|
with_items: "{{ global_ssh_keys + (ssh_keys[user] | default([])) + (ssh_keys['*'] | default([])) }}"
|
||||||
|
|
||||||
|
|
||||||
- name: Create unit files dir
|
- name: Create unit files dir
|
||||||
|
@ -29,15 +29,15 @@
|
||||||
path: ~/.config/containers/systemd
|
path: ~/.config/containers/systemd
|
||||||
state: directory
|
state: directory
|
||||||
become: true
|
become: true
|
||||||
become_user: "{{ podman_user_name }}"
|
become_user: "{{ user }}"
|
||||||
|
|
||||||
# Note: We check whether lingering is already enabled so we show as OK/skipped instead of changed
|
# Note: We check whether lingering is already enabled so we show as OK/skipped instead of changed
|
||||||
- name: Check if user is lingering
|
- name: Check if user is lingering
|
||||||
ansible.builtin.stat:
|
ansible.builtin.stat:
|
||||||
path: "/var/lib/systemd/linger/{{ podman_user_name }}"
|
path: "/var/lib/systemd/linger/{{ user }}"
|
||||||
register: user_lingering
|
register: user_lingering
|
||||||
|
|
||||||
- name: Enable session lingering
|
- name: Enable session lingering
|
||||||
ansible.builtin.command: "loginctl enable-linger {{ podman_user_name }}"
|
ansible.builtin.command: "loginctl enable-linger {{ user }}"
|
||||||
when:
|
when:
|
||||||
- not user_lingering.stat.exists
|
- not user_lingering.stat.exists
|
||||||
|
|
|
@ -28,3 +28,12 @@
|
||||||
community.postgresql.postgresql_user:
|
community.postgresql.postgresql_user:
|
||||||
name: root
|
name: root
|
||||||
role_attr_flags: SUPERUSER
|
role_attr_flags: SUPERUSER
|
||||||
|
|
||||||
|
- name: Change listen addresses
|
||||||
|
community.postgresql.postgresql_set:
|
||||||
|
name: listen_addresses
|
||||||
|
value: "{{ postgresql.listen_addresses }}"
|
||||||
|
become: true
|
||||||
|
become_user: postgres
|
||||||
|
when: postgresql.listen_addresses is defined
|
||||||
|
notify: Restart PostgreSQL
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
(vhost-access-log) {
|
||||||
|
log {
|
||||||
|
output file /var/log/caddy/{args[0]}-access.log
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Note: Requires a new caddy version
|
||||||
|
#{
|
||||||
|
# persist_config off
|
||||||
|
#}
|
||||||
|
|
||||||
|
import /etc/caddy/sites-enabled/*.caddy
|
|
@ -0,0 +1,4 @@
|
||||||
|
- name: Reload Caddy
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: caddy
|
||||||
|
state: reloaded
|
|
@ -0,0 +1,25 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: Install Caddy
|
||||||
|
ansible.builtin.package:
|
||||||
|
name: caddy
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Update Caddyfile
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: Caddyfile
|
||||||
|
dest: /etc/caddy/Caddyfile
|
||||||
|
|
||||||
|
- name: Create site config directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
with_items:
|
||||||
|
- /etc/caddy/sites-available
|
||||||
|
- /etc/caddy/sites-enabled
|
||||||
|
|
||||||
|
- name: Enable and start the Caddy server
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: caddy.service
|
||||||
|
enabled: true
|
||||||
|
state: started
|
|
@ -3,9 +3,9 @@
|
||||||
- name: Check params
|
- name: Check params
|
||||||
ansible.builtin.assert:
|
ansible.builtin.assert:
|
||||||
that:
|
that:
|
||||||
- postgres_username is defined
|
- user is defined
|
||||||
- postgres_database is defined
|
- database is defined
|
||||||
- not(postgres_access_host is defined and postgres_password is defined)
|
- not(access_host is defined and password is not defined)
|
||||||
|
|
||||||
- name: Set up PostgreSQL
|
- name: Set up PostgreSQL
|
||||||
ansible.builtin.include_role:
|
ansible.builtin.include_role:
|
||||||
|
@ -13,25 +13,32 @@
|
||||||
|
|
||||||
- name: Create user
|
- name: Create user
|
||||||
community.postgresql.postgresql_user:
|
community.postgresql.postgresql_user:
|
||||||
name: "{{ postgres_username }}"
|
name: "{{ user }}"
|
||||||
password: "{{ postgres_password | default(omit) }}"
|
password: "{{ password | default(omit) }}"
|
||||||
become: true
|
become: true
|
||||||
become_user: postgres
|
become_user: postgres
|
||||||
|
|
||||||
- name: Create postgres_database
|
- name: Create database
|
||||||
community.postgresql.postgresql_db:
|
community.postgresql.postgresql_db:
|
||||||
name: "{{ postgres_database }}"
|
name: "{{ database }}"
|
||||||
owner: "{{ postgres_username }}"
|
owner: "{{ user }}"
|
||||||
become: true
|
become: true
|
||||||
become_user: postgres
|
become_user: postgres
|
||||||
|
|
||||||
|
- name: Get pg_hba.conf location
|
||||||
|
community.postgresql.postgresql_query:
|
||||||
|
query: SHOW hba_file
|
||||||
|
become: true
|
||||||
|
become_user: postgres
|
||||||
|
register: postgres_hba_file_query
|
||||||
|
|
||||||
- name: Update pg_hba scram
|
- name: Update pg_hba scram authentication
|
||||||
community.postgresql.postgresql_pg_hba:
|
community.postgresql.postgresql_pg_hba:
|
||||||
contype: host
|
contype: host
|
||||||
users: "{{ postgres_username }}"
|
users: "{{ user }}"
|
||||||
source: "{{ postgres_access_host }}"
|
source: "{{ access_host }}"
|
||||||
databases: "{{ postgres_database }}"
|
databases: "{{ database }}"
|
||||||
method: "scram-sha-256"
|
method: "scram-sha-256"
|
||||||
when: postgres_access_host is defined
|
dest: "{{ postgres_hba_file_query.query_result[0].hba_file }}"
|
||||||
|
when: access_host is defined
|
||||||
notify: Restart PostgreSQL
|
notify: Restart PostgreSQL
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
- name: Check params
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- app_name is defined
|
||||||
|
- external_url is defined
|
||||||
|
- proxy_url is defined
|
||||||
|
- not(tls.type == "cloudflare" and tls.cloudflare_token is undefined)
|
||||||
|
- not(tls.type == "file" and (tls.cert is undefined or tls.key is undefined))
|
||||||
|
- tls.type is not defined or (tls.type in ['auto', 'internal', 'cloudflare', 'file'] )
|
||||||
|
|
||||||
|
- name: Set up Caddy
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: reverse-proxy
|
||||||
|
|
||||||
|
- name: Template vhost file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: vhost.caddy.j2
|
||||||
|
dest: "/etc/caddy/sites-available/{{ app_name }}.caddy"
|
||||||
|
|
||||||
|
- name: Symlink vhost
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "/etc/caddy/sites-available/{{ app_name }}.caddy"
|
||||||
|
dest: "/etc/caddy/sites-enabled/{{ app_name }}.caddy"
|
||||||
|
state: link
|
||||||
|
notify: Reload Caddy
|
|
@ -0,0 +1,17 @@
|
||||||
|
{{ external_url }} {
|
||||||
|
|
||||||
|
{% if tls is defined and tls.type != 'auto' %}
|
||||||
|
{% if tls.type == 'internal' %}
|
||||||
|
tls internal
|
||||||
|
{% elif tls.type == 'cloudflare' %}
|
||||||
|
tls {
|
||||||
|
dns cloudflare {{ tls.cloudflare_token }}
|
||||||
|
}
|
||||||
|
{% elif tls.type == 'file' %}
|
||||||
|
tls {{ tls.cert }} {{ tls.key }}
|
||||||
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
reverse_proxy {{ proxy_url }}
|
||||||
|
import vhost-access-log {{ app_name }}
|
||||||
|
}
|
Loading…
Reference in New Issue