43 Commits

Author SHA1 Message Date
cyclane ef780275e7 Infisical no longer needs pinning
Infrastructure / Check and run Ansbile playbooks (pull_request) Failing after 3m30s
2024-03-29 16:24:22 +00:00
cyclane 87df3eb334 Merge branch 'main' into cleanup-playbooks 2024-03-29 16:23:17 +00:00
cyclane 9f51ce02d6 Fix #50: Remove custom network *completely* from Infisical docker-compose (#52)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 3m14s
Reviewed-on: #52
2024-03-29 15:57:07 +00:00
cyclane 719640a98d Fix #50: Trigger all secrets playbooks (#51)
Infrastructure / Check and run Ansbile playbooks (push) Failing after 5m46s
Keep forgetting this :/

Reviewed-on: #51
2024-03-29 15:48:14 +00:00
cyclane 20b72f085f Secrets VM: v2 (#50)
Infrastructure / Check and run Ansbile playbooks (push) Failing after 4m34s
Closes #44. We'll do a manual migration for stability and simplicity.

Reviewed-on: #50
2024-03-29 15:24:57 +00:00
cyclane da90d463de Fix Infisical Gitea Actions (#43)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m6s
For some reason secrets are failing: https://git.koval.net/cyclane/kovalhome/actions/runs/193

Reviewed-on: #43
2024-03-01 00:37:04 +00:00
cyclane 68259cb3cf Upgrade Immich to 1.95 (#42)
Infrastructure / Check and run Ansbile playbooks (push) Failing after 2m4s
And again...

https://github.com/immich-app/immich/releases/tag/v1.95.0

Reviewed-on: #42
2024-02-29 22:53:28 +00:00
cyclane 202abc79e3 Use requirements.yml for galaxy
Infrastructure / Check and run Ansbile playbooks (pull_request) Failing after 2m57s
2024-01-30 17:50:13 +00:00
cyclane 8ab4968371 Remove ansible-lint from requirements
Infrastructure / Check and run Ansbile playbooks (pull_request) Failing after 3m6s
2024-01-30 17:32:13 +00:00
cyclane 5ac073fc11 use ansible-lint action
Infrastructure / Check and run Ansbile playbooks (pull_request) Failing after 3m34s
2024-01-30 17:31:29 +00:00
cyclane 2834642cb7 Use strict linting
Infrastructure / Check and run Ansbile playbooks (pull_request) Successful in 2m1s
2024-01-30 13:01:28 +00:00
cyclane 594c97f4dc Add ansible-lint dependancy
Infrastructure / Check and run Ansbile playbooks (pull_request) Successful in 2m8s
2024-01-30 12:46:27 +00:00
cyclane 9689da7d11 Add ansible-lint to github actions
Infrastructure / Check and run Ansbile playbooks (pull_request) Failing after 1m36s
2024-01-30 12:42:41 +00:00
cyclane e1375aeb72 ansible-lint 2024-01-30 12:40:46 +00:00
cyclane 2aa297e901 docker_compose_v2 ansible (instead of shell) 2024-01-30 12:37:37 +00:00
cyclane 1a0114fa34 nextcloud aio:
- remove immich decommision (it's fine(tm))
- use ansible to create container, instead of bash script
2024-01-29 22:42:27 +00:00
cyclane e807abb376 Fix name of install docker playbooks 2024-01-29 22:41:33 +00:00
cyclane 334276e654 proxmox playbooks
- use handler for initial boot & wait
2024-01-29 22:28:02 +00:00
cyclane b9d0c5d55d Fix #36: Update samba file permissions in playbook (#40)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m50s
Reviewed-on: #40
2024-01-27 18:25:40 +00:00
cyclane 7eff8a43ef Fix #36: Fix mounts and trigger CI (#39)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m48s
We need to create each samba folder manually - do it with docker-compose I guess.

Reviewed-on: #39
2024-01-27 18:16:23 +00:00
cyclane 7916f12e73 Fix #36: Trigger all CI for samba (#38)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 7m48s
Reviewed-on: #38
2024-01-27 18:04:29 +00:00
cyclane aa78f334bd Fix #36: Samba VM - SRV NIC (#37)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m21s
Add SRV NIC back because Ansible uses it :/

Reviewed-on: #37
2024-01-27 17:54:59 +00:00
cyclane 47556c3a8c Samba VM (#36)
Infrastructure / Check and run Ansbile playbooks (push) Failing after 9m37s
Initialise new samba service. Currently will only be used for local network backups.

Reviewed-on: #36
2024-01-27 17:41:57 +00:00
cyclane 1a8fe73bf2 Fix #32: Format environment: properly. (#33)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m55s
Reviewed-on: #33
2024-01-07 00:03:40 +00:00
cyclane 3685590a58 Music VM: Set Navidrome to use LastFM for coverart before embedded images (#32)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m46s
Default is embedded before LastFM, but since we're downloading from YouTube embedded always exists, and is often not great. So use LastFM before embedded.

Reviewed-on: #32
2024-01-06 23:54:55 +00:00
cyclane 40410b2dff Fix #28: Do not use user: for metube and picard (#31)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m46s
Reviewed-on: #31
2024-01-06 18:31:05 +00:00
cyclane 5bfc02d3ae Fix #28: Need to become for permission changes (#30)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m37s
Reviewed-on: #30
2024-01-06 18:19:07 +00:00
cyclane 54cf382710 Fix #28: Set directory permissions (#29)
Infrastructure / Check and run Ansbile playbooks (push) Failing after 2m23s
Since we are using `user:` in docker-compose, we need to set the directory permissions so that everything doesn't crash immediately.

Reviewed-on: #29
2024-01-06 18:14:56 +00:00
cyclane d4d5511b78 Music VM (#28)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 8m20s
Provision a VM with Navidrome and some tools for downloading stuff from YouTube.

Reviewed-on: #28
2024-01-06 17:36:06 +00:00
cyclane f47ad0a125 Fix #25: Get value from Infisical result (#27)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m20s
Fixes #25 (again).

Reviewed-on: #27
2024-01-04 16:03:11 +00:00
cyclane 773b73f579 Fix #25: Use correct lookup name (#26)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m11s
Fixes #25

Reviewed-on: #26
2024-01-04 13:13:31 +00:00
cyclane 8529d56c44 Migrate Photos VM to read secrets from Infisical (#25)
Infrastructure / Check and run Ansbile playbooks (push) Failing after 2m3s
#21 provisioned an Infisical service (https://secrets.koval.net/). We can use this instead of the hacky solution that can explode.

Contributes to and closes #16.

Reviewed-on: #25
2024-01-04 13:09:16 +00:00
cyclane a8b7b1df4a Fix Infisical SMTP settings (#24)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m4s
Add SMTP_FROM_ADDRESS to infisical

Reviewed-on: #24
2024-01-04 12:50:41 +00:00
cyclane ed07a8ef71 Upgrade secrets VM CPU (#23)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 2m13s
Mongo requires AVX https://jira.mongodb.org/browse/SERVER-54407.

Otherwise logs:
```
infisical-mongo-1    | WARNING: MongoDB 5.0+ requires a CPU with AVX support, and your current system does not appear to have that!
infisical-mongo-1    |   see https://jira.mongodb.org/browse/SERVER-54407
infisical-mongo-1    |   see also https://www.mongodb.com/community/forums/t/mongodb-5-0-cpu-intel-g4650-compatibility/116610/2
infisical-mongo-1    |   see also https://github.com/docker-library/mongo/issues/485#issuecomment-891991814
infisical-mongo-1    |
infisical-mongo-1    | /usr/local/bin/docker-entrypoint.sh: line 416:    26 Illegal instruction     "${mongodHackedArgs[@]}" --fork
```

Reviewed-on: https://git.koval.net/cyclane/kovalhome/pulls/23
2024-01-04 11:58:27 +00:00
cyclane 82fee4eb19 Secrets VM (#21)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 5m29s
Setup Infiscal according to https://infisical.com/docs/self-hosting/deployment-options/docker-compose .

Contributes to #16.

Reviewed-on: #21
2024-01-04 11:22:21 +00:00
cyclane 89c5e1ea36 Upgrade Immich to 1.91 (#18)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 4m31s
Yet again Immich is introducing breaking changes.

Reviewed-on: #18
2023-12-16 22:57:15 +00:00
cyclane 6c8bab5748 Fix immich/0004 name
Infrastructure / Check and run Ansbile playbooks (push) Successful in 3m57s
2023-11-21 12:28:05 +00:00
cyclane 34fa3d2ba3 Upgrade Immich to 1.88 (#15)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 1m27s
Immich 1.87 → 1.88 [has breaking changes](https://github.com/immich-app/immich/discussions/5086), so we need an Ansible migration.

Reviewed-on: #15
2023-11-21 11:34:40 +00:00
cyclane 05a730ea52 Immich VM: Initial provision and decommission Immich from Cloud VM (#11)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 7m26s
Reviewed-on: #11
2023-09-28 12:44:24 +00:00
cyclane e39f826597 Cloud VM: Fix media deployment (#10)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 3m21s
Reviewed-on: #10
2023-09-27 21:31:32 +00:00
cyclane 47335e40f6 Cloud VM: Add immich & prepare for Nextcloud memories (#9)
Infrastructure / Check and run Ansbile playbooks (push) Failing after 2m50s
We want to test out what is better - Immich or Nextcloud memories.

Reviewed-on: #9
2023-09-27 21:18:49 +00:00
cyclane 21c6b627a8 Cloud VM: mount data to /var/lib/docker (#8)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 1m31s
Since Nextcloud AIO manages itself and uses docker volumes, the easiest way to persisty all data in a separate disk is to just mount it to `/var/lib/docker`. This is still an easier long-term solution than managing the entire stack manually - we can always migrate (relatively) easily in the future anyway.

Reviewed-on: #8
2023-09-26 23:24:07 +00:00
cyclane 68aff49459 Cloud VM (#7)
Infrastructure / Check and run Ansbile playbooks (push) Successful in 6m42s
- Nextcloud & potentially other "cloud" stuff VM

Reviewed-on: #7
2023-09-26 19:50:11 +00:00
38 changed files with 1563 additions and 58 deletions
+4
View File
@@ -0,0 +1,4 @@
strict: true
use_default_rules: true
skip_list:
- args[module]
+13 -7
View File
@@ -11,8 +11,8 @@ on:
- main
env:
# DEPLOY: ${{ github.ref == 'refs/heads/main' && ((startsWith(github.event.head_commit.message, '[deploy-all]') && 'all') || ('some')) || 'none' }}
DEPLOY: all
DEPLOY: ${{ github.ref == 'refs/heads/main' && ((startsWith(github.event.head_commit.message, '[deploy-all]') && 'all') || ('some')) || 'none' }}
# DEPLOY: all
jobs:
ansible-playbooks:
@@ -29,13 +29,14 @@ jobs:
apt update
apt install -y python3-pip
pip3 install -r requirements.txt
ansible-galaxy collection install community.general
ansible-galaxy collection install -r requirements.yml --force
- name: Run ansible-lint
uses: ansible/ansible-lint@v6
- name: Check playbooks
run: |
for file in $(find . -wholename "*/infra/*playbook.yaml" -type f); do
ansible-playbook --inventory ./inventory --syntax-check "$file"
done
ansible-playbook --inventory ./inventory --syntax-check infra/**/*playbook.yaml
- name: Get changed playbooks
id: files
@@ -72,4 +73,9 @@ jobs:
PROXMOX_TOKEN_ID: ${{ secrets.PROXMOX_TOKEN_ID }}
PROXMOX_TOKEN_SECRET: ${{ secrets.PROXMOX_TOKEN_SECRET }}
SSH_PUBLIC: ${{ secrets.SSH_PUBLIC }}
run: ansible-playbook --inventory ./inventory ${{ steps.playbooks.outputs.to_run }}
SMTP_PASSWORD: ${{ secrets.SMTP_PASSWORD }}
INFISICAL_ENCRYPTION_KEY: ${{ secrets.INFISICAL_ENCRYPTION_KEY }}
INFISICAL_AUTH_SECRET: ${{ secrets.INFISICAL_AUTH_SECRET }}
INFISICAL_TOKEN: ${{ secrets.INFISICAL_TOKEN }}
INFISICAL_URL: https://secrets.koval.net
run: ansible-playbook --inventory ./inventory ${{ steps.playbooks.outputs.to_run }} -vv
@@ -1,5 +1,5 @@
- name: Provision joplin Proxmox VM
hosts: joplin
- name: Provision cloud Proxmox VM
hosts: cloud
connection: ansible.builtin.local
gather_facts: false
vars:
@@ -36,7 +36,7 @@
community.general.proxmox_kvm:
clone: "{{ node }}-debian-12"
storage: nvme
register: create
notify: Initial boot
- name: Wait for status
community.general.proxmox_kvm:
state: current
@@ -46,11 +46,11 @@
until: vm.status is defined
# Networking and initial config
- name: Add HOME NIC
- name: Add PUB NIC
community.general.proxmox_nic:
interface: net0
firewall: false
bridge: HOME
bridge: PUB
- name: Add SRV NIC
community.general.proxmox_nic:
interface: net1
@@ -65,28 +65,21 @@
ipconfig0: ip=dhcp,ip6=auto
ipconfig1: ip=dhcp
# Initial boot
# For some reason debian cloud images don't use
# cloud-init for networking on first boot (cloud-init files
# are regenerated AFTER networking starts). But we need the
# hostname to be registered with DHCP later on so ¯\_(ツ)_/¯
- name: Initial boot
when: create.changed is true
block:
- name: Start
community.general.proxmox_kvm:
state: started
register: start
- name: Wait 3 min # Initial apt update, apt upgrade, cloud-init
ansible.builtin.wait_for:
timeout: 180
- name: Force all notified handlers to run
ansible.builtin.meta: flush_handlers
# VM Configuration
- name: Resize disk
- name: Resize root disk
community.general.proxmox_disk:
disk: scsi0
size: 64G
size: 16G
state: resized
- name: Create data disk
community.general.proxmox_disk:
disk: scsi1
backup: true
storage: nvme
size: 2048
- name: Update VM
community.general.proxmox_kvm:
update: true
@@ -95,10 +88,25 @@
- debian-12
- managed
onboot: true
cores: 2
memory: 2048
cores: 8
memory: 16384
- name: Retart VM
community.general.proxmox_kvm:
state: restarted
timeout: 60
handlers:
# Initial boot
# For some reason debian cloud images don't use
# cloud-init for networking on first boot (cloud-init files
# are regenerated AFTER networking starts). But we need the
# hostname to be registered with DHCP later on so ¯\_(ツ)_/¯
- name: Initial boot
block:
- name: Start
community.general.proxmox_kvm:
state: started
register: start
- name: Wait 1.5 min # Initial apt update, apt upgrade, cloud-init
ansible.builtin.wait_for:
timeout: 90
+42
View File
@@ -0,0 +1,42 @@
- name: Initialise VM
hosts: cloud
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install system packages
ansible.builtin.apt:
update_cache: true
pkg:
- qemu-guest-agent
- parted
become: true
- name: Enable qemu-guest-agent
ansible.builtin.systemd:
name: qemu-guest-agent
state: started
enabled: true
become: true
- name: Create data partition
community.general.parted:
device: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1
label: gpt
name: data
number: 1
state: present
become: true
- name: Create data filesystem
community.general.filesystem:
dev: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
fstype: ext4
become: true
- name: Mount data partition
ansible.posix.mount:
src: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
path: /var/lib/docker
fstype: ext4
opts: rw,errors=remount-ro,x-systemd.growfs
state: mounted
become: true
+47
View File
@@ -0,0 +1,47 @@
- name: Install docker
hosts: cloud
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install dependencies
ansible.builtin.apt:
update_cache: true
pkg:
- curl
- python3-apt
- gpg
become: true
- name: Add docker key
ansible.builtin.apt_key:
url: https://download.docker.com/linux/debian/gpg
keyring: /etc/apt/keyrings/docker.gpg
become: true
- name: Add docker repo
ansible.builtin.apt_repository:
repo: deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable
become: true
- name: Install docker
ansible.builtin.apt:
update_cache: true
pkg:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
become: true
- name: Add user to docker group
ansible.builtin.user:
user: debian
groups:
- docker
append: true
become: true
- name: Enable docker
ansible.builtin.systemd:
name: docker
state: started
enabled: true
become: true
@@ -0,0 +1,13 @@
- name: Cleanup old ~/nextcloud directory
hosts: cloud
gather_facts: false
vars:
app: nextcloud
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Delete nextcloud directory
ansible.builtin.file:
path: "$HOME/{{ app }}"
state: absent
+30
View File
@@ -0,0 +1,30 @@
- name: Deploy app
hosts: cloud
gather_facts: false
vars:
container: nextcloud-aio-mastercontainer
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Deploy master container
community.docker.docker_container:
image: nextcloud/all-in-one:latest
recreate: true
state: started
restart_policy: unless-stopped
init: true
name: "{{ container }}"
published_ports:
- 8080:8080
env:
NEXTCLOUD_UPLOAD_LIMIT: 16G
NEXTCLOUD_MAX_TIME: "7200"
NEXTCLOUD_ADDITIONAL_APKS: imagemagick ffmpeg
APACHE_PORT: "11000"
APACHE_IP_BINDING: "0.0.0.0"
TZ: Europe/London
AIO_DISABLE_BACKUP_SECTION: "true"
volumes:
- nextcloud_aio_mastercontainer:/mnt/docker-aio-config
- /var/run/docker.sock:/var/run/docker.sock:ro
-25
View File
@@ -1,25 +0,0 @@
- name: Setup Software
hosts: joplin
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Test some stuff
ansible.builtin.shell: |
touch ~/hmm
echo test > ~/test
echo test2 >> ~/test
mkdir ~/dir
touch ~/dir/testing
- name: Install some stuff
ansible.builtin.apt:
update_cache: true
name: qemu-guest-agent
become: true
- name: Enable some stuff
ansible.builtin.systemd:
name: qemu-guest-agent
state: started
enabled: true
become: true
+118
View File
@@ -0,0 +1,118 @@
- name: Provision music Proxmox VM
hosts: music
connection: ansible.builtin.local
gather_facts: false
vars:
api_user: "{{ lookup('ansible.builtin.env', 'PROXMOX_USER') }}"
api_host: "{{ lookup('ansible.builtin.env', 'PROXMOX_HOST' ) }}"
api_token_id: "{{ lookup('ansible.builtin.env', 'PROXMOX_TOKEN_ID') }}"
api_token_secret: "{{ lookup('ansible.builtin.env', 'PROXMOX_TOKEN_SECRET') }}"
ssh_public: "{{ lookup('ansible.builtin.env', 'SSH_PUBLIC') }}"
vmname: "{{ inventory_hostname | regex_replace('^([^\\.]+)\\..+$', '\\1') }}"
node: pve2
module_defaults:
community.general.proxmox_kvm:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
node: "{{ node }}"
community.general.proxmox_nic:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
community.general.proxmox_disk:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
tasks:
# Initial setup
- name: Create VM
community.general.proxmox_kvm:
clone: "{{ node }}-debian-12"
storage: nvme
notify: Initial boot
- name: Wait for status
community.general.proxmox_kvm:
state: current
register: vm
retries: 30
delay: 10
until: vm.status is defined
# Networking and initial config
- name: Add PUB NIC
community.general.proxmox_nic:
interface: net0
firewall: false
bridge: PUB
- name: Add SRV NIC
community.general.proxmox_nic:
interface: net1
firewall: false
bridge: SRV
- name: Configure cloud-init
community.general.proxmox_kvm:
update: true
ciuser: debian
sshkeys: "{{ ssh_public }}"
ipconfig:
ipconfig0: ip=dhcp,ip6=auto
ipconfig1: ip=dhcp
- name: Force all notified handlers to run
ansible.builtin.meta: flush_handlers
# VM Configuration
- name: Resize root disk
community.general.proxmox_disk:
disk: scsi0
size: 16G
state: resized
- name: Create data disk
community.general.proxmox_disk:
disk: scsi1
backup: true
storage: nvme
size: 64
- name: Create media disk
community.general.proxmox_disk:
disk: scsi2
backup: false
storage: nvme
size: 1024
- name: Update VM
community.general.proxmox_kvm:
update: true
agent: enabled=1
tags:
- debian-12
- managed
onboot: true
cores: 8
memory: 16384
- name: Retart VM
community.general.proxmox_kvm:
state: restarted
timeout: 60
handlers:
# Initial boot
# For some reason debian cloud images don't use
# cloud-init for networking on first boot (cloud-init files
# are regenerated AFTER networking starts). But we need the
# hostname to be registered with DHCP later on so ¯\_(ツ)_/¯
- name: Initial boot
block:
- name: Start
community.general.proxmox_kvm:
state: started
register: start
- name: Wait 1.5 min # Initial apt update, apt upgrade, cloud-init
ansible.builtin.wait_for:
timeout: 90
+64
View File
@@ -0,0 +1,64 @@
- name: Initialise VM
hosts: music
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install system packages
ansible.builtin.apt:
update_cache: true
pkg:
- qemu-guest-agent
- parted
become: true
- name: Enable qemu-guest-agent
ansible.builtin.systemd:
name: qemu-guest-agent
state: started
enabled: true
become: true
- name: Create data partition
community.general.parted:
device: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1
label: gpt
name: data
number: 1
state: present
become: true
- name: Create data filesystem
community.general.filesystem:
dev: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
fstype: ext4
become: true
- name: Mount data partition
ansible.posix.mount:
src: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
path: /var/lib/docker
fstype: ext4
opts: rw,errors=remount-ro,x-systemd.growfs
state: mounted
become: true
- name: Create media partition
community.general.parted:
device: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2
label: gpt
name: media
number: 1
state: present
become: true
- name: Create media filesystem
community.general.filesystem:
dev: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2-part1
fstype: ext4
become: true
- name: Mount media partition
ansible.posix.mount:
src: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2-part1
path: /mnt/media
fstype: ext4
opts: rw,errors=remount-ro,x-systemd.growfs
state: mounted
become: true
+47
View File
@@ -0,0 +1,47 @@
- name: Install docker
hosts: music
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install dependencies
ansible.builtin.apt:
update_cache: true
pkg:
- curl
- python3-apt
- gpg
become: true
- name: Add docker key
ansible.builtin.apt_key:
url: https://download.docker.com/linux/debian/gpg
keyring: /etc/apt/keyrings/docker.gpg
become: true
- name: Add docker repo
ansible.builtin.apt_repository:
repo: deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable
become: true
- name: Install docker
ansible.builtin.apt:
update_cache: true
pkg:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
become: true
- name: Add user to docker group
ansible.builtin.user:
user: debian
groups:
- docker
append: true
become: true
- name: Enable docker
ansible.builtin.systemd:
name: docker
state: started
enabled: true
become: true
+60
View File
@@ -0,0 +1,60 @@
- name: Deploy app
hosts: music
gather_facts: false
vars:
app: music
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Docker compose down
community.docker.docker_compose_v2:
project_src: "$HOME/{{ app }}"
state: absent
- name: Copy project
ansible.builtin.copy:
src: "./{{ app }}"
dest: "$HOME"
mode: "0744"
- name: Replace LastFM API key secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "LASTFM_APIKEY_VALUE"
replace: "{{ lookup('infisical.vault.read_secrets', env_slug='prod', path='/music', secret_name='LASTFM_APIKEY')['value'] }}"
- name: Replace LastFM secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "LASTFM_SECRET_VALUE"
replace: "{{ lookup('infisical.vault.read_secrets', env_slug='prod', path='/music', secret_name='LASTFM_SECRET')['value'] }}"
- name: Replace Mongo Password secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "SPOTIFY_ID_VALUE"
replace: "{{ lookup('infisical.vault.read_secrets', env_slug='prod', path='/music', secret_name='SPOTIFY_ID')['value'] }}"
- name: Replace SMTP Password secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "SPOTIFY_SECRET_VALUE"
replace: "{{ lookup('infisical.vault.read_secrets', env_slug='prod', path='/music', secret_name='SPOTIFY_SECRET')['value'] }}"
- name: Docker compose up
community.docker.docker_compose_v2:
project_src: "$HOME/{{ app }}"
- name: Update data permissions
ansible.builtin.file:
path: /mnt/nvme
state: directory
recurse: true
owner: debian
group: debian
become: true
- name: Update media permissions
ansible.builtin.file:
path: /mnt/media
state: directory
recurse: true
owner: debian
group: debian
become: true
+4
View File
@@ -0,0 +1,4 @@
LASTFM_APIKEY=LASTFM_APIKEY_VALUE
LASTFM_SECRET=LASTFM_SECRET_VALUE
SPOTIFY_ID=SPOTIFY_ID_VALUE
SPOTIFY_SECRET=SPOTIFY_SECRET_VALUE
+1
View File
@@ -0,0 +1 @@
!.env
+52
View File
@@ -0,0 +1,52 @@
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
restart: unless-stopped
user: 1000:1000
ports:
- 4533:4533
env_file: .env
environment:
- ND_BASEURL=https://music.koval.net
- ND_LASTFM_APIKEY=${LASTFM_APIKEY}
- ND_LASTFM_SECRET=${LASTFM_SECRET}
- ND_SPOTIFY_ID=${SPOTIFY_ID}
- ND_SPOTIFY_SECRET=${SPOTIFY_SECRET}
- ND_COVERARTPRIORITY=cover.*, folder.*, front.*, external, embedded
volumes:
- /mnt/nvme/navidrome:/data
- /mnt/media/music:/music:ro
metube:
image: ghcr.io/alexta69/metube
restart: unless-stopped
ports:
- 8081:8081
environment:
- STATE_DIR=/data/.metube
- TEMP_DIR=/data/downloads
volumes:
- /mnt/nvme/metube:/data
- /mnt/media/downloads:/downloads
picard:
image: mikenye/picard:latest
restart: unless-stopped
ports:
- 5800:5800
volumes:
- /mnt/nvme/picard:/config:rw
- /mnt/media/music:/storage/music:rw
- /mnt/media/downloads:/storage/downloads:rw
filebrowser:
image: filebrowser/filebrowser
restart: unless-stopped
user: 1000:1000
ports:
- 8080:80
environment:
- FB_DATABASE=/config/database.db
volumes:
- /mnt/nvme/filebrowser:/config
- /mnt/media/downloads:/srv/downloads
- /mnt/media/music:/srv/music
+118
View File
@@ -0,0 +1,118 @@
- name: Provision photos Proxmox VM
hosts: photos
connection: ansible.builtin.local
gather_facts: false
vars:
api_user: "{{ lookup('ansible.builtin.env', 'PROXMOX_USER') }}"
api_host: "{{ lookup('ansible.builtin.env', 'PROXMOX_HOST' ) }}"
api_token_id: "{{ lookup('ansible.builtin.env', 'PROXMOX_TOKEN_ID') }}"
api_token_secret: "{{ lookup('ansible.builtin.env', 'PROXMOX_TOKEN_SECRET') }}"
ssh_public: "{{ lookup('ansible.builtin.env', 'SSH_PUBLIC') }}"
vmname: "{{ inventory_hostname | regex_replace('^([^\\.]+)\\..+$', '\\1') }}"
node: pve
module_defaults:
community.general.proxmox_kvm:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
node: "{{ node }}"
community.general.proxmox_nic:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
community.general.proxmox_disk:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
tasks:
# Initial setup
- name: Create VM
community.general.proxmox_kvm:
clone: "{{ node }}-debian-12"
storage: nvme
notify: Initial boot
- name: Wait for status
community.general.proxmox_kvm:
state: current
register: vm
retries: 30
delay: 10
until: vm.status is defined
# Networking and initial config
- name: Add PUB NIC
community.general.proxmox_nic:
interface: net0
firewall: false
bridge: PUB
- name: Add SRV NIC
community.general.proxmox_nic:
interface: net1
firewall: false
bridge: SRV
- name: Configure cloud-init
community.general.proxmox_kvm:
update: true
ciuser: debian
sshkeys: "{{ ssh_public }}"
ipconfig:
ipconfig0: ip=dhcp,ip6=auto
ipconfig1: ip=dhcp
- name: Force all notified handlers to run
ansible.builtin.meta: flush_handlers
# VM Configuration
- name: Resize root disk
community.general.proxmox_disk:
disk: scsi0
size: 16G
state: resized
- name: Create data disk
community.general.proxmox_disk:
disk: scsi1
backup: true
storage: nvme
size: 64
- name: Create media disk
community.general.proxmox_disk:
disk: scsi2
backup: true
storage: nvme
size: 2048
- name: Update VM
community.general.proxmox_kvm:
update: true
agent: enabled=1
tags:
- debian-12
- managed
onboot: true
cores: 8
memory: 16384
- name: Retart VM
community.general.proxmox_kvm:
state: restarted
timeout: 60
handlers:
# Initial boot
# For some reason debian cloud images don't use
# cloud-init for networking on first boot (cloud-init files
# are regenerated AFTER networking starts). But we need the
# hostname to be registered with DHCP later on so ¯\_(ツ)_/¯
- name: Initial boot
block:
- name: Start
community.general.proxmox_kvm:
state: started
register: start
- name: Wait 1.5 min # Initial apt update, apt upgrade, cloud-init
ansible.builtin.wait_for:
timeout: 90
@@ -0,0 +1,64 @@
- name: Initialise VM
hosts: photos
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install system packages
ansible.builtin.apt:
update_cache: true
pkg:
- qemu-guest-agent
- parted
become: true
- name: Enable qemu-guest-agent
ansible.builtin.systemd:
name: qemu-guest-agent
state: started
enabled: true
become: true
- name: Create data partition
community.general.parted:
device: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1
label: gpt
name: data
number: 1
state: present
become: true
- name: Create data filesystem
community.general.filesystem:
dev: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
fstype: ext4
become: true
- name: Mount data partition
ansible.posix.mount:
src: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
path: /var/lib/docker
fstype: ext4
opts: rw,errors=remount-ro,x-systemd.growfs
state: mounted
become: true
- name: Create media partition
community.general.parted:
device: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2
label: gpt
name: media
number: 1
state: present
become: true
- name: Create media filesystem
community.general.filesystem:
dev: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2-part1
fstype: ext4
become: true
- name: Mount media partition
ansible.posix.mount:
src: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2-part1
path: /mnt/media
fstype: ext4
opts: rw,errors=remount-ro,x-systemd.growfs
state: mounted
become: true
+47
View File
@@ -0,0 +1,47 @@
- name: Install docker
hosts: photos
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install dependencies
ansible.builtin.apt:
update_cache: true
pkg:
- curl
- python3-apt
- gpg
become: true
- name: Add docker key
ansible.builtin.apt_key:
url: https://download.docker.com/linux/debian/gpg
keyring: /etc/apt/keyrings/docker.gpg
become: true
- name: Add docker repo
ansible.builtin.apt_repository:
repo: deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable
become: true
- name: Install docker
ansible.builtin.apt:
update_cache: true
pkg:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
become: true
- name: Add user to docker group
ansible.builtin.user:
user: debian
groups:
- docker
append: true
become: true
- name: Enable docker
ansible.builtin.systemd:
name: docker
state: started
enabled: true
become: true
+31
View File
@@ -0,0 +1,31 @@
- name: Deploy app
hosts: photos
gather_facts: false
vars:
app: immich
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Docker compose down
community.docker.docker_compose_v2:
project_src: "$HOME/{{ app }}"
state: absent
- name: Copy project
ansible.builtin.copy:
src: "./{{ app }}"
dest: "$HOME"
mode: "0744"
- name: Replace Typesense secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "TYPESENSE_API_KEY_VALUE"
replace: "{{ lookup('infisical.vault.read_secrets', env_slug='prod', path='/photos', secret_name='TYPESENSE_API_KEY')['value'] }}"
- name: Replace DB secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "DB_PASSWORD_VALUE"
replace: "{{ lookup('infisical.vault.read_secrets', env_slug='prod', path='/photos', secret_name='DB_PASSWORD')['value'] }}"
- name: Docker compose up -d
community.docker.docker_compose_v2:
project_src: "$HOME/{{ app }}"
+22
View File
@@ -0,0 +1,22 @@
# You can find documentation for all the supported env variables at https://immich.app/docs/install/environment-variables
# The location where your uploaded files are stored
UPLOAD_LOCATION=/mnt/media/immich
# The Immich version to use. You can pin this to a specific version like "v1.71.0"
IMMICH_VERSION=release
# Connection secrets for postgres and typesense. You should change these to random passwords
TYPESENSE_API_KEY=TYPESENSE_API_KEY_VALUE
DB_PASSWORD=DB_PASSWORD_VALUE
# Other
PUBLIC_LOGIN_PAGE_MESSAGE="KovalHome Photos & Videos"
# The values below this line do not need to be changed
###################################################################################
DB_HOSTNAME=immich_postgres
DB_USERNAME=postgres
DB_DATABASE_NAME=immich
REDIS_HOSTNAME=immich_redis
+1
View File
@@ -0,0 +1 @@
!.env
+64
View File
@@ -0,0 +1,64 @@
version: "3.8"
services:
immich-server:
container_name: immich_server
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
command: ["start.sh", "immich"]
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
env_file:
- .env
ports:
- 2283:3001
depends_on:
- redis
- database
restart: always
immich-microservices:
container_name: immich_microservices
image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release}
# extends:
# file: hwaccel.yml
# service: hwaccel
command: ["start.sh", "microservices"]
volumes:
- ${UPLOAD_LOCATION}:/usr/src/app/upload
env_file:
- .env
depends_on:
- redis
- database
restart: always
immich-machine-learning:
container_name: immich_machine_learning
image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release}
volumes:
- model-cache:/cache
env_file:
- .env
restart: always
redis:
container_name: immich_redis
image: redis:6.2-alpine@sha256:70a7a5b641117670beae0d80658430853896b5ef269ccf00d1827427e3263fa3
restart: always
database:
container_name: immich_postgres
image: tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
env_file:
- .env
environment:
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_USER: ${DB_USERNAME}
POSTGRES_DB: ${DB_DATABASE_NAME}
volumes:
- pgdata:/var/lib/postgresql/data
restart: always
volumes:
pgdata:
model-cache:
+117
View File
@@ -0,0 +1,117 @@
- name: Provision samba Proxmox VM
hosts: samba
connection: ansible.builtin.local
gather_facts: false
vars:
api_user: "{{ lookup('ansible.builtin.env', 'PROXMOX_USER') }}"
api_host: "{{ lookup('ansible.builtin.env', 'PROXMOX_HOST' ) }}"
api_token_id: "{{ lookup('ansible.builtin.env', 'PROXMOX_TOKEN_ID') }}"
api_token_secret: "{{ lookup('ansible.builtin.env', 'PROXMOX_TOKEN_SECRET') }}"
ssh_public: "{{ lookup('ansible.builtin.env', 'SSH_PUBLIC') }}"
vmname: "{{ inventory_hostname | regex_replace('^([^\\.]+)\\..+$', '\\1') }}"
node: pve
module_defaults:
community.general.proxmox_kvm:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
node: "{{ node }}"
community.general.proxmox_nic:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
community.general.proxmox_disk:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
tasks:
# Initial setup
- name: Create VM
community.general.proxmox_kvm:
clone: "{{ node }}-debian-12"
storage: nvme
notify: Initial boot
- name: Wait for status
community.general.proxmox_kvm:
state: current
register: vm
retries: 30
delay: 10
until: vm.status is defined
# Networking and initial config
- name: Add PUB NIC
community.general.proxmox_nic:
interface: net0
firewall: false
bridge: PUB
- name: Add SRV NIC
community.general.proxmox_nic:
interface: net1
firewall: false
bridge: SRV
- name: Configure cloud-init
community.general.proxmox_kvm:
update: true
ciuser: debian
sshkeys: "{{ ssh_public }}"
ipconfig:
ipconfig0: ip=dhcp,ip6=auto
ipconfig1: ip=dhcp
- name: Force all notified handlers to run
ansible.builtin.meta: flush_handlers
# VM Configuration
- name: Resize root disk
community.general.proxmox_disk:
disk: scsi0
size: 16G
state: resized
- name: Create data disk
community.general.proxmox_disk:
disk: scsi1
backup: true
storage: nvme
size: 64
- name: Create share disk
community.general.proxmox_disk:
disk: scsi2
backup: false
storage: zfs
size: 2048
- name: Update VM
community.general.proxmox_kvm:
update: true
agent: enabled=1
tags:
- debian-12
- managed
onboot: true
cores: 4
memory: 8192
- name: Retart VM
community.general.proxmox_kvm:
state: restarted
timeout: 60
handlers:
# Initial boot
# For some reason debian cloud images don't use
# cloud-init for networking on first boot (cloud-init files
# are regenerated AFTER networking starts). But we need the
# hostname to be registered with DHCP later on so ¯\_(ツ)_/¯
- name: Initial boot
block:
- name: Start
community.general.proxmox_kvm:
state: started
register: start
- name: Wait 1.5 min # Initial apt update, apt upgrade, cloud-init
ansible.builtin.wait_for:
timeout: 90
+65
View File
@@ -0,0 +1,65 @@
- name: Initialise VM
hosts: samba
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install system packages
ansible.builtin.apt:
update_cache: true
pkg:
- qemu-guest-agent
- parted
become: true
- name: Enable qemu-guest-agent
ansible.builtin.systemd:
name: qemu-guest-agent
state: started
enabled: true
become: true
- name: Create data partition
community.general.parted:
device: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1
label: gpt
name: data
number: 1
state: present
become: true
- name: Create data filesystem
community.general.filesystem:
dev: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
fstype: ext4
become: true
- name: Mount data partition
ansible.posix.mount:
src: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
path: /var/lib/docker/volumes
fstype: ext4
opts: rw,errors=remount-ro,x-systemd.growfs
state: mounted
become: true
- name: Create share partition
community.general.parted:
device: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2
label: gpt
name: data
number: 1
state: present
become: true
- name: Create share filesystem
community.general.filesystem:
dev: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2-part1
fstype: ext4
become: true
- name: Mount data partition
ansible.posix.mount:
src: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:2-part1
path: /mnt/share
fstype: ext4
opts: rw,errors=remount-ro,x-systemd.growfs
state: mounted
become: true
+48
View File
@@ -0,0 +1,48 @@
- name: Install docker
hosts: samba
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install dependencies
ansible.builtin.apt:
update_cache: true
pkg:
- curl
- python3-apt
- gpg
become: true
- name: Add docker key
ansible.builtin.apt_key:
url: https://download.docker.com/linux/debian/gpg
keyring: /etc/apt/keyrings/docker.gpg
become: true
- name: Add docker repo
ansible.builtin.apt_repository:
repo: deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable
become: true
- name: Install docker
ansible.builtin.apt:
update_cache: true
pkg:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
become: true
- name: Add user to docker group
ansible.builtin.user:
user: debian
groups:
- docker
append: true
become: true
- name: Enable docker
ansible.builtin.systemd:
name: docker
state: started
enabled: true
become: true
+37
View File
@@ -0,0 +1,37 @@
- name: Deploy app
hosts: samba
gather_facts: false
vars:
app: samba
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Docker compose down
community.docker.docker_compose_v2:
project_src: "$HOME/{{ app }}"
state: absent
- name: Copy project
ansible.builtin.copy:
src: "./{{ app }}"
dest: "$HOME"
mode: "0744"
- name: Replace KVK Password secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/config.yml"
regexp: "KVK_PASSWORD"
replace: "{{ lookup('infisical.vault.read_secrets', env_slug='prod', path='/samba', secret_name='KVK_PASSWORD')['value'] }}"
- name: Docker compose up
community.docker.docker_compose_v2:
project_src: "$HOME/{{ app }}"
- name: Update samba permissions
ansible.builtin.file:
path: /mnt/share/samba
state: directory
recurse: true
owner: debian
group: debian
become: true
+26
View File
@@ -0,0 +1,26 @@
auth:
- user: debian
group: debian
uid: 1000
gid: 1000
- user: kvk
group: kvk
uid: 1001
gid: 1001
password: KVK_PASSWORD
global:
- "force user = debian"
- "force group = debian"
share:
- name: kvkbackups
comment: KVK Backups
path: /samba/kvkbackups
validusers: kvk
writelist: kvk
browsable: true
readonly: false
guestok: false
veto: false
+16
View File
@@ -0,0 +1,16 @@
version: "3"
services:
samba:
image: crazymax/samba
restart: unless-stopped
network_mode: host
volumes:
- samba-data:/data
- ./config.yml:/data/config.yml
- /mnt/share/samba/kvkbackups:/samba/kvkbackups
environment:
- TZ=Europe/London
volumes:
samba-data:
+112
View File
@@ -0,0 +1,112 @@
- name: Provision secrets Proxmox VM
hosts: secrets
connection: ansible.builtin.local
gather_facts: false
vars:
api_user: "{{ lookup('ansible.builtin.env', 'PROXMOX_USER') }}"
api_host: "{{ lookup('ansible.builtin.env', 'PROXMOX_HOST' ) }}"
api_token_id: "{{ lookup('ansible.builtin.env', 'PROXMOX_TOKEN_ID') }}"
api_token_secret: "{{ lookup('ansible.builtin.env', 'PROXMOX_TOKEN_SECRET') }}"
ssh_public: "{{ lookup('ansible.builtin.env', 'SSH_PUBLIC') }}"
vmname: "{{ inventory_hostname | regex_replace('^([^\\.]+)\\..+$', '\\1') }}"
node: pve2
module_defaults:
community.general.proxmox_kvm:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
node: "{{ node }}"
community.general.proxmox_nic:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
community.general.proxmox_disk:
api_user: "{{ api_user }}"
api_host: "{{ api_host }}"
api_token_id: "{{ api_token_id }}"
api_token_secret: "{{ api_token_secret }}"
name: "{{ vmname }}"
tasks:
# Initial setup
- name: Create VM
community.general.proxmox_kvm:
clone: "{{ node }}-debian-12"
storage: nvme
notify: Initial boot
- name: Wait for status
community.general.proxmox_kvm:
state: current
register: vm
retries: 30
delay: 10
until: vm.status is defined
# Networking and initial config
- name: Add PUB NIC
community.general.proxmox_nic:
interface: net0
firewall: false
bridge: PUB
- name: Add SRV NIC
community.general.proxmox_nic:
interface: net1
firewall: false
bridge: SRV
- name: Configure cloud-init
community.general.proxmox_kvm:
update: true
ciuser: debian
sshkeys: "{{ ssh_public }}"
ipconfig:
ipconfig0: ip=dhcp,ip6=auto
ipconfig1: ip=dhcp
- name: Force all notified handlers to run
ansible.builtin.meta: flush_handlers
# VM Configuration
- name: Resize root disk
community.general.proxmox_disk:
disk: scsi0
size: 16G
state: resized
- name: Create data disk
community.general.proxmox_disk:
disk: scsi1
backup: true
storage: nvme
size: 64
- name: Update VM
community.general.proxmox_kvm:
update: true
agent: enabled=1
tags:
- debian-12
- managed
onboot: true
cores: 4
memory: 4096
cpu: x86-64-v3,flags=+spec-ctrl;+aes
- name: Retart VM
community.general.proxmox_kvm:
state: restarted
timeout: 60
handlers:
# Initial boot
# For some reason debian cloud images don't use
# cloud-init for networking on first boot (cloud-init files
# are regenerated AFTER networking starts). But we need the
# hostname to be registered with DHCP later on so ¯\_(ツ)_/¯
- name: Initial boot
block:
- name: Start
community.general.proxmox_kvm:
state: started
register: start
- name: Wait 1.5 min # Initial apt update, apt upgrade, cloud-init
ansible.builtin.wait_for:
timeout: 90
@@ -0,0 +1,42 @@
- name: Initialise VM
hosts: secrets
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install system packages
ansible.builtin.apt:
update_cache: true
pkg:
- qemu-guest-agent
- parted
become: true
- name: Enable qemu-guest-agent
ansible.builtin.systemd:
name: qemu-guest-agent
state: started
enabled: true
become: true
- name: Create data partition
community.general.parted:
device: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1
label: gpt
name: data
number: 1
state: present
become: true
- name: Create data filesystem
community.general.filesystem:
dev: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
fstype: ext4
become: true
- name: Mount data partition
ansible.posix.mount:
src: /dev/disk/by-path/pci-0000:00:05.0-scsi-0:0:0:1-part1
path: /var/lib/docker
fstype: ext4
opts: rw,errors=remount-ro,x-systemd.growfs
state: mounted
become: true
+48
View File
@@ -0,0 +1,48 @@
- name: Install docker
hosts: secrets
gather_facts: false
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Install dependencies
ansible.builtin.apt:
update_cache: true
pkg:
- curl
- python3-apt
- gpg
become: true
- name: Add docker key
ansible.builtin.apt_key:
url: https://download.docker.com/linux/debian/gpg
keyring: /etc/apt/keyrings/docker.gpg
become: true
- name: Add docker repo
ansible.builtin.apt_repository:
repo: deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian bookworm stable
become: true
- name: Install docker
ansible.builtin.apt:
update_cache: true
pkg:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
become: true
- name: Add user to docker group
ansible.builtin.user:
user: debian
groups:
- docker
append: true
become: true
- name: Enable docker
ansible.builtin.systemd:
name: docker
state: started
enabled: true
become: true
+37
View File
@@ -0,0 +1,37 @@
- name: Deploy app
hosts: secrets
gather_facts: false
vars:
app: infisical
tasks:
- name: Wait for connection
ansible.builtin.wait_for_connection:
timeout: 300
- name: Docker compose down
community.docker.docker_compose_v2:
project_src: "$HOME/{{ app }}"
state: absent
- name: Copy project
ansible.builtin.copy:
src: "./{{ app }}"
dest: "$HOME"
mode: "0744"
- name: Replace Encryption Key secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "ENCRYPTION_KEY_VALUE"
replace: "{{ lookup('ansible.builtin.env', 'INFISICAL_ENCRYPTION_KEY') }}"
- name: Replace Auth secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "AUTH_SECRET_VALUE"
replace: "{{ lookup('ansible.builtin.env', 'INFISICAL_AUTH_SECRET') }}"
- name: Replace SMTP Password secret
ansible.builtin.replace:
path: "$HOME/{{ app }}/.env"
regexp: "SMTP_PASSWORD_VALUE"
replace: "{{ lookup('ansible.builtin.env', 'SMTP_PASSWORD') }}"
- name: Docker compose up -d
community.docker.docker_compose_v2:
project_src: "$HOME/{{ app }}"
+71
View File
@@ -0,0 +1,71 @@
# Keys
# Required key for platform encryption/decryption ops
# THIS IS A SAMPLE ENCRYPTION KEY AND SHOULD NEVER BE USED FOR PRODUCTION
ENCRYPTION_KEY=ENCRYPTION_KEY_VALUE
# JWT
# Required secrets to sign JWT tokens
# THIS IS A SAMPLE AUTH_SECRET KEY AND SHOULD NEVER BE USED FOR PRODUCTION
AUTH_SECRET=AUTH_SECRET_VALUE
# Postgres creds
POSTGRES_PASSWORD=infisical
POSTGRES_USER=infisical
POSTGRES_DB=infisical
# Required
DB_CONNECTION_URI=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}
# Redis
REDIS_URL=redis://redis:6379
# Website URL
# Required
SITE_URL=https://secrets.koval.net
# Mail/SMTP
SMTP_HOST=mx.koval.net
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USERNAME=no-reply@koval.net
SMTP_PASSWORD=SMTP_PASSWORD_VALUE
SMTP_FROM_NAME=KovalHome Infisical
SMTP_FROM_ADDRESS=no-reply@koval.net
# Integration
# Optional only if integration is used
CLIENT_ID_HEROKU=
CLIENT_ID_VERCEL=
CLIENT_ID_NETLIFY=
CLIENT_ID_GITHUB=
CLIENT_ID_GITLAB=
CLIENT_ID_BITBUCKET=
CLIENT_SECRET_HEROKU=
CLIENT_SECRET_VERCEL=
CLIENT_SECRET_NETLIFY=
CLIENT_SECRET_GITHUB=
CLIENT_SECRET_GITLAB=
CLIENT_SECRET_BITBUCKET=
CLIENT_SLUG_VERCEL=
# Sentry (optional) for monitoring errors
SENTRY_DSN=
# Infisical Cloud-specific configs
# Ignore - Not applicable for self-hosted version
POSTHOG_HOST=
POSTHOG_PROJECT_API_KEY=
# SSO-specific variables
CLIENT_ID_GOOGLE_LOGIN=
CLIENT_SECRET_GOOGLE_LOGIN=
CLIENT_ID_GITHUB_LOGIN=
CLIENT_SECRET_GITHUB_LOGIN=
CLIENT_ID_GITLAB_LOGIN=
CLIENT_SECRET_GITLAB_LOGIN=
# Other
INVITE_ONLY_SIGNUP=true
TELEMETRY_ENABLED=false
+1
View File
@@ -0,0 +1 @@
!.env
@@ -0,0 +1,50 @@
version: "3"
services:
db-migration:
depends_on:
db:
condition: service_healthy
image: infisical/infisical:latest-postgres
env_file: .env
command: npm run migration:latest
pull_policy: always
backend:
restart: unless-stopped
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
db-migration:
condition: service_completed_successfully
image: infisical/infisical:latest-postgres
pull_policy: always
env_file: .env
ports:
- 80:8080
environment:
- NODE_ENV=production
redis:
image: redis
env_file: .env
environment:
- ALLOW_EMPTY_PASSWORD=yes
ports:
- 6379:6379
volumes:
- /mnt/nvme/redis_data:/data
db:
image: postgres:14-alpine
restart: always
env_file: .env
volumes:
- /mnt/nvme/pg_data:/var/lib/postgresql/data
healthcheck:
test: "pg_isready --username=${POSTGRES_USER} && psql --username=${POSTGRES_USER} --list"
interval: 5s
timeout: 10s
retries: 10
+14 -2
View File
@@ -8,9 +8,21 @@ proxmox:
pve2.mgmt.home.local.koval.net:
managed:
children:
joplin:
cloud:
hosts:
joplin2.srv.home.local.koval.net:
cloud.srv.home.local.koval.net:
photos:
hosts:
photos.srv.home.local.koval.net:
secrets:
hosts:
secrets.srv.home.local.koval.net:
music:
hosts:
music.srv.home.local.koval.net:
samba:
hosts:
samba.srv.home.local.koval.net:
vars:
ansible_user: debian
ansible_ssh_private_key_file: ~/.ssh/id_rsa
+1
View File
@@ -1,3 +1,4 @@
ansible
proxmoxer
requests
infisical
+4
View File
@@ -0,0 +1,4 @@
collections:
- name: community.general
- name: community.docker
- name: infisical.vault