diff --git a/roles/authelia-for-forgejo/defaults/main.json b/roles/authelia-for-forgejo/defaults/main.json new file mode 100644 index 0000000..211419e --- /dev/null +++ b/roles/authelia-for-forgejo/defaults/main.json @@ -0,0 +1,5 @@ +{ + "var_authelia_for_forgejo_forgejo_url_base": "https://forgejo.example.org", + "var_authelia_for_forgejo_client_id": "forgejo", + "var_authelia_for_forgejo_client_secret": "REPLACE_ME" +} diff --git a/roles/authelia-for-forgejo/info.md b/roles/authelia-for-forgejo/info.md new file mode 100644 index 0000000..14a539f --- /dev/null +++ b/roles/authelia-for-forgejo/info.md @@ -0,0 +1,9 @@ +## Beschreibung + +Um [Forgejo](../forgejo) gegen [Authelia](../authelia) authentifizieren zu lassen + + +## Verweise + +- [Forgejo-Dokumentation | Configuration | OpenID](https://forgejo.org/docs/latest/admin/config-cheat-sheet/#openid-openid) +- [Authelia-Dokumentation | Gitea Integration](https://www.authelia.com/integration/openid-connect/gitea/) diff --git a/roles/authelia-for-forgejo/tasks/main.json b/roles/authelia-for-forgejo/tasks/main.json new file mode 100644 index 0000000..a0aa05d --- /dev/null +++ b/roles/authelia-for-forgejo/tasks/main.json @@ -0,0 +1,25 @@ +[ + { + "name": "configuration | emplace", + "become": true, + "ansible.builtin.template": { + "src": "authelia-client-conf.json.j2", + "dest": "/etc/authelia/conf.d/clients/forgejo.json" + } + }, + { + "name": "configuration | apply", + "become": true, + "ansible.builtin.command": { + "cmd": "/usr/bin/authelia-conf-compose" + } + }, + { + "name": "restart service", + "become": true, + "ansible.builtin.systemd_service": { + "state": "restarted", + "name": "authelia" + } + } +] diff --git a/roles/authelia-for-forgejo/templates/authelia-client-conf.json.j2 b/roles/authelia-for-forgejo/templates/authelia-client-conf.json.j2 new file mode 100644 index 0000000..3f0e1c7 --- /dev/null +++ b/roles/authelia-for-forgejo/templates/authelia-client-conf.json.j2 @@ -0,0 +1,17 @@ +{ + "client_id": "{{var_authelia_for_forgejo_client_id}}", + "client_secret": "{{var_authelia_for_forgejo_client_secret}}", + "client_name": "Forgejo", + "public": false, + "authorization_policy": "one_factor", + "redirect_uris": [ + "{{var_authelia_for_forgejo_forgejo_url_base}}/user/oauth2/authelia/callback" + ], + "scopes": [ + "openid", + "email", + "profile" + ], + "userinfo_signed_response_alg": "none", + "token_endpoint_auth_method": "client_secret_basic" +} diff --git a/roles/forgejo-and-nginx/defaults/main.json b/roles/forgejo-and-nginx/defaults/main.json new file mode 100644 index 0000000..fadcf82 --- /dev/null +++ b/roles/forgejo-and-nginx/defaults/main.json @@ -0,0 +1,5 @@ +{ + "var_forgejo_and_nginx_domain": "forgejo.example.org", + "var_forgejo_and_nginx_port": 2378, + "var_forgejo_and_nginx_tls_mode": "force" +} diff --git a/roles/forgejo-and-nginx/info.md b/roles/forgejo-and-nginx/info.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/roles/forgejo-and-nginx/info.md @@ -0,0 +1 @@ + diff --git a/roles/forgejo-and-nginx/tasks/main.json b/roles/forgejo-and-nginx/tasks/main.json new file mode 100644 index 0000000..7dc3b80 --- /dev/null +++ b/roles/forgejo-and-nginx/tasks/main.json @@ -0,0 +1,35 @@ +[ + { + "name": "deactivate default site", + "become": true, + "ansible.builtin.file": { + "state": "absent", + "dest": "/etc/nginx/sites-enabled/default" + } + }, + { + "name": "emplace configuration | data", + "become": true, + "ansible.builtin.template": { + "src": "conf.j2", + "dest": "/etc/nginx/sites-available/{{var_forgejo_and_nginx_domain}}" + } + }, + { + "name": "emplace configuration | link", + "become": true, + "ansible.builtin.file": { + "state": "link", + "src": "/etc/nginx/sites-available/{{var_forgejo_and_nginx_domain}}", + "dest": "/etc/nginx/sites-enabled/{{var_forgejo_and_nginx_domain}}" + } + }, + { + "name": "restart nginx", + "become": true, + "ansible.builtin.systemd_service": { + "state": "restarted", + "name": "nginx" + } + } +] diff --git a/roles/forgejo-and-nginx/templates/conf.j2 b/roles/forgejo-and-nginx/templates/conf.j2 new file mode 100644 index 0000000..4e78b94 --- /dev/null +++ b/roles/forgejo-and-nginx/templates/conf.j2 @@ -0,0 +1,34 @@ +{% macro forgejo_common() %} + location / { + proxy_pass http://localhost:{{var_forgejo_and_nginx_port | string}}; + client_max_body_size 20M; + } +{% endmacro %} + +server { + listen 80; + listen [::]:80; + + server_name {{var_forgejo_and_nginx_domain}}; + +{% if var_forgejo_and_nginx_tls_mode == 'force' %} + return 301 https://$http_host$request_uri; +{% else %} +{{ forgejo_common() }} +{% endif %} +} + +{% if var_forgejo_and_nginx_tls_mode != 'disable' %} +server { + listen 443 ssl; + listen [::]:443 ssl; + + server_name {{var_forgejo_and_nginx_domain}}; + + ssl_certificate_key /etc/ssl/private/{{var_forgejo_and_nginx_domain}}.pem; + ssl_certificate /etc/ssl/fullchains/{{var_forgejo_and_nginx_domain}}.pem; + include /etc/nginx/ssl-hardening.conf; + +{{ forgejo_common() }} +} +{% endif %} diff --git a/roles/forgejo-and-nginx/vardef.json b/roles/forgejo-and-nginx/vardef.json new file mode 100644 index 0000000..882b53b --- /dev/null +++ b/roles/forgejo-and-nginx/vardef.json @@ -0,0 +1,19 @@ +{ + "domain": { + "mandatory": false, + "type": "string" + }, + "port": { + "mandatory": false, + "type": "integer" + }, + "tls_mode": { + "mandatory": false, + "type": "string", + "options": [ + "disable", + "enable", + "force" + ] + } +} diff --git a/roles/forgejo/defaults/main.json b/roles/forgejo/defaults/main.json new file mode 100644 index 0000000..fb59d7b --- /dev/null +++ b/roles/forgejo/defaults/main.json @@ -0,0 +1,31 @@ +{ + "var_forgejo_user": "forgejo", + "var_forgejo_directory_main": "/opt/forgejo", + "var_forgejo_directory_repositories": "/var/forgejo/repositories", + "var_forgejo_version": "7.0.5", + "var_forgejo_platform": "linux-amd64", + "var_forgejo_secret_key": "REPLACE_ME", + "var_forgejo_internal_token": "REPLACE_ME", + "var_forgejo_domain": "forgejo.example.org", + "var_forgejo_listen_address": "0.0.0.0", + "var_forgejo_listen_port": 2378, + "var_forgejo_database_kind": "sqlite", + "var_forgejo_database_data_sqlite_path": "/var/forgejo/data.sqlite", + "var_forgejo_database_data_postgresql_host": "postgresql.example.org", + "var_forgejo_database_data_postgresql_port": 5432, + "var_forgejo_database_data_postgresql_username": "forgejo_user", + "var_forgejo_database_data_postgresql_password": "REPLACE_ME", + "var_forgejo_database_data_postgresql_scheme": "forgejo", + "var_forgejo_authentication_kind": "internal", + "var_forgejo_authentication_data_authelia_url_base": "https://authelia.example.org", + "var_forgejo_authentication_data_authelia_client_id": "forgejo", + "var_forgejo_authentication_data_authelia_client_secret": "REPLACE_ME", + "var_forgejo_smtp_host": "smtp.example.org", + "var_forgejo_smtp_port": 465, + "var_forgejo_smtp_username": "REPLACE_ME", + "var_forgejo_smtp_password": "REPLACE_ME", + "var_forgejo_email_sending_enabled": false, + "var_forgejo_email_sending_sender": "forgejo@example.org", + "var_forgejo_email_sending_html": false, + "var_forgejo_title": "Forgejo: Beyond coding. We Forge." +} diff --git a/roles/forgejo/info.md b/roles/forgejo/info.md new file mode 100644 index 0000000..db535da --- /dev/null +++ b/roles/forgejo/info.md @@ -0,0 +1,14 @@ +## Beschreibung + +Zur Einrichtung der DevOps-Platform [Forgejo](https://forgejo.org/) + + +## Verweise + +- [Forgejo | Documentation | Administrator Guide](https://forgejo.org/docs/latest/admin/) +- [Forgejo | Documentation | Configuration Cheat Sheet](https://forgejo.org/docs/latest/admin/config-cheat-sheet/) + + +## ToDo + +- Download verfizieren diff --git a/roles/forgejo/tasks/main.json b/roles/forgejo/tasks/main.json new file mode 100644 index 0000000..5905488 --- /dev/null +++ b/roles/forgejo/tasks/main.json @@ -0,0 +1,101 @@ +[ + { + "name": "packages", + "become": true, + "ansible.builtin.apt": { + "update_cache": true, + "pkg": [ + "git" + ] + } + }, + { + "name": "user", + "become": true, + "ansible.builtin.user": { + "name": "{{var_forgejo_user}}", + "create_home": true, + "home": "{{var_forgejo_directory_main}}" + } + }, + { + "name": "directories | external", + "become": true, + "loop": [ + "{{var_forgejo_database_data_sqlite_path | dirname}}", + "{{var_forgejo_directory_repositories}}" + ], + "ansible.builtin.file": { + "path": "{{item}}", + "state": "directory", + "owner": "{{var_forgejo_user}}" + } + }, + { + "name": "directories | internal", + "become": true, + "become_user": "{{var_forgejo_user}}", + "loop": [ + "{{var_forgejo_directory_main}}/custom/conf" + ], + "ansible.builtin.file": { + "path": "{{item}}", + "state": "directory" + } + }, + { + "name": "download", + "become": true, + "become_user": "{{var_forgejo_user}}", + "ansible.builtin.get_url": { + "url": "https://codeberg.org/forgejo/forgejo/releases/download/v{{var_forgejo_version}}/forgejo-{{var_forgejo_version}}-{{var_forgejo_platform}}", + "dest": "{{var_forgejo_directory_main}}/forgejo", + "mode": "u+rx" + } + }, + { + "name": "config | base", + "become": true, + "become_user": "{{var_forgejo_user}}", + "ansible.builtin.template": { + "src": "config.ini.j2", + "dest": "{{var_forgejo_directory_main}}/custom/conf/app.ini" + } + }, + { + "name": "config | database", + "become": true, + "become_user": "{{var_forgejo_user}}", + "ansible.builtin.command": { + "chdir": "{{var_forgejo_directory_main}}", + "cmd": "./forgejo migrate" + } + }, + { + "name": "config | authelia", + "when": "var_forgejo_authentication_kind == 'authelia'", + "become": true, + "become_user": "{{var_forgejo_user}}", + "ansible.builtin.shell": { + "chdir": "{{var_forgejo_directory_main}}", + "cmd": "(./forgejo admin auth list | grep authelia) || ./forgejo admin auth add-oauth --provider='openidConnect' --name='authelia' --key={{var_forgejo_authentication_data_authelia_client_id}} --secret={{var_forgejo_authentication_data_authelia_client_secret}} --auto-discover-url='{{var_forgejo_authentication_data_authelia_url_base}}/.well-known/openid-configuration' --scopes='openid email profile'" + } + }, + { + "name": "systemd unit", + "become": true, + "ansible.builtin.template": { + "src": "systemd-unit.j2", + "dest": "/etc/systemd/system/forgejo.service" + } + }, + { + "name": "start", + "become": true, + "ansible.builtin.systemd_service": { + "enabled": true, + "state": "restarted", + "name": "forgejo" + } + } +] diff --git a/roles/forgejo/templates/config.ini.j2 b/roles/forgejo/templates/config.ini.j2 new file mode 100644 index 0000000..524cfd8 --- /dev/null +++ b/roles/forgejo/templates/config.ini.j2 @@ -0,0 +1,123 @@ +APP_NAME = {{var_forgejo_title}} +RUN_USER = {{var_forgejo_user}} +RUN_MODE = prod + +[server] +DOMAIN = {{var_forgejo_domain}} +ROOT_URL = https://{{var_forgejo_domain}} +;HTTP_ADDR = {{var_forgejo_listen_address}} +HTTP_PORT = {{var_forgejo_listen_port | string}} +;LANDING_PAGE = home + +[database] +{% if var_forgejo_database_kind == 'sqlite' %} +DB_TYPE = sqlite3 +PATH = {{var_forgejo_database_data_sqlite_path}} +{% endif %} +{% if var_forgejo_database_kind == 'postgresql' %} +DB_TYPE = postgres +HOST = {{var_forgejo_database_data_postgresql_host}}:{{var_forgejo_database_data_postgresql_port | string}} +USER = {{var_forgejo_database_data_postgresql_username}} +PASSWD = {{var_forgejo_database_data_postgresql_password}} +NAME = {{var_forgejo_database_data_postgresql_scheme}} +{% endif %} + +[security] +INSTALL_LOCK = true +SECRET_KEY = {{var_forgejo_secret_key}} +INTERNAL_TOKEN = {{var_forgejo_internal_token}} +DISABLE_GIT_HOOKS = true + +[oauth2] +ENABLED = false + +[log] +MODE = console +LEVEL = Info + +[git] +HOME_PATH = {{var_forgejo_directory_main}} + +[service] +REGISTER_EMAIL_CONFIRM = false + +{% if var_forgejo_authentication_kind == 'internal' %} +DISABLE_REGISTRATION = false +ALLOW_ONLY_INTERNAL_REGISTRATION = true +ALLOW_ONLY_EXTERNAL_REGISTRATION = false +SHOW_REGISTRATION_BUTTON = true +{% else %} +DISABLE_REGISTRATION = false +ALLOW_ONLY_INTERNAL_REGISTRATION = false +ALLOW_ONLY_EXTERNAL_REGISTRATION = true +SHOW_REGISTRATION_BUTTON = false +{% endif %} + +;REQUIRE_SIGNIN_VIEW = false +ENABLE_NOTIFY_MAIL = true + +;ENABLE_BASIC_AUTHENTICATION = true +;ENABLE_REVERSE_PROXY_AUTHENTICATION = false +;ENABLE_REVERSE_PROXY_AUTHENTICATION_API = false +;ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false +;ENABLE_REVERSE_PROXY_EMAIL = false +;ENABLE_REVERSE_PROXY_FULL_NAME = false + +;DEFAULT_KEEP_EMAIL_PRIVATE = false +;DEFAULT_ALLOW_CREATE_ORGANIZATION = true +;DEFAULT_USER_IS_RESTRICTED = false +;DEFAULT_USER_VISIBILITY = public +;ALLOWED_USER_VISIBILITY_MODES = public,limited,private +;DEFAULT_ORG_VISIBILITY = public +;DEFAULT_ORG_MEMBER_VISIBLE = false +;DEFAULT_ENABLE_DEPENDENCIES = true +;ALLOW_CROSS_REPOSITORY_DEPENDENCIES = true +ENABLE_USER_HEATMAP = false +ENABLE_TIMETRACKING = false +DEFAULT_ENABLE_TIMETRACKING = false + +{% if var_forgejo_authentication_kind == 'internal' %} +SHOW_REGISTRATION_BUTTON = true +{% else %} +SHOW_REGISTRATION_BUTTON = false +{% endif %} + +AUTO_WATCH_NEW_REPOS = false +AUTO_WATCH_ON_CHANGES = false + +[repository] +ROOT = {{var_forgejo_directory_repositories}} + +{% if var_forgejo_authentication_kind == 'internal' %} +[openid] +ENABLE_OPENID_SIGNIN = false +ENABLE_OPENID_SIGNUP = false +{% else %} +[openid] +ENABLE_OPENID_SIGNIN = false +ENABLE_OPENID_SIGNUP = true +WHITELISTED_URIS = {{var_forgejo_authentication_data_authelia_url_base}} + +[oauth2_client] +REGISTER_EMAIL_CONFIRM = false +OPENID_CONNECT_SCOPES = openid email profile +ENABLE_AUTO_REGISTRATION = true +USERNAME = nickname +{% endif %} + +[mailer] +{% if var_forgejo_email_sending_enabled %} +ENABLED = true +SMTP_ADDR = {{var_forgejo_smtp_host}} +SMTP_PORT = {{var_forgejo_smtp_port | string}} +FROM = {{var_forgejo_email_sending_sender}} +USER = {{var_forgejo_smtp_username}} +PASSWD = {{var_forgejo_smtp_password}} +{% if var_forgejo_email_sending_html %} +SEND_AS_PLAIN_TEXT = false +{% else %} +SEND_AS_PLAIN_TEXT = true +{% endif %} +{% else %} +ENABLED = false +{% endif %} diff --git a/roles/forgejo/templates/systemd-unit.j2 b/roles/forgejo/templates/systemd-unit.j2 new file mode 100644 index 0000000..8e2ed2e --- /dev/null +++ b/roles/forgejo/templates/systemd-unit.j2 @@ -0,0 +1,21 @@ +[Unit] +Description=Forgejo +After=network.target +{% if var_forgejo_database_kind == 'postgresql' %} +Wants=postgresql.service +After=postgresql.service +{% endif %} + +[Service] +RestartSec=2s +Type=simple +User={{var_forgejo_user}} +Group={{var_forgejo_user}} +WorkingDirectory={{var_forgejo_directory_main}} +ExecStart={{var_forgejo_directory_main}}/forgejo web --config {{var_forgejo_directory_main}}/custom/conf/app.ini +Restart=always +# Environment=USER=git HOME=/home/git FORGEJO_WORK_DIR=/var/lib/forgejo +# Environment=PATH=/path/to/git/bin:/bin:/sbin:/usr/bin:/usr/sbin + +[Install] +WantedBy=multi-user.target diff --git a/roles/forgejo/vardef.json b/roles/forgejo/vardef.json new file mode 100644 index 0000000..025ef2e --- /dev/null +++ b/roles/forgejo/vardef.json @@ -0,0 +1,126 @@ +{ + "user": { + "type": "string", + "mandatory": false + }, + "directory_main": { + "type": "string", + "mandatory": false + }, + "directory_repositories": { + "type": "string", + "mandatory": false + }, + "version": { + "type": "string", + "mandatory": false + }, + "platform": { + "type": "string", + "mandatory": false + }, + "secret_key": { + "type": "string", + "mandatory": true + }, + "internal_token": { + "type": "string", + "mandatory": true + }, + "domain": { + "type": "string", + "mandatory": false + }, + "listen_address": { + "type": "string", + "mandatory": false + }, + "listen_port": { + "type": "integer", + "mandatory": false + }, + "database_kind": { + "mandatory": false, + "type": "string", + "options": [ + "sqlite", + "postgresql" + ] + }, + "database_data_sqlite_path": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_host": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_port": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_username": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_password": { + "mandatory": false, + "type": "string" + }, + "database_data_postgresql_schema": { + "mandatory": false, + "type": "string" + }, + "authentication_kind": { + "mandatory": false, + "type": "string", + "options": [ + "internal", + "authelia" + ] + }, + "authentication_data_authelia_url_base": { + "mandatory": false, + "type": "string" + }, + "authentication_data_authelia_client_id": { + "mandatory": false, + "type": "string" + }, + "authentication_data_authelia_client_secret": { + "mandatory": false, + "type": "string" + }, + "smtp_host": { + "mandatory": false, + "type": "string" + }, + "smtp_port": { + "mandatory": false, + "type": "integer" + }, + "smtp_username": { + "mandatory": false, + "type": "string" + }, + "smtp_password": { + "mandatory": false, + "type": "string" + }, + "email_sending_enabled": { + "mandatory": false, + "type": "boolean" + }, + "email_sending_sender": { + "mandatory": false, + "type": "string" + }, + "email_sending_html": { + "mandatory": false, + "type": "boolean" + }, + "title": { + "mandatory": false, + "type": "string" + } +} diff --git a/roles/postgresql-for-forgejo/defaults/main.json b/roles/postgresql-for-forgejo/defaults/main.json new file mode 100644 index 0000000..2fecd7a --- /dev/null +++ b/roles/postgresql-for-forgejo/defaults/main.json @@ -0,0 +1,5 @@ +{ + "var_postgresql_for_forgejo_username": "forgejo_user", + "var_postgresql_for_forgejo_password": "REPLACE_ME", + "var_postgresql_for_forgejo_schema": "forgejo" +} diff --git a/roles/postgresql-for-forgejo/tasks/main.json b/roles/postgresql-for-forgejo/tasks/main.json new file mode 100644 index 0000000..6427c07 --- /dev/null +++ b/roles/postgresql-for-forgejo/tasks/main.json @@ -0,0 +1,49 @@ +[ + { + "name": "packages", + "become": true, + "ansible.builtin.apt": { + "update_cache": true, + "pkg": [ + "acl", + "python3-psycopg2" + ] + } + }, + { + "name": "user", + "become": true, + "become_user": "postgres", + "community.postgresql.postgresql_user": { + "state": "present", + "name": "{{var_postgresql_for_forgejo_username}}", + "password": "{{var_postgresql_for_forgejo_password}}" + }, + "environment": { + "PGOPTIONS": "-c password_encryption=scram-sha-256" + } + }, + { + "name": "schema", + "become": true, + "become_user": "postgres", + "community.postgresql.postgresql_db": { + "state": "present", + "name": "{{var_postgresql_for_forgejo_schema}}", + "owner": "{{var_postgresql_for_forgejo_username}}" + } + }, + { + "name": "rights", + "become": true, + "become_user": "postgres", + "community.postgresql.postgresql_privs": { + "state": "present", + "db": "{{var_postgresql_for_forgejo_schema}}", + "objs": "ALL_IN_SCHEMA", + "roles": "{{var_postgresql_for_forgejo_username}}", + "privs": "ALL", + "grant_option": true + } + } +]