From d8f4307969fbe8f9adb62bd6cd24847a732a1c3d Mon Sep 17 00:00:00 2001 From: Twirre Meulenbelt <43213592+TwirreM@users.noreply.github.com> Date: Wed, 22 Apr 2026 18:29:36 +0200 Subject: [PATCH] fix: fixes for problems encountered during deployment --- README.md | 9 ++- ansible.cfg | 4 +- group_vars/all/main.yml | 8 +-- roles/bun_app/tasks/app.yml | 110 +++++++++++++++++++++++++++++++++ roles/bun_app/tasks/main.yml | 115 ++--------------------------------- roles/gitea/tasks/main.yml | 4 +- site.yml | 4 -- 7 files changed, 131 insertions(+), 123 deletions(-) create mode 100644 roles/bun_app/tasks/app.yml diff --git a/README.md b/README.md index 0e765c6..08dd16f 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Going for an Esperanto naming theme. -Portable Ansible provisioning for Twirre infrastructure. The current layout is built around Debian-family hosts, `/srv` for deployed services, `/etc` for config, and systemd-managed apps. +Portable Ansible provisioning for Twirre infrastructure. The current layout uses Ubuntu 24.04 package names, `/srv` for deployed services, `/etc` for config, and systemd-managed apps, so it will not work on Debian without adjustment. ## What this provisions @@ -55,7 +55,7 @@ ansible-playbook --syntax-check site.yml Run the playbook: ```bash -ansible-playbook site.yml +ansible-playbook site.yml --ask-vault-pass ``` ## Notes @@ -64,6 +64,11 @@ ansible-playbook site.yml - If you enable `certbot_manage_certificates`, run the playbook a second time after the first successful issuance so nginx can switch to the live certificates automatically. - ACME issuance is disabled by default through `certbot_manage_certificates: false` so the first provisioning run can complete before DNS and public reachability are finalized. +## Manual post-provisioning steps + +- Set up ACME DNS records for the domains and enable `certbot_manage_certificates: true` before the next playbook run. +- Restore backups for Gitea and Mailserver data. + ## Future plans - [ ] Encryption for non-boot files with LUKS (/home, /srv, /var/lib/). diff --git a/ansible.cfg b/ansible.cfg index d73debb..6e2a2da 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -4,9 +4,9 @@ roles_path = roles host_key_checking = False retry_files_enabled = False interpreter_python = auto_silent -stdout_callback = yaml +stdout_callback = ansible.builtin.default +result_format = yaml local_tmp = /tmp/ansible-local -remote_tmp = /tmp/.ansible/tmp [ssh_connection] pipelining = True diff --git a/group_vars/all/main.yml b/group_vars/all/main.yml index dc78fa1..9b51e4f 100644 --- a/group_vars/all/main.yml +++ b/group_vars/all/main.yml @@ -49,7 +49,7 @@ backupagent: docker_packages: - docker.io - - docker-compose-plugin + - docker-compose-v2 bun_version: "1.3.10" bun_arch_map: @@ -163,7 +163,7 @@ twirre_io_files: bun_apps: - name: twirre-io - repo: git@github.com:twirre/twirre.io.git + repo: git@github.com:TwirreM/twirre.io.git version: main deploy_user: twirre-io deploy_group: twirre-io @@ -187,7 +187,7 @@ bun_apps: - path: "{{ twirre_io_files.visible_dir }}" - path: "{{ twirre_io_files.hidden_dir }}" - name: twirre-me - repo: git@github.com:twirre/twirre.me.git + repo: git@github.com:TwirreM/twirre.me.git version: main deploy_user: twirre-me deploy_group: twirre-me @@ -216,7 +216,7 @@ mailserver: service_group: docker path: /srv/mail compose_project_name: mailserver - image: ghcr.io/docker-mailserver/docker-mailserver:v15.1.0 + image: ghcr.io/docker-mailserver/docker-mailserver:15.1.0 hostname: mail.twirre.io env: ENABLE_SPAMASSASSIN: "0" diff --git a/roles/bun_app/tasks/app.yml b/roles/bun_app/tasks/app.yml new file mode 100644 index 0000000..d2a68d8 --- /dev/null +++ b/roles/bun_app/tasks/app.yml @@ -0,0 +1,110 @@ +--- +- name: Ensure Bun app group exists + ansible.builtin.group: + name: "{{ bun_app.deploy_group }}" + state: present + +- name: Ensure Bun app user exists + ansible.builtin.user: + name: "{{ bun_app.deploy_user }}" + group: "{{ bun_app.deploy_group }}" + system: true + shell: /usr/sbin/nologin + create_home: true + +- name: Ensure Bun app directories exist + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: "{{ bun_app.deploy_user }}" + group: "{{ bun_app.deploy_group }}" + mode: "0755" + loop: + - "{{ bun_app.path }}" + - "/var/lib/{{ bun_app.name }}" + - "/etc/{{ bun_app.name }}" + +- name: Ensure Bun app extra directories exist + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + owner: "{{ item.owner | default(bun_app.deploy_user) }}" + group: "{{ item.group | default(bun_app.deploy_group) }}" + mode: "{{ item.mode | default('0755') }}" + loop: "{{ bun_app.extra_directories | default([]) }}" + +- name: Install Bun app deploy key when provided + ansible.builtin.copy: + dest: "/etc/{{ bun_app.name }}/deploy_key" + content: "{{ bun_app.git_ssh_key }}" + owner: "{{ bun_app.deploy_user }}" + group: "{{ bun_app.deploy_group }}" + mode: "0600" + when: + - bun_app.git_ssh_key is defined + - bun_app.git_ssh_key | length > 0 + +- name: Deploy Bun app checkout + ansible.builtin.git: + repo: "{{ bun_app.repo }}" + version: "{{ bun_app.version }}" + dest: "{{ bun_app.path }}" + accept_hostkey: true + key_file: "{{ '/etc/' ~ bun_app.name ~ '/deploy_key' if (bun_app.git_ssh_key is defined and bun_app.git_ssh_key | length > 0) else omit }}" + update: true + become_user: "{{ bun_app.deploy_user }}" + register: bun_app_checkout + +- name: Check whether Bun app has package metadata + ansible.builtin.stat: + path: "{{ bun_app.path }}/package.json" + register: bun_app_package_json + +- name: Check whether Bun app dependencies are installed + ansible.builtin.stat: + path: "{{ bun_app.path }}/node_modules" + register: bun_app_node_modules + +- name: Install Bun app dependencies + ansible.builtin.command: + cmd: "{{ bun_bin_path }} install" + chdir: "{{ bun_app.path }}" + become_user: "{{ bun_app.deploy_user }}" + when: + - bun_app_package_json.stat.exists + - bun_app_checkout.changed or not bun_app_node_modules.stat.exists + register: bun_app_install + +- name: Render Bun app environment file + ansible.builtin.template: + src: bun-app.env.j2 + dest: "/etc/{{ bun_app.name }}/app.env" + owner: root + group: "{{ bun_app.deploy_group }}" + mode: "0640" + register: bun_app_env + +- name: Install Bun app systemd unit + ansible.builtin.template: + src: bun-app.service.j2 + dest: "/etc/systemd/system/{{ bun_app.service_name }}.service" + owner: root + group: root + mode: "0644" + register: bun_app_unit + +- name: Reload systemd for Bun app changes + ansible.builtin.systemd_service: + daemon_reload: true + when: bun_app_unit.changed + +- name: Ensure Bun app service is enabled and running + ansible.builtin.service: + name: "{{ bun_app.service_name }}" + state: >- + {{ + 'restarted' + if (bun_app_checkout.changed or bun_app_env.changed or bun_app_unit.changed or (bun_app_install is defined and bun_app_install.changed)) + else 'started' + }} + enabled: true diff --git a/roles/bun_app/tasks/main.yml b/roles/bun_app/tasks/main.yml index d2a68d8..9e3d4d2 100644 --- a/roles/bun_app/tasks/main.yml +++ b/roles/bun_app/tasks/main.yml @@ -1,110 +1,7 @@ --- -- name: Ensure Bun app group exists - ansible.builtin.group: - name: "{{ bun_app.deploy_group }}" - state: present - -- name: Ensure Bun app user exists - ansible.builtin.user: - name: "{{ bun_app.deploy_user }}" - group: "{{ bun_app.deploy_group }}" - system: true - shell: /usr/sbin/nologin - create_home: true - -- name: Ensure Bun app directories exist - ansible.builtin.file: - path: "{{ item }}" - state: directory - owner: "{{ bun_app.deploy_user }}" - group: "{{ bun_app.deploy_group }}" - mode: "0755" - loop: - - "{{ bun_app.path }}" - - "/var/lib/{{ bun_app.name }}" - - "/etc/{{ bun_app.name }}" - -- name: Ensure Bun app extra directories exist - ansible.builtin.file: - path: "{{ item.path }}" - state: directory - owner: "{{ item.owner | default(bun_app.deploy_user) }}" - group: "{{ item.group | default(bun_app.deploy_group) }}" - mode: "{{ item.mode | default('0755') }}" - loop: "{{ bun_app.extra_directories | default([]) }}" - -- name: Install Bun app deploy key when provided - ansible.builtin.copy: - dest: "/etc/{{ bun_app.name }}/deploy_key" - content: "{{ bun_app.git_ssh_key }}" - owner: "{{ bun_app.deploy_user }}" - group: "{{ bun_app.deploy_group }}" - mode: "0600" - when: - - bun_app.git_ssh_key is defined - - bun_app.git_ssh_key | length > 0 - -- name: Deploy Bun app checkout - ansible.builtin.git: - repo: "{{ bun_app.repo }}" - version: "{{ bun_app.version }}" - dest: "{{ bun_app.path }}" - accept_hostkey: true - key_file: "{{ '/etc/' ~ bun_app.name ~ '/deploy_key' if (bun_app.git_ssh_key is defined and bun_app.git_ssh_key | length > 0) else omit }}" - update: true - become_user: "{{ bun_app.deploy_user }}" - register: bun_app_checkout - -- name: Check whether Bun app has package metadata - ansible.builtin.stat: - path: "{{ bun_app.path }}/package.json" - register: bun_app_package_json - -- name: Check whether Bun app dependencies are installed - ansible.builtin.stat: - path: "{{ bun_app.path }}/node_modules" - register: bun_app_node_modules - -- name: Install Bun app dependencies - ansible.builtin.command: - cmd: "{{ bun_bin_path }} install" - chdir: "{{ bun_app.path }}" - become_user: "{{ bun_app.deploy_user }}" - when: - - bun_app_package_json.stat.exists - - bun_app_checkout.changed or not bun_app_node_modules.stat.exists - register: bun_app_install - -- name: Render Bun app environment file - ansible.builtin.template: - src: bun-app.env.j2 - dest: "/etc/{{ bun_app.name }}/app.env" - owner: root - group: "{{ bun_app.deploy_group }}" - mode: "0640" - register: bun_app_env - -- name: Install Bun app systemd unit - ansible.builtin.template: - src: bun-app.service.j2 - dest: "/etc/systemd/system/{{ bun_app.service_name }}.service" - owner: root - group: root - mode: "0644" - register: bun_app_unit - -- name: Reload systemd for Bun app changes - ansible.builtin.systemd_service: - daemon_reload: true - when: bun_app_unit.changed - -- name: Ensure Bun app service is enabled and running - ansible.builtin.service: - name: "{{ bun_app.service_name }}" - state: >- - {{ - 'restarted' - if (bun_app_checkout.changed or bun_app_env.changed or bun_app_unit.changed or (bun_app_install is defined and bun_app_install.changed)) - else 'started' - }} - enabled: true +- name: Deploy configured Bun applications + ansible.builtin.include_tasks: app.yml + loop: "{{ bun_apps }}" + loop_control: + loop_var: bun_app + label: "{{ bun_app.name }}" diff --git a/roles/gitea/tasks/main.yml b/roles/gitea/tasks/main.yml index f19b129..ab1165d 100644 --- a/roles/gitea/tasks/main.yml +++ b/roles/gitea/tasks/main.yml @@ -21,8 +21,8 @@ - name: Set Gitea runtime UID and GID from host account ansible.builtin.set_fact: - gitea_runtime_uid: "{{ getent_passwd[gitea.service_user][1] }}" - gitea_runtime_gid: "{{ getent_group[gitea.service_group][1] }}" + gitea_runtime_uid: "{{ ansible_facts['getent_passwd'][gitea.service_user][1] }}" + gitea_runtime_gid: "{{ ansible_facts['getent_group'][gitea.service_group][1] }}" - name: Ensure Gitea directories exist ansible.builtin.file: diff --git a/site.yml b/site.yml index 3ba0c3a..3768d60 100644 --- a/site.yml +++ b/site.yml @@ -52,10 +52,6 @@ - role: mailserver when: mailserver_enabled | bool - role: bun_app - loop: "{{ bun_apps }}" - loop_control: - loop_var: bun_app - label: "{{ bun_app.name }}" when: bun_enabled | bool - role: nginx when: nginx_enabled | bool