Ansible config for hetzner mailserver

This commit is contained in:
Ruben Hensen
2026-03-14 22:24:53 +01:00
parent bc2f75294d
commit 2a3bfb5d1a
30 changed files with 775 additions and 0 deletions
@@ -0,0 +1,22 @@
---
- name: Initialize Stalwart
ansible.builtin.command:
cmd: "{{ stalwart_executable_path }} --init {{ stalwart_install_path }}"
creates: "{{ stalwart_config_file_path }}"
become: true
become_user: "{{ stalwart_system_user }}"
- name: Deploy configuration
ansible.builtin.template:
src: "config.toml.j2"
dest: "{{ stalwart_config_file_path }}"
owner: "{{ stalwart_system_user }}"
group: "{{ stalwart_system_group }}"
mode: "0640"
notify: restart stalwart
- name: Ensure service is in correct state
ansible.builtin.service:
name: "{{ stalwart_service_name }}"
state: "{{ stalwart_service_state }}"
enabled: "{{ stalwart_service_enabled }}"
@@ -0,0 +1,36 @@
---
- name: Ensure directories exist
ansible.builtin.file:
path: "{{ directory_to_create }}"
state: "directory"
owner: "{{ stalwart_system_user }}"
group: "{{ stalwart_system_group }}"
mode: "0750"
loop:
- "{{ stalwart_install_path }}"
- "{{ stalwart_bin_path }}"
- "{{ stalwart_config_path }}"
- "{{ stalwart_logs_path }}"
- "{{ stalwart_data_path }}"
loop_control:
loop_var: "directory_to_create"
- name: Download and extract Stalwart
ansible.builtin.unarchive:
src: "{{ stalwart_download_url }}"
dest: "{{ stalwart_bin_path }}"
owner: "{{ stalwart_system_user }}"
group: "{{ stalwart_system_group }}"
mode: "0750"
remote_src: true
notify: restart stalwart
when: (not stalwart_exec.stat.exists) or (stalwart_current_version != stalwart_version)
- name: Install systemd service file
ansible.builtin.template:
src: "stalwart.service.j2"
dest: "{{ stalwart_service_file_path }}"
mode: "0644"
notify:
- reload systemd
- restart stalwart
@@ -0,0 +1,9 @@
---
- name: Import prepare tasks
ansible.builtin.import_tasks: "prepare.yml"
- name: Import install tasks
ansible.builtin.import_tasks: "install.yml"
- name: Import configure tasks
ansible.builtin.import_tasks: "configure.yml"
@@ -0,0 +1,67 @@
---
- name: Create Stalwart group
ansible.builtin.group:
name: "{{ stalwart_system_group }}"
system: true
- name: Create Stalwart user
ansible.builtin.user:
name: "{{ stalwart_system_user }}"
group: "{{ stalwart_system_group }}"
create_home: false
home: "{{ stalwart_install_path }}"
shell: "/usr/sbin/nologin"
system: true
- name: Create Ansible remote_tmp for stalwart user
ansible.builtin.file:
path: "{{ stalwart_install_path }}/.ansible/tmp"
state: directory
owner: "{{ stalwart_system_user }}"
group: "{{ stalwart_system_group }}"
mode: "0755"
- name: Check if already installed
ansible.builtin.stat:
path: "{{ stalwart_executable_path }}"
register: stalwart_exec
- name: Get version if stalwart is installed
when: stalwart_exec.stat.exists
block:
- name: Get version
ansible.builtin.command: "{{ stalwart_executable_path }} -V"
failed_when: false
changed_when: false
check_mode: false
register: stalwart_output
- name: Set current installed version
ansible.builtin.set_fact:
stalwart_current_version: "{{ stalwart_output.stdout_lines[0] }}"
- name: Check if config exists
ansible.builtin.stat:
path: "{{ stalwart_config_file_path }}"
register: stalwart_config_file_st
- name: Preserve admin password salt from existing config
when: stalwart_config_file_st.stat.exists
block:
- name: Get config file content
ansible.builtin.slurp:
src: "{{ stalwart_config_file_path }}"
register: config_file_content
- name: Get existing password hash
ansible.builtin.set_fact:
hash_stored: "{{ config_file_content['content'] | b64decode | regex_search('(\\n|^)(secret|authentication\\.fallback-admin\\.secret) = \"(.*)\"\\n', '\\3') }}"
- name: Get existing salt
ansible.builtin.set_fact:
stalwart_fallback_admin_password_salt: "{{ (hash_stored[0] | split('$'))[2] }}"
- name: Create salt if it does not exist
ansible.builtin.set_fact:
stalwart_fallback_admin_password_salt: "{{ lookup('password', '/dev/null length=16 chars=ascii_letters,digits') }}"
when: stalwart_fallback_admin_password_salt is undefined