diff --git a/ansible/playbooks/indri.yml b/ansible/playbooks/indri.yml index c3d5112..6e962f1 100644 --- a/ansible/playbooks/indri.yml +++ b/ansible/playbooks/indri.yml @@ -22,6 +22,45 @@ no_log: true tags: [borgmatic] + # Forgejo secrets + - name: Fetch forgejo LFS JWT secret + ansible.builtin.command: + cmd: op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get w3663ffnvkewbftncqxtcpeavy --fields lfs-jwt-secret --reveal + delegate_to: localhost + register: _forgejo_lfs_jwt + changed_when: false + no_log: true + check_mode: false + tags: [forgejo] + + - name: Fetch forgejo internal token + ansible.builtin.command: + cmd: op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get w3663ffnvkewbftncqxtcpeavy --fields internal-token --reveal + delegate_to: localhost + register: _forgejo_internal_token + changed_when: false + no_log: true + check_mode: false + tags: [forgejo] + + - name: Fetch forgejo OAuth2 JWT secret + ansible.builtin.command: + cmd: op --vault vg6xf6vvfmoh5hqjjhlhbeoaie item get w3663ffnvkewbftncqxtcpeavy --fields oauth2-jwt-secret --reveal + delegate_to: localhost + register: _forgejo_oauth2_jwt + changed_when: false + no_log: true + check_mode: false + tags: [forgejo] + + - name: Set forgejo secrets facts + ansible.builtin.set_fact: + forgejo_lfs_jwt_secret: "{{ _forgejo_lfs_jwt.stdout }}" + forgejo_internal_token: "{{ _forgejo_internal_token.stdout }}" + forgejo_oauth2_jwt_secret: "{{ _forgejo_oauth2_jwt.stdout }}" + no_log: true + tags: [forgejo] + roles: - role: alloy tags: alloy diff --git a/ansible/roles/forgejo/defaults/main.yml b/ansible/roles/forgejo/defaults/main.yml new file mode 100644 index 0000000..23396e8 --- /dev/null +++ b/ansible/roles/forgejo/defaults/main.yml @@ -0,0 +1,51 @@ +--- +# Forgejo configuration +# Secrets are fetched from 1Password in the playbook pre_tasks + +forgejo_app_name: Forgejo +forgejo_app_slogan: "Beyond coding. We Forge." +forgejo_run_user: forgejo +forgejo_run_mode: prod + +# Paths (brew-managed for now, will change to mcquack in Phase 3) +forgejo_work_path: /opt/homebrew/var/forgejo +forgejo_config_path: "{{ forgejo_work_path }}/custom/conf/app.ini" +forgejo_data_path: "{{ forgejo_work_path }}/data" +forgejo_repo_root: "{{ forgejo_data_path }}/forgejo-repositories" +forgejo_lfs_path: "{{ forgejo_data_path }}/lfs" +forgejo_log_path: "{{ forgejo_work_path }}/log" + +# Server settings +forgejo_http_addr: 0.0.0.0 +forgejo_http_port: 3001 +forgejo_domain: forge.tail8d86e.ts.net +forgejo_ssh_domain: "{{ forgejo_domain }}" +forgejo_root_url: "https://{{ forgejo_domain }}/" +forgejo_offline_mode: true + +# SSH settings (built-in SSH server) +forgejo_disable_ssh: false +forgejo_start_ssh_server: true +forgejo_builtin_ssh_user: forgejo +forgejo_ssh_port: 22 +forgejo_ssh_listen_port: 2200 +forgejo_lfs_start_server: true + +# Database (SQLite) +forgejo_db_type: sqlite3 +forgejo_db_path: "{{ forgejo_data_path }}/forgejo.db" + +# Service settings +forgejo_disable_registration: true +forgejo_require_signin_view: false + +# Session +forgejo_session_provider: file + +# Logging +forgejo_log_mode: console +forgejo_log_level: info + +# Actions (Forgejo CI) +forgejo_actions_enabled: true +forgejo_actions_default_url: https://code.forgejo.org diff --git a/ansible/roles/forgejo/tasks/main.yml b/ansible/roles/forgejo/tasks/main.yml index 1e021c4..a6d27b9 100644 --- a/ansible/roles/forgejo/tasks/main.yml +++ b/ansible/roles/forgejo/tasks/main.yml @@ -1,26 +1,29 @@ --- -# Note: forgejo config at /opt/homebrew/var/forgejo/custom/conf/app.ini -# is not managed here (contains secrets). It is backed up by borgmatic. +# Forgejo role +# +# Currently uses brew-managed forgejo. Phase 3 of ci-cd-bootstrap will +# transition to mcquack LaunchAgent with CI-built binary. +# +# Secrets (lfs_jwt_secret, internal_token, oauth2_jwt_secret) are fetched +# from 1Password in the playbook pre_tasks. - name: Install forgejo via homebrew community.general.homebrew: name: forgejo state: present -- name: Check forgejo config exists - ansible.builtin.stat: - path: /opt/homebrew/var/forgejo/custom/conf/app.ini - register: forgejo_config +- name: Ensure forgejo config directory exists + ansible.builtin.file: + path: "{{ forgejo_work_path }}/custom/conf" + state: directory + mode: '0755' -- name: Fail if forgejo config is missing - ansible.builtin.fail: - msg: | - Forgejo config not found at /opt/homebrew/var/forgejo/custom/conf/app.ini - This file contains secrets and is not managed by ansible. - To restore from backup, run: - borgmatic --config ~/.config/borgmatic/config.yaml extract --archive latest \ - --path /opt/homebrew/var/forgejo/custom/conf/app.ini - when: not forgejo_config.stat.exists +- name: Deploy forgejo config + ansible.builtin.template: + src: app.ini.j2 + dest: "{{ forgejo_config_path }}" + mode: '0600' + notify: Restart forgejo - name: Ensure forgejo service is started ansible.builtin.command: brew services start forgejo diff --git a/ansible/roles/forgejo/templates/app.ini.j2 b/ansible/roles/forgejo/templates/app.ini.j2 new file mode 100644 index 0000000..ec0c396 --- /dev/null +++ b/ansible/roles/forgejo/templates/app.ini.j2 @@ -0,0 +1,82 @@ +# {{ ansible_managed }} +APP_NAME = {{ forgejo_app_name }} +APP_SLOGAN = {{ forgejo_app_slogan }} +RUN_USER = {{ forgejo_run_user }} +WORK_PATH = {{ forgejo_work_path }} +RUN_MODE = {{ forgejo_run_mode }} + +[server] +HTTP_ADDR = {{ forgejo_http_addr }} +HTTP_PORT = {{ forgejo_http_port }} +SSH_DOMAIN = {{ forgejo_ssh_domain }} +DOMAIN = {{ forgejo_domain }} +ROOT_URL = {{ forgejo_root_url }} +APP_DATA_PATH = {{ forgejo_data_path }} +DISABLE_SSH = {{ forgejo_disable_ssh | lower }} +START_SSH_SERVER = {{ forgejo_start_ssh_server | lower }} +BUILTIN_SSH_SERVER_USER = {{ forgejo_builtin_ssh_user }} +SSH_PORT = {{ forgejo_ssh_port }} +SSH_LISTEN_PORT = {{ forgejo_ssh_listen_port }} +LFS_START_SERVER = {{ forgejo_lfs_start_server | lower }} +LFS_JWT_SECRET = {{ forgejo_lfs_jwt_secret }} +OFFLINE_MODE = {{ forgejo_offline_mode | lower }} + +[database] +DB_TYPE = {{ forgejo_db_type }} +PATH = {{ forgejo_db_path }} +LOG_SQL = false + +[repository] +ROOT = {{ forgejo_repo_root }} +DEFAULT_REPO_UNITS = repo.code,repo.issues,repo.pulls,repo.releases,repo.wiki,repo.projects,repo.packages,repo.actions + +[lfs] +PATH = {{ forgejo_lfs_path }} + +[mailer] +ENABLED = false + +[service] +REGISTER_EMAIL_CONFIRM = false +ENABLE_NOTIFY_MAIL = false +DISABLE_REGISTRATION = {{ forgejo_disable_registration | lower }} +ALLOW_ONLY_EXTERNAL_REGISTRATION = false +ENABLE_CAPTCHA = false +REQUIRE_SIGNIN_VIEW = {{ forgejo_require_signin_view | lower }} +DEFAULT_KEEP_EMAIL_PRIVATE = false +DEFAULT_ALLOW_CREATE_ORGANIZATION = true +DEFAULT_ENABLE_TIMETRACKING = true +NO_REPLY_ADDRESS = noreply.indri + +[openid] +ENABLE_OPENID_SIGNIN = false +ENABLE_OPENID_SIGNUP = false + +[cron.update_checker] +ENABLED = false + +[session] +PROVIDER = {{ forgejo_session_provider }} + +[log] +MODE = {{ forgejo_log_mode }} +LEVEL = {{ forgejo_log_level }} +ROOT_PATH = {{ forgejo_log_path }} + +[repository.pull-request] +DEFAULT_MERGE_STYLE = merge + +[repository.signing] +DEFAULT_TRUST_MODEL = committer + +[security] +INSTALL_LOCK = true +INTERNAL_TOKEN = {{ forgejo_internal_token }} +PASSWORD_HASH_ALGO = pbkdf2_hi + +[oauth2] +JWT_SECRET = {{ forgejo_oauth2_jwt_secret }} + +[actions] +ENABLED = {{ forgejo_actions_enabled | lower }} +DEFAULT_ACTIONS_URL = {{ forgejo_actions_default_url }}