Helm chart + Ansible role для Authelia 4.38: - Forward-auth для ingress-nginx через аннотации auth-url/auth-signin - OIDC provider: Gitea, Grafana, ArgoCD, MinIO, Vault, Nextcloud - SQLite default или PostgreSQL; опциональный Redis для сессий - RSA ключ OIDC генерируется автоматически если не задан в vault - ConfigMap authelia-forward-auth с готовыми аннотациями для любого сервиса - README: install, users, protect service, OIDC per-service, debug, test
207 lines
8.8 KiB
YAML
207 lines
8.8 KiB
YAML
---
|
|
# ── Validate required secrets ─────────────────────────────────────────────────
|
|
|
|
- name: Validate Authelia required secrets are set
|
|
ansible.builtin.assert:
|
|
that:
|
|
- authelia_jwt_secret is defined and authelia_jwt_secret | length >= 64
|
|
- authelia_session_secret is defined and authelia_session_secret | length >= 64
|
|
- authelia_storage_encryption_key is defined and authelia_storage_encryption_key | length >= 20
|
|
- authelia_oidc_hmac_secret is defined and authelia_oidc_hmac_secret | length >= 32
|
|
fail_msg: >
|
|
Required secrets are missing or too short in vault.yml.
|
|
authelia_jwt_secret (min 64 chars) : openssl rand -base64 64
|
|
authelia_session_secret (min 64 chars) : openssl rand -base64 64
|
|
authelia_storage_encryption_key (min 20 chars): openssl rand -base64 32
|
|
authelia_oidc_hmac_secret (min 32 chars) : openssl rand -base64 48
|
|
|
|
- name: Validate admin user password hash is set
|
|
ansible.builtin.assert:
|
|
that:
|
|
- authelia_user_admin_password_hash is defined
|
|
- authelia_user_admin_password_hash | length > 0
|
|
fail_msg: >
|
|
authelia_user_admin_password_hash is not set in vault.yml.
|
|
Generate with: docker run authelia/authelia:latest authelia hash-password 'yourpassword'
|
|
Then paste the $argon2id$... hash into vault.yml
|
|
|
|
- name: Validate OIDC client secrets when OIDC is enabled
|
|
ansible.builtin.assert:
|
|
that:
|
|
- authelia_oidc_secret_gitea is defined and authelia_oidc_secret_gitea | length >= 16
|
|
- authelia_oidc_secret_grafana is defined and authelia_oidc_secret_grafana | length >= 16
|
|
fail_msg: >
|
|
authelia_oidc_secret_gitea and authelia_oidc_secret_grafana must be set in vault.yml.
|
|
Generate with: openssl rand -hex 32
|
|
when: authelia_oidc_enabled | bool
|
|
|
|
# ── Generate OIDC RSA private key if not provided ────────────────────────────
|
|
|
|
- name: Check if OIDC private key is already set
|
|
ansible.builtin.set_fact:
|
|
_authelia_oidc_key_provided: >-
|
|
{{ authelia_oidc_private_key is defined and
|
|
authelia_oidc_private_key | length > 0 }}
|
|
|
|
- name: Generate RSA-4096 OIDC private key (if not in vault)
|
|
ansible.builtin.command: openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096
|
|
register: _generated_oidc_key
|
|
changed_when: true
|
|
no_log: true
|
|
when:
|
|
- authelia_oidc_enabled | bool
|
|
- not _authelia_oidc_key_provided | bool
|
|
|
|
- name: Use generated OIDC private key
|
|
ansible.builtin.set_fact:
|
|
_authelia_oidc_private_key_final: "{{ _generated_oidc_key.stdout }}"
|
|
no_log: true
|
|
when:
|
|
- authelia_oidc_enabled | bool
|
|
- not _authelia_oidc_key_provided | bool
|
|
|
|
- name: Use vault-provided OIDC private key
|
|
ansible.builtin.set_fact:
|
|
_authelia_oidc_private_key_final: "{{ authelia_oidc_private_key }}"
|
|
no_log: true
|
|
when: _authelia_oidc_key_provided | bool
|
|
|
|
- name: Set empty OIDC private key (OIDC disabled)
|
|
ansible.builtin.set_fact:
|
|
_authelia_oidc_private_key_final: ""
|
|
when: not (authelia_oidc_enabled | bool)
|
|
|
|
# ── Create namespace ──────────────────────────────────────────────────────────
|
|
|
|
- name: Create authelia namespace
|
|
ansible.builtin.command: >
|
|
k3s kubectl create namespace {{ authelia_namespace }}
|
|
--dry-run=client -o yaml | k3s kubectl apply -f -
|
|
become: true
|
|
changed_when: false
|
|
|
|
# ── Copy Helm chart ───────────────────────────────────────────────────────────
|
|
|
|
- name: Ensure chart temp directory is clean
|
|
ansible.builtin.file:
|
|
path: /tmp/authelia-chart
|
|
state: absent
|
|
become: true
|
|
|
|
- name: Create chart temp directory
|
|
ansible.builtin.file:
|
|
path: /tmp/authelia-chart
|
|
state: directory
|
|
mode: "0755"
|
|
become: true
|
|
|
|
- name: Copy Helm chart to master
|
|
ansible.builtin.copy:
|
|
src: "{{ role_path }}/chart/"
|
|
dest: /tmp/authelia-chart/
|
|
mode: preserve
|
|
become: true
|
|
|
|
# ── Template Helm values ──────────────────────────────────────────────────────
|
|
|
|
- name: Template Helm values
|
|
ansible.builtin.template:
|
|
src: values.yaml.j2
|
|
dest: /tmp/authelia-values.yaml
|
|
mode: "0600"
|
|
become: true
|
|
no_log: true
|
|
|
|
# ── Lint chart ────────────────────────────────────────────────────────────────
|
|
|
|
- name: Lint Helm chart
|
|
ansible.builtin.command: >
|
|
helm lint /tmp/authelia-chart
|
|
--values /tmp/authelia-values.yaml
|
|
become: true
|
|
changed_when: false
|
|
register: _helm_lint
|
|
failed_when: _helm_lint.rc != 0
|
|
|
|
# ── Deploy chart ──────────────────────────────────────────────────────────────
|
|
|
|
- name: Deploy Authelia via Helm
|
|
ansible.builtin.command: >
|
|
helm upgrade --install {{ authelia_release_name }}
|
|
/tmp/authelia-chart
|
|
--namespace {{ authelia_namespace }}
|
|
--values /tmp/authelia-values.yaml
|
|
--atomic
|
|
--wait
|
|
--timeout 180s
|
|
become: true
|
|
register: _helm_result
|
|
changed_when: true
|
|
|
|
# ── Cleanup ───────────────────────────────────────────────────────────────────
|
|
|
|
- name: Remove temp values file (contains secrets)
|
|
ansible.builtin.file:
|
|
path: /tmp/authelia-values.yaml
|
|
state: absent
|
|
become: true
|
|
|
|
# ── Wait for readiness ────────────────────────────────────────────────────────
|
|
|
|
- name: Wait for Authelia pod to be ready
|
|
ansible.builtin.command: >
|
|
k3s kubectl -n {{ authelia_namespace }} rollout status
|
|
deployment/authelia --timeout=120s
|
|
become: true
|
|
changed_when: false
|
|
|
|
# ── Get status ────────────────────────────────────────────────────────────────
|
|
|
|
- name: Get pod status
|
|
ansible.builtin.command: >
|
|
k3s kubectl -n {{ authelia_namespace }} get pods,svc,ingress -o wide
|
|
become: true
|
|
changed_when: false
|
|
register: _status
|
|
|
|
- name: Get forward-auth annotations reference
|
|
ansible.builtin.command: >
|
|
k3s kubectl -n {{ authelia_namespace }} get cm authelia-forward-auth
|
|
-o jsonpath='{.data.annotations\.yaml}'
|
|
become: true
|
|
changed_when: false
|
|
register: _annotations
|
|
|
|
# ── Summary ───────────────────────────────────────────────────────────────────
|
|
|
|
- name: "=== Authelia SSO Ready ==="
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "╔══════════════════════════════════════════════════════════════╗"
|
|
- "║ Authelia SSO — Deployed ║"
|
|
- "╚══════════════════════════════════════════════════════════════╝"
|
|
- ""
|
|
- " Portal : http{{ 's' if authelia_ingress_tls_enabled else '' }}://{{ authelia_host }}/"
|
|
- " Namespace : {{ authelia_namespace }}"
|
|
- " OIDC : {{ 'enabled' if authelia_oidc_enabled else 'disabled' }}"
|
|
- " Storage : {{ authelia_storage_type }}"
|
|
- " Redis : {{ 'enabled' if authelia_redis_enabled else 'disabled' }}"
|
|
- ""
|
|
- " ── Protect a new service (add to its Ingress) ──"
|
|
- "{{ _annotations.stdout_lines | to_yaml }}"
|
|
- ""
|
|
- " ── OIDC Issuer URL ──"
|
|
- " http{{ 's' if authelia_ingress_tls_enabled else '' }}://{{ authelia_host }}"
|
|
- ""
|
|
- " ── Pods / Services ──"
|
|
- "{{ _status.stdout_lines | to_yaml }}"
|
|
- ""
|
|
- " Login: open http{{ 's' if authelia_ingress_tls_enabled else '' }}://{{ authelia_host }}/"
|
|
- " user: admin | pass: <your vault plaintext password>"
|
|
- ""
|
|
- "{% if not _authelia_oidc_key_provided %}"
|
|
- " ⚠ OIDC private key was AUTO-GENERATED. Save it to vault.yml for reproducibility:"
|
|
- " kubectl -n {{ authelia_namespace }} get secret authelia-secrets \\"
|
|
- " -o jsonpath='{.data.oidc_private_key}' | base64 -d"
|
|
- "{% endif %}"
|