Prepare multi-host Ansible repo

This commit is contained in:
Sam A. 2023-10-29 20:46:52 +01:00
parent a6b721c888
commit ee351c8304
Signed by: samsapti
GPG key ID: CBBBE7371E81C4EA
55 changed files with 285 additions and 501 deletions

3
.gitignore vendored
View file

@ -1,2 +1,5 @@
# ---> Ansible
*.retry
# ---> VS Code
.vscode/

View file

@ -1,3 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
collections:
- name: community.general
version: '>=7.5.0'

View file

@ -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' }

View file

@ -1,5 +0,0 @@
[appservers]
sapt-lapb-app01.servers.local.sapti.me
[dbservers]
sapt-labp-db01.servers.local.sapti.me

View file

@ -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

View file

@ -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"

View file

@ -0,0 +1,4 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
db_data_root: "{{ encrypted_fs }}/db"

View file

@ -0,0 +1,10 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
apps_include:
- postfix
- emby
- nextcloud
- pihole
- restic
- watchtower

View file

@ -0,0 +1,8 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
apps_include:
- ipfs
- monerod
- snowflake
- watchtower

View file

@ -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

View file

@ -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

5
inventories/shared/hosts Normal file
View file

@ -0,0 +1,5 @@
[proxyservers]
sapt-labn-prx01.servers.local.sapti.me
[monitoringservers]
sapt-labn-mon01.servers.local.sapti.me

View file

@ -1,5 +0,0 @@
[appservers]
sapt-labv-app01.servers.local.sapti.me
[dbservers]
sapt-labv-db01.servers.local.sapti.me

View file

@ -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

View file

@ -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

View file

@ -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"

View file

@ -0,0 +1,4 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
db_data_root: "{{ encrypted_fs }}/db"

View file

@ -0,0 +1,10 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
apps_include:
- postfix
- emby
- nextcloud
- pihole
- restic
- watchtower

View file

@ -0,0 +1,8 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
apps_include:
- ipfs
- monerod
- snowflake
- watchtower

View file

@ -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

View file

@ -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

View file

@ -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 }}"

View file

@ -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

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Emby volume directories
ansible.builtin.file:

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create IPFS Kubo volume directories
ansible.builtin.file:

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Monero node volume directory
ansible.builtin.file:

View file

@ -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

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Pi-hole volume base directory
ansible.builtin.file:

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Docker network for Postfix
community.docker.docker_network:

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Deploy Restic with Docker Compose
community.docker.docker_compose:

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Deploy snowflake-proxy Docker container
community.docker.docker_container:

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Create Docker network for Watchtower
community.docker.docker_network:

View file

@ -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

View file

@ -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 }}"

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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
}

View file

@ -1,2 +1,4 @@
# code: language=ansible-jinja
RemoteIPHeader X-Forwarded-For
RemoteIPInternalProxy {{ services.caddy.docker_ipv4 }}

View file

@ -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

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Set hostname
ansible.builtin.hostname:

View file

@ -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

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Allow necessary ports in UFW
community.general.ufw:

View file

@ -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

View file

@ -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

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Allow SSH login with public keys
ansible.builtin.lineinfile:

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Add users
ansible.builtin.user:

View file

@ -1,2 +0,0 @@
topic={{ secrets.ntfy_topic }}
hour=20

View file

@ -0,0 +1,4 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
docker_data_root: /var/lib/docker

View file

@ -0,0 +1,7 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Restart Docker daemon
ansible.builtin.service:
name: docker
state: restarted

View file

@ -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

View file

@ -0,0 +1,5 @@
{
"data-root": "{{ docker_data_root }}",
"experimental": true,
"ip6tables": true
}

View file

@ -1,4 +1,5 @@
# vim: ft=yaml.ansible
# code: language=ansible
---
- name: Base configuration
hosts: all