diff --git a/README.md b/README.md index a044a1a..08cd448 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,42 @@ -# ansible-role-template +# ansible_role_proxmox_provision -> A reusable Ansible role template for deploying and managing -> applications/services with security best practices. +> A reusable Ansible role template for for Proxmox VE +> with a focus on provisioning and managing. [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![Ansible Version](https://img.shields.io/badge/Ansible-2.12+-blue)](https://www.ansible.com/) -[![Platforms](https://img.shields.io/badge/Platforms-Debian-blue)](https://www.debian.org/) +[![Proxmox](https://img.shields.io/badge/Proxmox-9-orange?logo=proxmox&logoColor=white)](https://www.proxmox.com/) ## πŸ“Œ Key Features -βœ… **Idempotent** - Safe to run multiple times -βœ… **Security Hardened** - Follows Ansible security best practices -βœ… **Modular** - Clear separation of concerns -βœ… **Documented** - Comprehensive README and variable documentation -βœ… **Tested** - Includes example playbook for validation +βœ… **Proxmox VE Optimized** - Specifically designed for Proxmox Virtual Environment +⬜ **Idempotent** - Safe to run multiple times +⏳ **Security Hardened** - Follows Ansible security best practices +⏳ **Modular** - Clear separation of concerns +⏳ **Documented** - Comprehensive README and variable documentation +⏳ **Tested** - Includes example playbook for validation + +## πŸ“Š Compatibility Matrix + +| Feature | VE 7 | VE 8 | VE 9 | +| ------------------------ | ---- | ---- | ---- | +| No-subscription repo | βœ… | βœ… | βœ… | +| Enterprise repo disabled | βœ… | βœ… | βœ… | +| Subscription nag removed | βœ… | βœ… | βœ… | +| Swap handling | βœ… | βœ… | βœ… | +| Logrotate protection | βœ… | βœ… | βœ… | +| Powertop auto-tune | βœ… | βœ… | βœ… | + ## πŸ“‚ Directory Structure ```text -ansible-role-template/ +ansible_role_proxmox_provision/ β”œβ”€β”€ README.md # This file -β”œβ”€β”€ defaults/ # Default role variables +β”œβ”€β”€ defaults/ # Default role variables (overridable) β”‚ └── main.yml -β”œβ”€β”€ handlers/ # Role handlers +β”œβ”€β”€ handlers/ # Role handlers (for follow-up actions) β”‚ └── main.yml -β”œβ”€β”€ files/ # Static files to deploy β”œβ”€β”€ meta/ # Role metadata β”‚ └── main.yml β”œβ”€β”€ tasks/ # Main role tasks @@ -36,38 +48,38 @@ ansible-role-template/ └── main.yml ``` -## πŸ› οΈ Development - -### Prerequisites - -- Ansible 2.12+ -- Python 3.8+ - ## πŸ”§ Configuration ## Default Variables (`defaults/main.yml`) ```yaml # Default values for role variables -role_template_service_name: "default_service" -role_template_service_port: 80 -role_template_backup_enabled: false -role_template_service_backup_dir: "/var/backups/{{ role_template_service_name }}" -role_template_monitoring_enabled: false +## Swap handling +proxmox_disable_swap: true +proxmox_swapiness: 10 +proxmox_min_ram_mb_for_no_swap: 16384 + +## Powertop +proxmox_enable_powertop: true + +## Logrotate +proxmox_logrotate_maxsize: "100M" +proxmox_logrotate_rotate: 7 ``` ## Example usage -### Example Playbook (`example-playbook.yml`) +### Example Playbook (example-playbook.yml) ```yaml --- -- hosts: all +- hosts: proxmox_hosts roles: - - role: yourorg.ansible-role-template + - role: ansible_role_proxmox_provision vars: - role_template_service_name: "myapp" - role_template_service_port: 8080 + proxmox_disable_swap: false + proxmox_swapiness: 20 + proxmox_enable_powertop: true ``` ### 3. Run the Playbook @@ -76,6 +88,23 @@ role_template_monitoring_enabled: false ansible-playbook -i inventory.ini example-playbook.yml ``` +## πŸš€ Installation and Setup + +### Prerequisites + +- Ansible 2.12 or higher +- Python 3.8 or higher +- Proxmox VE 7.x or higher +- Root/sudo access to Proxmox hosts + +### Installation + +1. Clone this repository or add as a dependency in your project: + +```bash +git clone https://server.com/user/ansible_role_proxmox_provision.git +``` + ## πŸ“„ License This project is licensed under the MIT License @@ -83,6 +112,9 @@ See the [LICENSE](LICENSE) file for details. ## TODO -☐ refactor -☐ debug -☐ docs +⏳ Make the nag patch checksum-based (auto-repatch after upgrades) +❌ Add kernel power-saving tunables ? +πŸ”„ Split into VE version–aware tags ? +πŸ•’ refactor +βœ— debug +⭐ Improve documentation diff --git a/defaults/main.yml b/defaults/main.yml index 3595bb4..ea0e3a3 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -1,38 +1,16 @@ --- -# ansible-role-template/defaults/main.yml +# ansible_role_proxmox_provision/defaults/main.yml # Default values for role variables # =================================== -# Service configuration -role_template_service_name: "default_service" -role_template_service_port: 80 +# Swap handling +proxmox_disable_swap: true +proxmox_swapiness: 10 +proxmox_min_ram_mb_for_no_swap: 16384 -# User and permissions -role_template_service_user: "nobody" -role_template_service_group: "nogroup" -role_template_service_uid: 65534 -role_template_service_gid: 65534 -role_template_service_mode: "0755" +# Powertop +proxmox_enable_powertop: true -# Directory structure -role_template_service_dir: "/opt/{{ role_template_service_name }}" -role_template_service_backup_dir: "/var/backups/{{ role_template_service_name }}" - -# Systemd configuration (if applicable) -role_template_systemd_enabled: false -role_template_systemd_override_dir: "/etc/systemd/system/{{ role_template_service_name }}.d" - -# Security -role_template_validate_certs: true -role_template_ssl_ciphers: "HIGH:!aNULL:!MD5" -role_template_ssl_protocols: "TLSv1.2:TLSv1.3" - -# Backup -role_template_backup_enabled: false -role_template_backup_retention: 7 -role_template_backup_archive_path: "/var/backups/{{ role_template_service_name }}/archive" - -# Monitoring (optional) -role_template_monitoring_enabled: false -role_template_monitoring_interval: 60 -role_template_monitoring_notify_email: "admin@example.com" +# Logrotate +proxmox_logrotate_maxsize: "100M" +proxmox_logrotate_rotate: 7 diff --git a/handlers/main.yml b/handlers/main.yml index 9d6ad3b..7afd6de 100644 --- a/handlers/main.yml +++ b/handlers/main.yml @@ -1,45 +1,15 @@ --- -# ansible-role-template/handlers/main.yml +# ansible_role_proxmox_provision/handlers/main.yml # Handlers for role # ================== +- name: apt update + apt: + update_cache: yes -# Service handlers -- name: Restart {{ role_template_service_name }} - ansible.builtin.service: - name: "{{ role_template_service_name }}" +- name: restart pveproxy + systemd: + name: pveproxy state: restarted - listen: "restart {{ role_template_service_name }}" - when: role_template_service_enabled -- name: Reload systemd - ansible.builtin.systemd: - daemon_reload: true - listen: "restart {{ role_template_service_name }}" - when: role_template_systemd_enabled - -# Configuration handlers -- name: Reload nginx - ansible.builtin.service: - name: nginx - state: reloaded - listen: "reload nginx" - when: "'nginx' in role_template_service_name" - -# Backup handlers -- name: Rotate logs - ansible.builtin.command: logger -p local0.info "Rotating logs for {{ role_template_service_name }}" - changed_when: true - listen: "rotate logs" - -# Monitoring handlers -- name: Notify monitoring - ansible.builtin.uri: - url: "{{ role_template_monitoring_webhook_url }}" - method: POST - body_format: json - body: "{{ lookup('template', 'monitoring_notification.json.j2') }}" - status_code: 200 - delegate_to: localhost - run_once: true - listen: "notify monitoring" - when: role_template_monitoring_enabled +- name: reload systemd + command: systemctl daemon-reexec diff --git a/meta/main.yml b/meta/main.yml index 58608a5..07e908d 100644 --- a/meta/main.yml +++ b/meta/main.yml @@ -1,18 +1,15 @@ --- -# ansible-role-template/meta/main.yml +# ansible_role_proxmox_provision/meta/main.yml galaxy_info: - role_name: ansible_role_template # if absent directory name hosting role is used instead + role_name: ansible_role_proxmox_provision namespace: joseraj # if absent, author is used instead author: joseraj - description: > - A reusable Ansible role template for deploying and managing applications/services - with security best practices, modularity, and idempotency. + description: Proxmox VE tuning (repos, nag removal, swap, logrotate, powertop) license: MIT min_ansible_version: "2.12" platforms: - name: Debian versions: - - buster - bullseye - bookworm - trixie diff --git a/tasks/backup.yml b/tasks/backup.yml deleted file mode 100644 index 04998aa..0000000 --- a/tasks/backup.yml +++ /dev/null @@ -1,28 +0,0 @@ ---- -# # ansible-role-template/tasks/backup.yml -# Backup tasks -# ============ - -- name: backup | Ensure backup directory exists - ansible.builtin.file: - path: "{{ role_template_backup_dir }}" - state: directory - mode: "0750" - owner: root - group: root - -- name: backup | Create backup script - ansible.builtin.template: - src: templates/backup_script.sh.j2 - dest: /usr/local/bin/backup_{{ role_template_service_name }} - mode: "0755" - owner: root - group: root - -- name: backup | Create cron job for backups - ansible.builtin.cron: - name: "Backup {{ role_template_service_name }}" - user: root - minute: "0" - hour: "3" - job: "/usr/local/bin/backup_{{ role_template_service_name }}" diff --git a/tasks/logrotate.yml b/tasks/logrotate.yml new file mode 100644 index 0000000..c3e037b --- /dev/null +++ b/tasks/logrotate.yml @@ -0,0 +1,8 @@ +--- +- name: Configure Proxmox logrotate limits + template: + src: logrotate-pve.j2 + dest: /etc/logrotate.d/proxmox + owner: root + group: root + mode: "0644" diff --git a/tasks/main.yml b/tasks/main.yml index 4742445..901d92f 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -1,8 +1,23 @@ --- -# ansible-role-template/tasks/main.yml +# ansible_role_proxmox_provision/tasks/main.yml # Main tasks for role # =================== +- name: Disable enterprise repo, enable no-subscription + ansible.builtin.import_tasks: repos.yml + +- name: Remove the infamous subscription nag + ansible.builtin.import_tasks: subscription.yml + +- name: Disable swap or tune it + ansible.builtin.import_tasks: swap.yml + +- name: Stop logs from quietly murdering / + ansible.builtin.import_tasks: logrotate.yml + +- name: Install, auto-tune, and make it persistent + ansible.builtin.import_tasks: powertop.yml + # Import backup tasks - name: Import backup tasks ansible.builtin.import_tasks: backup.yml diff --git a/tasks/monitoring.yml b/tasks/monitoring.yml deleted file mode 100644 index 5c524d0..0000000 --- a/tasks/monitoring.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -# # ansible-role-template/tasks/monitoring.yml -# Monitoring tasks -# ================ - -- name: monitoring | Ensure monitoring directory exists - ansible.builtin.file: - path: "/var/log/monitoring/{{ role_template_service_name }}" - state: directory - mode: "0755" - -- name: monitoring | Create monitoring configuration - ansible.builtin.template: - src: templates/monitoring_config.yml.j2 - dest: "/etc/monitoring/{{ role_template_service_name }}.yml" - mode: "0640" - -- name: monitoring | Ensure monitoring service is running - ansible.builtin.service: - name: monitoring-service - state: started - enabled: yes diff --git a/tasks/powertop.yml b/tasks/powertop.yml new file mode 100644 index 0000000..ad5029f --- /dev/null +++ b/tasks/powertop.yml @@ -0,0 +1,22 @@ +--- +- name: Install powertop + apt: + name: powertop + state: present + update_cache: yes + when: proxmox_enable_powertop + +- name: Create powertop systemd service + template: + src: powertop.service.j2 + dest: /etc/systemd/system/powertop.service + mode: "0644" + when: proxmox_enable_powertop + notify: reload systemd + +- name: Enable and start powertop service + systemd: + name: powertop + enabled: true + state: started + when: proxmox_enable_powertop diff --git a/tasks/repos.yml b/tasks/repos.yml new file mode 100644 index 0000000..b84fbf8 --- /dev/null +++ b/tasks/repos.yml @@ -0,0 +1,15 @@ +--- +- name: Remove enterprise repo files (all known locations) + file: + path: "{{ item }}" + state: absent + loop: + - /etc/apt/sources.list.d/pve-enterprise.list + - /etc/apt/sources.list.d/ceph.list + +- name: Enable Proxmox no-subscription repo + copy: + dest: /etc/apt/sources.list.d/pve-no-subscription.list + content: | + deb http://download.proxmox.com/debian/pve {{ ansible_distribution_release }} pve-no-subscription + notify: apt update diff --git a/tasks/subscription.yml b/tasks/subscription.yml new file mode 100644 index 0000000..20c1fe9 --- /dev/null +++ b/tasks/subscription.yml @@ -0,0 +1,16 @@ +--- +- name: Remove subscription nag (legacy proxmoxlib.js) + replace: + path: /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js + regexp: "if \\(data.status !== 'Active'\\)" + replace: "if (false)" + ignore_errors: true + notify: restart pveproxy + +- name: Remove subscription nag (minified bundle for VE 8/9) + replace: + path: /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.min.js + regexp: "data.status!=='Active'" + replace: "false" + ignore_errors: true + notify: restart pveproxy diff --git a/tasks/swap.yml b/tasks/swap.yml new file mode 100644 index 0000000..318be35 --- /dev/null +++ b/tasks/swap.yml @@ -0,0 +1,23 @@ +--- +- name: Set vm.swappiness + sysctl: + name: vm.swappiness + value: "{{ proxmox_swapiness }}" + state: present + reload: yes + +- name: Disable swap if host has enough RAM + command: swapoff -a + when: + - proxmox_disable_swap + - ansible_memtotal_mb >= proxmox_min_ram_mb_for_no_swap + changed_when: false + +- name: Remove swap from fstab + replace: + path: /etc/fstab + regexp: '^\S+\s+\S+\s+swap\s+.*$' + replace: '' + when: + - proxmox_disable_swap + - ansible_memtotal_mb >= proxmox_min_ram_mb_for_no_swap diff --git a/templates/logrotate-pve.j2 b/templates/logrotate-pve.j2 new file mode 100644 index 0000000..6d78e57 --- /dev/null +++ b/templates/logrotate-pve.j2 @@ -0,0 +1,13 @@ +/var/log/pve/*.log /var/log/pve/tasks/*.log { + daily + rotate {{ proxmox_logrotate_rotate }} + compress + missingok + notifempty + maxsize {{ proxmox_logrotate_maxsize }} + create 0640 root adm + sharedscripts + postrotate + systemctl reload rsyslog >/dev/null 2>&1 || true + endscript +} diff --git a/templates/powertop.service.j2 b/templates/powertop.service.j2 new file mode 100644 index 0000000..4f2e260 --- /dev/null +++ b/templates/powertop.service.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=Powertop auto tune +After=multi-user.target + +[Service] +Type=oneshot +ExecStart=/usr/sbin/powertop --auto-tune +RemainAfterExit=true + +[Install] +WantedBy=multi-user.target diff --git a/vars/main.yml b/vars/main.yml index 075a9a6..2f988b2 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -1,2 +1,2 @@ --- -# ansible-role-template/vars/main.yml +# ansible_role_proxmox_provision/vars/main.yml