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:
@@ -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.
|
||||
@@ -1,6 +0,0 @@
|
||||
[defaults]
|
||||
inventory = inventory/hosts.ini
|
||||
host_key_checking = False
|
||||
retry_files_enabled = False
|
||||
interpreter_python = auto_silent
|
||||
roles_path = roles
|
||||
@@ -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=
|
||||
@@ -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
|
||||
@@ -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 }}"
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
- name: Manage Proxmox VMs
|
||||
hosts: "{{ target_host | default('proxmox') }}"
|
||||
become: yes
|
||||
roles:
|
||||
- proxmox_vm
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
collections:
|
||||
- name: community.general
|
||||
@@ -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"
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
- name: Apply Netplan
|
||||
shell: netplan apply
|
||||
async: 45
|
||||
poll: 0
|
||||
ignore_errors: yes
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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 }}"
|
||||
@@ -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 %}
|
||||
@@ -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
|
||||
@@ -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.
|
||||
@@ -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: ""
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
- name: Create VM Backup
|
||||
command: >
|
||||
vzdump {{ vmid }}
|
||||
--mode {{ backup_mode }}
|
||||
--compress {{ backup_compress }}
|
||||
--storage {{ backup_storage }}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
- name: Stop VM (Force Stop)
|
||||
command: "qm stop {{ vmid }}"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Destroy VM
|
||||
command: "qm destroy {{ vmid }} --purge"
|
||||
@@ -1,3 +0,0 @@
|
||||
---
|
||||
- name: Dispatch task based on action
|
||||
include_tasks: "{{ proxmox_action }}.yml"
|
||||
Reference in New Issue
Block a user