diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..757cb2c --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,9 @@ +skip_list: + - 'yaml' + - 'risky-shell-pipe' + - 'role-name' + +kinds: + - meta: "**/meta/main.yml" + - tasks: "**/tasks/*.yml" + - vars: "**/vars/*.yml" \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..37f76e9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2022 Laur Ivan + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/defaults/main.yml b/defaults/main.yml index e160065..5d7786d 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,2 +1,59 @@ --- # defaults file for authentik + +authentik_container_name: "authentik" +authentik_image_version: "2022.8.2" + +# Don't forget to change the secret key! +# +authentik_secret_key: "changeme" +authentik_error_reporting: "false" + +# Because of a PostgreSQL limitation, only passwords up to 99 chars are supported +# See https://www.postgresql.org/message-id/09512C4F-8CB9-4021-B455-EF4C4F0D55A0@amazon.com +authentik_db: "authentik" +authentik_db_user: "authentik" +authentik_db_password: "changeme" + +# SMTP configuration +# +# SMTP Host Emails are sent to +authentik_email_host: "localhost" +authentik_email_port: "25" +# Optionally authenticate (don't add quotation marks to you password) +authentik_email_username: +authentik_email_password: +# Use StartTLS +authentik_email_use_tls: "false" +# Use SSL +authentik_email_use_ssl: "false" +authentik_email_timeout: "10" +# Email address authentik will send from, should have a correct @domain +authentik_email_from: "authentik@localhost" + +# Allow the DB to be located somewhere else +# +authentik_authentik_geoip: "/geoip/GeoLite2-City.mmdb" + +# Authentik ports (ports mapped from docker) +authentik_port_http: 80 +authentik_port_https: 443 + +# Authentik volumes +# +# base path to be used by others as default +authentik_volume_base: "/mnt/authentik" +# media +authentik_volume_config: "{{ authentik_volume_base }}/config" +# media +authentik_volume_media: "{{ authentik_volume_base }}/media" +# certs for https +authentik_volume_certs: "{{ authentik_volume_base }}/certs" +# geoip db location +authentik_volume_geoip: "{{ authentik_volume_base }}/geoip" +# custom templates +authentik_volume_templates: "{{ authentik_volume_base }}/templates" +# db +authentik_volume_db: "{{ authentik_volume_base }}/db" +# redis +authentik_volume_redis: "{{ authentik_volume_base }}/redis" \ No newline at end of file diff --git a/handlers/main.yml b/handlers/main.yml index 5a4b316..963cf49 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,2 +1,9 @@ --- # handlers file for authentik + +- name: Restart authentik + community.docker.docker_compose: + project_src: ~/authentik/ + build: false + restarted: true + become: false diff --git a/meta/main.yml b/meta/main.yml index e5b89bc..a3560aa 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,53 +1,34 @@ galaxy_info: - author: your name + author: Laur Ivan namespace: laurivan - description: your role description - company: your company (optional) + role_name: authentik + description: Authentik installation via docker + license: license (BSD, MIT) - # 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 + min_ansible_version: "2.4" + min_ansible_container_version: "2.4" - # 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) + platforms: + - name: Debian + versions: + - buster + - bullseye + - name: Ubuntu + versions: + - bionic + - focal + - jammy + - name: Alpine + version: + - all + - name: ArchLinux + versions: + - all - min_ansible_version: 2.1 - - # If this a Container Enabled role, provide the minimum Ansible Container version. - # min_ansible_container_version: - - # - # Provide a list of supported platforms, and for each platform a list of versions. - # If you don't wish to enumerate all versions for a particular platform, use 'all'. - # To view available platforms and versions (or releases), visit: - # https://galaxy.ansible.com/api/v1/platforms/ - # - # platforms: - # - name: Fedora - # versions: - # - all - # - 25 - # - name: SomePlatform - # versions: - # - all - # - 1.0 - # - 7 - # - 99.99 - - 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. + galaxy_tags: + - docker + - authentik + - sso + - authentication dependencies: [] - # List your role dependencies here, one per line. Be sure to remove the '[]' above, - # if you add dependencies to this list. diff --git a/molecule/default/converge.yml b/molecule/default/converge.yml index 46259e7..b48a918 100644 --- a/molecule/default/converge.yml +++ b/molecule/default/converge.yml @@ -1,8 +1,22 @@ --- - name: Converge hosts: all - gather_facts: false - tasks: - - name: "Include laurivan.authentik" - ansible.builtin.include_role: - name: "laurivan.authentik" + # gather_facts: false + pre_tasks: + - name: Install docker + vars: + docker_service_manage: false + include_role: + name: geerlingguy.docker + - name: Update apt cache. + apt: update_cache=yes cache_valid_time=600 + when: ansible_os_family == 'Debian' + - name: Install python requests + pip: + name: + - requests + - docker + - docker-compose + + roles: + - role: laurivan.authentik diff --git a/molecule/default/create.yml b/molecule/default/create-old.yml similarity index 97% rename from molecule/default/create.yml rename to molecule/default/create-old.yml index 09489e3..39c83d2 100644 --- a/molecule/default/create.yml +++ b/molecule/default/create-old.yml @@ -2,7 +2,7 @@ - name: Create hosts: localhost connection: local - gather_facts: false + # gather_facts: false no_log: "{{ molecule_no_log }}" tasks: diff --git a/molecule/default/molecule.yml b/molecule/default/molecule.yml index 74c8557..2e74ab0 100644 --- a/molecule/default/molecule.yml +++ b/molecule/default/molecule.yml @@ -1,11 +1,30 @@ --- +role_name_check: 1 dependency: name: galaxy + options: + ignore-certs: true + ignore-errors: true + role-file: molecule/default/requirements.yml + requirements-file: molecule/default/requirements.yml driver: - name: delegated + name: docker platforms: - - name: instance + - name: instance-authentik + image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos8}-ansible:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + volumes: + - /sys/fs/cgroup:/sys/fs/cgroup:ro + - /var/run/docker.sock:/tmp/docker.sock + privileged: true + pre_build_image: true provisioner: name: ansible + playbooks: + converge: ${MOLECULE_PLAYBOOK:-converge.yml} verifier: name: ansible +lint: | + set -e + yamllint . + ansible-lint . \ No newline at end of file diff --git a/molecule/default/prepare.yml b/molecule/default/prepare.yml new file mode 100644 index 0000000..8d23523 --- /dev/null +++ b/molecule/default/prepare.yml @@ -0,0 +1,12 @@ +--- +- name: Setup the intragate machine + hosts: instance-authentik + tasks: + - name: create docker.sock + raw: touch /var/run/docker.sock + become: true + changed_when: false + - name: move docker.sock from tmp + raw: mount --move /tmp/docker.sock /var/run/docker.sock + become: true + changed_when: false diff --git a/molecule/default/requirements.yml b/molecule/default/requirements.yml new file mode 100644 index 0000000..626d077 --- /dev/null +++ b/molecule/default/requirements.yml @@ -0,0 +1,6 @@ +--- +roles: + - geerlingguy.docker +collections: + # - community.general + - community.docker \ No newline at end of file diff --git a/tasks/main.yml b/tasks/main.yml index 0b26a10..b1dd8fc 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,2 +1,42 @@ --- # tasks file for authentik + +- name: Set up directories + file: + state: directory + path: "{{ item }}" + mode: 0755 + with_items: + - "{{ authentik_volume_media }}" + - "{{ authentik_volume_certs }}" + - "{{ authentik_volume_geoip }}" + - "{{ authentik_volume_templates }}" + - "{{ authentik_volume_db }}" + - "{{ authentik_volume_config }}" + - "{{ authentik_volume_redis }}" + - "~/authentik" + tags: + - configuration + become: false + +- name: Copy Authentik docker-compose template. + ansible.builtin.template: + src: templates/docker-compose.yml.j2 + dest: ~/authentik/docker-compose.yml + mode: '0640' + become: false + notify: Restart authentik + +- name: Copy Authentik configuration. + ansible.builtin.template: + src: templates/env.authentik.conf.j2 + dest: "{{ authentik_volume_config }}/env.authentik.conf" + mode: '0640' + become: false + notify: Restart authentik + +- name: Ensure Authentik is running. + community.docker.docker_compose: + project_src: ~/authentik/ + build: false + become: false diff --git a/templates/docker-compose.yml.j2 b/templates/docker-compose.yml.j2 new file mode 100644 index 0000000..ab8a421 --- /dev/null +++ b/templates/docker-compose.yml.j2 @@ -0,0 +1,97 @@ +--- +version: '3.4' + +services: + postgresql-authentik: + image: docker.io/library/postgres:12-alpine + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "pg_isready -d $${POSTGRES_DB} -U $${POSTGRES_USER}"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 5s + volumes: + - {{ authentik_volume_db }}:/var/lib/postgresql/data + environment: + - POSTGRES_PASSWORD={{ authentik_db_password }} + - POSTGRES_USER={{ authentik_db_user }} + - POSTGRES_DB={{ authentik_db }} + env_file: + - {{ authentik_volume_config }}/env.authentik.conf + networks: + - authentik + redis-authentik: + image: docker.io/library/redis:alpine + command: --save 60 1 --loglevel warning + restart: unless-stopped + healthcheck: + test: ["CMD-SHELL", "redis-cli ping | grep PONG"] + start_period: 20s + interval: 30s + retries: 5 + timeout: 3s + volumes: + - {{ authentik_volume_redis }}:/data + networks: + - authentik + server: + image: ghcr.io/goauthentik/server:{{ authentik_image_version }} + restart: unless-stopped + command: server + environment: + AUTHENTIK_REDIS__HOST: redis-authentik + AUTHENTIK_POSTGRESQL__HOST: postgresql-authentik + AUTHENTIK_POSTGRESQL__NAME: "{{ authentik_db }}" + AUTHENTIK_POSTGRESQL__USER: "{{ authentik_db_user }}" + AUTHENTIK_POSTGRESQL__PASSWORD: "{{ authentik_db_password }}" + # AUTHENTIK_ERROR_REPORTING__ENABLED: "true" + # WORKERS: 2 + volumes: + - {{ authentik_volume_media }}:/media + - {{ authentik_volume_templates }}:/templates + - {{ authentik_volume_geoip }}:/geoip + env_file: + - {{ authentik_volume_config }}/env.authentik.conf + ports: + - "0.0.0.0:{{ authentik_port_http }}:9000" + - "0.0.0.0:{{ authentik_port_https }}:9443" + networks: + - authentik + worker: + image: ghcr.io/goauthentik/server:{{ authentik_image_version }} + restart: unless-stopped + command: worker + environment: + AUTHENTIK_REDIS__HOST: redis-authentik + AUTHENTIK_POSTGRESQL__HOST: postgresql-authentik + AUTHENTIK_POSTGRESQL__NAME: "{{ authentik_db }}" + AUTHENTIK_POSTGRESQL__USER: "{{ authentik_db_user }}" + AUTHENTIK_POSTGRESQL__PASSWORD: "{{ authentik_db_password }}" + # AUTHENTIK_ERROR_REPORTING__ENABLED: "true" + # This is optional, and can be removed. If you remove this, the following will happen + # - The permissions for the /media folders aren't fixed, so make sure they are 1000:1000 + # - The docker socket can't be accessed anymore + user: root + volumes: + - {{ authentik_volume_media }}:/media + - {{ authentik_volume_certs }}:/certs + - /var/run/docker.sock:/var/run/docker.sock + - {{ authentik_volume_templates }}:/templates + - {{ authentik_volume_geoip }}:/geoip + env_file: + - {{ authentik_volume_config }}/env.authentik.conf + geoipupdate: + image: "maxmindinc/geoipupdate:latest" + volumes: + - "{{ authentik_volume_geoip }}:/usr/share/GeoIP" + environment: + GEOIPUPDATE_EDITION_IDS: "GeoLite2-City" + GEOIPUPDATE_FREQUENCY: "8" + env_file: + - {{ authentik_volume_config }}/env.authentik.conf + networks: + - authentik + +networks: + authentik: {} diff --git a/templates/env.authentik.conf.j2 b/templates/env.authentik.conf.j2 new file mode 100644 index 0000000..bcff2f2 --- /dev/null +++ b/templates/env.authentik.conf.j2 @@ -0,0 +1,46 @@ +AUTHENTIK_SECRET_KEY={{ authentik_secret_key }} +AUTHENTIK_ERROR_REPORTING__ENABLED={{ authentik_error_reporting }} + + +{% if authentik_email_host is defined and authentik_email_host|length %} +# SMTP Host Emails are sent to + AUTHENTIK_EMAIL__HOST={{ authentik_email_host }} + AUTHENTIK_EMAIL__PORT={{ authentik_email_port }} +# Optionally authenticate (don't add quotation marks to you password) + AUTHENTIK_EMAIL__USERNAME={{ authentik_email_username }} + AUTHENTIK_EMAIL__PASSWORD={{ authentik_email_password }} +# Use StartTLS + AUTHENTIK_EMAIL__USE_TLS={{ authentik_email_use_tls }} +# Use SSL + AUTHENTIK_EMAIL__USE_SSL={{ authentik_email_use_ssl }} + AUTHENTIK_EMAIL__TIMEOUT={{ authentik_email_timeout }} +# Email address authentik will send from, should have a correct @domain + AUTHENTIK_EMAIL__FROM={{ authentik_email_from }} +{% else %} +# +# no email facilities +# +{% endif %} + +# REDIS +# +AUTHENTIK_REDIS__HOST=redis-authentik + +# DB +# +AUTHENTIK_POSTGRESQL__HOST=db-authentik +AUTHENTIK_POSTGRESQL__USER={{ authentik_db_user }} +AUTHENTIK_POSTGRESQL__NAME=authentik +AUTHENTIK_POSTGRESQL__PASSWORD={{ authentik_db_password }} + +# AUTHENTIK_LOG_LEVEL=debug + +# Air-gapped environment +AUTHENTIK_DISABLE_UPDATE_CHECK=true +AUTHENTIK_ERROR_REPORTING__ENABLED=false +AUTHENTIK_DISABLE_STARTUP_ANALYTICS=true +AUTHENTIK_AVATARS=none + +# First-time password +AK_ADMIN_PASS=akadmin +