diff --git a/.gitignore b/.gitignore index 2db929b..71e0acf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ # ---> Ansible *.retry + +# ---> VS Code +.vscode/ \ No newline at end of file diff --git a/collections/requirements.yml b/collections/requirements.yml index 12fbe51..a0fc143 100644 --- a/collections/requirements.yml +++ b/collections/requirements.yml @@ -1,3 +1,5 @@ +# vim: ft=yaml.ansible +# code: language=ansible collections: - name: community.general version: '>=7.5.0' diff --git a/group_vars/all/vars.yml b/group_vars/all/vars.yml deleted file mode 100644 index 7092cc3..0000000 --- a/group_vars/all/vars.yml +++ /dev/null @@ -1,26 +0,0 @@ -# vim: ft=yaml.ansible ---- -hostname: default -timezone: Europe/Copenhagen - -users: - - name: ubuntu - comment: System Administration - password: $6$YitakVLuUxjnPfDd$aFnEDcc98y6MlRYxLPAhb.eHsKqSIz385i4VrHW1Q8b986IqUhtu62gaOIALzM4FAU3dnWaHNUTGxY0zgA6jC0 - groups: - - sudo - ssh_keys: - - sk-ssh-ed25519@openssh.com AAAAGnNrLXNzaC1lZDI1NTE5QG9wZW5zc2guY29tAAAAIFWZGLov8wPBNxuvnaPK+8vv6wK5hHUVEFzXKsN9QeuBAAAADHNzaDpzYW1zYXB0aQ== ssh:samsapti - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPd/4fQV7CL8/KVwbo/phiV5UdXFBIDlkZ+ps8C7FeRf cardno:14 336 332 - -open_ports: - - { port: '22', proto: 'tcp', comment: 'SSH (not port-forwarded)' } - - { port: '53', proto: 'tcp', comment: 'Pi-hole (not port-forwarded)' } - - { port: '53', proto: 'udp', comment: 'Pi-hole (not port-forwarded)' } - - { port: '80', proto: 'tcp', comment: 'HTTP' } - - { port: '443', proto: 'tcp', comment: 'HTTPS' } - - { port: '443', proto: 'udp', comment: 'HTTPS' } - - { port: '4001', proto: 'tcp', comment: 'IPFS Kubo P2P' } - - { port: '4001', proto: 'udp', comment: 'IPFS Kubo P2P' } - - { port: '18080', proto: 'tcp', comment: 'monerod P2P' } - - { port: '18089', proto: 'tcp', comment: 'monerod RPC' } diff --git a/inventories/production b/inventories/production deleted file mode 100644 index 9dbfc90..0000000 --- a/inventories/production +++ /dev/null @@ -1,5 +0,0 @@ -[appservers] -sapt-lapb-app01.servers.local.sapti.me - -[dbservers] -sapt-labp-db01.servers.local.sapti.me diff --git a/group_vars/all/secrets.yml b/inventories/production/group_vars/all/secrets.yml similarity index 100% rename from group_vars/all/secrets.yml rename to inventories/production/group_vars/all/secrets.yml diff --git a/inventories/production/group_vars/all/vars.yml b/inventories/production/group_vars/all/vars.yml new file mode 100644 index 0000000..b96cd9b --- /dev/null +++ b/inventories/production/group_vars/all/vars.yml @@ -0,0 +1,12 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +base_domain: sapti.me +local_domain: local.{{ base_domain }} + +encrypted_fs: /data +docker_data_root: "{{ encrypted_fs }}/docker" + +hostname: "{{ inventory_hostname_short }}" +timezone: Europe/Copenhagen +username: lab_admin diff --git a/inventories/production/group_vars/appservers/vars.yml b/inventories/production/group_vars/appservers/vars.yml new file mode 100644 index 0000000..728b968 --- /dev/null +++ b/inventories/production/group_vars/appservers/vars.yml @@ -0,0 +1,6 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +apps_base_domain: "{{ base_domain }}" +apps_local_domain: "{{ local_domain }}" +apps_data_root: "{{ encrypted_fs }}/apps" diff --git a/inventories/production/group_vars/dbservers/vars.yml b/inventories/production/group_vars/dbservers/vars.yml new file mode 100644 index 0000000..ef48fc4 --- /dev/null +++ b/inventories/production/group_vars/dbservers/vars.yml @@ -0,0 +1,4 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +db_data_root: "{{ encrypted_fs }}/db" diff --git a/inventories/production/host_vars/sapt-labp-app01.yml b/inventories/production/host_vars/sapt-labp-app01.yml new file mode 100644 index 0000000..bbaeaf3 --- /dev/null +++ b/inventories/production/host_vars/sapt-labp-app01.yml @@ -0,0 +1,10 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +apps_include: + - postfix + - emby + - nextcloud + - pihole + - restic + - watchtower diff --git a/inventories/production/host_vars/sapt-labp-app02.yml b/inventories/production/host_vars/sapt-labp-app02.yml new file mode 100644 index 0000000..a54f22c --- /dev/null +++ b/inventories/production/host_vars/sapt-labp-app02.yml @@ -0,0 +1,8 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +apps_include: + - ipfs + - monerod + - snowflake + - watchtower diff --git a/inventories/production/hosts b/inventories/production/hosts new file mode 100644 index 0000000..1a6d1f0 --- /dev/null +++ b/inventories/production/hosts @@ -0,0 +1,6 @@ +[appservers] +sapt-labp-app01.servers.local.sapti.me +sapt-labp-app02.servers.local.sapti.me + +[dbservers] +sapt-labp-db01.servers.local.sapti.me \ No newline at end of file diff --git a/inventories/shared b/inventories/shared deleted file mode 100644 index d7e7aeb..0000000 --- a/inventories/shared +++ /dev/null @@ -1,8 +0,0 @@ -[shdservers] -sapt-labn-shd01.servers.local.sapti.me - -[trnservers] -sapt-labn-trn01.servers.local.sapti.me - -[monservers] -sapt-labn-mon01.servers.local.sapti.me diff --git a/inventories/shared/hosts b/inventories/shared/hosts new file mode 100644 index 0000000..05cf742 --- /dev/null +++ b/inventories/shared/hosts @@ -0,0 +1,5 @@ +[proxyservers] +sapt-labn-prx01.servers.local.sapti.me + +[monitoringservers] +sapt-labn-mon01.servers.local.sapti.me \ No newline at end of file diff --git a/inventories/staging b/inventories/staging deleted file mode 100644 index e26f59f..0000000 --- a/inventories/staging +++ /dev/null @@ -1,5 +0,0 @@ -[appservers] -sapt-labv-app01.servers.local.sapti.me - -[dbservers] -sapt-labv-db01.servers.local.sapti.me diff --git a/inventories/staging/group_vars/all/secrets.yml b/inventories/staging/group_vars/all/secrets.yml new file mode 100644 index 0000000..7d7dbd2 --- /dev/null +++ b/inventories/staging/group_vars/all/secrets.yml @@ -0,0 +1,54 @@ +$ANSIBLE_VAULT;1.1;AES256 +65653764303436313934646462396636636335303334636532306438613635333362313530323731 +3236383962303039393238646362626665613463666335610a353261343163663934353366656630 +65356562616661326535626238373635366233326366343631386165653735373637656330343735 +3330376331306633300a393530313436653737366630336165653839616437626531346331653466 +35626530373932303962333933626265326166656136623139666533643934653666383436383838 +35643430383763323038646461313563373462353736376137323230613338613430303763376164 +32633833653236323561643636373461353932663232663561636164383361663361346263376436 +33346335323530666436393538326531623931643838633631646137306563306630336238333166 +34346634306337313938626632663131333534356631386564363233643339623338363539326262 +62336331646134626439313032626231383833353831343038393739366435663766333262633461 +61383830656566666262376162376637313933336533396664303830306266323234323463613966 +33383864393964323866613937623331343966373432643732383663343335316562326637353837 +32646362613631633263386566353930363665353361353934393537353461383333343331356639 +31633861346635386432363835373736363133303266383835633436313533393835616231313165 +62363835623866323961313664333430656131373061373764316331343639653437633037636339 +37656363366137666138333835353661613363333963333134313338386362656435633063353538 +64346464336230323131346537653565383630613532356264633035363962303131663036343065 +31363536366362303164373339333462653166333031616362653631383234303836613532633332 +64333337343362613161626166393634636336373265643561323230383534326663643536366333 +63393230343735346631306461653636396634343864623532306661326564633661623131346639 +38363331613463616266633863303161326237313037643934383032663834366634363965396238 +63633330636130373331393533393531623535656361306165623539383962653839353334643233 +35663566383434396135323531353230643763326134323865343863616461326530353963376232 +31373965353732386630366130656266623464666333383433393062613366363136333933343461 +61323832626466386433636134383765383834643536363635623830303535646530613238343437 +36363566396465313830326137396532393762623436646663643663393266396631363663343936 +32383561643237386630353730323563313636663633623036363131366139396235343138306134 +66653538663937616266343065333366613236313235346635326337633866363263313832653732 +35663634363432383066386561663661643265613532386165646230313531356535353165343666 +38663764643439633664353439366536323763663063626664623365613734386265393934383532 +66323963303133653465366138666132666339353630323739383633383462373532323762663432 +30643436376539303430343164663238376634346437623063656466653138626237663538626436 +30623836393362666231323435383238643731623931396235346330323539643966663365363632 +65646564656563303064643161353930396663363638383965616662663238646434373862316430 +39343932656532626631323035633563373730393163396338653064326631626436373533333734 +65626361346162383530626134336230346234653936366462393538353137373933376533313839 +34383932343637623262373134636233373839313339393433303337363566643833353066396337 +66643966373436393937363064353365363239323461653034626161383936303236313364366535 +65316335333235623463613766633836643730363634666465386663386235306334376364323162 +39333466383333643339633538336632376333623439646234643666333162326135663130303536 +39663234633761633632346534383966313234613763323038626466346235333165303934633431 +36313565346631623166383338643739346634393663303264373962343932376430663333376165 +62613462396531323634613966616331623538306636343235393362396437633239366136616436 +65323638393566363034633231643565636431356431386234316233636266663136656139663532 +38613637636432626236323066643632343661316565343361323764353335313265383831373764 +64323361333463346438626134323166623231393338373333653161623663336434383931393163 +36633163393235636435323931313265633234623433653134616132346262653234636364376238 +66313761333436336663323663626563656566366665336439643461623837666338313565313964 +31666466663863623334316164316432353362316336616662666666363766306231653664306663 +37613839383864386533326634336433633464343831303835656366616339393332633965323431 +65643136643866653834353538356233623662663237303261333564346566643839633532366262 +66653162366563666463353533656665323661326566383966306332626566663732353730313732 +65323034326161306165613364336336386265313735396237623633346263333966 diff --git a/inventories/staging/group_vars/all/vars.yml b/inventories/staging/group_vars/all/vars.yml new file mode 100644 index 0000000..20bdfe5 --- /dev/null +++ b/inventories/staging/group_vars/all/vars.yml @@ -0,0 +1,12 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +base_domain: staging.sapti.me +local_domain: local.{{ base_domain }} + +encrypted_fs: /data +docker_data_root: "{{ encrypted_fs }}/docker" + +hostname: "{{ inventory_hostname_short }}" +timezone: Europe/Copenhagen +username: lab_admin diff --git a/inventories/staging/group_vars/appservers/vars.yml b/inventories/staging/group_vars/appservers/vars.yml new file mode 100644 index 0000000..728b968 --- /dev/null +++ b/inventories/staging/group_vars/appservers/vars.yml @@ -0,0 +1,6 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +apps_base_domain: "{{ base_domain }}" +apps_local_domain: "{{ local_domain }}" +apps_data_root: "{{ encrypted_fs }}/apps" diff --git a/inventories/staging/group_vars/dbservers/vars.yml b/inventories/staging/group_vars/dbservers/vars.yml new file mode 100644 index 0000000..ef48fc4 --- /dev/null +++ b/inventories/staging/group_vars/dbservers/vars.yml @@ -0,0 +1,4 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +db_data_root: "{{ encrypted_fs }}/db" diff --git a/inventories/staging/host_vars/sapt-labs-app01.yml b/inventories/staging/host_vars/sapt-labs-app01.yml new file mode 100644 index 0000000..bbaeaf3 --- /dev/null +++ b/inventories/staging/host_vars/sapt-labs-app01.yml @@ -0,0 +1,10 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +apps_include: + - postfix + - emby + - nextcloud + - pihole + - restic + - watchtower diff --git a/inventories/staging/host_vars/sapt-labs-app02.yml b/inventories/staging/host_vars/sapt-labs-app02.yml new file mode 100644 index 0000000..a54f22c --- /dev/null +++ b/inventories/staging/host_vars/sapt-labs-app02.yml @@ -0,0 +1,8 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +apps_include: + - ipfs + - monerod + - snowflake + - watchtower diff --git a/inventories/staging/hosts b/inventories/staging/hosts new file mode 100644 index 0000000..cb83b06 --- /dev/null +++ b/inventories/staging/hosts @@ -0,0 +1,6 @@ +[appservers] +sapt-labs-app01.servers.local.sapti.me +sapt-labs-app02.servers.local.sapti.me + +[dbservers] +sapt-labs-db01.servers.local.sapti.me diff --git a/playbooks/appservers.yml b/playbooks/appservers.yml index e03e5ed..deb2ba2 100644 --- a/playbooks/appservers.yml +++ b/playbooks/appservers.yml @@ -1,9 +1,10 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: App server configuration hosts: appservers become: true - become_method: sudo + become_method: ansible.builtin.sudo roles: - docker - apps diff --git a/roles/apps/defaults/main.yml b/roles/apps/defaults/main.yml index c5f52f9..b6e825b 100644 --- a/roles/apps/defaults/main.yml +++ b/roles/apps/defaults/main.yml @@ -1,41 +1,36 @@ # vim: ft=yaml.ansible +# code: language=ansible --- -base_domain: sapti.me -local_domain: local.{{ base_domain }} -base_volume: "{{ ssd_mount_point }}/apps" -mass_data_volume: "{{ hdd_mount_point }}/apps" - -services: - caddy: - volume: "{{ base_volume }}/caddy" - docker_ipv4: 172.16.3.2 - version: '2.7.4' +apps_base_domain: "example.com" +apps_local_domain: "local.{{ apps_base_domain }}" +apps_data_root: /apps +apps_docker_network: apps_network +apps_vars: postfix: - domain: smtp.{{ base_domain }} - volume: "{{ base_volume }}/postfix" + domain: smtp.{{ apps_base_domain }} + volume: "{{ apps_data_root }}/postfix" version: latest-alpine emby: - domain: watch.{{ base_domain }} - volume: "{{ base_volume }}/emby" - data_volume: "{{ mass_data_volume }}/emby" + domain: watch.{{ apps_base_domain }} + volume: "{{ apps_data_root }}/emby" version: latest ipfs: - domain: ipfs.{{ local_domain }} - gateway_domain: ipfs-gateway.{{ base_domain }} - volume: "{{ base_volume }}/ipfs" + domain: ipfs.{{ apps_local_domain }} + gateway_domain: ipfs-gateway.{{ apps_base_domain }} + volume: "{{ apps_data_root }}/ipfs" version: v0.19.2 # https://github.com/ipfs/kubo/issues/9901 monerod: - domain: xmr.{{ base_domain }} - volume: "{{ base_volume }}/monerod" + domain: xmr.{{ apps_base_domain }} + volume: "{{ apps_data_root }}/monerod" version: latest nextcloud: - domain: cloud.{{ base_domain }} - volume: "{{ base_volume }}/nextcloud" + domain: cloud.{{ apps_base_domain }} + volume: "{{ apps_data_root }}/nextcloud" version: 27-apache postgres_version: 14-alpine redis_version: 7-alpine @@ -44,8 +39,8 @@ services: version: latest pihole: - domain: pi-hole.{{ local_domain }} - volume: "{{ base_volume }}/pi-hole" + domain: pi-hole.{{ apps_local_domain }} + volume: "{{ apps_data_root }}/pi-hole" docker_ipv4: 172.18.3.2 version: '2023.05.2' unbound_version: latest @@ -57,17 +52,19 @@ services: watchtower: version: '1.5.3' -local_ipv4s: +apps_include: [] # empty == all + +apps_local_ipv4s: - '192.168.1.0/24' - '192.168.8.0/24' -restic_volumes: +apps_restic_volumes: - "/var/run/docker.sock:/var/run/docker.sock:rw" - - "{{ services.caddy.volume }}:/mnt/volumes/caddy:ro" - - "{{ services.postfix.volume }}:/mnt/volumes/postfix:ro" - - "{{ services.emby.volume }}:/mnt/volumes/emby:ro" - - "{{ services.nextcloud.volume }}:/mnt/volumes/nextcloud:ro" - - "{{ services.pihole.volume }}:/mnt/volumes/pi-hole:ro" + - "{{ apps_vars.caddy.volume }}:/mnt/volumes/caddy:ro" + - "{{ apps_vars.postfix.volume }}:/mnt/volumes/postfix:ro" + - "{{ apps_vars.emby.volume }}:/mnt/volumes/emby:ro" + - "{{ apps_vars.nextcloud.volume }}:/mnt/volumes/nextcloud:ro" + - "{{ apps_vars.pihole.volume }}:/mnt/volumes/pi-hole:ro" -sender_domains: - - "{{ services.nextcloud.domain }}" +apps_sender_domains: + - "{{ apps_vars.nextcloud.domain }}" diff --git a/roles/apps/handlers/main.yml b/roles/apps/handlers/main.yml deleted file mode 100644 index 323c86a..0000000 --- a/roles/apps/handlers/main.yml +++ /dev/null @@ -1,10 +0,0 @@ -# vim: ft=yaml.ansible ---- -- name: Build Caddy Docker image - community.docker.docker_image: - name: custom/caddy:{{ services.caddy.version }}-alpine - source: build - build: - path: "{{ services.caddy.volume }}" - dockerfile: caddy.Dockerfile - state: present diff --git a/roles/apps/tasks/services/emby.yml b/roles/apps/tasks/apps/emby.yml similarity index 97% rename from roles/apps/tasks/services/emby.yml rename to roles/apps/tasks/apps/emby.yml index 3212cc5..02d5eb5 100644 --- a/roles/apps/tasks/services/emby.yml +++ b/roles/apps/tasks/apps/emby.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Create Emby volume directories ansible.builtin.file: diff --git a/roles/apps/tasks/services/ipfs.yml b/roles/apps/tasks/apps/ipfs.yml similarity index 98% rename from roles/apps/tasks/services/ipfs.yml rename to roles/apps/tasks/apps/ipfs.yml index d3e5a25..ba011c8 100644 --- a/roles/apps/tasks/services/ipfs.yml +++ b/roles/apps/tasks/apps/ipfs.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Create IPFS Kubo volume directories ansible.builtin.file: diff --git a/roles/apps/tasks/services/monerod.yml b/roles/apps/tasks/apps/monerod.yml similarity index 96% rename from roles/apps/tasks/services/monerod.yml rename to roles/apps/tasks/apps/monerod.yml index 2cde9cc..4355c24 100644 --- a/roles/apps/tasks/services/monerod.yml +++ b/roles/apps/tasks/apps/monerod.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Create Monero node volume directory ansible.builtin.file: diff --git a/roles/apps/tasks/services/nextcloud.yml b/roles/apps/tasks/apps/nextcloud.yml similarity index 98% rename from roles/apps/tasks/services/nextcloud.yml rename to roles/apps/tasks/apps/nextcloud.yml index 48d91de..d6faf4d 100644 --- a/roles/apps/tasks/services/nextcloud.yml +++ b/roles/apps/tasks/apps/nextcloud.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Create Nextcloud apache2 directory ansible.builtin.file: @@ -24,7 +25,7 @@ - name: Copy Apache2 remoteip config file ansible.builtin.template: - src: remoteip.conf.j2 + src: nextcloud/remoteip.conf.j2 dest: "{{ services.nextcloud.volume }}/apache2/remoteip.conf" owner: root mode: u=rw,g=r,o=r diff --git a/roles/apps/tasks/services/pihole.yml b/roles/apps/tasks/apps/pihole.yml similarity index 98% rename from roles/apps/tasks/services/pihole.yml rename to roles/apps/tasks/apps/pihole.yml index 6efb47d..298eacd 100644 --- a/roles/apps/tasks/services/pihole.yml +++ b/roles/apps/tasks/apps/pihole.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Create Pi-hole volume base directory ansible.builtin.file: diff --git a/roles/apps/tasks/services/postfix.yml b/roles/apps/tasks/apps/postfix.yml similarity index 97% rename from roles/apps/tasks/services/postfix.yml rename to roles/apps/tasks/apps/postfix.yml index 207261e..2851c31 100644 --- a/roles/apps/tasks/services/postfix.yml +++ b/roles/apps/tasks/apps/postfix.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Create Docker network for Postfix community.docker.docker_network: diff --git a/roles/apps/tasks/services/restic.yml b/roles/apps/tasks/apps/restic.yml similarity index 99% rename from roles/apps/tasks/services/restic.yml rename to roles/apps/tasks/apps/restic.yml index bb9b1ec..5786be6 100644 --- a/roles/apps/tasks/services/restic.yml +++ b/roles/apps/tasks/apps/restic.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Deploy Restic with Docker Compose community.docker.docker_compose: diff --git a/roles/apps/tasks/services/snowflake.yml b/roles/apps/tasks/apps/snowflake.yml similarity index 94% rename from roles/apps/tasks/services/snowflake.yml rename to roles/apps/tasks/apps/snowflake.yml index 63d8d56..fbb0612 100644 --- a/roles/apps/tasks/services/snowflake.yml +++ b/roles/apps/tasks/apps/snowflake.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Deploy snowflake-proxy Docker container community.docker.docker_container: diff --git a/roles/apps/tasks/services/watchtower.yml b/roles/apps/tasks/apps/watchtower.yml similarity index 96% rename from roles/apps/tasks/services/watchtower.yml rename to roles/apps/tasks/apps/watchtower.yml index a1d3d5c..147994c 100644 --- a/roles/apps/tasks/services/watchtower.yml +++ b/roles/apps/tasks/apps/watchtower.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Create Docker network for Watchtower community.docker.docker_network: diff --git a/roles/apps/tasks/config.yml b/roles/apps/tasks/config.yml deleted file mode 100644 index 4238ab9..0000000 --- a/roles/apps/tasks/config.yml +++ /dev/null @@ -1,28 +0,0 @@ -# vim: ft=yaml.ansible ---- -- name: Copy Docker daemon config file - ansible.builtin.template: - src: daemon.json.j2 - dest: /etc/docker/daemon.json - owner: root - mode: u=rw,g=r,o=r - register: daemon_config - -- name: Disable and (re)start Docker daemon - ansible.builtin.service: - name: "{{ item }}" - enabled: false - state: "{{ 'restarted' if daemon_config.changed else 'started' }}" - loop: - - docker.socket - - docker.service - when: down is undefined or not down - -- name: Configure cron job to prune unused Docker data weekly - ansible.builtin.cron: - name: Prune unused Docker data - cron_file: ansible_docker_prune - job: 'docker system prune -fa && docker volume prune -fa' - special_time: weekly - user: root - state: present diff --git a/roles/apps/tasks/main.yml b/roles/apps/tasks/main.yml index c29689c..df241a9 100644 --- a/roles/apps/tasks/main.yml +++ b/roles/apps/tasks/main.yml @@ -1,50 +1,22 @@ # vim: ft=yaml.ansible +# code: language=ansible --- -- name: Add Docker PGP key - ansible.builtin.apt_key: - keyserver: keyserver.ubuntu.com - id: '0x8D81803C0EBFCD88' +- name: Create Docker network for apps + community.docker.docker_network: + name: "{{ apps_docker_network }}" + enable_ipv6: true + ipam_config: + - subnet: 172.17.2.0/24 + - subnet: fd02::/64 state: present -- name: Add Docker apt repository - ansible.builtin.apt_repository: - repo: 'deb [arch=arm64] https://download.docker.com/linux/ubuntu focal stable' - state: present - update_cache: true - -- name: Install Docker - ansible.builtin.apt: - name: "{{ pkgs }}" - state: present - vars: - pkgs: - - docker-ce - - docker-compose-plugin - -- name: Create docker-compose symlink +- name: Create base directories for Docker volumes ansible.builtin.file: - name: /usr/local/bin/docker-compose - src: /usr/libexec/docker/cli-plugins/docker-compose - state: link + name: "{{ apps_data_root }}" + owner: root + mode: u=rwx,g=rx,o=rx + state: directory -- name: Install Python bindings for Docker - ansible.builtin.pip: - name: "{{ pkgs }}" - state: present - executable: pip3 - vars: - pkgs: - - docker - - docker-compose - -- name: Configure Docker - ansible.builtin.import_tasks: config.yml - tags: - - docker_config - - reboot - -- name: Set up Docker services - ansible.builtin.import_tasks: services.yml - tags: - - services - - reboot +- name: Configure apps + ansible.builtin.include_tasks: apps/{{ item.key }}.yml + loop: "{{ apps_vars | dict2items }}" diff --git a/roles/apps/tasks/services.yml b/roles/apps/tasks/services.yml deleted file mode 100644 index 6f6ced0..0000000 --- a/roles/apps/tasks/services.yml +++ /dev/null @@ -1,30 +0,0 @@ -# vim: ft=yaml.ansible ---- -- name: Create Docker network for services - community.docker.docker_network: - name: services - enable_ipv6: true - ipam_config: - - subnet: 172.16.0.0/16 - - subnet: fd02::/64 - state: present - -- name: Create base directories for Docker volumes - ansible.builtin.file: - name: "{{ item }}" - owner: root - mode: u=rwx,g=rx,o=rx - state: directory - loop: - - "{{ base_volume }}" - - "{{ mass_data_volume }}" - -- name: Deploy services - ansible.builtin.include_tasks: services/{{ item.key }}.yml - loop: "{{ services | dict2items }}" - when: single_service is not defined - -- name: Deploy single service - ansible.builtin.include_tasks: services/{{ single_service }}.yml - when: single_service is defined and - single_service in services diff --git a/roles/apps/tasks/services/caddy.yml b/roles/apps/tasks/services/caddy.yml deleted file mode 100644 index a6248ff..0000000 --- a/roles/apps/tasks/services/caddy.yml +++ /dev/null @@ -1,59 +0,0 @@ -# vim: ft=yaml.ansible ---- -- name: Create Caddy volume directories - ansible.builtin.file: - name: "{{ services.caddy.volume }}/{{ dir }}" - owner: root - mode: u=rwx,g=rx,o=rx - state: directory - loop: - - config - - data - loop_control: - loop_var: dir - -- name: Copy Caddyfile - ansible.builtin.template: - src: Caddyfile.j2 - dest: "{{ services.caddy.volume }}/Caddyfile" - owner: root - mode: u=rw,g=r,o=r - -- name: Copy caddy.Dockerfile - ansible.builtin.template: - src: caddy.Dockerfile.j2 - dest: "{{ services.caddy.volume }}/caddy.Dockerfile" - owner: root - mode: u=rw,g=r,o=r - register: dockerfile - notify: Build Caddy Docker image - -- name: Flush handlers - ansible.builtin.meta: flush_handlers - -- name: Deploy Caddy Docker container - community.docker.docker_container: - name: caddy - state: "{{ 'absent' if down is defined and down else 'started' }}" - restart: "{{ restart is defined and restart }}" - recreate: "{{ dockerfile.changed or (recreate is defined and recreate) }}" - image: custom/caddy:{{ services.caddy.version }}-alpine - restart_policy: always - default_host_ip: '' - networks: - - name: services - ipv4_address: 172.16.3.2 - published_ports: - - 80:80/tcp - - 443:443/tcp - - 443:443/udp - - 18089:18089/tcp - volumes: - - "{{ services.caddy.volume }}/Caddyfile:/etc/caddy/Caddyfile:ro" - - "{{ services.caddy.volume }}/config:/config:rw" - - "{{ services.caddy.volume }}/data:/data:rw" - capabilities: - - net_bind_service - - dac_override - cap_drop: - - all diff --git a/roles/apps/templates/Caddyfile.j2 b/roles/apps/templates/Caddyfile.j2 deleted file mode 100644 index 6bd3ffd..0000000 --- a/roles/apps/templates/Caddyfile.j2 +++ /dev/null @@ -1,96 +0,0 @@ -{ - admin off -} - -{{ services.emby.domain }} { - tls {{ secrets.tls_email }} - - header { - Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" - -Server - } - - reverse_proxy emby:8096 -} - -{{ services.ipfs.domain }} { - tls {{ secrets.tls_email }} { - dns njalla {{ secrets.caddy.njalla_api_token }} - } - - header { - Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" - -Server - } - - @local { - remote_ip {{ local_ipv4s | join(' ') }} - } - - handle @local { - reverse_proxy ipfs_kubo:5001 - } - - respond 403 -} - -{{ services.ipfs.gateway_domain }}, -*.ipfs.{{ services.ipfs.gateway_domain }}, -*.ipns.{{ services.ipfs.gateway_domain }} { - tls {{ secrets.tls_email }} { - dns njalla {{ secrets.caddy.njalla_api_token }} - } - - header { - Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" - -Server - } - - reverse_proxy ipfs_kubo:8080 -} - -{{ services.monerod.domain }}:18089 { - tls {{ secrets.tls_email }} - - header { - Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" - -Server - } - - reverse_proxy monerod:18089 -} - -{{ services.nextcloud.domain }} { - tls {{ secrets.tls_email }} - - rewrite /.well-known/caldav /remote.php/dav - rewrite /.well-known/carddav /remote.php/dav - - header { - Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" - -Server - } - - reverse_proxy nextcloud:80 -} - -{{ services.pihole.domain }} { - tls {{ secrets.tls_email }} { - dns njalla {{ secrets.caddy.njalla_api_token }} - } - - header { - Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" - -Server - } - - @local { - remote_ip {{ local_ipv4s | join(' ') }} - } - - handle @local { - reverse_proxy pihole:80 - } - - respond 403 -} diff --git a/roles/apps/templates/caddy.Dockerfile.j2 b/roles/apps/templates/caddy.Dockerfile.j2 deleted file mode 100644 index 2ed5828..0000000 --- a/roles/apps/templates/caddy.Dockerfile.j2 +++ /dev/null @@ -1,8 +0,0 @@ -FROM caddy:{{ services.caddy.version }}-builder-alpine AS builder - -RUN xcaddy build v{{ services.caddy.version }} \ - --with github.com/caddy-dns/njalla - -FROM caddy:{{ services.caddy.version }}-alpine - -COPY --from=builder /usr/bin/caddy /usr/bin/caddy diff --git a/roles/apps/templates/daemon.json.j2 b/roles/apps/templates/daemon.json.j2 deleted file mode 100644 index 3daea73..0000000 --- a/roles/apps/templates/daemon.json.j2 +++ /dev/null @@ -1,11 +0,0 @@ -{ - "data-root": "{{ ssd_mount_point }}/docker-runtime", - "default-address-pools": [ - { - "base": "172.17.0.0/16", - "size": 24 - } - ], - "experimental": true, - "ip6tables": true -} diff --git a/roles/apps/templates/remoteip.conf.j2 b/roles/apps/templates/nextcloud/remoteip.conf.j2 similarity index 72% rename from roles/apps/templates/remoteip.conf.j2 rename to roles/apps/templates/nextcloud/remoteip.conf.j2 index fde5405..7350e36 100644 --- a/roles/apps/templates/remoteip.conf.j2 +++ b/roles/apps/templates/nextcloud/remoteip.conf.j2 @@ -1,2 +1,4 @@ +# code: language=ansible-jinja + RemoteIPHeader X-Forwarded-For RemoteIPInternalProxy {{ services.caddy.docker_ipv4 }} diff --git a/roles/common/handlers/main.yml b/roles/common/handlers/main.yml index 34e382d..f8ac884 100644 --- a/roles/common/handlers/main.yml +++ b/roles/common/handlers/main.yml @@ -1,41 +1,11 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Restart systemd-resolved ansible.builtin.service: name: systemd-resolved state: restarted -- name: Create .env for apt-update-push - ansible.builtin.template: - src: env.j2 - dest: /home/{{ ansible_user }}/apt-update-push/.env - owner: root - mode: u=rw,go= - listen: apt-update-push - -- name: Install apt-update-push - ansible.builtin.command: /home/{{ ansible_user }}/apt-update-push/install.sh - listen: apt-update-push - -- name: Change GPIO_PIN - ansible.builtin.lineinfile: - path: /home/{{ ansible_user }}/pi-fan-controller/fancontrol.py - regexp: '^GPIO_PIN = ' - line: GPIO_PIN = 14 - state: present - listen: pi-fan-controller - -- name: Install requirements for pi-fan-controller - ansible.builtin.pip: - requirements: /home/{{ ansible_user }}/pi-fan-controller/requirements.txt - executable: pip3 - state: present - listen: pi-fan-controller - -- name: Install pi-fan-controller - ansible.builtin.command: /home/{{ ansible_user }}/pi-fan-controller/script/install - listen: pi-fan-controller - - name: Restart sshd ansible.builtin.service: name: sshd diff --git a/roles/common/tasks/base.yml b/roles/common/tasks/base.yml index d9cee31..2f73c15 100644 --- a/roles/common/tasks/base.yml +++ b/roles/common/tasks/base.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Set hostname ansible.builtin.hostname: diff --git a/roles/common/tasks/disks.yml b/roles/common/tasks/disks.yml deleted file mode 100644 index cff7189..0000000 --- a/roles/common/tasks/disks.yml +++ /dev/null @@ -1,52 +0,0 @@ -# vim: ft=yaml.ansible ---- -- name: (Create and) open LUKS containers - community.crypto.luks_device: - uuid: "{{ item.disk.uuid }}" - passphrase: "{{ item.disk.luks_pw }}" - name: "{{ item.name }}" - type: luks2 - state: opened - loop: - - disk: "{{ secrets.hdd }}" - name: "{{ hdd_name }}" - - disk: "{{ secrets.ssd }}" - name: "{{ ssd_name }}" - no_log: true - -- name: Create filesystems if they do not exist - community.general.filesystem: - dev: "{{ item }}" - fstype: ext4 - state: present - loop: - - /dev/mapper/{{ hdd_name }} - - /dev/mapper/{{ ssd_name }} - -- name: Mount filesystems - ansible.posix.mount: - src: "{{ item.dev }}" - path: "{{ item.path }}" - fstype: ext4 - state: ephemeral - loop: - - dev: /dev/mapper/{{ hdd_name }} - path: "{{ hdd_mount_point }}" - - dev: /dev/mapper/{{ ssd_name }} - path: "{{ ssd_mount_point }}" - when: ansible_mounts | selectattr('device', 'eq', item.dev) | length == 0 - -- name: Create swapfile - community.general.filesize: - path: "{{ ssd_mount_point }}/swapfile" - size: 2G - blocksize: 512B - owner: root - mode: u=rw,go= - when: ansible_swaptotal_mb == 0 - -- name: Mount swapfile - ansible.builtin.shell: | - mkswap {{ ssd_mount_point }}/swapfile - swapon {{ ssd_mount_point }}/swapfile - when: ansible_swaptotal_mb == 0 diff --git a/roles/common/tasks/firewall.yml b/roles/common/tasks/firewall.yml index 8ac4113..809a3e3 100644 --- a/roles/common/tasks/firewall.yml +++ b/roles/common/tasks/firewall.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Allow necessary ports in UFW community.general.ufw: diff --git a/roles/common/tasks/main.yml b/roles/common/tasks/main.yml index 51b5041..0d34968 100644 --- a/roles/common/tasks/main.yml +++ b/roles/common/tasks/main.yml @@ -1,34 +1,14 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Configure user accounts ansible.builtin.import_tasks: users.yml - tags: - - users - name: Configure system base ansible.builtin.import_tasks: base.yml - tags: - - base - -- name: Reboot if needed - ansible.builtin.import_tasks: reboot.yml - tags: - - reboot - name: Configure firewall ansible.builtin.import_tasks: firewall.yml - tags: - - firewall - name: Configure SSH ansible.builtin.import_tasks: ssh.yml - tags: - - ssh - -- name: Configure disks - ansible.builtin.import_tasks: disks.yml - tags: - - reboot - -- name: Flush handlers - ansible.builtin.meta: flush_handlers diff --git a/roles/common/tasks/reboot.yml b/roles/common/tasks/reboot.yml deleted file mode 100644 index fab3a96..0000000 --- a/roles/common/tasks/reboot.yml +++ /dev/null @@ -1,30 +0,0 @@ -# vim: ft=yaml.ansible ---- -- name: Check if a reboot is needed - ansible.builtin.stat: - path: /var/run/reboot-required - register: needs_reboot - -- name: Include docker_services role for service shutdown - ansible.builtin.include_role: - name: docker_services - tasks_from: services.yml - apply: - ignore_errors: true - vars: - down: true - when: needs_reboot.stat.exists or - (do_reboot is defined and do_reboot) - -- name: Reboot host - ansible.builtin.reboot: - when: needs_reboot.stat.exists or - (do_reboot is defined and do_reboot) - register: rebooted - -- name: Re-gather facts - ansible.builtin.setup: - filter: - - ansible_mounts - - ansible_swaptotal_mb - when: rebooted.rebooted is defined and rebooted.rebooted diff --git a/roles/common/tasks/ssh.yml b/roles/common/tasks/ssh.yml index 31e54db..a8f2b39 100644 --- a/roles/common/tasks/ssh.yml +++ b/roles/common/tasks/ssh.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Allow SSH login with public keys ansible.builtin.lineinfile: diff --git a/roles/common/tasks/users.yml b/roles/common/tasks/users.yml index 822af75..54a5bb4 100644 --- a/roles/common/tasks/users.yml +++ b/roles/common/tasks/users.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Add users ansible.builtin.user: diff --git a/roles/common/templates/env.j2 b/roles/common/templates/env.j2 deleted file mode 100644 index 3f25473..0000000 --- a/roles/common/templates/env.j2 +++ /dev/null @@ -1,2 +0,0 @@ -topic={{ secrets.ntfy_topic }} -hour=20 diff --git a/roles/docker/defaults/main.yml b/roles/docker/defaults/main.yml new file mode 100644 index 0000000..09f1aad --- /dev/null +++ b/roles/docker/defaults/main.yml @@ -0,0 +1,4 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +docker_data_root: /var/lib/docker diff --git a/roles/docker/handlers/main.yml b/roles/docker/handlers/main.yml new file mode 100644 index 0000000..032afa2 --- /dev/null +++ b/roles/docker/handlers/main.yml @@ -0,0 +1,7 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +- name: Restart Docker daemon + ansible.builtin.service: + name: docker + state: restarted diff --git a/roles/docker/tasks/main.yml b/roles/docker/tasks/main.yml new file mode 100644 index 0000000..1ce3e8a --- /dev/null +++ b/roles/docker/tasks/main.yml @@ -0,0 +1,46 @@ +# vim: ft=yaml.ansible +# code: language=ansible +--- +- name: Add Docker PGP key + ansible.builtin.apt_key: + keyserver: keyserver.ubuntu.com + id: '0x8D81803C0EBFCD88' + state: present + +- name: Add Docker apt repository + ansible.builtin.apt_repository: + repo: 'deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian bullseye stable' + update_cache: true + state: present + +- name: Install Docker + ansible.builtin.apt: + name: "{{ pkgs }}" + state: present + vars: + pkgs: + - docker-ce + - docker-compose-plugin + +- name: Copy Docker daemon config file + ansible.builtin.template: + src: etc/docker/daemon.json.j2 + dest: /etc/docker/daemon.json + owner: root + mode: u=rw,g=r,o=r + notify: Restart Docker daemon + +- name: Ensure Docker daemon is enabled and running + ansible.builtin.service: + name: docker + enabled: true + state: started + +- name: Configure cron job to prune unused Docker data weekly + ansible.builtin.cron: + name: Prune unused Docker data + cron_file: ansible_docker_prune + job: 'docker system prune -fa && docker volume prune -fa' + special_time: weekly + user: root + state: present diff --git a/roles/docker/templates/etc/docker/daemon.json.j2 b/roles/docker/templates/etc/docker/daemon.json.j2 new file mode 100644 index 0000000..f7cbd2b --- /dev/null +++ b/roles/docker/templates/etc/docker/daemon.json.j2 @@ -0,0 +1,5 @@ +{ + "data-root": "{{ docker_data_root }}", + "experimental": true, + "ip6tables": true +} diff --git a/site.yml b/site.yml index 50d3b76..4f6e9b5 100644 --- a/site.yml +++ b/site.yml @@ -1,4 +1,5 @@ # vim: ft=yaml.ansible +# code: language=ansible --- - name: Base configuration hosts: all