aboutsummaryrefslogtreecommitdiff
path: root/roles/host/tasks
diff options
context:
space:
mode:
authorRoman Ilin <me@romanilin.is>2026-06-15 12:59:09 +0300
committerRoman Ilin <me@romanilin.is>2026-06-15 22:04:41 +0300
commit5e4bf1268c266e63d0e92e845ad910a2103b86ff (patch)
tree532c01a9658a05048ef1ba76d4f30fca84005643 /roles/host/tasks
downloadinfrastructure-5e4bf1268c266e63d0e92e845ad910a2103b86ff.tar.gz
Diffstat (limited to 'roles/host/tasks')
-rw-r--r--roles/host/tasks/main.yaml195
1 files changed, 195 insertions, 0 deletions
diff --git a/roles/host/tasks/main.yaml b/roles/host/tasks/main.yaml
new file mode 100644
index 0000000..007d44d
--- /dev/null
+++ b/roles/host/tasks/main.yaml
@@ -0,0 +1,195 @@
+- name: Install firewalld and systemd-networkd packages
+ ansible.builtin.dnf:
+ name:
+ - firewalld
+ - systemd-container
+ - systemd-networkd
+ - openssl
+ - python3-libsemanage
+ - policycoreutils
+ state: present
+
+- name: Configure Polkit to allow machinectl fast user auth
+ ansible.builtin.copy:
+ src: 60-machinectl-fast-user-auth.rules
+ dest: /etc/polkit-1/rules.d/60-machinectl-fast-user-auth.rules
+ mode: "0644"
+ notify: Restart Polkit
+
+- name: Ensure firewalld and systemd-networkd are running
+ ansible.builtin.systemd:
+ name: "{{ item }}"
+ state: started
+ enabled: yes
+ loop:
+ - firewalld
+ - systemd-networkd
+
+- name: Enable masquerading for container internet access
+ ansible.posix.firewalld:
+ masquerade: yes
+ state: enabled
+ permanent: yes
+ zone: public
+ notify: Reload Firewalld
+
+- name: Open HTTP and HTTPS (TCP) for Nginx
+ ansible.posix.firewalld:
+ service: "{{ item }}"
+ state: enabled
+ permanent: yes
+ zone: public
+ loop:
+ - http
+ - https
+ notify: Reload Firewalld
+
+- name: Open HTTPS (UDP) for HTTP/3 QUIC support
+ ansible.posix.firewalld:
+ port: 443/udp
+ state: enabled
+ permanent: yes
+ zone: public
+ notify: Reload Firewalld
+
+- name: Configure Host Firewall Port Forwarding dynamically
+ ansible.posix.firewalld:
+ port_forward:
+ - port: "{{ item.1 }}"
+ proto: tcp
+ toaddr: "{{ item.0.value.ip }}"
+ toport: "{{ item.1 }}"
+ permanent: yes
+ state: enabled
+ loop: "{{ containers | dict2items | subelements('value.forward_ports', skip_missing=True) }}"
+ notify: Reload Firewalld
+
+- name: Create bridge netdev on host
+ ansible.builtin.copy:
+ dest: /etc/systemd/network/10-nspawn-br0.netdev
+ content: |
+ [NetDev]
+ Name=nspawn-br0
+ Kind=bridge
+ notify: Restart Host systemd-networkd
+
+- name: Assign IP to the host bridge
+ ansible.builtin.copy:
+ dest: /etc/systemd/network/10-nspawn-br0.network
+ content: |
+ [Match]
+ Name=nspawn-br0
+ [Network]
+ Address={{ bridge_ip }}/24
+ notify: Restart Host systemd-networkd
+
+- name: Apply networking changes immediately
+ ansible.builtin.meta: flush_handlers
+
+- name: Ensure containers are bootstrapped (AlmaLinux 10)
+ ansible.builtin.dnf:
+ installroot: "/var/lib/machines/{{ item.key }}"
+ releasever: "10"
+ name:
+ - almalinux-release
+ - systemd
+ - dbus
+ - systemd-networkd
+ - passwd
+ - dnf
+ - iproute
+ state: present
+ loop: "{{ containers | dict2items }}"
+
+- name: Initialize machine-id for containers
+ ansible.builtin.command: systemd-machine-id-setup --root=/var/lib/machines/{{ item.key }}
+ args:
+ creates: "/var/lib/machines/{{ item.key }}/etc/machine-id"
+ loop: "{{ containers | dict2items }}"
+
+- name: Fix SELinux contexts in container rootfs
+ ansible.builtin.command: restorecon -R /var/lib/machines/{{ item.key }}
+ register: restorecon_result
+ changed_when: "'Relabeled' in restorecon_result.stdout"
+ loop: "{{ containers | dict2items }}"
+
+- name: Ensure systemd-nspawn directory exists
+ ansible.builtin.file:
+ path: /etc/systemd/nspawn
+ state: directory
+ mode: "0755"
+
+- name: Ensure Let's Encrypt mock directories exist
+ ansible.builtin.file:
+ path: "{{ item }}"
+ state: directory
+ mode: '0755'
+ loop:
+ - "/etc/letsencrypt/archive/{{ vault_public_domain }}"
+ - "/etc/letsencrypt/live/{{ vault_public_domain }}"
+
+- name: Check if Let's Encrypt certificate exists
+ ansible.builtin.stat:
+ path: "/etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem"
+ register: le_cert
+
+- name: Generate self-signed fallback cert in Let's Encrypt paths if missing
+ ansible.builtin.command: >
+ openssl req -x509 -nodes -days 365
+ -newkey ec -pkeyopt ec_paramgen_curve:prime256v1
+ -keyout /etc/letsencrypt/live/{{ vault_public_domain }}/privkey.pem
+ -out /etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem
+ -subj "/CN={{ vault_public_domain }}"
+ args:
+ creates: "/etc/letsencrypt/live/{{ vault_public_domain }}/fullchain.pem"
+ when: not le_cert.stat.exists
+
+- name: Create systemd-nspawn configuration
+ ansible.builtin.template:
+ src: nspawn.j2
+ dest: "/etc/systemd/nspawn/{{ item.key }}.nspawn"
+ loop: "{{ containers | dict2items }}"
+ notify: Restart Containers
+
+- name: Enable and Start Containers
+ ansible.builtin.systemd:
+ name: "systemd-nspawn@{{ item.key }}"
+ state: started
+ enabled: yes
+ loop: "{{ containers | dict2items }}"
+
+- name: Install Nginx
+ ansible.builtin.dnf:
+ name: nginx
+ state: present
+
+- name: Allow Nginx to connect to upstream servers (SELinux)
+ ansible.posix.seboolean:
+ name: httpd_can_network_connect
+ state: yes
+ persistent: yes
+
+- name: Configure Nginx dynamically
+ ansible.builtin.template:
+ src: nginx.conf.j2
+ dest: /etc/nginx/nginx.conf
+ validate: nginx -t -c %s
+ notify: Restart Nginx
+
+- name: Ensure Nginx is enabled and running
+ ansible.builtin.systemd:
+ name: nginx
+ state: started
+ enabled: yes
+
+- name: Ensure Let's Encrypt renewal hook directory exists
+ ansible.builtin.file:
+ path: /etc/letsencrypt/renewal-hooks/post
+ state: directory
+ mode: '0755'
+
+- name: Deploy Let's Encrypt post-renewal hook for Nginx
+ ansible.builtin.template:
+ src: nginx-reload.sh.j2
+ dest: /etc/letsencrypt/renewal-hooks/post/nginx-reload.sh
+ mode: '0755'