Files
awoooi/infra/ansible/playbooks/110-devops.yml
Your Name ff18872a23
Some checks failed
Code Review / ai-code-review (push) Successful in 14s
Deploy Alert Rules / Deploy Prometheus Alert Rules (push) Failing after 26s
Ansible / Reboot Recovery Contract / validate (push) Has been cancelled
feat(ops): 新增 host runaway process aiops guard
2026-06-18 14:17:03 +08:00

256 lines
8.8 KiB
YAML
Raw Permalink 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.
---
# AWOOOI Ansible — 192.168.0.110 DevOps 金庫完整狀態描述
# 執行: ansible-playbook -i inventory/hosts.yml playbooks/110-devops.yml
#
# 預期狀態:
# swap: 8GB (swap.img 3.8G + swap2.img 4G)
# harbor: running (docker compose, port 5000)
# sentry: running (docker compose, 0 restarting)
# gitea: running (port 3001)
# langfuse: running (port 3100)
# bitan: running docker (port 3003)
# wooo-aiops: running PM2 (port 3000)
# runners: 5x GitHub Actions runners (systemd)
# nginx: harbor conf -> 127.0.0.1:5000
# keepalived: BACKUP priority 90 VIP:200
- name: "192.168.0.110 DevOps 金庫 — 預期狀態收斂"
hosts: host_110
become: true
vars:
ansible_become_pass: "{{ vault_sudo_password | default(omit) }}"
roles:
- role: cold-start-monitor
tags: cold_start_monitor
- role: runner-guardrails
tags: runner_guardrails
- role: host-textfile-exporters
vars:
host_textfile_user: wooo
host_textfile_host_label: "110"
host_textfile_manage_runaway_process: true
host_textfile_manage_systemd_units: true
host_textfile_systemd_unit_glob: "actions.runner.*.service"
host_textfile_systemd_units:
- docker.service
- nginx.service
- prometheus.service
- alertmanager.service
- gitea.service
tags: textfile_exporters
tasks:
# ========================================================================
# Swap 檢查
# ========================================================================
- name: "Swap | 確認 swap.img 存在"
ansible.builtin.stat:
path: /swap.img
register: swap1_stat
tags: swap
- name: "Swap | 確認 swap2.img 存在"
ansible.builtin.stat:
path: /swap2.img
register: swap2_stat
tags: swap
- name: "Swap | 建立 swap2.img (若不存在)"
ansible.builtin.command:
cmd: "fallocate -l 4G /swap2.img"
creates: /swap2.img
when: not swap2_stat.stat.exists
tags: swap
- name: "Swap | 格式化 swap2.img (若剛建立)"
ansible.builtin.command:
cmd: "mkswap /swap2.img"
changed_when: true
when: not swap2_stat.stat.exists
tags: swap
- name: "Swap | 設定 swap2.img 權限"
ansible.builtin.file:
path: /swap2.img
mode: "0600"
tags: swap
- name: "Swap | 加入 swap2.img 到 fstab"
ansible.builtin.lineinfile:
path: /etc/fstab
line: "/swap2.img none swap sw 0 0"
state: present
tags: swap
- name: "Swap | 啟用 swap"
ansible.builtin.command:
cmd: "swapon --all"
changed_when: false
tags: swap
# ========================================================================
# Docker 服務健康檢查
# ========================================================================
- name: "Docker | 確認 Harbor 容器運作中"
ansible.builtin.command:
cmd: "docker ps --filter name=harbor --filter status=running --format '{{ '{{' }}.Names{{ '}}' }}'"
register: harbor_status
changed_when: false
tags: docker
- name: "Docker | Harbor 狀態警告"
ansible.builtin.debug:
msg: "⚠️ Harbor 容器未完全運作,請手動檢查 /opt/harbor"
when: harbor_status.stdout == ""
tags: docker
- name: "Docker | 確認 Gitea 容器運作中"
ansible.builtin.command:
cmd: "docker ps --filter name=gitea --filter status=running --format '{{ '{{' }}.Names{{ '}}' }}'"
register: gitea_status
changed_when: false
tags: docker
- name: "Docker | 確認 Sentry 無 restart 容器"
ansible.builtin.command:
cmd: "docker ps --filter status=restarting --filter name=sentry --format '{{ '{{' }}.Names{{ '}}' }}'"
register: sentry_restarting
changed_when: false
tags: docker
- name: "Docker | Sentry crash loop 警告"
ansible.builtin.debug:
msg: "⚠️ Sentry 容器 crash loop: {{ sentry_restarting.stdout }}"
when: sentry_restarting.stdout != ""
tags: docker
# ========================================================================
# bitan pharmacy Docker 服務
# ========================================================================
- name: "Bitan | 確認 bitan container 運作中"
ansible.builtin.command:
cmd: "docker ps --filter name=bitan --filter status=running --format '{{ '{{' }}.Names{{ '}}' }}'"
register: bitan_status
changed_when: false
tags: bitan
- name: "Bitan | 若停止則啟動"
ansible.builtin.command:
cmd: "docker compose up -d"
chdir: /home/wooo/apps/bitan-pharmacy
changed_when: true
when: bitan_status.stdout == ""
tags: bitan
# ========================================================================
# GitHub Runners
# ========================================================================
- name: "Runners | 確認 runner 服務狀態"
ansible.builtin.systemd:
name: "github-runner-{{ item }}"
register: runner_status
loop: "{{ range(1, github_runner_count + 1) | list }}"
ignore_errors: true
tags: runners
# ========================================================================
# keepalived
# ========================================================================
- name: "Keepalived | 確認服務運作中"
ansible.builtin.systemd:
name: keepalived
register: keepalived_status
tags: keepalived
- name: "Keepalived | 警告keepalived 未運作"
ansible.builtin.debug:
msg: "⚠️ keepalived 未運作VIP 200 可能失效"
when: keepalived_status.status.ActiveState != "active"
tags: keepalived
# ========================================================================
# Nginx harbor conf 指向確認
# ========================================================================
- name: "Nginx | 確認 harbor nginx conf 存在"
ansible.builtin.stat:
path: /etc/nginx/sites-enabled/harbor.conf
register: harbor_nginx
tags: nginx
- name: "Nginx | 確認 harbor conf 指向 :5000 (非 :5050)"
ansible.builtin.command:
cmd: "grep -c ':5050' /etc/nginx/sites-enabled/harbor.conf"
register: harbor_conf_check
changed_when: false
failed_when: false
when: harbor_nginx.stat.exists
tags: nginx
- name: "Nginx | 警告harbor conf 仍指向 :5050"
ansible.builtin.debug:
msg: "⚠️ harbor nginx conf 仍有 :5050請確認已修正為 :5000"
when: harbor_nginx.stat.exists and harbor_conf_check.stdout != "0"
tags: nginx
# ========================================================================
# Backup / offsite source-of-truth
# ========================================================================
- name: "Backup | 確認 /backup/scripts 存在"
ansible.builtin.file:
path: /backup/scripts
state: directory
owner: wooo
group: wooo
mode: "0755"
tags: backup_jobs
- name: "Backup | 部署 110 備份腳本"
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../../scripts/backup/{{ item }}"
dest: "/backup/scripts/{{ item }}"
owner: wooo
group: wooo
mode: "0755"
loop:
- common.sh
- backup-all.sh
- backup-status.sh
- backup-gitea.sh
- backup-harbor.sh
- backup-momo.sh
- backup-awoooi.sh
- backup-awoooi-frequent.sh
- backup-configs.sh
- sync-offsite-backups.sh
- offsite-escrow-evidence-report.sh
- verify-offsite-full-sync.sh
tags: backup_jobs
- name: "Backup | 安裝 AWOOOI daily backup Telegram heartbeat"
ansible.builtin.cron:
name: "AWOOOI daily backup Telegram heartbeat"
user: wooo
minute: "5"
hour: "6"
job: "/backup/scripts/backup-status.sh >/tmp/awoooi-backup-status.cron.log 2>&1"
tags: backup_jobs
- name: "Backup | 安裝 offsite escrow evidence report cron"
ansible.builtin.cron:
name: "AWOOOI offsite escrow evidence report"
user: wooo
minute: "10"
hour: "7"
job: "/backup/scripts/offsite-escrow-evidence-report.sh --no-color >/tmp/awoooi-offsite-escrow-evidence.cron.log 2>&1"
tags: backup_jobs
- name: "Backup | 安裝 offsite full sync verifier cron"
ansible.builtin.cron:
name: "AWOOOI offsite full sync verifier"
user: wooo
minute: "20"
hour: "7"
job: "/backup/scripts/verify-offsite-full-sync.sh --write-textfile --no-color >/tmp/awoooi-offsite-full-sync-verify.cron.log 2>&1"
tags: backup_jobs