--- - name: Acquiring home of current user when: ansible_facts["system"] == "Linux" ansible.builtin.shell: cmd: "echo ~{{ ansible_user }}" register: ansible_user_home - name: Acquiring home of current user when: ansible_facts["system"] == "Linux" ansible.builtin.shell: cmd: "echo {{ ansible_user }}" register: current_user - name: Checking if ZFS filesystem is present ansible.builtin.shell: cmd: "findmnt -D | awk '{ print $2 }' | tail -n +2" register: fs_result - name: Logging presence of ZFS filesystem when: "'zfs' in fs_result.stdout" ansible.builtin.set_fact: zfs_present: true - name: Logging absence of ZFS filesystem when: "'zfs' not in fs_result.stdout" ansible.builtin.set_fact: zfs_present: false - name: Configuring ZFS support when: zfs_present block: - name: Getting available pools ansible.builtin.shell: cmd: "zpool list | awk '{ print $1 }' | tail -n +2" register: zpools - name: Turning available pools into list ansible.builtin.set_fact: zpool_list: "{{ zpools | replace('\n', ' ') | split(' ') }}" - name: Allowing choice of zpool ansible.builtin.pause: prompt: "Type preferred zpool from available (i.e., {{ zpool_list | join(', ') }})" register: preferred_zpool - name: Informing user of requirement of two main domains when: (certbot.domains | length) < 2 or (certbot.domains | length) > 2 ansible.builtin.fail: msg: Only two domains allowed and required - name: Informing user of requirement at least one wildcard when: (certbot.domains | select("regex", "^\\*\\.") | list | length) == 0 ansible.builtin.fail: msg: At least one of the FQDNs must have a wildcard - name: Getting public IP addresses block: - name: Getting public IPv4 address community.general.ipify_facts: validate_certs: false timeout: 20 - name: Getting public IPv6 address when: ipv6_enabled ansible.builtin.shell: cmd: curl -6 icanhazip.com register: ipify_public_ip6 - name: Getting available network interfaces ansible.builtin.shell: cmd: "ip link show | awk '/^[0-9]+: [a-z]/ { print $2 }' | grep -vE 'lo[0-9]*|wg[0-9]+-mullvad' | sed 's/://g'" register: intrfaces - name: Turning acquired network interfaces into list ansible.builtin.set_fact: main_interfaces: "{{ intrfaces.stdout | replace('\n', ' ') | split(' ') }}" # - name: Setting the FQDN for development # when: compose.mode == "dev" # ansible.builtin.set_fact: # web_fqdn: "{{ (certbot.domains | map('regex_replace', '\\.([^\\.]*)$', '.test') | reject('regex', '^\\*\\.') | list)[0] }}" - name: Setting the FQDN for production # when: compose.mode == "prod" ansible.builtin.set_fact: web_fqdn: "{{ (certbot.domains | reject('regex', '^\\*\\.') | list)[0] }}" - name: Moving git repository from initial path block: - name: Recursively copying directory and its contents to elsewhere become: true become_user: "{{ current_user.stdout }}" ansible.builtin.copy: src: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.compose.name }}" remote_src: true dest: "{{ ansible_user_home.stdout }}/repos/" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" register: new_compose_path - name: Deleting directory at previous path ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/repos/.foreign/{{ source_code.repos.compose.name }}" state: absent - name: Creating directory for new bare repository ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/src" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory - name: Creating bare repository ansible.builtin.command: cmd: "git init --bare {{ source_code.repos.compose.name }}.git" chdir: "{{ ansible_user_home.stdout }}/src" creates: "{{ ansible_user_home.stdout }}/src/{{ source_code.repos.compose.name }}.git" - name: Creating a ZFS dataset for container secrets become: true when: zfs_present community.general.zfs: name: "{{ preferred_zpool.user_input }}/container_secrets" state: present extra_zfs_properties: canmount: "on" mountpoint: "{{ ansible_user_home.stdout }}/.podsecrets" - name: Creating a directory for container secrets become: true ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.podsecrets" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" state: directory - name: Creating required SMTP-related container secret become: true ansible.builtin.copy: content: "{{ email.smtp.password }}" dest: "{{ ansible_user_home.stdout }}/.podsecrets/email.pass" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" backup: true - name: Creating environment file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/all.env.j2 dest: "{{ ansible_user_home.stdout }}/.all.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: environ - name: Creating environment file for email become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/email.env.j2 dest: "{{ ansible_user_home.stdout }}/.email.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: email_environ - name: Creating directory for DBMS server configuration ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.config/{{ item }}" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "755" state: directory loop: - caddy - letsencrypt - mysql - redis - forgejo - opengist - nodebb - syncplay - tailscale - glance - surge - grocy - kavita - stash - name: Creating environment file for NSFW streaming container specified in Compose file become: true become_user: "{{ current_user.stdout }}" when: "source_code.repos.compose.run and stash.containerized and (compose.containers.stash is defined and compose.containers.stash != None)" ansible.builtin.template: src: user/stash.env.j2 dest: "{{ ansible_user_home.stdout }}/.stash.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: stash_environ - name: Creating environment file for financial budgeting container specified in Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/actual.env.j2 dest: "{{ ansible_user_home.stdout }}/.actual.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: actual_environ - name: Creating directory for DBMS server configuration ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.{{ item }}" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "755" state: directory loop: - aria2 - flexget - xxx - name: Creating directory for DBMS server configuration ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/{{ item }}" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "755" state: directory loop: - media - downloads - name: Creating a ZFS dataset for container secrets become: true when: zfs_present community.general.zfs: name: "{{ preferred_zpool.user_input }}/server_contents" state: present extra_zfs_properties: canmount: "on" mountpoint: "{{ ansible_user_home.stdout }}/srv" - name: Creating directory for main website root ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/srv" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "755" state: directory - name: Creating directory for main website root ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/srv/{{ web_fqdn }}" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "755" state: directory - name: Creating directory for caddy configuration ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.config/caddy" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory - name: Creating requisite download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/media" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" - name: Creating requisite download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/downloads" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" - name: Creating requisite hidden download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.xxx" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" # - name: Pulling all needed container images for Compose services # become: true # become_user: "{{ current_user.stdout }}" # ansible.builtin.command: # cmd: podman-compose pull # chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Calculating desired container states block: - name: Calculating desired container state for VPN client ansible.builtin.set_fact: # @TODO write case of at least one vpn client having a boolean attribute declaring whether it is a container vpn_run: "{{ source_code.repos.compose.run and (compose.containers.vpn is defined and compose.containers.vpn != None) }}" - name: Calculating desired container state for web server or reverse proxy server ansible.builtin.set_fact: server_run: "{{ source_code.repos.compose.run and caddy.containerized and (compose.containers.webserver is defined and compose.containers.webserver != None) }}" - name: Calculatng desired container state for ACME challenge ansible.builtin.set_fact: ssl_run: "{{ server_run and certbot.containerized and (compose.containers.ssl is defined and compose.containers.ssl != None) }}" - name: Calculating desired container state for database management ansible.builtin.set_fact: dbms_run: "{{ source_code.repos.compose.run and mysql.containerized and (compose.containers.db is defined and compose.containers.db != None) }}" - name: Calculating desired container state for caching server ansible.builtin.set_fact: cache_run: "{{ source_code.repos.compose.run and redis.containerized and (compose.containers.cache is defined and compose.containers.cache != None) }}" - name: Calculating desired container state for cloud server ansible.builtin.set_fact: cloud_run: "{{ source_code.repos.compose.run and nextcloud.containerized and (compose.containers.cloud is defined and compose.containers.cloud != None) }}" - name: Calculating desired container state for forge server ansible.builtin.set_fact: forge_run: "{{ source_code.repos.compose.run and forgejo.containerized and (compose.containers.forge is defined and compose.containers.forge != None ) }}" - name: Calculating desired container state for pastebin server ansible.builtin.set_fact: pbin_run: "{{ source_code.repos.compose.run and gist.containerized and (compose.containers.pastebin is defined and compose.containers.pastebin != None) }}" - name: Calculating desired container state for pastebin server ansible.builtin.set_fact: # cast_run: "{{ source_code.repos.compose.run and cast.containerized and (compose.containers.cast is defined and compose.containers.cast != None) }}" cast_run: "{{ (compose.containers.cast is defined and compose.containers.cast != None) }}" - name: Calculating desired container state for tailnet client ansible.builtin.set_fact: tail_run: "{{ source_code.repos.compose.run and tailscale.containerized and (compose.containers.tail is defined and compose.containers.tail != None) }}" - name: Calculating desired container state for tailnet dashboard ansible.builtin.set_fact: dash_run: "{{ source_code.repos.compose.run and glance.containerized and (compose.containers.dash is defined and compose.containers.dash != None) }}" - name: Calculating whether correct domain for given configuration detected ansible.builtin.set_fact: correct_domain: "{{ (inventory_hostname in groups['homeserver'] or inventory_hostname in groups['homeserver.test']) or ((web_fqdn is defined and web_fqdn != None) and (web_fqdn in groups['homeserver'] or web_fqdn in groups['homeserver.test'])) }}" - name: Creating environment file for pastebin server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" when: vpn_run or pbin_run ansible.builtin.template: src: user/opengist.env.j2 dest: "{{ ansible_user_home.stdout }}/.opengist.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: opengist_environ - name: Creating environment file for forge server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" when: vpn_run or forge_run ansible.builtin.template: src: user/forgejo.env.j2 dest: "{{ ansible_user_home.stdout }}/.forgejo.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: forgejo_environ - name: Running VPN client Compose files when: vpn_run block: - name: Creating subdirectory for VPN client container specified by Compose file ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory - name: Copying VPN client configuration files become: true become_user: "{{ current_user.stdout }}" when: "source_code.repos.compose.rpath == '/dependent' and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.copy: src: "user/wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" dest: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "600" force: true backup: true loop: "{{ vpn.clients }}" loop_control: index_var: idx register: vpn_client_configs - name: Change allowed IPs policy for VPN client to include all IPv4 addresses # when: "source_code.repos.compose.rpath == '/dependent' and ((((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test'])))" when: "source_code.repos.compose.rpath == '/dependent' and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.lineinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" regexp: "^AllowedIPs ?= ?(([0-9]+\\.)+[0-9]+(\\/[0-9]+)?(, ?)?)*$" line: "AllowedIPs=0.0.0.0/0" insertafter: EOF state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Change allowed IPs policy for VPN client to include all IPv6 addresses # when: "source_code.repos.compose.rpath == '/dependent' and ((((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test'])))" when: "source_code.repos.compose.rpath == '/dependent' and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.lineinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" regexp: "^AllowedIPs ?= ?(([0-9]*:)+[0-9]*(\\/[0-9]+)?(, ?)?)*$" line: "AllowedIPs=::/0" insertafter: EOF state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Creating IPTables rule for VPN configuration # when: "source_code.repos.compose.rpath == '/dependent' and not ipv6_enabled and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and not ipv6_enabled and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE MANAGED IPTABLES RULES -->" block: | # Up rules PreUp=iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PreUp=ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PreUp=iptables -A INPUT -p icmp ! -d {{ ipify_public_ip }} -j ACCEPT PreUp=iptables -A INPUT -i lo -j ACCEPT PreUp=ip6tables -A INPUT -i lo -j ACCEPT PreUp=iptables -P INPUT DROP PreUp=ip6tables -P INPUT DROP # Down rules PostDown=iptables -D INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PostDown=ip6tables -D INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PostDown=iptables -D INPUT -p icmp ! -d {{ ipify_public_ip }} -j ACCEPT PostDown=iptables -D INPUT -i lo -j ACCEPT PostDown=ip6tables -D INPUT -i lo -j ACCEPT PostDown=iptables -P INPUT DROP PostDown=ip6tables -P INPUT DROP insertafter: "^PrivateKey ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Creating IPTables rule for VPN configuration # when: "source_code.repos.compose.rpath == '/dependent' and ipv6_enabled and ((((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test'])))" when: "source_code.repos.compose.rpath == '/dependent' and ipv6_enabled and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE MANAGED IPTABLES RULES -->" block: | # Up rules PreUp=iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PreUp=ip6tables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PreUp=iptables -A INPUT -p icmp ! -d {{ ipify_public_ip }} -j ACCEPT PreUp=ip6tables -A INPUT -p icmpv6 ! -d {{ ipify_public_ip6.stdout }} -j ACCEPT PreUp=iptables -A INPUT -i lo -j ACCEPT PreUp=ip6tables -A INPUT -i lo -j ACCEPT PreUp=iptables -P INPUT DROP PreUp=ip6tables -P INPUT DROP # Down rules PostDown=iptables -D INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PostDown=ip6tables -D INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PostDown=iptables -D INPUT -p icmp ! -d {{ ipify_public_ip }} -j ACCEPT PostDown=ip6tables -D INPUT -p icmpv6 ! -d {{ ipify_public_ip6.stdout }} -j ACCEPT PostDown=iptables -D INPUT -i lo -j ACCEPT PostDown=ip6tables -D INPUT -i lo -j ACCEPT PostDown=iptables -P INPUT DROP PostDown=ip6tables -P INPUT DROP insertafter: "^PrivateKey ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Creating and deploying VPN client container specified by Compose file become: true become_user: "{{ current_user.stdout }}" when: source_code.repos.compose.rpath == '/dependent' ansible.builtin.command: cmd: "podman-compose up -d {{ compose.containers.vpn.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up database management container specified by Compose file when: dbms_run block: - name: Creating required container secret for DBMS server container's root account become: true ansible.builtin.copy: content: "{{ mysql.password }}" dest: "{{ ansible_user_home.stdout }}/.podsecrets/root-mysql.pass" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" backup: true - name: Creatng required container secret for DBMS server container's primary non-root account become: true ansible.builtin.copy: content: "{{ mysql.users.admin.password }}" dest: "{{ ansible_user_home.stdout }}/.podsecrets/user-mysql.pass" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" backup: true - name: Creating environment file for DBMS server container specified in Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/mysql.env.j2 dest: "{{ ansible_user_home.stdout }}/.mysql.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: mysql_environ - name: Creating and deploying DBMS server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ mysql_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.db.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" # @TODO see if manual creation of additional databases is necessary for the DBMS server container # REDIS - name: Spinning up caching container specified by Compose file when: cache_run block: - name: Creating environment file for DBMS server container specified in Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/redis.env.j2 dest: "{{ ansible_user_home.stdout }}/.redis.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: redis_environ - name: Creating and deploying cache server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ environ.dest }} up -d {{ compose.containers.cache.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up cloud container specified by Compose file when: cloud_run block: - name: Creating database necessary for cloud server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" when: dbms_run containers.podman.podman_container_exec: name: "{{ compose.containers.db.name }}" argv: - mysql - "-u" - "{{ mysql.users.admin.username }}" - "-p{{ mysql.users.admin.password }}" - "-e" - "'CREATE DATABASE IF NOT EXISTS {{ mysql.users.admin.databases.nextcloud.name }};'" detach: true - name: Creating required cache-related container secret for cloud server container specified by Compose file become: true when: cache_run ansible.builtin.copy: content: "{{ redis.password }}" dest: "{{ ansible_user_home.stdout }}/.podsecrets/redis.pass" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" backup: true - name: Creating environment file for cloud server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/nextcloud.env.j2 dest: "{{ ansible_user_home.stdout }}/.nextcloud.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: nextcloud_environ # - name: Debugging # ansible.builtin.debug: # msg: "{{ vpn.clients }}" # - name: Prematurely ending # ansible.builtin.meta: end_play - name: Allowing rate limiting concurrent connections per IP on start # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE OPEN PORT 993 -->" block: | PreUp=iptables -A INPUT -p tcp --dport 993 -j ACCEPT PreUp=ip6tables -A INPUT -p tcp --dport 993 -j ACCEPT insertafter: "^PreUp ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Allowing rate limiting concurrent connections per IP on start # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE CLOSE PORT 993 -->" block: | PostDown=iptables -A INPUT -p tcp --dport 993 -j ACCEPT PostDown=ip6tables -A INPUT -p tcp --dport 993 -j ACCEPT insertafter: "^PostDown ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Restarting VPN container when: "source_code.repos.compose.rpath == '/dependent' and vpn_run" become: true become_user: "{{ current_user.stdout }}" containers.podman.podman_container: name: "{{ compose.containers.vpn.name }}" state: started force_restart: true - name: Creating and deploying DBMS server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ mysql_environ.dest }} --env-file {{ email_environ.dest }} --env-file {{ nextcloud_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.cloud.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Adding Caddyfile subdomain entry when: "server_run and mode == 'prod'" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | {{ nextcloud.subdomain }}.{{ web_fqdn }} { root /srv/{{ nextcloud.subdomain }}.{{ web_fqdn }} file_server php_fastcgi localhost:9000 handle_errors { root /srv/{{ web_fqdn }} rewrite /error/{err.status_code}.html templates encode gzip } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED CLOUD DOMAIN -->" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" create: true mode: "644" state: present - name: Adding Caddyfile subdomain entry when: "server_run and (mode == 'dev' or caddy.scheme == 'http')" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | http://{{ nextcloud.subdomain }}.{{ web_fqdn }} { root /srv/{{ nextcloud.subdomain }}.{{ web_fqdn }} file_server php_fastcgi localhost:9000 handle_errors { root /srv/{{ web_fqdn }} rewrite /error/{err.status_code}.html templates encode gzip } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED CLOUD DOMAIN -->" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" create: true mode: "644" state: present # - name: Restarting webserver / reverse proxy container # become: true # become_user: "{{ current_user.stdout }}" # when: server_run # containers.podman.podman_container: # name: "{{ compose.containers.webserver.name }}" # state: started # force_restart: true - name: Spinning up forge container specified by Compose file when: forge_run block: - name: Creating database necessary for forge server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" when: dbms_run containers.podman.podman_container_exec: name: "{{ compose.containers.db.name }}" argv: - mysql - "-u" - "{{ mysql.users.admin.username }}" - "-p{{ mysql.users.admin.password }}" - "-e" - "'CREATE DATABASE IF NOT EXISTS {{ mysql.users.admin.databases.forgejo.name }};'" detach: true - name: Allowing rate limiting concurrent connections per IP on start # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE OPEN PORT 2121 -->" block: | PreUp=iptables -A INPUT -p tcp --dport 2121 -j ACCEPT PreUp=ip6tables -A INPUT -p tcp --dport 2121 -j ACCEPT insertafter: "^PreUp ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Disabling rate limiting concurrent connections per IP on stop # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE CLOSE PORT 2121 -->" block: | PostDown=iptables -A INPUT -p tcp --dport 2121 -j ACCEPT PostDown=ip6tables -A INPUT -p tcp --dport 2121 -j ACCEPT insertafter: "^PostDown ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Restarting VPN container become: true become_user: "{{ current_user.stdout }}" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run" containers.podman.podman_container: name: "{{ compose.containers.vpn.name }}" state: started force_restart: true - name: Creating and deploying forge server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ mysql_environ.dest }} --env-file {{ email_environ.dest }} --env-file {{ forgejo_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.forge.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Adding Caddyfile subdomain entry when: "server_run and mode == 'prod'" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | {{ forgejo.subdomain }}.{{ web_fqdn }} { reverse_proxy localhost:3000 handle_errors { root /srv/{{ web_fqdn }} rewrite /error/{err.status_code}.html file_server templates encode gzip } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED FORGE DOMAIN -->" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" create: true mode: "644" state: present - name: Adding Caddyfile subdomain entry when: "server_run and (mode == 'dev' or caddy.scheme == 'http')" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | http://{{ forgejo.subdomain }}.{{ web_fqdn }} { reverse_proxy localhost:3000 handle_errors { root /srv/{{ web_fqdn }} rewrite /error/{err.status_code}.html file_server templates encode gzip } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED FORGE DOMAIN -->" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" create: true mode: "644" state: present # - name: Restarting webserver / reverse proxy container # become: true # become_user: "{{ current_user.stdout }}" # when: server_run # containers.podman.podman_container: # name: "{{ compose.containers.webserver.name }}" # state: started # force_restart: true - name: Spinning up pastebin container specified by Compose file when: pbin_run block: - name: Creating database necessary for pastebin server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" when: dbms_run containers.podman.podman_container_exec: name: "{{ compose.containers.db.name }}" argv: - mysql - "-u" - "{{ mysql.users.admin.username }}" - "-p{{ mysql.users.admin.password }}" - "-e" - "'CREATE DATABASE IF NOT EXISTS {{ mysql.users.admin.databases.opengist.name }};'" detach: true - name: Creating gist configuration file become: true become_user: "{{ current_user.stdout }}" when: pbin_run ansible.builtin.template: src: user/config/opengist/config.yml.j2 dest: "{{ ansible_user_home.stdout }}/.config/opengist/config.yml" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true - name: Allowing rate limiting concurrent connections per IP on start # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE OPEN PORT 2323 -->" block: | PreUp=iptables -A INPUT -p tcp --dport 2323 -j ACCEPT PreUp=ip6tables -A INPUT -p tcp --dport 2323 -j ACCEPT insertafter: "^PreUp ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Disabling rate limiting concurrent connections per IP on stop # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE CLOSE PORT 2323 -->" block: | PostDown=iptables -D INPUT -p tcp --dport 2323 -j ACCEPT PostDown=ip6tables -D INPUT -p tcp --dport 2323 -j ACCEPT insertafter: "^PostDown ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Restarting VPN container when: "source_code.repos.compose.rpath == '/dependent' and vpn_run" become: true become_user: "{{ current_user.stdout }}" containers.podman.podman_container: name: "{{ compose.containers.vpn.name }}" state: started force_restart: true - name: Creating and deploying pastebin server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" when: pbin_run ansible.builtin.command: cmd: "podman-compose --env-file {{ opengist_environ.dest }} --env-file {{ mysql_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.pastebin.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Adding Caddyfile subdomain entry when: "server_run and mode == 'prod'" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | {{ gist.subdomain }}.{{ web_fqdn }} { reverse_proxy localhost:6157 handle_errors { root /srv/{{ web_fqdn }} rewrite /error/{err.status_code}.html file_server templates encode gzip } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED PASTEBIN DOMAIN -->" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" create: true mode: "644" state: present - name: Adding Caddyfile subdomain entry when: "server_run and (mode == 'dev' or caddy.scheme == 'http')" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | http://{{ gist.subdomain }}.{{ web_fqdn }} { reverse_proxy localhost:6157 handle_errors { root /srv/{{ web_fqdn }} rewrite /error/{err.status_code}.html file_server templates encode gzip } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED PASTEBIN DOMAIN -->" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" create: true mode: "644" state: present # - name: Restarting webserver / reverse proxy container # become: true # become_user: "{{ current_user.stdout }}" # when: server_run # containers.podman.podman_container: # name: "{{ compose.containers.webserver.name }}" # state: started # force_restart: true - name: Spinning up video casting server container specified by Compose file when: "source_code.repos.compose.rpath == '/dependent' and cast_run" block: - name: Allowing rate limiting concurrent connections per IP on start # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE OPEN PORT 8080,1935 -->" block: | PreUp=iptables -A INPUT -p tcp --dport 8080 -j ACCEPT PreUp=iptables -A INPUT -p tcp --dport 1935 -j ACCEPT PreUp=ip6tables -A INPUT -p tcp --dport 8080 -j ACCEPT PreUp=ip6tables -A INPUT -p tcp --dport 1935 -j ACCEPT insertafter: "^PreUp ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Disabling rate limiting concurrent connections per IP on stop # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE CLOSE PORT 8080, 1935 -->" block: | PostDown=iptables -D INPUT -p tcp --dport 8080 -j ACCEPT PostDown=iptables -D INPUT -p tcp --dport 1935 -j ACCEPT PostDown=ip6tables -D INPUT -p tcp --dport 8080 -j ACCEPT PostDown=ip6tables -D INPUT -p tcp --dport 1935 -j ACCEPT insertafter: "^PostDown ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Creating and deploying video casting server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ environ.dest }} up -d {{ compose.containers.cast.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Adding Caddyfile subdomain entry when: "server_run and mode == 'prod'" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | cast.{{ web_fqdn }} { reverse_proxy localhost:8080 handle_errors { root /srv/{{ web_fqdn }} rewrite /error/{err.status_code}.html file_server templates encode gzip } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED CAST DOMAIN -->" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" create: true mode: "644" state: present - name: Adding Caddyfile subdomain entry when: "server_run and (mode == 'dev' or caddy.scheme == 'http')" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | http://cast.{{ web_fqdn }} { reverse_proxy localhost:8080 handle_errors { root /srv/{{ web_fqdn }} rewrite /error/{err.status_code}.html file_server templates encode gzip } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED CAST DOMAIN -->" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" create: true mode: "644" state: present - name: Spinning up web or reverse proxy server container specified by Compose file when: server_run block: - name: Creating directory for website subdomains ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/srv/{{ item }}.{{ web_fqdn }}" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory loop: - certbot - notes - blog - name: Creating a ZFS dataset for Caddy container configuration become: true when: zfs_present community.general.zfs: name: "{{ preferred_zpool.user_input }}/caddy_config" state: present extra_zfs_properties: canmount: "on" mountpoint: "{{ ansible_user_home.stdout }}/.caddy" - name: Creating directory for Caddy configuration ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.caddy" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "755" state: directory - name: Allowing rate limiting concurrent connections per IP on start # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE OPEN PORT 80 -->" block: | PreUp=iptables -A INPUT -p tcp --dport 80 -j ACCEPT PreUp=ip6tables -A INPUT -p tcp --dport 80 -j ACCEPT insertafter: "^PreUp ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Disabling rate limiting concurrent connections per IP on stop # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE CLOSE PORT 80 -->" block: | PostDown=iptables -D INPUT -p tcp --dport 80 -j ACCEPT PostDown=ip6tables -D INPUT -p tcp --dport 80 -j ACCEPT insertafter: "^PostDown ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Restarting VPN container when: "source_code.repos.compose.rpath == '/dependent' and vpn_run" become: true become_user: "{{ current_user.stdout }}" containers.podman.podman_container: name: "{{ compose.containers.vpn.name }}" state: started force_restart: true - name: Creating volume subdirectory for main website root's error pages ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/srv/{{ web_fqdn }}/error" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory - name: Creating image files for main website root's error path become: true become_user: "{{ current_user.stdout }}" ansible.builtin.copy: src: "user/srv/domain-root/error/{{ item }}" dest: "{{ ansible_user_home.stdout }}/srv/{{ web_fqdn }}/error/" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" backup: true mode: "644" loop: - 503.html - "mythe-sisyphus-klein.png" - "dark-matter.png" - name: Creating or updating Caddyfile at directory when: "mode == 'prod' and ssl_run" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | http://{{ web_fqdn }} { handle /.well-known/acme-challenge/* { reverse_proxy localhost:80 } handle { redir https://{host}{uri} 308 } } :80 { root /srv/certbot.{{ web_fqdn }} browse } {{ web_fqdn }} { respond 503 # root /srv/{{ web_fqdn }} file_server header /.well-known/openpgpkey/* { Content-Type application/octet-stream Access-Control-Allow-Origin * } handle_errors { rewrite /error/{err.status_code}.html templates } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED ROOT DOMAIN -->" create: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" state: present - name: Creating or updating Caddyfile at directory when: "mode == 'prod' and not ssl_run" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | {{ web_fqdn }} { respond 503 # root /srv/{{ web_fqdn }} file_server header /.well-known/openpgpkey/* { Content-Type application/octet-stream Access-Control-Allow-Origin * } handle_errors { rewrite /error/{err.status_code}.html templates } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED ROOT DOMAIN -->" create: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" state: present - name: Creating or updating Caddyfile at directory when: "mode == 'dev' or caddy.scheme == 'http'" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.config/caddy/Caddyfile" block: | http://{{ web_fqdn }} { respond 503 # root /srv/{{ web_fqdn }} file_server header /.well-known/openpgpkey/* { Content-Type application/octet-stream Access-Control-Allow-Origin * } handle_errors { rewrite /error/{err.status_code}.html templates } } prepend_newline: true marker: "# <-- {mark} ANSIBLE MANAGED ROOT DOMAIN -->" create: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" state: present - name: Creating and deploying webserver / reverse proxy server container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ environ.dest }} up -d {{ compose.containers.webserver.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up ACME challenge container specified by Compose file when: ssl_run ignore_errors: true block: - name: Creating environment file for SSL/TLS certificate acquisition container specified in Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/certbot.env.j2 dest: "{{ ansible_user_home.stdout }}/.certbot.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: certbot_environ - name: Allowing rate limiting concurrent connections per IP on start # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE OPEN PORT 443 -->" block: | PreUp=iptables -A INPUT -p tcp --dport 443 -j ACCEPT PreUp=iptables -A INPUT -p udp --dport 443 -j ACCEPT PreUp=ip6tables -A INPUT -p tcp --dport 443 -j ACCEPT PreUp=ip6tables -A INPUT -p udp --dport 443 -j ACCEPT insertafter: "^PreUp ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Disabling rate limiting concurrent connections per IP on stop # when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and (((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']))" when: "source_code.repos.compose.rpath == '/dependent' and vpn_run and ((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.blockinfile: path: "{{ ansible_user_home.stdout }}/.wg/authorized_clients.d/{{ item.name }}{{ (idx | string) }}.conf" marker: "# <-- {mark} ANSIBLE CLOSE PORT 443 -->" block: | PostDown=iptables -D INPUT -p tcp --dport 443 -j ACCEPT PostDown=iptables -D INPUT -p udp --dport 443 -j ACCEPT PostDown=ip6tables -D INPUT -p tcp --dport 443 -j ACCEPT PostDown=ip6tables -D INPUT -p udp --dport 443 -j ACCEPT insertafter: "^PostDown ?= ?" state: present loop: "{{ vpn.clients }}" loop_control: index_var: idx - name: Restarting VPN container when: "source_code.repos.compose.rpath == '/dependent' and vpn_run" become: true become_user: "{{ current_user.stdout }}" containers.podman.podman_container: name: "{{ compose.containers.vpn.name }}" state: started force_restart: true - name: Creating and deploying SSL/TLS certificate acquisition container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ certbot_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.ssl.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up synchronized playback container specified by Compose file when: (compose.containers.syncplay is defined and compose.containers.syncplay != None) and syncplay.containerized and source_code.repos.compose.rpath == '/dependent' block: - name: Creating environment file for synchronized playback container specified in Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/syncplay.env.j2 dest: "{{ ansible_user_home.stdout }}/.syncplay.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: syncplay_environ - name: Creating and deploying synchronized playback container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ syncplay_environ.dest }} --env-file {{ environ.dest }} up -d {{ compose.containers.syncplay.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up tailnet container specified by Compose file when: "tail_run and (source_code.repos.compose.rpath == '/dependent')" block: - name: Creating required tailnet container secret for tailnet container specified by Compose file become: true # when: ((fqdn is defined and fqdn != None) and fqdn in item.name) or (item.name in groups.homeserver or item.name in groups['homeserver.test']) when: "((inventory_hostname in item.name or web_fqdn in item.name) or correct_domain)" ansible.builtin.copy: src: "{{ item.name }}-{{ headscale.users.admin.username }}@headscale/headscale{{ (idx | string) }}.key" dest: "{{ ansible_user_home.stdout }}/.podsecrets/headscale.key" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true loop: "{{ headscale.clients }}" loop_control: index_var: idx - name: Creating tailnet configuration file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/config/tailscale/conf.json.j2 dest: "{{ ansible_user_home.stdout }}/.config/tailscale/conf.json" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" block_start_string: "<%" block_end_string: "%>" mode: "644" force: true backup: true - name: Creating and deploying tailnet container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ environ.dest }} --env-file {{ stash_environ.dest }} --env-file {{ actual_environ.dest }} up -d {{ compose.containers.tail.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up dashboard container specified by Compose file when: dash_run block: - name: Creating glance configuration file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/config/glance/glance.yml.j2 dest: "{{ ansible_user_home.stdout }}/.config/glance/glance.yml" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true - name: Creating and deploying dashboard container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose up -d {{ compose.containers.dash.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up download manager container specified by Compose file when: "source_code.repos.compose.run and (compose.containers.surge is defined and compose.containers.surge != None)" block: - name: Creating and deploying download manager container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose up -d {{ compose.containers.surge.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Acquiring Surge service token become: true become_user: "{{ current_user.stdout }}" containers.podman.podman_container_exec: name: "{{ compose.containers.surge.name }}" argv: - surge - token detach: true register: surge_token - name: Creating token file for container ansible.builtin.copy: content: "{{ surge_token.stdout }}" dest: "{{ ansible_user_home.stdout }}/.local/surge/token" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "600" register: surge_token_file - name: Restarting Surge container become: true become_user: "{{ current_user.stdout }}" containers.podman.podman_container: name: "{{ compose.containers.surge.name }}" state: started force_restart: true - name: Pausing to inquire about how to proceed ansible.builtin.pause: prompt: "Type \"fetch\" to get the Surge API token, or \"show\" to see it for manual copying instead" echo: true register: data_method - name: Presenting Surge API token to Control Node when: data_method.user_input == "show" ansible.builtin.debug: msg: "Make sure to store the following API token for Surge:\n {{ surge_token.stdout }}" - name: Giving opportunity to manually copy Surge API token when: data_method.user_input == "show" ansible.builtin.pause: - name: Placing Surge API token into file on control node when: data_method.user_input == "fetch" ansible.builtin.fetch: src: "{{ surge_token_file.dest }}" dest: "./.tmp/{{ inventory_hostname }}-surge/surge.secret" flat: true - name: Spinning up Aria2 container specified by Compose file when: "source_code.repos.compose.run and aria.containerized and (compose.containers.aria is defined and compose.containers.aria != None)" block: - name: Creating required SMTP-related container secret become: true ansible.builtin.copy: content: "{{ aria.rpc.secret }}" dest: "{{ ansible_user_home.stdout }}/.podsecrets/aria.token" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" backup: true - name: Creating environment file for Aria2 container specified in Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/aria.env.j2 dest: "{{ ansible_user_home.stdout }}/.aria.env" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true register: aria_environ - name: Creating directory to store Aria2 configuration file ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.aria2" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "755" state: directory - name: Creating Aria2 configuration become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: user/aria2/aria2.conf.j2 dest: "{{ ansible_user_home.stdout }}/.aria2/aria2.conf" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" mode: "644" force: true backup: true # validate: "aria2c --check" - name: Creating and deploying Aria2 container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ aria_environ.dest }} up -d {{ compose.containers.aria.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up Aria2 Web UI container specified by Compose file when: "source_code.repos.compose.run and (compose.containers.ariang is defined and compose.containers.ariang != None)" block: - name: Creating and deploying Aria2 Web UI container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose up -d {{ compose.containers.ariang.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up download automator container specified by Compose file when: "source_code.repos.compose.run and (compose.containers.flexget is defined and compose.containers.flexget != None) and (flexget.enabled and flexget.containerized)" block: - name: Creating requisite download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/media/vids/{{ item }}" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" loop: - series - features - name: Creating requisite download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/downloads/flexget/vids/series/torrents" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" - name: Creating requisite download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/downloads/flexget/vids/torrents" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" - name: Creating requisite hidden download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/downloads/.xxx/flexget/vids/torrents" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" - name: Creating requisite hidden download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/downloads/media/vids/{{ item }}" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" loop: - series - features - name: Creating requisite hidden file for film torrent links ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/downloads/media/vids/features/.films.csv" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: touch mode: "644" - name: Creating requisite hidden download paths ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/downloads/.xxx/media/vids" recurse: true owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: directory mode: "755" - name: Creating requisite hidden file for NSFW video torrent links ansible.builtin.file: path: "{{ ansible_user_home.stdout }}/.xxx/.vids.csv" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" state: touch mode: "644" - name: Configuring flexget become: true become_user: "{{ current_user.stdout }}" ansible.builtin.template: src: roles/init-server/templates/user/flexget/config.yml.j2 variable_start_string: "<<" variable_end_string: ">>" dest: "{{ ansible_user_home.stdout }}/.flexget/config.yml" owner: "{{ ansible_user }}" group: "{{ ansible_user }}" force: true backup: true # validate: "flexget check" - name: Creating and deploying downlaod automator container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose up -d {{ compose.containers.flexget.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up file-sharing container specified by Compose file when: "source_code.repos.compose.run and (compose.containers.soulseek is defined and compose.containers.soulseek != None)" block: - name: Creating and deploying file-sharing container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose up -d {{ compose.containers.soulseek.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up grocy container specified by Compose file when: "source_code.repos.compose.run and (compose.containers.grocy is defined and compose.containers.grocy != None)" block: - name: Creating and deploying download manager container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose up -d {{ compose.containers.grocy.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up financial budgeting container specified by Compose file when: "source_code.repos.compose.run and actual.containerized and (compose.containers.budget is defined and compose.containers.budget != None)" block: - name: Creating and deploying financial budgeting container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ actual_environ.dest }} up -d {{ compose.containers.budget.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up ebook library container specified by Compose file when: "source_code.repos.compose.run and kavita.containerized and (compose.containers.reader is defined and compose.containers.reader != None)" block: - name: Creating and deploying ebook library container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose up -d {{ compose.containers.reader.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Spinning up NSFW streaming container specified by Compose file when: "source_code.repos.compose.run and stash.containerized and (compose.containers.stash is defined and compose.containers.stash != None)" block: - name: Creating and deploying NSFW streaming container specified by Compose file become: true become_user: "{{ current_user.stdout }}" ansible.builtin.command: cmd: "podman-compose --env-file {{ stash_environ.dest }} up -d {{ compose.containers.stash.name }}" chdir: "{{ new_compose_path.dest }}{{ source_code.repos.compose.rpath | default('/independent') }}" - name: Making running containers persist on user logout become: true ansible.builtin.shell: cmd: loginctl enable-linger $(whoami)