From 2301a87a6e167eea3746ddeef8e7d76ff77dd7a8 Mon Sep 17 00:00:00 2001 From: jerick Date: Fri, 30 Jan 2026 14:40:48 -0500 Subject: [PATCH] first commit --- Jenkinsfile | 91 +++++++++++++++++++++++++++++ README.md | 96 +++++++++++++++++++++++++++++++ inventories/inventory.proxmox.yml | 25 ++++++++ playbooks/update.yaml | 28 +++++++++ 4 files changed, 240 insertions(+) create mode 100644 Jenkinsfile create mode 100644 README.md create mode 100644 inventories/inventory.proxmox.yml create mode 100644 playbooks/update.yaml diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..6454416 --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,91 @@ +pipeline { + agent any + + parameters { + choice( + name: 'PLAYBOOK', + choices: ['update.yaml', 'snapshotAndUpdate.yaml', 'dockerUpdate.yml', 'dockerPrune.yaml', 'newMachine.yaml'], + description: 'Select the playbook to run' + ) + string( + name: 'LIMIT', + defaultValue: '', + description: 'Limit to specific hosts or groups (e.g., "vms", "lxcs", "update_targets", or hostname) no.lan required' + ) + booleanParam( + name: 'DRY_RUN', + defaultValue: false, + description: 'Run in check mode (no changes made)' + ) + booleanParam( + name: 'CLEANUP_SNAPSHOTS', + defaultValue: false, + description: 'Remove snapshots after successful update (only for snapshotAndUpdate.yaml)' + ) + } + + environment { + PROXMOX_URL = 'https://192.168.0.166:8006' + PROXMOX_USER = 'dynamic-inventory@pve' + PROXMOX_TOKEN_ID = 'dynamic-inventory' + PROXMOX_TOKEN_SECRET = credentials('PROXMOX_TOKEN_SECRET') + ANSIBLE_HOST_KEY_CHECKING = 'False' + } + + stages { + stage('Checkout') { + steps { + checkout scm + } + } + + stage('Verify Inventory') { + steps { + sh ''' + echo "Testing dynamic inventory connection..." + ansible-inventory -i inventories/inventory.proxmox.yml --list | head -10 + ''' + } + } + + stage('Run Playbook') { + steps { + script { + // Set default limits based on playbook if not specified + def limitValue = params.LIMIT + if (!params.LIMIT) { + if (params.PLAYBOOK in ['dockerUpdate.yml', 'dockerPrune.yaml']) { + limitValue = 'docker_hosts' + } + } + def limitFlag = limitValue ? "--limit '${limitValue}'" : '' + def checkFlag = (params.DRY_RUN == true) ? '--check --diff' : '' + def extraVars = (params.CLEANUP_SNAPSHOTS == true) ? "-e cleanup_old_snapshots=true" : '' + + echo "DRY_RUN parameter: ${params.DRY_RUN}" + echo "Check flag: '${checkFlag}'" + echo "Limit: '${limitValue}'" + + sh """ + ansible-playbook \ + -i inventories/inventory.proxmox.yml \ + playbooks/${params.PLAYBOOK} \ + ${limitFlag} \ + ${checkFlag} \ + ${extraVars} \ + -v + """ + } + } + } + } + + post { + success { + echo "Playbook ${params.PLAYBOOK} completed successfully" + } + failure { + echo "Playbook ${params.PLAYBOOK} failed" + } + } +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..0ef8146 --- /dev/null +++ b/README.md @@ -0,0 +1,96 @@ +# Proxmox OS Update + +Ansible-based automation for managing and updating virtual machines and LXC containers on a Proxmox hypervisor. Uses Jenkins as a CI/CD orchestrator to execute playbooks for various maintenance tasks. + +## Features + +- **Dynamic Inventory**: Automatically discovers running VMs and LXCs from the Proxmox API +- **Tag-Based Targeting**: Group machines by Proxmox tags (update, docker, k8s) +- **CI/CD Integration**: Jenkins pipeline for scheduled and on-demand execution +- **Dry-Run Mode**: Test changes before applying them +- **Flexible Targeting**: Update specific hosts, groups, or all running machines + +## Project Structure + +``` +proxmox-os-update/ +├── Jenkinsfile # CI/CD pipeline configuration +├── README.md +├── inventories/ +│ └── inventory.proxmox.yml # Dynamic Proxmox inventory +└── playbooks/ + └── update.yaml # System update playbook +``` + +## Prerequisites + +- Ansible with `community.proxmox` collection +- Proxmox VE cluster with API token configured +- SSH access to target machines (as `jenkins` user) +- Jenkins server (for CI/CD execution) + +## Configuration + +### Proxmox API Token + +Create an API token in Proxmox for the `dynamic-inventory@pve` user. The token credentials should be stored in Jenkins. + +### Inventory Groups + +The dynamic inventory automatically creates these groups: + +| Group | Description | +|-------|-------------| +| `proxmox_all_running` | All running VMs and LXCs | +| `vms` | QEMU virtual machines | +| `lxcs` | LXC containers | +| `update_targets` | Machines tagged with 'update' | +| `docker_hosts` | Machines tagged with 'docker' | +| `kubernetes` | Machines tagged with 'k8s' | + +## Usage + +### Via Jenkins (Recommended) + +Trigger the Jenkins pipeline and select: +- **Playbook**: Which playbook to run +- **Limit**: Target specific hosts or groups (optional) +- **Dry Run**: Test without applying changes + +### Manual Execution + +```bash +# Update all running machines +ansible-playbook -i inventories/inventory.proxmox.yml playbooks/update.yaml + +# Target specific group +ansible-playbook -i inventories/inventory.proxmox.yml playbooks/update.yaml --limit docker_hosts + +# Dry run +ansible-playbook -i inventories/inventory.proxmox.yml playbooks/update.yaml --check --diff +``` + +### Ad-hoc Commands + +```bash +# Test connectivity to all VMs +ansible -i inventories/inventory.proxmox.yml vms -m ping + +# Test connectivity to a specific host +ansible -i inventories/inventory.proxmox.yml hostname -m ping +``` + +## Available Playbooks + +| Playbook | Description | +|----------|-------------| +| `update.yaml` | Updates apt cache and performs dist-upgrade | + +## Environment Variables + +| Variable | Description | +|----------|-------------| +| `PROXMOX_URL` | Proxmox API endpoint | +| `PROXMOX_USER` | API username | +| `PROXMOX_TOKEN_ID` | API token ID | +| `PROXMOX_TOKEN_SECRET` | API token secret | \ No newline at end of file diff --git a/inventories/inventory.proxmox.yml b/inventories/inventory.proxmox.yml new file mode 100644 index 0000000..f0ee66f --- /dev/null +++ b/inventories/inventory.proxmox.yml @@ -0,0 +1,25 @@ +# Proxmox Dynamic Inventory +# Requires PROXMOX_TOKEN_SECRET environment variable to be set +plugin: community.proxmox.proxmox +url: https://192.168.0.166:8006 +user: dynamic-inventory@pve +token_id: dynamic-inventory +validate_certs: false +want_facts: true + +# Filter to only running machines +filters: + - proxmox_status == 'running' + +# Group by Proxmox tags and type +groups: + vms: "'qemu' in proxmox_type" + lxcs: "'lxc' in proxmox_type" + # Tag-based groups - add tags in Proxmox to auto-group + update_targets: "'update' in (proxmox_tags | default([]))" + docker_hosts: "'docker' in (proxmox_tags | default([]))" + kubernetes: "'k8s' in (proxmox_tags | default([]))" + +compose: + ansible_host: name + '.lan' + ansible_user: 'jenkins' diff --git a/playbooks/update.yaml b/playbooks/update.yaml new file mode 100644 index 0000000..4583d40 --- /dev/null +++ b/playbooks/update.yaml @@ -0,0 +1,28 @@ +#ansible-playbook -i ../inventories/inventory.proxmox.yml update.yaml -kK +- name: Update all VMs + hosts: proxmox_all_running + + tasks: +# - name: Run Agent Uninstall +# include_tasks: zabbix/zabbixAgentUninstall.yml + - name: Update apt cache + become: true + apt: + update_cache: yes + cache_valid_time: 3600 + - name: Upgrade all apt packages + apt: + force_apt_get: yes + upgrade: dist + become: yes + +# - name: Install Zabbix Agent on servers +# hosts: proxmox_all_running +# become: yes +# tasks: +# - name: Run Debian Agent Install +# include_tasks: zabbix/zabbixDebianAgentInstall.yml +# when: ansible_distribution == "Debian" +# - name: Run Ubuntu Agent Install +# include_tasks: zabbix/zabbixUbuntuAgentInstall.yml +# when: ansible_distribution == "Ubuntu"