Remove obsolete Ansible configuration files and playbooks for Proxmox VM management, including ansible.cfg, README.md, inventory samples, and various playbooks. This cleanup eliminates unused roles and tasks, streamlining the project structure.

This commit is contained in:
Nikholas Pcenicni
2026-03-28 01:43:25 -04:00
parent d5f38bd766
commit 906c24b1d5
28 changed files with 0 additions and 798 deletions

View File

@@ -1,119 +0,0 @@
# Proxmox VM Management Suite
A comprehensive Ansible automation suite for managing Proxmox Virtual Machines. This suite allows you to easily create Cloud-Init templates, provision new VMs, manage backups, and decommission resources across multiple Proxmox hosts.
## Features
- **Template Management**:
- Automatically download Cloud Images (Ubuntu, Debian, etc.).
- Pre-configured with Cloud-Init (SSH keys, IP Config).
- Support for selecting images from a curated list or custom URLs.
- **VM Provisioning**:
- Clone from templates (Full or Linked clones).
- Auto-start option.
- **Lifecycle Management**:
- Backup VMs (Snapshot mode).
- Delete/Purge VMs.
- **Security**:
- **Automatic SSH Key Injection**: Automatically adds a defined Admin SSH key to every template.
- Support for injecting additional SSH keys per deployment.
## Setup
### 1. Requirements
Install the required Ansible collections:
```bash
ansible-galaxy install -r requirements.yml
```
### 2. Configuration
Edit `roles/proxmox_vm/defaults/main.yml` to set your global defaults, specifically the **Admin SSH Key**.
**Important Variable to Change:**
```yaml
# ansible/roles/proxmox_vm/defaults/main.yml
admin_ssh_key: "ssh-ed25519 AAAAC3... your-actual-public-key"
```
## Usage
The main entry point is the playbook `playbooks/manage_vm.yml`. You control the behavior using the `proxmox_action` variable.
### 1. Create a Cloud-Init Template
You can create a template by selecting a predefined alias (e.g., `ubuntu-22.04`) or providing a custom URL.
**Option A: Select from List (Default)**
Current aliases: `ubuntu-22.04`, `ubuntu-24.04`, `debian-12`.
```bash
# Create Ubuntu 22.04 Template (ID: 9000)
ansible-playbook playbooks/manage_vm.yml \
-e "proxmox_action=create_template vmid=9000 template_name=ubuntu-22-template image_alias=ubuntu-22.04"
```
**Option B: Custom URL**
```bash
ansible-playbook playbooks/manage_vm.yml \
-e "proxmox_action=create_template \
vmid=9001 \
template_name=custom-linux \
image_source_type=url \
custom_image_url='https://example.com/image.qcow2'"
```
### 2. Create a VM from Template
Clone a valid template to a new VM.
```bash
ansible-playbook playbooks/manage_vm.yml \
-e "proxmox_action=create_vm \
vmid=9000 \
new_vmid=105 \
new_vm_name=web-server-01"
```
### 3. Backup a VM
Create a snapshot backup of a specific VM.
```bash
ansible-playbook playbooks/manage_vm.yml \
-e "proxmox_action=backup_vm vmid=105"
```
### 4. Delete a VM
Stop and purge a VM.
```bash
ansible-playbook playbooks/manage_vm.yml \
-e "proxmox_action=delete_vm vmid=105"
```
## Advanced Usage
### Handling Multiple Hosts
You can target a specific Proxmox node using the `target_host` variable.
```bash
ansible-playbook playbooks/manage_vm.yml -e "proxmox_action=create_vm ... target_host=mercury"
```
### Injecting Additional SSH Keys
You can add extra SSH keys for a specific run (or add them to the defaults file).
```bash
ansible-playbook playbooks/manage_vm.yml \
-e "proxmox_action=create_template ... additional_ssh_keys=['ssh-rsa AAAAB3... key1', 'ssh-ed25519 AAAA... key2']"
```
## Directory Structure
- `roles/proxmox_vm/`: Core logic role.
- `defaults/main.yml`: Configuration variables (Images, Keys, Defaults).
- `tasks/`: Action modules (`create_template.yml`, `create_vm.yml`, etc.).
- `inventory/`: Host definitions.

View File

@@ -1,6 +0,0 @@
[defaults]
inventory = inventory/hosts.ini
host_key_checking = False
retry_files_enabled = False
interpreter_python = auto_silent
roles_path = roles

View File

@@ -1,14 +0,0 @@
[proxmox]
# Replace pve1 with your proxmox node hostname or IP
mercury ansible_host=192.168.50.100 ansible_user=root
[proxmox:vars]
# If using password auth (ssh key recommended though):
# ansible_ssh_pass=yourpassword
# Connection variables for the proxmox modules (api)
proxmox_api_user=root@pam
proxmox_api_password=CHANGE_ME
proxmox_api_host=192.168.50.100
# proxmox_api_token_id=
# proxmox_api_token_secret=

View File

@@ -1,16 +0,0 @@
---
- name: Create Ubuntu Cloud-Init Template
hosts: proxmox
become: yes
vars:
template_id: 9000
template_name: ubuntu-2204-cloud
# Override defaults if needed
image_alias: ubuntu-22.04
storage_pool: local-lvm
tasks:
- name: Run Proxmox Template Manage Role
include_role:
name: proxmox_template_manage

View File

@@ -1,33 +0,0 @@
---
- name: Hello World Provisioning
hosts: localhost # Run API calls from control node
gather_facts: no
vars_files:
- "../inventory/hosts.ini" # Load connection details if needed manually, OR rely on inventory
vars:
# Target Proxmox Details (override from inventory/extra vars)
proxmox_api_host: "192.168.50.100"
proxmox_api_user: "root@pam"
proxmox_api_password: "Hemroid8" # Consider moving to Vault!
proxmox_node: "mercury"
# VM Spec
vmid: 101
vm_name: "hello-world-vm"
template_name: "ubuntu-2204-cloud"
ci_user: "ubuntu"
# Replace with your actual public key or pass via -e "ssh_key=..."
ssh_keys:
- "{{ ssh_key | default('ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...') }}"
tasks:
- name: Run Proxmox Provision Role
include_role:
name: proxmox_provision
vars:
vmid: "{{ vmid }}"
vm_name: "{{ vm_name }}"
template_name: "{{ template_name }}"
ci_user: "{{ ci_user }}"
ssh_keys: "{{ ssh_keys }}"

View File

@@ -1,6 +0,0 @@
---
- name: Manage Proxmox VMs
hosts: "{{ target_host | default('proxmox') }}"
become: yes
roles:
- proxmox_vm

View File

@@ -1,26 +0,0 @@
---
- name: Register Target Host
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Verify target_host is defined
fail:
msg: "The 'target_host' variable must be defined (e.g. 192.168.1.10)"
when: target_host is not defined
- name: Add target host to inventory
add_host:
name: target_node
ansible_host: "{{ target_host }}"
ansible_user: "{{ target_user | default('root') }}"
ansible_ssh_pass: "{{ target_password | default(omit) }}"
ansible_ssh_private_key_file: "{{ target_private_key_file | default(omit) }}"
ansible_python_interpreter: /usr/bin/python3
- name: Bootstrap Node
hosts: target_node
become: yes
gather_facts: yes
roles:
- common

View File

@@ -1,29 +0,0 @@
---
- name: Register Target Host
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Verify target_host is defined
fail:
msg: "The 'target_host' variable must be defined (e.g. 192.168.1.10)"
when: target_host is not defined
- name: Add target host to inventory
add_host:
name: target_node
ansible_host: "{{ target_host }}"
ansible_user: "{{ target_user | default('root') }}"
ansible_ssh_pass: "{{ target_password | default(omit) }}"
ansible_ssh_private_key_file: "{{ target_private_key_file | default(omit) }}"
ansible_python_interpreter: /usr/bin/python3
- name: Configure Networking
hosts: target_node
become: yes
gather_facts: yes
tasks:
- name: Run networking task from common role
include_role:
name: common
tasks_from: networking.yml

View File

@@ -1,29 +0,0 @@
---
- name: Register Target Host
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Verify target_host is defined
fail:
msg: "The 'target_host' variable must be defined (e.g. 192.168.1.10)"
when: target_host is not defined
- name: Add target host to inventory
add_host:
name: target_node
ansible_host: "{{ target_host }}"
ansible_user: "{{ target_user | default('root') }}"
ansible_ssh_pass: "{{ target_password | default(omit) }}"
ansible_ssh_private_key_file: "{{ target_private_key_file | default(omit) }}"
ansible_python_interpreter: /usr/bin/python3
- name: Configure Users
hosts: target_node
become: yes
gather_facts: yes
tasks:
- name: Run users task from common role
include_role:
name: common
tasks_from: users.yml

View File

@@ -1,34 +0,0 @@
---
- name: Register Proxmox Host
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Verify proxmox_host is defined
fail:
msg: "The 'proxmox_host' variable must be defined."
when: proxmox_host is not defined
- name: Verify proxmox_action is defined
fail:
msg: "The 'proxmox_action' variable must be defined (e.g. create_vm, create_template, delete_vm)."
when: proxmox_action is not defined
- name: Add Proxmox host to inventory
add_host:
name: proxmox_node
ansible_host: "{{ proxmox_host }}"
ansible_user: "{{ proxmox_user | default('root') }}"
ansible_ssh_pass: "{{ proxmox_password | default(omit) }}"
ansible_ssh_private_key_file: "{{ proxmox_private_key_file | default(omit) }}"
ansible_python_interpreter: /usr/bin/python3
- name: Execute Proxmox Action
hosts: proxmox_node
become: yes
gather_facts: yes
vars:
# Explicitly map the action variable if needed, though role should pick it up from host vars or extra vars
proxmox_action: "{{ proxmox_action }}"
roles:
- proxmox_vm

View File

@@ -1,2 +0,0 @@
collections:
- name: community.general

View File

@@ -1,30 +0,0 @@
---
# Common packages to install
common_packages:
- curl
- wget
- git
- vim
- htop
- net-tools
- unzip
- dnsutils
- software-properties-common
- ca-certificates
- gnupg
- openssh-server
# SSH Configuration
common_ssh_users:
- name: "{{ ansible_user_id }}"
keys: []
# Add your keys in inventory or group_vars override
# Networking
common_configure_static_ip: false
common_interface_name: "eth0"
# common_ip_address: "192.168.1.100/24"
# common_gateway: "192.168.1.1"
common_dns_servers:
- "1.1.1.1"
- "8.8.8.8"

View File

@@ -1,6 +0,0 @@
---
- name: Apply Netplan
shell: netplan apply
async: 45
poll: 0
ignore_errors: yes

View File

@@ -1,10 +0,0 @@
---
- name: Install common packages
import_tasks: packages.yml
- name: Configure users and SSH keys
import_tasks: users.yml
- name: Configure networking
import_tasks: networking.yml
when: common_configure_static_ip | bool

View File

@@ -1,23 +0,0 @@
---
- name: Verify required variables for static IP
fail:
msg: "common_ip_address and common_interface_name must be defined when common_configure_static_ip is true."
when:
- common_configure_static_ip | bool
- (common_ip_address is not defined or common_ip_address | length == 0 or common_interface_name is not defined)
- name: Install netplan.io
apt:
name: netplan.io
state: present
when: ansible_os_family == "Debian"
- name: Configure Netplan
template:
src: netplan_config.yaml.j2
dest: /etc/netplan/01-netcfg.yaml
owner: root
group: root
mode: '0644'
notify: Apply Netplan
when: common_configure_static_ip | bool

View File

@@ -1,12 +0,0 @@
---
- name: Update apt cache
apt:
update_cache: yes
cache_valid_time: 3600
when: ansible_os_family == "Debian"
- name: Install common packages
apt:
name: "{{ common_packages }}"
state: present
when: ansible_os_family == "Debian"

View File

@@ -1,18 +0,0 @@
---
- name: Ensure users exist
user:
name: "{{ item.name }}"
shell: /bin/bash
groups: sudo
append: yes
state: present
loop: "{{ common_ssh_users }}"
when: item.create_user | default(false)
- name: Add SSH keys
authorized_key:
user: "{{ item.0.name }}"
key: "{{ item.1 }}"
loop: "{{ common_ssh_users | subelements('keys', skip_missing=True) }}"
loop_control:
label: "{{ item.0.name }}"

View File

@@ -1,15 +0,0 @@
network:
version: 2
ethernets:
{{ common_interface_name }}:
dhcp4: no
addresses:
- {{ common_ip_address }}
{% if common_gateway %}
gateway4: {{ common_gateway }}
{% endif %}
nameservers:
addresses:
{% for server in common_dns_servers %}
- {{ server }}
{% endfor %}

View File

@@ -1,23 +0,0 @@
---
# Defaults for proxmox_provision role
# Connection Details (fallbacks, but ideally inherited from inventory group_vars)
proxmox_api_host: "{{ ansible_host | default(inventory_hostname) }}"
proxmox_node: "{{ inventory_hostname }}"
# VM Details
vmid: 0 # 0 lets Proxmox choose next available, or specify fixed ID
vm_name: "new-vm"
template_name: "ubuntu-2204-cloud"
vm_memory: 2048
vm_cores: 2
vm_storage: "local-lvm"
vm_net_bridge: "vmbr0"
# Cloud Init / User Data
ci_user: "ubuntu"
# ssh_keys should be a list of public keys
ssh_keys: []
# State
vm_state: started

View File

@@ -1,39 +0,0 @@
---
- name: Provision VM from Template
community.general.proxmox_kvm:
api_host: "{{ proxmox_api_host }}"
api_user: "{{ proxmox_api_user }}"
api_password: "{{ proxmox_api_password }}"
# Use remote host verification if you have valid certs, else ignore
validate_certs: false
node: "{{ proxmox_node }}"
vmid: "{{ vmid if vmid | int > 0 else omit }}"
name: "{{ vm_name }}"
clone: "{{ template_name }}"
full: true # Full clone
cores: "{{ vm_cores }}"
memory: "{{ vm_memory }}"
storage: "{{ vm_storage }}"
net:
net0: "virtio,bridge={{ vm_net_bridge }}"
# Cloud Init
ciuser: "{{ ci_user }}"
sshkeys: "{{ ssh_keys | join('\n') }}"
ipconfig:
ipconfig0: "ip=dhcp"
state: "{{ vm_state }}"
register: vm_provision_result
- name: Debug Provision Result
debug:
var: vm_provision_result
# Note: Waiting for SSH requires knowing the IP.
# If qemu-guest-agent is installed in the template, we can fetch it.
# Otherwise, we might need a fixed IP or DNS check.

View File

@@ -1,41 +0,0 @@
---
# Defaults for proxmox_template_manage role
# Target Proxmox Node (where commands run)
proxmox_node: "{{ inventory_hostname }}"
# Storage Pool for Disks
storage_pool: local-lvm
# Template ID and Name
template_id: 9000
template_name: ubuntu-2204-cloud-template
# Hardware Specs
template_memory: 2048
template_cores: 2
# Image Source
# Options: 'list' (use image_alias) or 'url' (use custom_image_url)
image_source_type: list
image_list:
ubuntu-22.04:
url: "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
filename: "ubuntu-22.04-server-cloudimg-amd64.img"
ubuntu-24.04:
url: "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
filename: "ubuntu-24.04-server-cloudimg-amd64.img"
debian-12:
url: "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
filename: "debian-12-generic-amd64.qcow2"
image_alias: ubuntu-22.04
custom_image_url: ""
custom_image_name: "custom-image.img"
# Cloud Init / SSH
# Optional: Embed a default admin key into the template
embed_admin_ssh_key: false
admin_ssh_key: ""

View File

@@ -1,90 +0,0 @@
---
- name: Resolve Image Variables (List)
set_fact:
_image_url: "{{ image_list[image_alias].url }}"
_image_name: "{{ image_list[image_alias].filename }}"
when: image_source_type == 'list'
- name: Resolve Image Variables (URL)
set_fact:
_image_url: "{{ custom_image_url }}"
_image_name: "{{ custom_image_name }}"
when: image_source_type == 'url'
- name: Check if template already exists
command: "qm status {{ template_id }}"
register: vm_status
failed_when: false
changed_when: false
- name: Fail if template ID exists
fail:
msg: "VM ID {{ template_id }} already exists. Please delete it or choose a different ID."
when: vm_status.rc == 0
- name: Download Cloud Image
get_url:
url: "{{ _image_url }}"
dest: "/tmp/{{ _image_name }}"
mode: '0644'
- name: Install libguestfs-tools (for virt-customize if needed)
apt:
name: libguestfs-tools
state: present
ignore_errors: yes
- name: Create VM with hardware config
command: >
qm create {{ template_id }}
--name "{{ template_name }}"
--memory {{ template_memory }}
--core {{ template_cores }}
--net0 virtio,bridge=vmbr0
--scsihw virtio-scsi-pci
--ostype l26
--serial0 socket --vga serial0
- name: Import Disk
command: "qm importdisk {{ template_id }} /tmp/{{ _image_name }} {{ storage_pool }}"
- name: Attach Disk to SCSI
command: "qm set {{ template_id }} --scsi0 {{ storage_pool }}:vm-{{ template_id }}-disk-0"
- name: Add Cloud-Init Drive
command: "qm set {{ template_id }} --ide2 {{ storage_pool }}:cloudinit"
- name: Set Boot Order
command: "qm set {{ template_id }} --boot c --bootdisk scsi0"
- name: Configure Cloud-Init (Optional Admin Key)
block:
- name: Prepare SSH Keys File
copy:
content: "{{ admin_ssh_key }}"
dest: "/tmp/ssh_key_{{ template_id }}.pub"
mode: '0600'
- name: Set SSH Keys on Template
command: "qm set {{ template_id }} --sshkeys /tmp/ssh_key_{{ template_id }}.pub"
- name: Cleanup Key File
file:
path: "/tmp/ssh_key_{{ template_id }}.pub"
state: absent
when: embed_admin_ssh_key | bool and admin_ssh_key | length > 0
- name: Set Cloud-Init IP Config (DHCP)
command: "qm set {{ template_id }} --ipconfig0 ip=dhcp"
- name: Resize Disk (to Minimum 10G)
command: "qm resize {{ template_id }} scsi0 10G"
ignore_errors: yes
- name: Convert to Template
command: "qm template {{ template_id }}"
- name: Remove Downloaded Image
file:
path: "/tmp/{{ _image_name }}"
state: absent

View File

@@ -1,58 +0,0 @@
---
# Defaults for proxmox_vm role
# Action to perform: create_template, create_vm, delete_vm, backup_vm
proxmox_action: create_vm
# Common settings
storage_pool: Lithium
vmid: 9000
target_node: "{{ inventory_hostname }}"
# --- Template Creation Settings ---
# Image Source Selection
# Options: 'list' (use image_alias) or 'url' (use custom_image_url)
image_source_type: list
# Predefined Image List
# You can select these by setting image_alias
image_list:
ubuntu-22.04:
url: "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
filename: "ubuntu-22.04-server-cloudimg-amd64.img"
ubuntu-24.04:
url: "https://cloud-images.ubuntu.com/noble/current/noble-server-cloudimg-amd64.img"
filename: "ubuntu-24.04-server-cloudimg-amd64.img"
debian-12:
url: "https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-generic-amd64.qcow2"
filename: "debian-12-generic-amd64.qcow2"
# Selection (Default)
image_alias: ubuntu-22.04
# Custom URL (Used if image_source_type is 'url')
custom_image_url: ""
custom_image_name: "custom-image.img"
# Template Config
template_name: ubuntu-cloud-template
memory: 2048
cores: 2
# --- SSH Key Configuration ---
# The Admin Key is always added
admin_ssh_key: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI..." # REPLACE THIS with your actual public key
# Additional keys (list of strings)
additional_ssh_keys: []
# --- Create VM Settings (Cloning) ---
new_vm_name: new-vm
clone_full: true # Full clone (independent) vs Linked clone
start_after_create: true
# --- Backup Settings ---
backup_mode: snapshot # snapshot, suspend, stop
backup_compress: zstd
backup_storage: Lithium

View File

@@ -1,7 +0,0 @@
---
- name: Create VM Backup
command: >
vzdump {{ vmid }}
--mode {{ backup_mode }}
--compress {{ backup_compress }}
--storage {{ backup_storage }}

View File

@@ -1,91 +0,0 @@
---
- name: Resolve Image Variables (List)
set_fact:
_image_url: "{{ image_list[image_alias].url }}"
_image_name: "{{ image_list[image_alias].filename }}"
when: image_source_type == 'list'
- name: Resolve Image Variables (URL)
set_fact:
_image_url: "{{ custom_image_url }}"
_image_name: "{{ custom_image_name }}"
when: image_source_type == 'url'
- name: Check if template already exists
command: "qm status {{ vmid }}"
register: vm_status
failed_when: false
changed_when: false
- name: Fail if template ID exists
fail:
msg: "VM ID {{ vmid }} already exists. Please choose a different ID or delete the existing VM."
when: vm_status.rc == 0
- name: Download Cloud Image
get_url:
url: "{{ _image_url }}"
dest: "/tmp/{{ _image_name }}"
mode: '0644'
- name: Install libguestfs-tools
apt:
name: libguestfs-tools
state: present
ignore_errors: yes
- name: Create VM with hardware config
command: >
qm create {{ vmid }}
--name "{{ template_name }}"
--memory {{ memory }}
--core {{ cores }}
--net0 virtio,bridge=vmbr0
--scsihw virtio-scsi-pci
--ostype l26
--serial0 socket --vga serial0
- name: Import Disk
command: "qm importdisk {{ vmid }} /tmp/{{ _image_name }} {{ storage_pool }}"
- name: Attach Disk to SCSI
command: "qm set {{ vmid }} --scsi0 {{ storage_pool }}:vm-{{ vmid }}-disk-0"
- name: Add Cloud-Init Drive
command: "qm set {{ vmid }} --ide2 {{ storage_pool }}:cloudinit"
- name: Set Boot Order
command: "qm set {{ vmid }} --boot c --bootdisk scsi0"
- name: Prepare SSH Keys File
copy:
content: |
{{ admin_ssh_key }}
{% for key in additional_ssh_keys %}
{{ key }}
{% endfor %}
dest: "/tmp/ssh_keys_{{ vmid }}.pub"
mode: '0600'
- name: Configure Cloud-Init (SSH Keys, User, IP)
command: >
qm set {{ vmid }}
--sshkeys /tmp/ssh_keys_{{ vmid }}.pub
--ipconfig0 ip=dhcp
- name: Resize Disk (Default 10G)
command: "qm resize {{ vmid }} scsi0 10G"
ignore_errors: yes
- name: Convert to Template
command: "qm template {{ vmid }}"
- name: Remove Downloaded Image
file:
path: "/tmp/{{ _image_name }}"
state: absent
- name: Remove Temporary SSH Keys File
file:
path: "/tmp/ssh_keys_{{ vmid }}.pub"
state: absent

View File

@@ -1,11 +0,0 @@
---
- name: Clone VM from Template
command: >
qm clone {{ vmid }} {{ new_vmid }}
--name "{{ new_vm_name }}"
--full {{ 1 if clone_full | bool else 0 }}
register: clone_result
- name: Start VM (Optional)
command: "qm start {{ new_vmid }}"
when: start_after_create | default(false) | bool

View File

@@ -1,7 +0,0 @@
---
- name: Stop VM (Force Stop)
command: "qm stop {{ vmid }}"
ignore_errors: yes
- name: Destroy VM
command: "qm destroy {{ vmid }} --purge"

View File

@@ -1,3 +0,0 @@
---
- name: Dispatch task based on action
include_tasks: "{{ proxmox_action }}.yml"