Compare commits
24 Commits
0b286b5496
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| db217f4ce2 | |||
| cdfcc844e0 | |||
| 71a98b34ca | |||
| d2ee60c0fb | |||
| baab14c3fc | |||
| 5e253db9c7 | |||
| 54ec2bdbee | |||
| 91d4dabea8 | |||
| 857813d78f | |||
| 9200553be6 | |||
| d833004dee | |||
| 43ce6a94c0 | |||
| e9d38ece4d | |||
| 04894aef9f | |||
| 1ecc1775ef | |||
| b698108980 | |||
| 1ed42f148c | |||
| 5215f8d082 | |||
| 122157eeeb | |||
| 6d584bc582 | |||
| 0daa4a4cf9 | |||
| 09145ac1e5 | |||
| 271213d1ca | |||
| ca24bb73dc |
@@ -16,6 +16,6 @@ jobs:
|
||||
if: github.event.pull_request.merged == true
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Trigger the webhook to start pulling new Ansible configs
|
||||
# LAN IP is used because those hosts are in the same network
|
||||
- name: Trigger the webhook to run the playbook
|
||||
# LAN IP is used because those hosts are in the same network
|
||||
run: curl "http://192.168.0.38:9000/hooks/run-maintain-playbook"
|
||||
|
||||
@@ -2,3 +2,4 @@
|
||||
|
||||
ansible_become_passwd: "{{ ansible_password }}"
|
||||
human_admin_user: max
|
||||
proxmox_1_host: 192.168.0.2
|
||||
|
||||
+40
-12
@@ -1,13 +1,41 @@
|
||||
---
|
||||
physical:
|
||||
hosts:
|
||||
localhost:
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
ansible_connection: local
|
||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||
192.168.0.98:
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
192.168.0.6:
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
192.168.0.8:
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
all:
|
||||
children:
|
||||
physical:
|
||||
proxmox_1:
|
||||
ansible_host: "{{ proxmox_1_host }}"
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
services_to_run: []
|
||||
virtual:
|
||||
hosts:
|
||||
localhost:
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
ansible_connection: local
|
||||
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||
services_to_run:
|
||||
- webhook
|
||||
nfs-server:
|
||||
ansible_host: 192.168.0.6
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
services_to_run: []
|
||||
jellyfin:
|
||||
ansible_host: 192.168.0.8
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
services_to_run: []
|
||||
frigate:
|
||||
ansible_host: 192.168.0.12
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
services_to_run: []
|
||||
vs-code:
|
||||
ansible_host: 192.168.0.16
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
services_to_run: []
|
||||
gitea-server:
|
||||
ansible_host: 192.168.0.39
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
services_to_run: []
|
||||
ai-host:
|
||||
ansible_host: 192.168.0.50
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
services_to_run:
|
||||
- coder_ai
|
||||
|
||||
@@ -25,6 +25,10 @@
|
||||
prompt: "IP address for the container (in x.x.x.x/x formant)"
|
||||
private: false
|
||||
|
||||
- name: lxc_is_privileged
|
||||
prompt: "Unprivileged LXC (true/false)?"
|
||||
private: false
|
||||
|
||||
pre_tasks:
|
||||
- name: Validate hostname
|
||||
ansible.builtin.fail:
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
---
|
||||
- name: Deploy and set up an LXC container in Proxmox
|
||||
hosts: all
|
||||
hosts: virtual
|
||||
remote_user: ansible
|
||||
|
||||
vars_files:
|
||||
../inventory/group_vars/all/secrets.yaml
|
||||
vars:
|
||||
ansible_user_passwd_hash: "{{ ansible_password | password_hash('sha512', 's3edscrj45e6r') }}"
|
||||
user_passwd_hash: "{{ user_password | password_hash('sha512', 's3ed6123jhgcr') }}"
|
||||
|
||||
roles:
|
||||
# Check the Internet connection
|
||||
@@ -21,3 +18,5 @@
|
||||
- ../roles/harden_ssh
|
||||
# Update configs - omz, nvim, ranger and so on. Distribute the last version of those configs
|
||||
- ../roles/update_configs
|
||||
# Make sure that the services that are supposed to run are running
|
||||
- ../roles/check_services
|
||||
|
||||
+7
-2
@@ -4,29 +4,34 @@ ansible-lint==26.6.0
|
||||
attrs==26.1.0
|
||||
black==26.5.1
|
||||
bracex==3.0
|
||||
certifi==2026.7.22
|
||||
cffi==2.1.0
|
||||
charset-normalizer==3.4.9
|
||||
click==8.4.2
|
||||
cryptography==49.0.0
|
||||
distro==1.9.0
|
||||
filelock==3.29.7
|
||||
idna==3.18
|
||||
Jinja2==3.1.6
|
||||
jsonschema==4.26.0
|
||||
jsonschema-specifications==2025.9.1
|
||||
MarkupSafe==3.0.3
|
||||
mypy_extensions==1.1.0
|
||||
netaddr==1.3.0
|
||||
packaging==26.2
|
||||
pathspec==1.1.1
|
||||
platformdirs==4.10.0
|
||||
proxmoxer>=2.3
|
||||
proxmoxer==2.3.0
|
||||
pycparser==3.0
|
||||
pytokens==0.4.1
|
||||
PyYAML==6.0.3
|
||||
referencing==0.37.0
|
||||
requests>=2.34.2
|
||||
requests==2.34.2
|
||||
resolvelib==1.2.1
|
||||
rpds-py==2026.6.3
|
||||
ruamel.yaml==0.19.1
|
||||
ruamel.yaml.clib==0.2.15
|
||||
subprocess-tee==0.4.2
|
||||
urllib3==2.7.0
|
||||
wcmatch==11.0
|
||||
yamllint==1.38.0
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
|
||||
collections:
|
||||
- name: ansible.posix
|
||||
version: 2.2.2
|
||||
|
||||
- name: ansible.utils
|
||||
version: 6.0.3
|
||||
|
||||
- name: community.general
|
||||
version: 13.2.0
|
||||
|
||||
- name: community.library_inventory_filtering_v1
|
||||
version: 1.1.5
|
||||
|
||||
- name: community.proxmox
|
||||
version: 2.0.0
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
|
||||
- name: Make sure required services are running
|
||||
ansible.builtin.service:
|
||||
name: "{{ item }}"
|
||||
state: started
|
||||
loop: "{{ services_to_run }}"
|
||||
@@ -23,8 +23,8 @@
|
||||
become: false
|
||||
# We have to use this complicated pipeline because of Alpine and its wierd df implementation
|
||||
ansible.builtin.shell: set -o pipefail && df -h / | tail -1 | awk '{gsub(/%/, "", $5); print $5}'
|
||||
register: free_disk_space_result
|
||||
failed_when: free_disk_space_result.stdout | int > 85
|
||||
register: common_healthcheck_space_left_result
|
||||
failed_when: common_healthcheck_space_left_result.stdout | int > 85
|
||||
changed_when: false # This task does not change the system
|
||||
|
||||
rescue:
|
||||
@@ -41,5 +41,9 @@
|
||||
body:
|
||||
- "{{ ansible_facts['hostname'] }}: Disk space is low"
|
||||
delegate_to: 127.0.0.1
|
||||
failed_when: false
|
||||
failed_when: false # It's OK if it fails, not critical
|
||||
changed_when: false # This task does not change the system
|
||||
|
||||
- name: Resize rootfs if it's an LXC
|
||||
ansible.builtin.include_tasks: resize_lxc_rootfs.yaml
|
||||
when: ansible_virtualization_type == 'lxc'
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
- name: Get container info by name
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
community.general.proxmox_vm_info:
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
name: "{{ inventory_hostname }}"
|
||||
type: lxc
|
||||
register: common_healthcheck_vmid
|
||||
|
||||
- name: Resize LXC's rootfs
|
||||
become: true
|
||||
ansible.builtin.command:
|
||||
cmd: pct resize {{ common_healthcheck_vmid.proxmox_vms[0].vmid }} rootfs +5G
|
||||
delegate_to: 192.168.0.2
|
||||
changed_when: true
|
||||
vars:
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
@@ -6,7 +6,7 @@
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_host: "{{ proxmox_1_host }}"
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
password: "{{ lxc_root_password }}"
|
||||
hostname: "{{ lxc_hostname }}"
|
||||
ostemplate: 'main:vztmpl/debian-13-golden-image.tar.gz'
|
||||
unprivileged: "{{ lxc_is_privileged }}"
|
||||
memory: 2048
|
||||
cores: 2
|
||||
state: present
|
||||
@@ -33,7 +34,7 @@
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_host: "{{ proxmox_1_host }}"
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_host: "{{ proxmox_1_host }}"
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_host: "{{ proxmox_1_host }}"
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_host: "{{ proxmox_1_host }}"
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
@@ -64,10 +64,9 @@
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_host: "{{ proxmox_1_host }}"
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
name: "{{ vm_hostname }}"
|
||||
state: started
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_host: "{{ proxmox_1_host }}"
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
validate_certs: false
|
||||
node: proxmox-server
|
||||
api_user: root@pam
|
||||
api_host: 192.168.0.2
|
||||
api_host: "{{ proxmox_1_host }}"
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
@@ -19,4 +19,3 @@
|
||||
timeout: 120
|
||||
delegate_to: localhost
|
||||
changed_when: false
|
||||
|
||||
|
||||
@@ -1,3 +1,11 @@
|
||||
#!/bin/bash
|
||||
|
||||
# 1 - Pull the latest code
|
||||
git pull origin main
|
||||
|
||||
# 2 - Update dependencies and modules
|
||||
./scripts/update_modules.sh
|
||||
|
||||
# 3 - Run the job
|
||||
source .venv/bin/activate
|
||||
ansible-playbook playbooks/maintain.yaml --vault-pass-file ~/vault_password -i inventory/hosts.yaml --private-key ~/.ssh/ansible_key
|
||||
Executable
+12
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
source .venv/bin/activate
|
||||
|
||||
# Install python packages
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Install collections from the file
|
||||
ansible-galaxy collection install -r requirements.yaml -p ./collections/
|
||||
|
||||
# Install roles
|
||||
ansible-galaxy role install -r requirements.yaml -p ./roles/
|
||||
@@ -6,10 +6,10 @@ Wants=network-online.target
|
||||
[Service]
|
||||
Type=oneshot
|
||||
# CAHNGE TO MATCH YOUR REQUIREMENTS
|
||||
User=max
|
||||
Group=max
|
||||
WorkingDirectory=/home/max/projects/ansible_home
|
||||
ExecStart=/home/max/projects/ansible_home/run_playbook.sh /home/max/projects/ansible_home/playbooks/maintain.yaml
|
||||
User=ansible
|
||||
Group=ansible
|
||||
WorkingDirectory=/home/ansible/ansible-production
|
||||
ExecStart=/home/ansible/ansible-production/run_maintain_playbook.sh
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
# Optional: prevent runaway if the playbook hangs
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
[Unit]
|
||||
Description=Timer for Ansible maintenance playbook, runs every 10 minutes
|
||||
Description=Timer for Ansible maintenance playbook, runs every day
|
||||
Requires=ansible-maintenance.service
|
||||
|
||||
[Timer]
|
||||
OnUnitActiveSec=10min
|
||||
OnUnitActiveSec=1d
|
||||
Persistent=true
|
||||
Unit=ansible-maintenance.service
|
||||
|
||||
|
||||
Reference in New Issue
Block a user