--- - name: Update package cache apt: update_cache: yes cache_valid_time: 86400 - name: Upgrade installed packages (safe — не трогает pve-kernel и pve-пакеты) apt: upgrade: safe notify: reboot if kernel updated - name: Install essential base packages apt: name: - curl - wget - gnupg - apt-transport-https - ca-certificates - lsb-release - net-tools - iproute2 - pciutils - smartmontools - htop - vim - bash-completion state: present - name: Ensure 'locales' is installed (required for locale_gen) apt: name: locales state: present when: system_locale is defined and system_locale | length > 0 - name: Remove unused packages apt: autoremove: yes autoclean: yes - name: Disable IPv6 via sysctl sysctl: name: "{{ item.name }}" value: "{{ item.value }}" sysctl_set: yes state: present reload: yes loop: - { name: 'net.ipv6.conf.all.disable_ipv6', value: '1' } - { name: 'net.ipv6.conf.default.disable_ipv6', value: '1' } - name: Ensure /root/.bashrc exists file: path: /root/.bashrc state: touch mode: '0644' - name: Add custom aliases and env to ~/.bashrc blockinfile: path: /root/.bashrc marker: "# {mark} ANSIBLE MANAGED BLOCK: PROXMOX CUSTOM ALIASES" block: | # ——— Общие ——— alias rm='rm -i' # Защита от случайного удаления alias cp='cp -i' alias mv='mv -i' alias ls='ls --color=auto' alias ll='ls -lah' alias l.='ls -d .* --color=auto' alias mount='mount | column -t' alias h='history' alias c='clear' alias now='date +%T' alias nowdate='date +%Y-%m-%d' alias ping5='ping -c 5' alias ports='ss -tulnp' # современная замена netstat alias meminfo='free -h' alias psmem='ps aux --sort=-%mem | head -11' # ——— Proxmox ——— alias lxcstat='pct list' alias qmstat='qm list' alias ha='pvecm status && pve-ha-manager status' alias stor='pvesm status' # ——— RAID / Диски ——— alias storcli='/opt/MegaRAID/storcli/storcli64' # ——— Обновление ——— alias aptup='apt update && apt list --upgradable' owner: root mode: '0644' - name: Configure timezone timezone: name: "{{ timezone }}" - name: Generate system locale locale_gen: name: "{{ system_locale }}" state: present when: system_locale is defined and system_locale | length > 0 - name: Set default LANG in /etc/default/locale lineinfile: path: /etc/default/locale regexp: '^LANG=' line: "LANG={{ system_locale }}" state: present create: yes when: system_locale is defined and system_locale | length > 0 - name: Ensure common dirs exist file: path: "{{ item }}" state: directory mode: '0755' loop: - /opt/scripts - /etc/apt/keyrings - name: Ensure python3-requests is available (for custom scripts) apt: name: python3-requests state: present - name: Ensure SSH directory exists file: path: /root/.ssh state: directory mode: '0700' - name: Add authorized SSH keys for root authorized_key: user: root state: present key: "{{ item }}" loop: "{{ ssh_public_keys | default([]) }}" - name: Harden SSH configuration lineinfile: path: /etc/ssh/sshd_config regexp: "^{{ item.key }}\\s" line: "{{ item.key }} {{ item.value }}" state: present loop: - { key: 'PasswordAuthentication', value: 'no' } - { key: 'PermitRootLogin', value: 'prohibit-password' } - { key: 'PubkeyAuthentication', value: 'yes' } - { key: 'X11Forwarding', value: 'no' } notify: restart ssh # ========== Node Exporter ========== - name: Create node_exporter user user: name: node_exporter system: yes shell: /usr/sbin/nologin create_home: no - name: Download node_exporter get_url: url: "https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz" dest: /tmp/node_exporter-1.8.2.linux-amd64.tar.gz checksum: "sha256:https://github.com/prometheus/node_exporter/releases/download/v1.8.2/sha256sums.txt" mode: '0644' timeout: 60 - name: Extract node_exporter unarchive: src: /tmp/node_exporter-1.8.2.linux-amd64.tar.gz dest: /tmp/ remote_src: yes creates: /tmp/node_exporter-1.8.2.linux-amd64/node_exporter - name: Install node_exporter binary copy: src: /tmp/node_exporter-1.8.2.linux-amd64/node_exporter dest: /usr/local/bin/node_exporter owner: root group: root mode: '0755' remote_src: yes notify: restart node_exporter - name: Create textfile_collector directory file: path: /var/lib/node_exporter/textfile_collector state: directory owner: node_exporter group: node_exporter mode: '0755' - name: Deploy node_exporter systemd service template: src: node_exporter.service.j2 dest: /etc/systemd/system/node_exporter.service owner: root group: root mode: '0644' notify: restart node_exporter # ========== storcli — проверка и сбор метрик (без установки) ========== - name: Detect MegaRAID controller (lspci check) command: lspci -d 1000: | grep -q "MegaRAID" register: lspci_megaraid ignore_errors: yes changed_when: false - name: Check storcli binary exists stat: path: /opt/MegaRAID/storcli/storcli64 register: storcli_bin when: lspci_megaraid.rc == 0 - name: Ensure storcli symlink in PATH file: src: /opt/MegaRAID/storcli/storcli64 dest: /usr/local/bin/storcli state: link force: yes when: - lspci_megaraid.rc == 0 - storcli_bin.stat.exists - name: Verify storcli functionality command: storcli /call show register: storcli_test changed_when: false failed_when: - storcli_test.rc != 0 - "'Controller' not in storcli_test.stdout" when: - lspci_megaraid.rc == 0 - storcli_bin.stat.exists - name: Set fact — storcli is available set_fact: storcli_available: true when: - lspci_megaraid.rc == 0 - storcli_bin.stat.exists - storcli_test is success - name: Set fact — storcli NOT available set_fact: storcli_available: false when: not (lspci_megaraid.rc == 0 and storcli_bin.stat.exists) # Сбор метрик ТОЛЬКО при наличии storcli - name: Deploy storcli metrics script template: src: storcli_metrics.sh.j2 dest: /opt/scripts/storcli_metrics.sh owner: root group: root mode: '0755' when: storcli_available | default(false) - name: Deploy storcli_metrics systemd units block: - name: Create storcli_metrics.service copy: content: | [Unit] Description=Collect RAID/disk metrics via storcli After=network.target [Service] Type=oneshot ExecStart=/opt/scripts/storcli_metrics.sh User=root StandardOutput=journal StandardError=journal dest: /etc/systemd/system/storcli_metrics.service owner: root mode: '0644' - name: Create storcli_metrics.timer (every 5 min) copy: content: | [Unit] Description=Run storcli metrics collector every 5 minutes Requires=storcli_metrics.service [Timer] OnBootSec=60 OnUnitActiveSec=5m AccuracySec=1s [Install] WantedBy=timers.target dest: /etc/systemd/system/storcli_metrics.timer owner: root mode: '0644' - name: Enable & start storcli_metrics.timer systemd: name: storcli_metrics.timer state: started enabled: yes daemon_reload: yes when: storcli_available | default(false) notify: restart storcli_metrics