Compare commits
	
		
			43 Commits
		
	
	
		
			initial-vm
			...
			cleanup-pl
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ef780275e7 | |||
| 87df3eb334 | |||
| 9f51ce02d6 | |||
| 719640a98d | |||
| 20b72f085f | |||
| da90d463de | |||
| 68259cb3cf | |||
| 202abc79e3 | |||
| 8ab4968371 | |||
| 5ac073fc11 | |||
| 2834642cb7 | |||
| 594c97f4dc | |||
| 9689da7d11 | |||
| e1375aeb72 | |||
| 2aa297e901 | |||
| 1a0114fa34 | |||
| e807abb376 | |||
| 334276e654 | |||
| b9d0c5d55d | |||
| 7eff8a43ef | |||
| 7916f12e73 | |||
| aa78f334bd | |||
| 47556c3a8c | |||
| 1a8fe73bf2 | |||
| 3685590a58 | |||
| 40410b2dff | |||
| 5bfc02d3ae | |||
| 54cf382710 | |||
| d4d5511b78 | |||
| f47ad0a125 | |||
| 773b73f579 | |||
| 8529d56c44 | |||
| a8b7b1df4a | |||
| ed07a8ef71 | |||
| 82fee4eb19 | |||
| 89c5e1ea36 | |||
| 6c8bab5748 | |||
| 34fa3d2ba3 | |||
| 05a730ea52 | |||
| e39f826597 | |||
| 47335e40f6 | |||
| 21c6b627a8 | |||
| 68aff49459 | 
							
								
								
									
										4
									
								
								.ansible-lint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								.ansible-lint
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | strict: true | ||||||
|  | use_default_rules: true | ||||||
|  | skip_list: | ||||||
|  |   - args[module] | ||||||
							
								
								
									
										38
									
								
								.github/workflows/infra.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										38
									
								
								.github/workflows/infra.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -4,7 +4,7 @@ on: | |||||||
|     branches: |     branches: | ||||||
|       - main |       - main | ||||||
|     paths: |     paths: | ||||||
|       - infra/**-playbook.yaml |       - infra/**playbook.yaml | ||||||
|       - .github/workflows/infra.yaml |       - .github/workflows/infra.yaml | ||||||
|   push: |   push: | ||||||
|     branches: |     branches: | ||||||
| @@ -12,6 +12,7 @@ on: | |||||||
|  |  | ||||||
| env: | env: | ||||||
|   DEPLOY: ${{ github.ref == 'refs/heads/main' && ((startsWith(github.event.head_commit.message, '[deploy-all]') && 'all') || ('some')) || 'none' }} |   DEPLOY: ${{ github.ref == 'refs/heads/main' && ((startsWith(github.event.head_commit.message, '[deploy-all]') && 'all') || ('some')) || 'none' }} | ||||||
|  |   # DEPLOY: all | ||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   ansible-playbooks: |   ansible-playbooks: | ||||||
| @@ -23,28 +24,26 @@ jobs: | |||||||
|         with: |         with: | ||||||
|           fetch-depth: ${{ env.DEPLOY == 'some' && 2 || 1 }} |           fetch-depth: ${{ env.DEPLOY == 'some' && 2 || 1 }} | ||||||
|  |  | ||||||
|       - name: Setup Python |  | ||||||
|         uses: actions/setup-python@v4 |  | ||||||
|         with: |  | ||||||
|           python-version: "3.11" |  | ||||||
|  |  | ||||||
|       - name: Install dependencies |       - name: Install dependencies | ||||||
|         run: | |         run: | | ||||||
|  |           apt update | ||||||
|  |           apt install -y python3-pip | ||||||
|           pip3 install -r requirements.txt |           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 |       - name: Check playbooks | ||||||
|         run: | |         run: | | ||||||
|           for file in $(find . -wholename "*/infra/*-playbook.yaml" -type f); do |           ansible-playbook --inventory ./inventory --syntax-check infra/**/*playbook.yaml | ||||||
|             ansible-playbook --inventory ./inventory --check "$file" |  | ||||||
|           done |  | ||||||
|  |  | ||||||
|       - name: Get changed playbooks |       - name: Get changed playbooks | ||||||
|         id: files |         id: files | ||||||
|         if: env.DEPLOY == 'some' |         if: env.DEPLOY == 'some' | ||||||
|         uses: tj-actions/changed-files@v38 |         uses: tj-actions/changed-files@v38 | ||||||
|         with: |         with: | ||||||
|           files: infra/**/*-playbook.yaml |           files: infra/**/*playbook.yaml | ||||||
|  |  | ||||||
|       - name: Get playbooks |       - name: Get playbooks | ||||||
|         id: playbooks |         id: playbooks | ||||||
| @@ -53,12 +52,19 @@ jobs: | |||||||
|           if [[ "${{ env.DEPLOY }}" == "some" ]]; then |           if [[ "${{ env.DEPLOY }}" == "some" ]]; then | ||||||
|             export TO_RUN="${{ steps.files.outputs.all_changed_files }}" |             export TO_RUN="${{ steps.files.outputs.all_changed_files }}" | ||||||
|           else |           else | ||||||
|             export TO_RUN="$(find . -wholename './infra/*-playbook.yaml' -type f)" |             export TO_RUN="$(find . -wholename './infra/*playbook.yaml' -type f)" | ||||||
|           fi |           fi | ||||||
|           export TO_RUN="$( echo -n $TO_RUN | tr ' ' '\n' | sort | tr '\n' ' ' )" # run things in order :) |           export TO_RUN="$( echo -n $TO_RUN | tr ' ' '\n' | sort | tr '\n' ' ' )" # run things in order :) | ||||||
|           echo "will run playbooks: $TO_RUN" |           echo "will run playbooks: $TO_RUN" | ||||||
|           echo "to_run=$TO_RUN" >> "$GITHUB_OUTPUT" |           echo "to_run=$TO_RUN" >> "$GITHUB_OUTPUT" | ||||||
|  |  | ||||||
|  |       - name: Setup environment | ||||||
|  |         if: env.DEPLOY != 'none' && steps.playbooks.outputs.to_run != '' | ||||||
|  |         run: | | ||||||
|  |           mkdir -p -m 700 ~/.ssh | ||||||
|  |           echo "${{ secrets.SSH_PRIVATE }}" > ~/.ssh/id_rsa | ||||||
|  |           chmod 600 ~/.ssh/id_rsa | ||||||
|  |  | ||||||
|       - name: Run playbooks |       - name: Run playbooks | ||||||
|         if: env.DEPLOY != 'none' && steps.playbooks.outputs.to_run != '' |         if: env.DEPLOY != 'none' && steps.playbooks.outputs.to_run != '' | ||||||
|         env: |         env: | ||||||
| @@ -66,4 +72,10 @@ jobs: | |||||||
|           PROXMOX_USER: ${{ secrets.PROXMOX_USER }} |           PROXMOX_USER: ${{ secrets.PROXMOX_USER }} | ||||||
|           PROXMOX_TOKEN_ID: ${{ secrets.PROXMOX_TOKEN_ID }} |           PROXMOX_TOKEN_ID: ${{ secrets.PROXMOX_TOKEN_ID }} | ||||||
|           PROXMOX_TOKEN_SECRET: ${{ secrets.PROXMOX_TOKEN_SECRET }} |           PROXMOX_TOKEN_SECRET: ${{ secrets.PROXMOX_TOKEN_SECRET }} | ||||||
|         run: ansible-playbook --inventory ./inventory ${{ steps.playbooks.outputs.to_run }} |           SSH_PUBLIC: ${{ secrets.SSH_PUBLIC }} | ||||||
|  |           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 | ||||||
|   | |||||||
| @@ -7,4 +7,4 @@ This repository contains any automations used in deploying *.koval.net services. | |||||||
| All 'managed' infrastructure is deployed and provisioned with [Ansible](https://www.ansible.com/). | All 'managed' infrastructure is deployed and provisioned with [Ansible](https://www.ansible.com/). | ||||||
| However, some 'unmanaged' (manually managed) resources also exist - primarily everything required for this repository to work (I don't want to make a dependency loop). | However, some 'unmanaged' (manually managed) resources also exist - primarily everything required for this repository to work (I don't want to make a dependency loop). | ||||||
|  |  | ||||||
| Ansible playbooks are ran in alphanumerical order and are expected idempotent. | Ansible playbooks are ran in alphanumerical order and are expected to be idempotent. | ||||||
|   | |||||||
							
								
								
									
										112
									
								
								infra/cloud/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								infra/cloud/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,112 @@ | |||||||
|  | - name: Provision cloud Proxmox VM | ||||||
|  |   hosts: cloud | ||||||
|  |   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: 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 | ||||||
							
								
								
									
										42
									
								
								infra/cloud/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								infra/cloud/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/cloud/0002_docker_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								infra/cloud/0002_docker_playbook.yaml
									
									
									
									
									
										Normal 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 | ||||||
							
								
								
									
										13
									
								
								infra/cloud/0003_00_cleanup_script_deploy_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								infra/cloud/0003_00_cleanup_script_deploy_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -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
									
								
								infra/cloud/0003_nextcloud_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								infra/cloud/0003_nextcloud_playbook.yaml
									
									
									
									
									
										Normal 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 | ||||||
							
								
								
									
										118
									
								
								infra/music/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								infra/music/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/music/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								infra/music/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/music/0002_docker_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								infra/music/0002_docker_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/music/0003_music_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								infra/music/0003_music_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/music/music/.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								infra/music/music/.env
									
									
									
									
									
										Normal 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
									
								
								infra/music/music/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								infra/music/music/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | !.env | ||||||
							
								
								
									
										52
									
								
								infra/music/music/docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								infra/music/music/docker-compose.yml
									
									
									
									
									
										Normal 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
									
								
								infra/photos/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								infra/photos/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal 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 | ||||||
							
								
								
									
										64
									
								
								infra/photos/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								infra/photos/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -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
									
								
								infra/photos/0002_docker_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								infra/photos/0002_docker_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/photos/0003_immich_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								infra/photos/0003_immich_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/photos/immich/.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								infra/photos/immich/.env
									
									
									
									
									
										Normal 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
									
								
								infra/photos/immich/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								infra/photos/immich/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | !.env | ||||||
							
								
								
									
										64
									
								
								infra/photos/immich/docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								infra/photos/immich/docker-compose.yml
									
									
									
									
									
										Normal 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
									
								
								infra/samba/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										117
									
								
								infra/samba/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/samba/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								infra/samba/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/samba/0002_docker_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								infra/samba/0002_docker_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/samba/0003_samba_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								infra/samba/0003_samba_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/samba/samba/config.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								infra/samba/samba/config.yml
									
									
									
									
									
										Normal 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
									
								
								infra/samba/samba/docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								infra/samba/samba/docker-compose.yml
									
									
									
									
									
										Normal 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
									
								
								infra/secrets/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										112
									
								
								infra/secrets/0000_proxmox_playbook.yaml
									
									
									
									
									
										Normal 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 | ||||||
							
								
								
									
										42
									
								
								infra/secrets/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								infra/secrets/0001_initialise_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -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
									
								
								infra/secrets/0002_docker_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								infra/secrets/0002_docker_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/secrets/0003_infiscal_playbook.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								infra/secrets/0003_infiscal_playbook.yaml
									
									
									
									
									
										Normal 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
									
								
								infra/secrets/infisical/.env
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								infra/secrets/infisical/.env
									
									
									
									
									
										Normal 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
									
								
								infra/secrets/infisical/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								infra/secrets/infisical/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | !.env | ||||||
							
								
								
									
										50
									
								
								infra/secrets/infisical/docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								infra/secrets/infisical/docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -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 | ||||||
| @@ -7,6 +7,25 @@ proxmox: | |||||||
|             pve.mgmt.home.local.koval.net: |             pve.mgmt.home.local.koval.net: | ||||||
|             pve2.mgmt.home.local.koval.net: |             pve2.mgmt.home.local.koval.net: | ||||||
|         managed: |         managed: | ||||||
|  |           children: | ||||||
|  |             cloud: | ||||||
|               hosts: |               hosts: | ||||||
|  |                 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 | ||||||
|  |             ansible_ssh_common_args: -o StrictHostKeyChecking=accept-new # TODO: Improve this | ||||||
|         unmanaged: |         unmanaged: | ||||||
|           hosts: |           hosts: | ||||||
|   | |||||||
| @@ -1,3 +1,4 @@ | |||||||
| ansible | ansible | ||||||
| proxmoxer | proxmoxer | ||||||
| requests | requests | ||||||
|  | infisical | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								requirements.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								requirements.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | collections: | ||||||
|  |   - name: community.general | ||||||
|  |   - name: community.docker | ||||||
|  |   - name: infisical.vault | ||||||
		Reference in New Issue
	
	Block a user