diff --git a/README.md b/README.md new file mode 100644 index 0000000..48e8e96 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# authentik diff --git a/compose.yml b/compose.yml deleted file mode 100644 index 7b5a8ec..0000000 --- a/compose.yml +++ /dev/null @@ -1,123 +0,0 @@ -services: - postgresql: - environment: - POSTGRES_DB: ${PG_DB:-authentik} - POSTGRES_PASSWORD: ${PG_PASS:?database password required} - POSTGRES_USER: ${PG_USER:-authentik} - healthcheck: - interval: 30s - retries: 5 - start_period: 20s - test: - - CMD-SHELL - - pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER} - timeout: 5s - image: docker.io/library/postgres:16-alpine - networks: - - internal - restart: unless-stopped - volumes: - - database:/var/lib/postgresql/data - server: - # Server includes embeded proxy outpost - command: server - hostname: authentik-proxy - depends_on: - postgresql: - condition: service_healthy - environment: - AUTHENTIK_POSTGRESQL__HOST: postgresql - AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} - AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} - AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} - AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required} - - AUTHENTIK_EMAIL__HOST: mail.postale.io - AUTHENTIK_EMAIL__PORT: 587 - AUTHENTIK_EMAIL__USERNAME: ${EMAIL__ADDRESS} - AUTHENTIK_EMAIL__PASSWORD: ${EMAIL__PASSWORD} - AUTHENTIK_EMAIL__USE_TLS: true - AUTHENTIK_EMAIL__USE_SSL: false - AUTHENTIK_EMAIL__TIMEOUT: 60 - AUTHENTIK_EMAIL__FROM: ${EMAIL__ADDRESS} - image: ghcr.io/goauthentik/server:2025.10.3 - networks: - - proxy - - internal - restart: unless-stopped - volumes: - - shared_media:/media - - shared_data:/data - - shared_templates:/templates - labels: - traefik.enable: true - traefik.http.routers.authentik.rule: "Host(`auth.urmel.de`)" - traefik.http.routers.authentik.tls: true - traefik.http.routers.authentik.tls.certresolver: hetzner - traefik.http.routers.authentik.priority: 100000001 - traefik.http.routers.authentik.service: authentik - traefik.http.services.authentik.loadbalancer.server.port: 9000 - - # https://goneuland.de/authentik-in-kombination-mit-traefik/#2_Authentik_im_Stack_vorbereiten - traefik.http.routers.authentik-outpost.rule: "HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.urmel.de`) && PathPrefix(`/outpost.goauthentik.io/`)" - traefik.http.routers.authentik-outpost.tls: true - traefik.http.routers.authentik-outpost.priority: 100000000 - traefik.http.routers.authentik-outpost.service: authentik-outpost - traefik.http.services.authentik-outpost.loadbalancer.server.port: 9000 - - worker: - command: worker - depends_on: - postgresql: - condition: service_healthy - environment: - AUTHENTIK_POSTGRESQL__HOST: postgresql - AUTHENTIK_POSTGRESQL__NAME: ${PG_DB:-authentik} - AUTHENTIK_POSTGRESQL__PASSWORD: ${PG_PASS} - AUTHENTIK_POSTGRESQL__USER: ${PG_USER:-authentik} - AUTHENTIK_SECRET_KEY: ${AUTHENTIK_SECRET_KEY:?secret key required} - - AUTHENTIK_EMAIL__HOST: mail.postale.io - AUTHENTIK_EMAIL__PORT: 587 - AUTHENTIK_EMAIL__USERNAME: ${EMAIL__ADDRESS} - AUTHENTIK_EMAIL__PASSWORD: ${EMAIL__PASSWORD} - AUTHENTIK_EMAIL__USE_TLS: true - AUTHENTIK_EMAIL__USE_SSL: false - AUTHENTIK_EMAIL__TIMEOUT: 60 - AUTHENTIK_EMAIL__FROM: ${EMAIL__ADDRESS} - image: ghcr.io/goauthentik/server:2025.10.3 - networks: - - internal - restart: unless-stopped - user: root - volumes: - - /var/run/docker.sock:/var/run/docker.sock - - shared_media:/media - - worker_certs:/certs - - shared_data:/data - - shared_templates:/templates - - radius_outpost: - image: ghcr.io/goauthentik/radius:2025.10.3 - networks: - - internal - ports: - - 1812:1812/udp - environment: - AUTHENTIK_HOST: https://auth.urmel.de - AUTHENTIK_INSECURE: false - AUTHENTIK_TOKEN: ${AUTHENTIK_SECRET_KEY:?secret key required} - -networks: - proxy: - name: traefik_exposed - external: true - internal: - -volumes: - database: - driver: local - shared_media: - shared_data: - shared_templates: - worker_certs: diff --git a/defaults/main.yml b/defaults/main.yml new file mode 100644 index 0000000..a859a2d --- /dev/null +++ b/defaults/main.yml @@ -0,0 +1,14 @@ +path: /srv/{{ role_name }} + +authentik_override: {} +authentik_defaults: + url: "" + db_password: "" + secret: "" + mail: + user: "" + password: "" + host: "" + port: 587 + radius: + enabled: false diff --git a/theme/main.css b/files/theme/main.css similarity index 100% rename from theme/main.css rename to files/theme/main.css diff --git a/handlers/main.yml b/handlers/main.yml new file mode 100644 index 0000000..f0c8ab0 --- /dev/null +++ b/handlers/main.yml @@ -0,0 +1,9 @@ +- name: restart container +community.docker.docker_compose_v2: + project_src: "{{ path }}" + project_name: "{{ role_name }}" + recreate: "always" + services: ["authentik"] + state: "restarted" +when: not _authentik_already_restarted + diff --git a/meta/main.yml b/meta/main.yml new file mode 100644 index 0000000..4d4b40d --- /dev/null +++ b/meta/main.yml @@ -0,0 +1,20 @@ +--- +galaxy_info: + author: "Niklas Freese " + description: authentik + company: "Urmel Services" + license: AGPL-3.0-or-later + 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: +# - role: base diff --git a/tasks/main.yml b/tasks/main.yml new file mode 100644 index 0000000..0f9908b --- /dev/null +++ b/tasks/main.yml @@ -0,0 +1,31 @@ +--- +- name: "set local variables from overrides and defaults" + set_fact: + authentik: "{{ (authentik_defaults | combine(authentik_override, recursive=True)) if authentik_override else authentik_defaults }}" + +- name: ensure that path exists + file: + path: "{{ path }}/config/authentik" + state: directory + +- name: Template .env + template: + src: .env.j2 + dest: "{{ path }}/.env" + +- name: Template compose + template: + src: compose.yml.j2 + dest: "{{ path }}/compose.yml" + +- name: ensure containers are running + community.docker.docker_compose_v2: + project_src: "{{ path }}" + project_name: "{{ role_name }}" + state: "present" + pull: "always" + wait: true + services: >- + {{ ['postgresql', 'authentik-proxy', 'authentik-worker'] + + (['radius_outpost'] if authentik.radius.enabled else []) }} + register: _compose_result diff --git a/templates/.env.j2 b/templates/.env.j2 new file mode 100644 index 0000000..0c5d4e1 --- /dev/null +++ b/templates/.env.j2 @@ -0,0 +1,14 @@ +AUTHENTIK_POSTGRESQL__HOST: postgresql +AUTHENTIK_POSTGRESQL__NAME: authentik +AUTHENTIK_POSTGRESQL__PASSWORD: "{{ authentik.db_password }}" +AUTHENTIK_POSTGRESQL__USER: authentik +AUTHENTIK_SECRET_KEY: "{{ authentik.secret }}" + +AUTHENTIK_EMAIL__HOST: "{{ authentik.mail.host }}" +AUTHENTIK_EMAIL__PORT: "{{ authentik.mail.port }}" +AUTHENTIK_EMAIL__USERNAME: "{{ authentik.mail.user }}" +AUTHENTIK_EMAIL__PASSWORD: "{{ authentik.mail.password }}" +AUTHENTIK_EMAIL__USE_TLS: true +AUTHENTIK_EMAIL__USE_SSL: false +AUTHENTIK_EMAIL__TIMEOUT: 60 +AUTHENTIK_EMAIL__FROM: "{{ authentik.mail.user }}" diff --git a/templates/compose.yml.j2 b/templates/compose.yml.j2 new file mode 100644 index 0000000..6c542fc --- /dev/null +++ b/templates/compose.yml.j2 @@ -0,0 +1,86 @@ +services: + postgresql: + environment: + POSTGRES_DB: authentik + POSTGRES_PASSWORD: "{{ authentik.db_password }}" + POSTGRES_USER: authentik + healthcheck: + interval: 30s + retries: 5 + start_period: 20s + test: + - CMD-SHELL + - pg_isready -d authentik -U authentik + timeout: 5s + image: docker.io/library/postgres:16-alpine + networks: + - internal + restart: unless-stopped + volumes: + - ./data/db:/var/lib/postgresql/data + + authentik-proxy: + # Server includes embeded proxy outpost + command: server + depends_on: + postgresql: + condition: service_healthy + env_file: ".env" + image: ghcr.io/goauthentik/server:2025.10.3 + networks: + - proxy + - internal + restart: unless-stopped + volumes: + - ./data/authentik_media:/media + - ./data/authentik_data:/data + - ./data/authentik_templates:/templates + labels: + traefik.enable: true + traefik.http.routers.authentik.rule: "Host(`{{ authentik.url }}`)" + traefik.http.routers.authentik.tls: true + traefik.http.routers.authentik.tls.certresolver: hetzner + traefik.http.routers.authentik.priority: 100000001 + traefik.http.routers.authentik.service: authentik + traefik.http.services.authentik.loadbalancer.server.port: 9000 + + # https://goneuland.de/authentik-in-kombination-mit-traefik/#2_Authentik_im_Stack_vorbereiten + traefik.http.routers.authentik-outpost.rule: "HostRegexp(`{subdomain:[a-zA-Z0-9-]+}.{{ authentik.url.split('.', 1)[1] }}`) && PathPrefix(`/outpost.goauthentik.io/`)" + traefik.http.routers.authentik-outpost.tls: true + traefik.http.routers.authentik-outpost.priority: 100000000 + traefik.http.routers.authentik-outpost.service: authentik-outpost + traefik.http.services.authentik-outpost.loadbalancer.server.port: 9000 + + authentik-worker: + command: worker + depends_on: + postgresql: + condition: service_healthy + env_file: ".env" + image: ghcr.io/goauthentik/server:2025.10.3 + networks: + - internal + restart: unless-stopped + user: root + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - ./data/authentik_media:/media + - ./data/authentik_data:/data + - ./data/authentik_templates:/templates + - ./data/authentik_certs:/certs + + {% if authentik.radius.enabled -%} + radius_outpost: + image: ghcr.io/goauthentik/radius:2025.10.3 + networks: + - internal + ports: + - 1812:1812/udp + env_file: ".env" + {{ endif -}} + +networks: + proxy: + name: traefik_exposed + external: true + internal: