first commit
This commit is contained in:
173
Jenkinsfile
vendored
Normal file
173
Jenkinsfile
vendored
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
pipeline {
|
||||||
|
agent any
|
||||||
|
|
||||||
|
parameters {
|
||||||
|
choice(
|
||||||
|
name: 'PROVISION_TYPE',
|
||||||
|
choices: ['VM', 'LXC'],
|
||||||
|
description: 'Select whether to provision a VM or LXC container'
|
||||||
|
)
|
||||||
|
choice(
|
||||||
|
name: 'TARGET_NODE',
|
||||||
|
choices: ['homeapp1', 'homeapp2', 'homestrg1', 'homeflux1'],
|
||||||
|
description: 'Select the Proxmox node to provision on'
|
||||||
|
)
|
||||||
|
string(
|
||||||
|
name: 'HOSTNAME',
|
||||||
|
defaultValue: '',
|
||||||
|
description: 'Hostname for the new VM/LXC (required)'
|
||||||
|
)
|
||||||
|
string(
|
||||||
|
name: 'CPU_CORES',
|
||||||
|
defaultValue: '2',
|
||||||
|
description: 'Number of CPU cores'
|
||||||
|
)
|
||||||
|
string(
|
||||||
|
name: 'RAM_GB',
|
||||||
|
defaultValue: '2',
|
||||||
|
description: 'RAM in GB'
|
||||||
|
)
|
||||||
|
booleanParam(
|
||||||
|
name: 'INSTALL_DOCKER',
|
||||||
|
defaultValue: false,
|
||||||
|
description: 'Install Docker and Docker Compose'
|
||||||
|
)
|
||||||
|
booleanParam(
|
||||||
|
name: 'INSTALL_NFS',
|
||||||
|
defaultValue: false,
|
||||||
|
description: 'Install NFS and mount NFSFolder'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
environment {
|
||||||
|
ANSIBLE_HOST_KEY_CHECKING = 'False'
|
||||||
|
ANSIBLE_FORCE_COLOR = 'true'
|
||||||
|
}
|
||||||
|
|
||||||
|
stages {
|
||||||
|
stage('Validate Parameters') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
if (!params.HOSTNAME?.trim()) {
|
||||||
|
error("HOSTNAME is required")
|
||||||
|
}
|
||||||
|
if (!params.CPU_CORES.isInteger() || params.CPU_CORES.toInteger() < 1) {
|
||||||
|
error("CPU_CORES must be a positive integer")
|
||||||
|
}
|
||||||
|
if (!params.RAM_GB.isInteger() || params.RAM_GB.toInteger() < 1) {
|
||||||
|
error("RAM_GB must be a positive integer")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Install Ansible Collections') {
|
||||||
|
steps {
|
||||||
|
sh 'ansible-galaxy collection install -r requirements.yml --force'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Provision VM/LXC') {
|
||||||
|
steps {
|
||||||
|
withCredentials([string(credentialsId: 'proxmox-resource-creator', variable: 'PROXMOX_TOKEN')]) {
|
||||||
|
script {
|
||||||
|
// Parse the token: format is user@realm!tokenid=secret
|
||||||
|
def tokenParts = PROXMOX_TOKEN.split('!')
|
||||||
|
def apiUser = tokenParts[0]
|
||||||
|
def tokenIdAndSecret = tokenParts[1].split('=')
|
||||||
|
def apiTokenId = tokenIdAndSecret[0]
|
||||||
|
def apiTokenSecret = tokenIdAndSecret[1]
|
||||||
|
|
||||||
|
sh """
|
||||||
|
ansible-playbook playbooks/provision.yml \
|
||||||
|
-e "proxmox_api_user=${apiUser}" \
|
||||||
|
-e "proxmox_api_token_id=${apiTokenId}" \
|
||||||
|
-e "proxmox_api_token_secret=${apiTokenSecret}" \
|
||||||
|
-e "provision_type=${params.PROVISION_TYPE}" \
|
||||||
|
-e "target_node=${params.TARGET_NODE}" \
|
||||||
|
-e "vm_hostname=${params.HOSTNAME}" \
|
||||||
|
-e "cpu_cores=${params.CPU_CORES}" \
|
||||||
|
-e "ram_gb=${params.RAM_GB}"
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Wait for Machine to Boot') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def targetHost = "${params.HOSTNAME}.lan"
|
||||||
|
echo "Waiting for ${targetHost} to become available..."
|
||||||
|
|
||||||
|
// Wait up to 3 minutes for the machine to respond to ping
|
||||||
|
timeout(time: 3, unit: 'MINUTES') {
|
||||||
|
waitUntil {
|
||||||
|
def result = sh(
|
||||||
|
script: "ping -c 1 ${targetHost} > /dev/null 2>&1",
|
||||||
|
returnStatus: true
|
||||||
|
)
|
||||||
|
return result == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Additional wait for SSH to be ready
|
||||||
|
sleep(time: 30, unit: 'SECONDS')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Copy Jenkins SSH Key') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def targetHost = "${params.HOSTNAME}.lan"
|
||||||
|
|
||||||
|
// Use sshpass or expect to handle the initial connection
|
||||||
|
// This assumes the template has a default user that accepts the key
|
||||||
|
sh """
|
||||||
|
sudo -u jenkins ssh-copy-id -i /var/lib/jenkins/.ssh/id_ed25519.pub -o StrictHostKeyChecking=no jenkins@${targetHost}
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stage('Configure Machine') {
|
||||||
|
steps {
|
||||||
|
script {
|
||||||
|
def targetHost = "${params.HOSTNAME}.lan"
|
||||||
|
|
||||||
|
// Create a temporary inventory file with the new host
|
||||||
|
writeFile file: 'temp_inventory.yml', text: """---
|
||||||
|
all:
|
||||||
|
hosts:
|
||||||
|
new_host:
|
||||||
|
ansible_host: ${targetHost}
|
||||||
|
ansible_user: jenkins
|
||||||
|
ansible_ssh_private_key_file: /var/lib/jenkins/.ssh/id_ed25519
|
||||||
|
"""
|
||||||
|
|
||||||
|
sh """
|
||||||
|
ansible-playbook playbooks/configure.yml \
|
||||||
|
-i temp_inventory.yml \
|
||||||
|
-e "install_docker=${params.INSTALL_DOCKER}" \
|
||||||
|
-e "install_nfs=${params.INSTALL_NFS}"
|
||||||
|
"""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
post {
|
||||||
|
always {
|
||||||
|
// Clean up temporary inventory file
|
||||||
|
sh 'rm -f temp_inventory.yml || true'
|
||||||
|
}
|
||||||
|
success {
|
||||||
|
echo "Successfully provisioned ${params.PROVISION_TYPE} '${params.HOSTNAME}' on ${params.TARGET_NODE}"
|
||||||
|
echo "Machine is accessible at ${params.HOSTNAME}.lan"
|
||||||
|
}
|
||||||
|
failure {
|
||||||
|
echo "Failed to provision ${params.PROVISION_TYPE} '${params.HOSTNAME}'"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
131
README.md
Normal file
131
README.md
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
# Proxmox Template Clone
|
||||||
|
|
||||||
|
An Infrastructure-as-Code automation project for provisioning and configuring virtual machines (VMs) and Linux containers (LXCs) on a Proxmox cluster using Ansible and Jenkins.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This project automates the complete lifecycle of VM/LXC deployment:
|
||||||
|
|
||||||
|
- Clone VMs or LXCs from pre-built templates
|
||||||
|
- Configure system resources (CPU, RAM)
|
||||||
|
- Optionally install Docker and Docker Compose
|
||||||
|
- Optionally mount NFS shares
|
||||||
|
- All orchestrated through a Jenkins CI/CD pipeline
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
proxmox-template-clone/
|
||||||
|
├── Jenkinsfile # Jenkins pipeline definition
|
||||||
|
├── ansible.cfg # Ansible configuration
|
||||||
|
├── requirements.yml # Galaxy collection dependencies
|
||||||
|
├── inventory/
|
||||||
|
│ └── hosts.yml # Ansible inventory
|
||||||
|
├── playbooks/
|
||||||
|
│ ├── provision.yml # VM/LXC provisioning
|
||||||
|
│ └── configure.yml # Post-provision configuration
|
||||||
|
└── roles/
|
||||||
|
├── proxmox_vm/ # VM cloning role
|
||||||
|
├── proxmox_lxc/ # LXC cloning role
|
||||||
|
├── docker/ # Docker installation role
|
||||||
|
└── nfs/ # NFS mounting role
|
||||||
|
```
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Infrastructure
|
||||||
|
|
||||||
|
- **Proxmox cluster** with token-based API authentication
|
||||||
|
- **Jenkins server** with Ansible installed
|
||||||
|
- **Pre-built templates:**
|
||||||
|
- `ubuntu24vm` - Ubuntu 24 VM template
|
||||||
|
- `ubuntu24lxc` - Ubuntu 24 LXC template
|
||||||
|
- **Storage:** `local-lvm` backend for VM/LXC disks
|
||||||
|
|
||||||
|
### Jenkins Configuration
|
||||||
|
|
||||||
|
- SSH key pair at `/var/lib/jenkins/.ssh/id_ed25519`
|
||||||
|
- Proxmox API token stored as Jenkins credential with ID `proxmox-resource-creator`
|
||||||
|
- Format: `user@realm!tokenid=secret`
|
||||||
|
|
||||||
|
### Ansible Collections
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- community.general >= 8.0.0
|
||||||
|
- ansible.posix >= 1.5.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Install with:
|
||||||
|
```bash
|
||||||
|
ansible-galaxy install -r requirements.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Jenkins Pipeline Parameters
|
||||||
|
|
||||||
|
| Parameter | Type | Default | Description |
|
||||||
|
|-----------|------|---------|-------------|
|
||||||
|
| `PROVISION_TYPE` | Choice | - | `VM` or `LXC` |
|
||||||
|
| `TARGET_NODE` | Choice | - | Proxmox node (homeapp1, homeapp2, homestrg1, homeflux1) |
|
||||||
|
| `HOSTNAME` | String | - | Name for the new machine (required) |
|
||||||
|
| `CPU_CORES` | Integer | 2 | Number of CPU cores |
|
||||||
|
| `RAM_GB` | Integer | 2 | RAM in gigabytes |
|
||||||
|
| `INSTALL_DOCKER` | Boolean | false | Install Docker and Docker Compose |
|
||||||
|
| `INSTALL_NFS` | Boolean | false | Mount NFS share |
|
||||||
|
|
||||||
|
### Pipeline Workflow
|
||||||
|
|
||||||
|
1. **Validate Parameters** - Ensures hostname is provided and resources are valid
|
||||||
|
2. **Install Collections** - Downloads required Ansible Galaxy collections
|
||||||
|
3. **Provision** - Clones template and configures VM/LXC resources
|
||||||
|
4. **Wait for Boot** - Polls target machine until SSH is ready (up to 3 minutes)
|
||||||
|
5. **Copy SSH Key** - Enables passwordless SSH access for Jenkins
|
||||||
|
6. **Configure** - Runs system updates, installs Docker/NFS as requested
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Network
|
||||||
|
|
||||||
|
- Machines use `.lan` domain (e.g., `hostname.lan`)
|
||||||
|
- VMs bridge to `vmbr0` using virtio
|
||||||
|
- LXCs use DHCP on `eth0`
|
||||||
|
|
||||||
|
### NFS (Optional)
|
||||||
|
|
||||||
|
When enabled, mounts:
|
||||||
|
```
|
||||||
|
192.168.0.161:/mnt/share1/NFSFolder → /var/NFSFolder
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker (Optional)
|
||||||
|
|
||||||
|
Installs:
|
||||||
|
- Docker CE
|
||||||
|
- Docker CLI
|
||||||
|
- containerd
|
||||||
|
- Docker Compose plugin
|
||||||
|
- Adds jenkins user to docker group
|
||||||
|
|
||||||
|
## Customization
|
||||||
|
|
||||||
|
### Proxmox API Host
|
||||||
|
|
||||||
|
Update the API host in [playbooks/provision.yml](playbooks/provision.yml):
|
||||||
|
```yaml
|
||||||
|
proxmox_api_host: "192.168.0.166"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Target Nodes
|
||||||
|
|
||||||
|
Modify available nodes in the `Jenkinsfile` parameters section.
|
||||||
|
|
||||||
|
### Templates
|
||||||
|
|
||||||
|
Update template names in the respective role task files:
|
||||||
|
- [roles/proxmox_vm/tasks/main.yml](roles/proxmox_vm/tasks/main.yml)
|
||||||
|
- [roles/proxmox_lxc/tasks/main.yml](roles/proxmox_lxc/tasks/main.yml)
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is provided as-is for home lab and educational use.
|
||||||
10
ansible.cfg
Normal file
10
ansible.cfg
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[defaults]
|
||||||
|
inventory = ./inventory/hosts.yml
|
||||||
|
host_key_checking = False
|
||||||
|
retry_files_enabled = False
|
||||||
|
gathering = smart
|
||||||
|
fact_caching = memory
|
||||||
|
|
||||||
|
[ssh_connection]
|
||||||
|
pipelining = True
|
||||||
|
ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null
|
||||||
10
inventory/hosts.yml
Normal file
10
inventory/hosts.yml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
---
|
||||||
|
all:
|
||||||
|
hosts:
|
||||||
|
localhost:
|
||||||
|
ansible_connection: local
|
||||||
|
ansible_python_interpreter: "{{ ansible_playbook_python }}"
|
||||||
|
children:
|
||||||
|
proxmox:
|
||||||
|
hosts:
|
||||||
|
localhost:
|
||||||
39
playbooks/configure.yml
Normal file
39
playbooks/configure.yml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
- name: Configure provisioned machine
|
||||||
|
hosts: new_host
|
||||||
|
become: true
|
||||||
|
gather_facts: true
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Wait for system to be ready
|
||||||
|
ansible.builtin.wait_for_connection:
|
||||||
|
timeout: 300
|
||||||
|
|
||||||
|
- name: Gather facts after connection
|
||||||
|
ansible.builtin.setup:
|
||||||
|
|
||||||
|
- name: Update apt cache
|
||||||
|
ansible.builtin.apt:
|
||||||
|
update_cache: true
|
||||||
|
cache_valid_time: 3600
|
||||||
|
|
||||||
|
- name: Upgrade all packages
|
||||||
|
ansible.builtin.apt:
|
||||||
|
upgrade: dist
|
||||||
|
autoremove: true
|
||||||
|
|
||||||
|
- name: Include Docker role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: docker
|
||||||
|
when: install_docker | default(false) | bool
|
||||||
|
|
||||||
|
- name: Include NFS role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: nfs
|
||||||
|
when: install_nfs | default(false) | bool
|
||||||
|
|
||||||
|
- name: Reboot if required
|
||||||
|
ansible.builtin.reboot:
|
||||||
|
reboot_timeout: 300
|
||||||
|
when: ansible_facts['distribution'] == 'Ubuntu'
|
||||||
|
ignore_errors: true
|
||||||
21
playbooks/provision.yml
Normal file
21
playbooks/provision.yml
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
---
|
||||||
|
- name: Provision Proxmox VM or LXC
|
||||||
|
hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
vars:
|
||||||
|
proxmox_api_host: "192.168.0.166"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Include VM provisioning role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: proxmox_vm
|
||||||
|
when: provision_type | lower == 'vm'
|
||||||
|
|
||||||
|
- name: Include LXC provisioning role
|
||||||
|
ansible.builtin.include_role:
|
||||||
|
name: proxmox_lxc
|
||||||
|
when: provision_type | lower == 'lxc'
|
||||||
|
|
||||||
|
- name: Display created resource info
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Created {{ provision_type }} '{{ vm_hostname }}' with VMID {{ created_vmid }} on node {{ target_node }}"
|
||||||
6
requirements.yml
Normal file
6
requirements.yml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
collections:
|
||||||
|
- name: community.general
|
||||||
|
version: ">=8.0.0"
|
||||||
|
- name: ansible.posix
|
||||||
|
version: ">=1.5.0"
|
||||||
63
roles/docker/tasks/main.yml
Normal file
63
roles/docker/tasks/main.yml
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
- name: Install required packages for Docker
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- apt-transport-https
|
||||||
|
- ca-certificates
|
||||||
|
- curl
|
||||||
|
- gnupg
|
||||||
|
- lsb-release
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Create keyrings directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/apt/keyrings
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Add Docker GPG key
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: https://download.docker.com/linux/ubuntu/gpg
|
||||||
|
dest: /etc/apt/keyrings/docker.asc
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Get system architecture
|
||||||
|
ansible.builtin.command: dpkg --print-architecture
|
||||||
|
register: dpkg_arch
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Get Ubuntu codename
|
||||||
|
ansible.builtin.command: lsb_release -cs
|
||||||
|
register: ubuntu_codename
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Add Docker repository
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: "deb [arch={{ dpkg_arch.stdout }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ubuntu_codename.stdout }} stable"
|
||||||
|
state: present
|
||||||
|
filename: docker
|
||||||
|
|
||||||
|
- name: Install Docker packages
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- docker-ce
|
||||||
|
- docker-ce-cli
|
||||||
|
- containerd.io
|
||||||
|
- docker-buildx-plugin
|
||||||
|
- docker-compose-plugin
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Ensure Docker service is started and enabled
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: docker
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
- name: Add jenkins user to docker group
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: jenkins
|
||||||
|
groups: docker
|
||||||
|
append: true
|
||||||
|
ignore_errors: true
|
||||||
28
roles/nfs/tasks/main.yml
Normal file
28
roles/nfs/tasks/main.yml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
- name: Install NFS client packages
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name:
|
||||||
|
- nfs-common
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Create NFS mount directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /var/NFSFolder
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Add NFS mount to fstab
|
||||||
|
ansible.builtin.lineinfile:
|
||||||
|
path: /etc/fstab
|
||||||
|
line: "192.168.0.161:/mnt/share1/NFSFolder /var/NFSFolder nfs auto,nofail,noatime,nolock,intr,tcp,actimeo=1800 0 0"
|
||||||
|
state: present
|
||||||
|
create: true
|
||||||
|
|
||||||
|
- name: Mount NFS share
|
||||||
|
ansible.posix.mount:
|
||||||
|
path: /var/NFSFolder
|
||||||
|
src: "192.168.0.161:/mnt/share1/NFSFolder"
|
||||||
|
fstype: nfs
|
||||||
|
opts: "auto,nofail,noatime,nolock,intr,tcp,actimeo=1800"
|
||||||
|
state: mounted
|
||||||
51
roles/proxmox_lxc/tasks/main.yml
Normal file
51
roles/proxmox_lxc/tasks/main.yml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
- name: Get next available VMID
|
||||||
|
community.general.proxmox_next_id:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
register: next_vmid
|
||||||
|
|
||||||
|
- name: Clone LXC from template
|
||||||
|
community.general.proxmox:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
node: "{{ target_node }}"
|
||||||
|
clone: "ubuntu24lxc"
|
||||||
|
hostname: "{{ vm_hostname }}"
|
||||||
|
vmid: "{{ next_vmid.vmid }}"
|
||||||
|
full: true
|
||||||
|
storage: "local-lvm"
|
||||||
|
timeout: 300
|
||||||
|
register: cloned_lxc
|
||||||
|
|
||||||
|
- name: Configure LXC resources
|
||||||
|
community.general.proxmox:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
node: "{{ target_node }}"
|
||||||
|
vmid: "{{ next_vmid.vmid }}"
|
||||||
|
cores: "{{ cpu_cores }}"
|
||||||
|
memory: "{{ ram_gb | int * 1024 }}"
|
||||||
|
netif:
|
||||||
|
net0: "name=eth0,bridge=vmbr0,ip=dhcp"
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Start the LXC container
|
||||||
|
community.general.proxmox:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
node: "{{ target_node }}"
|
||||||
|
vmid: "{{ next_vmid.vmid }}"
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Set VMID fact for later use
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
created_vmid: "{{ next_vmid.vmid }}"
|
||||||
51
roles/proxmox_vm/tasks/main.yml
Normal file
51
roles/proxmox_vm/tasks/main.yml
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
---
|
||||||
|
- name: Get next available VMID
|
||||||
|
community.general.proxmox_next_id:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
register: next_vmid
|
||||||
|
|
||||||
|
- name: Clone VM from template
|
||||||
|
community.general.proxmox_kvm:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
node: "{{ target_node }}"
|
||||||
|
clone: "ubuntu24vm"
|
||||||
|
name: "{{ vm_hostname }}"
|
||||||
|
vmid: "{{ next_vmid.vmid }}"
|
||||||
|
full: true
|
||||||
|
storage: "local-lvm"
|
||||||
|
timeout: 300
|
||||||
|
register: cloned_vm
|
||||||
|
|
||||||
|
- name: Configure VM resources
|
||||||
|
community.general.proxmox_kvm:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
node: "{{ target_node }}"
|
||||||
|
vmid: "{{ next_vmid.vmid }}"
|
||||||
|
cores: "{{ cpu_cores }}"
|
||||||
|
memory: "{{ ram_gb | int * 1024 }}"
|
||||||
|
net:
|
||||||
|
net0: "virtio,bridge=vmbr0"
|
||||||
|
update: true
|
||||||
|
|
||||||
|
- name: Start the VM
|
||||||
|
community.general.proxmox_kvm:
|
||||||
|
api_host: "{{ proxmox_api_host }}"
|
||||||
|
api_user: "{{ proxmox_api_user }}"
|
||||||
|
api_token_id: "{{ proxmox_api_token_id }}"
|
||||||
|
api_token_secret: "{{ proxmox_api_token_secret }}"
|
||||||
|
node: "{{ target_node }}"
|
||||||
|
vmid: "{{ next_vmid.vmid }}"
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Set VMID fact for later use
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
created_vmid: "{{ next_vmid.vmid }}"
|
||||||
Reference in New Issue
Block a user