Compare commits

...

10 commits

Author SHA1 Message Date
d00ffe54e4
Add restoration example playbook 2024-10-13 20:13:16 +02:00
3934bffbd1
Add backup restoration logic to NFS role
Passing the `backup_nfs_restore` variable will restore that timestamp.
2024-10-13 20:12:26 +02:00
63c767f116
Add two example playbooks 2024-10-13 19:44:09 +02:00
11f20db2d2
Fix typo 2024-10-13 19:37:48 +02:00
8ff8832f85
Add simple NFS backup role 2024-10-13 19:34:14 +02:00
3416eb490c
Add additional proxy headers to nginx config
This is required to have better log output.
2024-10-13 18:03:16 +02:00
82713dabce
Make user for podman containers configurable 2024-10-13 14:44:30 +02:00
f916260c90
Make nginx_htpasswd required 2024-10-13 14:38:42 +02:00
120968ee54
Rename variable to follow linting conventions 2024-10-13 14:36:30 +02:00
c13796dd22
Add stub CHANGELOG file to please the linter
Currently, the churn in the code is expected to be too high to have a
meaningfull CHANGELOG.
2024-10-13 14:33:08 +02:00
21 changed files with 204 additions and 8 deletions

3
CHANGELOG.md Normal file
View file

@ -0,0 +1,3 @@
# Changelog
WIP: development velocity / expected churn is too high at this time.

View file

@ -0,0 +1,19 @@
---
- name: Run example SCE backup restoration playbook
hosts: sce-targets
become: true
roles:
- role: wingelaar.sce.backup_nfs
vars:
backup_nfs_remote: 127.0.0.1
backup_nfs_restore: 20241013T180449
backup_nfs_targets:
- user: podman
containers:
- name: forgejo
volumes:
- forgejo
- name: certbot
volumes:
- certbot-etc
- certbot-var-lib

View file

@ -0,0 +1,18 @@
---
- name: Run example SCE backup creation playbook
hosts: sce-targets
become: true
roles:
- role: wingelaar.sce.backup_nfs
vars:
backup_nfs_remote: 127.0.0.1
backup_nfs_targets:
- user: podman
containers:
- name: forgejo
volumes:
- forgejo
- name: certbot
volumes:
- certbot-etc
- certbot-var-lib

23
playbooks/example.yml Normal file
View file

@ -0,0 +1,23 @@
---
- name: Run example SCE playbook
hosts: sce-targets
become: true
roles:
- wingelaar.sce.install
- role: wingelaar.sce.firewall_nft
vars:
firewall_nft_port_mapping:
- "80:8080"
- "22:2222"
- role: wingelaar.sce.podman_certbot
vars:
podman_certbot_domains: git.example.com
podman_certbot_email: certbot@example.com
- wingelaar.sce.podman_certbot_root_transfer
- role: wingelaar.sce.nginx
vars:
nginx_htpasswd: super_secure_password
nginx_sites:
- name: git.example.com
port: 3000
- role: wingelaar.sce.podman_forgejo

View file

@ -0,0 +1,4 @@
---
backup_nfs_create_directory: /podman-nfs-backups
backup_nfs_restore_directory: /podman-nfs-backups
backup_nfs_mountpoint: /opt/podman-nfs-backups

View file

@ -0,0 +1,6 @@
---
- name: Import per-user tasks
ansible.builtin.import_tasks: per-user.yml
become_method: community.general.machinectl
become_user: "{{ backup_nfs_users['user'] }}"
become: true

View file

@ -0,0 +1,50 @@
---
- name: Install NFS client software
ansible.builtin.apt:
name: nfs-common
state: present
- name: Check existence of mount directory
ansible.builtin.stat:
path: "{{ backup_nfs_mountpoint }}"
register: mountpoint
- name: Create mountpoint if it does not exist
ansible.builtin.file:
path: "{{ backup_nfs_mountpoint }}"
state: directory
mode: "0700"
owner: root
group: root
when: not mountpoint.stat.exists
- name: This block ensures the NFS directory will be unmounted if a task fails
block:
- name: Mount backup NFS directory (for creating backups)
ansible.posix.mount:
src: "{{ backup_nfs_remote }}:{{ backup_nfs_create_directory }}"
path: "{{ backup_nfs_mountpoint }}"
opts: rw,sync,hard,vers=4
state: ephemeral
fstype: nfs
when: backup_nfs_restore is undefined
- name: Mount backup NFS directory (for restoring backups)
ansible.posix.mount:
src: "{{ backup_nfs_remote }}:{{ backup_nfs_restore_directory }}"
path: "{{ backup_nfs_mountpoint }}"
opts: ro,sync,hard,vers=4
state: ephemeral
fstype: nfs
when: backup_nfs_restore is defined
- name: Execute backup tasks inside service account
ansible.builtin.include_tasks: machinectl.yml
loop: "{{ backup_nfs_targets }}"
loop_control:
loop_var: backup_nfs_users
always:
- name: Unmount backup NFS directory
ansible.posix.mount:
path: "{{ backup_nfs_mountpoint }}"
state: unmounted

View file

@ -0,0 +1,24 @@
---
- name: Ensure container is stopped
ansible.builtin.systemd_service:
name: container-{{ container }}.service
state: stopped
scope: user
register: container_state
- name: Create volume export
containers.podman.podman_export:
volume: "{{ item }}"
dest: "{{ backup_nfs_mountpoint }}/{{ container }}-{{ item }}-{{ ansible_date_time['iso8601_basic_short'] }}.tar"
loop: "{{ backup_nfs_containers['volumes'] }}"
# A container is not always running, so if it was stopped before
# the backup procedure even started, do not start it again.
# It's quite a hassle to have this behaviour with a handler, so
# we just suppress the linting error.
- name: Start container again if necessary # noqa: no-handler
ansible.builtin.systemd_service:
name: container-{{ container }}.service
state: started
scope: user
when: container_state is changed

View file

@ -0,0 +1,24 @@
---
- name: Ensure container is stopped
ansible.builtin.systemd_service:
name: container-{{ container }}.service
state: stopped
scope: user
register: container_state
- name: Import the volumes
containers.podman.podman_import:
volume: "{{ item }}"
src: "{{ backup_nfs_mountpoint }}/{{ container }}-{{ item }}-{{ backup_nfs_restore }}.tar"
loop: "{{ backup_nfs_containers['volumes'] }}"
# A container is not always running, so if it was stopped before
# the backup procedure even started, do not start it again.
# It's quite a hassle to have this behaviour with a handler, so
# we just suppress the linting error.
- name: Start container again if necessary # noqa: no-handler
ansible.builtin.systemd_service:
name: container-{{ container }}.service
state: started
scope: user
when: container_state is changed

View file

@ -0,0 +1,18 @@
---
- name: Iterate over configured nginx sites
ansible.builtin.include_tasks: per-container-create.yml
loop: "{{ backup_nfs_users['containers'] }}"
loop_control:
loop_var: backup_nfs_containers
vars:
container: "{{ backup_nfs_containers['name'] }}"
when: backup_nfs_restore is undefined
- name: Iterate over configured nginx sites
ansible.builtin.include_tasks: per-container-restore.yml
loop: "{{ backup_nfs_users['containers'] }}"
loop_control:
loop_var: backup_nfs_containers
vars:
container: "{{ backup_nfs_containers['name'] }}"
when: backup_nfs_restore is defined

View file

@ -1,3 +1,4 @@
--- ---
firewall_nft_table_name: sce_table firewall_nft_table_name: sce_table
firewall_nft_table_filename: sce-port-mapping firewall_nft_table_filename: sce-port-mapping
firewall_nft_port_mapping: []

View file

@ -17,7 +17,7 @@ table inet {{ firewall_nft_table_name }} {
chain sce_port_mapping { chain sce_port_mapping {
type nat hook prerouting priority filter + 1; type nat hook prerouting priority filter + 1;
policy accept; policy accept;
{% for item in port_mapping %} {% for item in firewall_nft_port_mapping %}
{% set from_port, to_port = item.split(':') %} {% set from_port, to_port = item.split(':') %}
tcp dport {{ from_port }} counter redirect to :{{ to_port }} tcp dport {{ from_port }} counter redirect to :{{ to_port }}
{% endfor %} {% endfor %}

View file

@ -18,7 +18,6 @@
owner: root owner: root
group: www-data group: www-data
mode: "0640" mode: "0640"
when: nginx_htpasswd is defined
- name: Check if the passwdfile exists - name: Check if the passwdfile exists
ansible.builtin.stat: ansible.builtin.stat:

View file

@ -15,5 +15,10 @@ server {
location / { location / {
proxy_pass http://127.0.0.1:{{ site_port }}; proxy_pass http://127.0.0.1:{{ site_port }};
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
} }
} }

View file

@ -1,3 +1,4 @@
--- ---
podman_certbot_port_mapping: "8080:80" podman_certbot_port_mapping: "8080:80"
podman_certbot_timer: weekly podman_certbot_timer: weekly
podman_certbot_user: podman

View file

@ -4,5 +4,5 @@
daemon_reload: true daemon_reload: true
scope: user scope: user
become_method: community.general.machinectl become_method: community.general.machinectl
become_user: podman become_user: "{{ podman_certbot_user }}"
become: true become: true

View file

@ -2,5 +2,5 @@
- name: Configure Certbot service - name: Configure Certbot service
ansible.builtin.import_tasks: machinectl.yml ansible.builtin.import_tasks: machinectl.yml
become_method: community.general.machinectl become_method: community.general.machinectl
become_user: podman become_user: "{{ podman_certbot_user }}"
become: true become: true

View file

@ -4,5 +4,5 @@
daemon_reload: true daemon_reload: true
scope: user scope: user
become_method: community.general.machinectl become_method: community.general.machinectl
become_user: podman become_user: "{{ podman_certbot_user }}"
become: true become: true

View file

@ -20,7 +20,7 @@
- name: Allow podman user to execute the move command - name: Allow podman user to execute the move command
community.general.sudoers: community.general.sudoers:
name: allow-podman-move-certificates name: allow-podman-move-certificates
user: podman user: "{{ podman_certbot_user }}"
state: present state: present
commands: commands:
- /usr/local/bin/move-certificate-files-to-root - /usr/local/bin/move-certificate-files-to-root
@ -29,5 +29,5 @@
- name: Configure Certbot service - name: Configure Certbot service
ansible.builtin.import_tasks: machinectl.yml ansible.builtin.import_tasks: machinectl.yml
become_method: community.general.machinectl become_method: community.general.machinectl
become_user: podman become_user: "{{ podman_certbot_user }}"
become: true become: true

View file

@ -1,2 +1,3 @@
--- ---
podman_forgejo_version: 8.0.1 podman_forgejo_version: 8.0.1
podman_forgejo_user: podman

View file

@ -2,5 +2,5 @@
- name: Configure Forgejo service - name: Configure Forgejo service
ansible.builtin.import_tasks: machinectl.yml ansible.builtin.import_tasks: machinectl.yml
become_method: community.general.machinectl become_method: community.general.machinectl
become_user: podman become_user: "{{ podman_forgejo_user }}"
become: true become: true