Files
infra/ansible/roles/uptime_kuma/tasks/main.yml
T
DmitryandClaude Sonnet 5 a3fe8031fe feat: migrate all managed LXC provisioning to OpenTofu (blue-green)
Blue-green: a new container is created beside the old one, data is copied, the
IP is moved onto it, and the old container is kept stopped as rollback for at
least a week. Keeping the IP means only the VMID changes, and its consumers
(backup jobs, backup audit) already derive it from the registry.

Batch 1 (2026-09-02): emergency-bot 148->151, docker-test 145->152,
gitea 141->153, vaultwarden 140->154, monitoring 146->155, gyro 150->156,
grimmory 149->157.
Batch 2 (2026-09-03): adguard 144->158, mihomo 143->159, ovpn-mini 132->160.
All migratable LXC are now provisioner: tofu. hermes-ai (frozen) and pbs stay.

- tofu/services.tf + tofu/svc-*.tf: one resource per service, reproducing the
  pct-config etalon. /dev/fuse -> features.fuse; /dev/net/tun ->
  device_passthrough (first live use on mihomo and ovpn-mini); gitea bind mount
  -> datastore volume (data finally reaches PBS); console { type = "shell" }
  declared explicitly (provider tracks cmode there).
- services.yml: vmid + provisioner: tofu for every migrated service; features
  strings and device notes updated to the tofu representation; also drops the
  memoir-bot entry and adds homelab_reverse_proxy_image/_unit.
- pve-*.yml: configuration play target is `{{ pve_config_target | default(...) }}`
  so it can run against <name>-new on a temp address (a bare --limit zeroes the
  play instead of retargeting it). Container-creation plays are gated behind
  `provisioner != 'tofu'` / `pve_provisioning_enabled` (meta: end_play), so a
  stray run cannot pct start a stopped OLD VMID on a live IP. Override for
  intentional legacy rollback: -e pve_<svc>_legacy_provisioning_enabled=true.
- ssh_config: drop memoir-bot; ovpn-mini gets ProxyJump none (a jump via ru-vps
  would route through the very tunnel ovpn-mini terminates).
- gyro.yml / uptime-kuma.yml: same pve_config_target override.
- roles/uptime_kuma: only freeze homelab-monitoring when the unit actually
  exists (a fresh blue-green container never had it).
- offsite-restic-yadisk.yml: the gitea restic profile now runs inside the LXC
  (hosts: gitea), since the bind-mount host path is gone after the volume move;
  lost+found excluded (unreadable in an unprivileged LXC, restic exit 3).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012uoq5AVK8mkBgg83Mq6o5V
2026-09-03 07:05:46 +03:00

170 lines
5.0 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
- name: Install Uptime Kuma runtime packages
ansible.builtin.apt:
name:
- ca-certificates
- docker.io
- docker-compose
- ufw
state: present
update_cache: true
- name: Ensure Docker is enabled and running
ansible.builtin.systemd:
name: docker
enabled: true
state: started
- name: Allow SSH and Uptime Kuma access from the LAN
community.general.ufw:
rule: allow
port: "{{ item }}"
proto: tcp
src: "{{ uptime_kuma_lan_cidr }}"
loop:
- "22"
- "{{ uptime_kuma_port }}"
- name: Allow SSH from the OpenVPN gateway
community.general.ufw:
rule: allow
port: "22"
proto: tcp
src: "{{ uptime_kuma_openvpn_gateway_ip }}"
- name: Enable Uptime Kuma LXC firewall
community.general.ufw:
state: enabled
policy: deny
direction: incoming
- name: Create Uptime Kuma directories
ansible.builtin.file:
path: "{{ item }}"
state: directory
owner: root
group: root
mode: "0750"
loop:
- "{{ uptime_kuma_root }}"
- "{{ uptime_kuma_root }}/data"
- name: Check if the configured Uptime Kuma image is present
ansible.builtin.command: "docker image inspect {{ uptime_kuma_image }}"
register: uptime_kuma_image_inspect
changed_when: false
failed_when: false
- name: Pull the configured Uptime Kuma image
ansible.builtin.command: "docker pull {{ uptime_kuma_image }}"
when: uptime_kuma_image_inspect.rc != 0
register: uptime_kuma_image_pull
changed_when: true
- name: Install Uptime Kuma compose definition
ansible.builtin.copy:
dest: "{{ uptime_kuma_root }}/compose.yml"
owner: root
group: root
mode: "0640"
content: |
services:
uptime-kuma:
image: {{ uptime_kuma_image }}
container_name: uptime-kuma
restart: unless-stopped
network_mode: host
environment:
HTTP_PROXY: {{ uptime_kuma_http_proxy }}
HTTPS_PROXY: {{ uptime_kuma_http_proxy }}
http_proxy: {{ uptime_kuma_http_proxy }}
https_proxy: {{ uptime_kuma_http_proxy }}
NO_PROXY: {{ uptime_kuma_no_proxy }}
no_proxy: {{ uptime_kuma_no_proxy }}
volumes:
- {{ uptime_kuma_root }}/data:/app/data
notify: restart uptime kuma
- name: Validate Uptime Kuma Compose configuration
ansible.builtin.command: >-
docker-compose -f {{ uptime_kuma_root }}/compose.yml config --quiet
changed_when: false
- name: Install Uptime Kuma systemd unit
ansible.builtin.copy:
dest: /etc/systemd/system/uptime-kuma.service
owner: root
group: root
mode: "0644"
content: |
[Unit]
Description=Uptime Kuma
Requires=docker.service
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory={{ uptime_kuma_root }}
ExecStart=/usr/bin/docker-compose -f {{ uptime_kuma_root }}/compose.yml up -d --remove-orphans
ExecStop=/usr/bin/docker-compose -f {{ uptime_kuma_root }}/compose.yml down
[Install]
WantedBy=multi-user.target
register: uptime_kuma_unit
notify: restart uptime kuma
- name: Reload systemd when the Uptime Kuma unit changes
ansible.builtin.systemd:
daemon_reload: true
when: uptime_kuma_unit.changed
- name: Enable and start Uptime Kuma
ansible.builtin.systemd:
name: uptime-kuma
enabled: true
state: "{{ 'restarted' if uptime_kuma_unit.changed or uptime_kuma_image_pull is changed else 'started' }}"
- name: Apply pending Uptime Kuma configuration changes
ansible.builtin.meta: flush_handlers
- name: Check Uptime Kuma web interface
ansible.builtin.uri:
url: "http://{{ uptime_kuma_listen_address }}:{{ uptime_kuma_port }}/"
status_code: 200
register: uptime_kuma_health
retries: 24
delay: 5
until: uptime_kuma_health.status == 200
# На хосте, где замороженный стек никогда не разворачивался (например, новый
# контейнер blue-green переезда), юнита homelab-monitoring нет, и systemd-модуль
# упал бы с "Could not find the requested service". Смысл шага — "legacy-стек не
# должен работать", а на чистом хосте это уже так. Проверено 2026-09-02.
- name: Detect the legacy monitoring unit
ansible.builtin.stat:
path: /etc/systemd/system/homelab-monitoring.service
register: uptime_kuma_legacy_unit
- name: Freeze the legacy Prometheus monitoring stack after Uptime Kuma is healthy
ansible.builtin.systemd:
name: homelab-monitoring
enabled: false
state: stopped
when: uptime_kuma_legacy_unit.stat.exists
- name: Remove legacy monitoring firewall rules
community.general.ufw:
rule: allow
port: "{{ item.port }}"
proto: tcp
src: "{{ item.src }}"
delete: true
loop:
- port: "3000"
src: "{{ uptime_kuma_lan_cidr }}"
- port: "9091"
src: "{{ uptime_kuma_openvpn_gateway_ip }}"
- port: "9100"
src: "172.16.0.0/12"