Examples/15-CloudInitProvisioning.ps1
|
<# .SYNOPSIS Deploy a VM using cloud-init for automated provisioning. .DESCRIPTION This script demonstrates deploying a cloud-ready VM image with cloud-init: 1. Create a VM configured for cloud-init 2. Import a cloud image (Ubuntu/Debian cloud image) 3. Add a network interface 4. Create cloud-init files for automated provisioning 5. Power on the VM (cloud-init runs on first boot) Cloud-init automatically configures the VM on first boot based on the user-data, meta-data, and network-config files you provide. .NOTES Prerequisites: - PowerShell 7.4 or later - PSVergeOS module installed - Connected to a VergeOS system - A cloud image uploaded (e.g., noble-server-cloudimg-amd64.ova) Cloud-init file types: - /user-data: User configuration (packages, users, SSH keys, run commands) - /meta-data: Instance metadata (instance-id, hostname) - /network-config: Network configuration (DHCP or static IP) .EXAMPLE # Customize the variables below and run the script .\15-CloudInitProvisioning.ps1 #> # Import the module Import-Module PSVergeOS -ErrorAction Stop #region Configuration Variables # ============================================================================ # CUSTOMIZE THESE VARIABLES FOR YOUR ENVIRONMENT # ============================================================================ # VM Configuration $VMName = "pstest-cloudinit" # Name for the new VM $VMDescription = "Ubuntu server deployed via cloud-init" $CPUCores = 2 # Number of CPU cores $RAMSizeMB = 2048 # RAM in MB (2GB) # Cloud Image (must be uploaded to VergeOS files) $CloudImageName = "noble-server-cloudimg-amd64.ova" # Network Configuration $NetworkName = "External" # Network to connect to # Cloud-Init User Configuration $Hostname = "ubuntu-server" # VM hostname $Username = "admin" # User to create $SSHPublicKey = "" # Your SSH public key (optional) $Packages = @("curl", "htop", "vim") # Packages to install #endregion #region Pre-flight Checks # ============================================================================ # VERIFY PREREQUISITES BEFORE PROCEEDING # ============================================================================ Write-Host "Performing pre-flight checks..." -ForegroundColor Cyan # Verify connection $connection = Get-VergeConnection -Default if (-not $connection) { throw "Not connected to VergeOS. Run Connect-VergeOS first." } Write-Host " Connected to: $($connection.Server)" -ForegroundColor Green # Verify cloud image exists $cloudImage = Get-VergeFile -Name $CloudImageName -ErrorAction SilentlyContinue if (-not $cloudImage) { Write-Warning "Cloud image '$CloudImageName' not found." Write-Host " Available importable files:" -ForegroundColor Yellow Get-VergeFile | Where-Object { $_.Name -match '\.(ova|ovf|qcow2|vmdk)$' } | ForEach-Object { Write-Host " - $($_.Name)" -ForegroundColor Yellow } throw "Upload a cloud image or update the `$CloudImageName variable." } Write-Host " Cloud image found: $($cloudImage.Name)" -ForegroundColor Green # Verify network exists $network = Get-VergeNetwork -Name $NetworkName -ErrorAction SilentlyContinue if (-not $network) { throw "Network '$NetworkName' not found." } Write-Host " Network '$NetworkName' found (Key: $($network.Key))" -ForegroundColor Green # Check if VM already exists $existingVM = Get-VergeVM -Name $VMName -ErrorAction SilentlyContinue if ($existingVM) { throw "VM '$VMName' already exists (Key: $($existingVM.Key)). Change `$VMName or delete existing VM." } Write-Host "Pre-flight checks passed!" -ForegroundColor Green Write-Host "" #endregion #region Create VM # ============================================================================ # STEP 1: CREATE THE VIRTUAL MACHINE WITH CLOUD-INIT ENABLED # ============================================================================ Write-Host "Creating VM '$VMName' with cloud-init..." -ForegroundColor Cyan $vm = New-VergeVM ` -Name $VMName ` -Description $VMDescription ` -CPUCores $CPUCores ` -RAM $RAMSizeMB ` -OSFamily Linux ` -UEFI ` -GuestAgent ` -CloudInit ConfigDrive ` -PassThru Write-Host " VM created (Key: $($vm.Key))" -ForegroundColor Green Write-Host " Cloud-init datasource: Config Drive v2" -ForegroundColor Green Write-Host "" #endregion #region Import Cloud Image # ============================================================================ # STEP 2: IMPORT CLOUD IMAGE AS BOOT DRIVE # ============================================================================ Write-Host "Importing cloud image as boot drive..." -ForegroundColor Cyan Import-VergeDrive ` -VM $vm ` -FileName $CloudImageName ` -Name "Boot" ` -Interface virtio-scsi ` -Tier 1 Write-Host " Cloud image imported successfully" -ForegroundColor Green Write-Host "" #endregion #region Add Network Interface # ============================================================================ # STEP 3: ADD NETWORK INTERFACE # ============================================================================ Write-Host "Adding network interface..." -ForegroundColor Cyan $nic = New-VergeNIC ` -VM $vm ` -NetworkName $NetworkName ` -Name "eth0" ` -Interface virtio ` -PassThru Write-Host " NIC connected to '$NetworkName' (Key: $($nic.Key))" -ForegroundColor Green Write-Host "" #endregion #region Create Cloud-Init Files # ============================================================================ # STEP 4: CREATE CLOUD-INIT CONFIGURATION FILES # ============================================================================ Write-Host "Creating cloud-init configuration..." -ForegroundColor Cyan # --- user-data: Main configuration file --- $userData = @" #cloud-config # Set the hostname hostname: $Hostname fqdn: $Hostname.local # Create user account users: - name: $Username groups: sudo, adm shell: /bin/bash sudo: ALL=(ALL) NOPASSWD:ALL lock_passwd: false $(if ($SSHPublicKey) { " ssh_authorized_keys: - $SSHPublicKey" }) # Update packages and install specified packages package_update: true package_upgrade: true $(if ($Packages.Count -gt 0) { "packages: $(($Packages | ForEach-Object { " - $_" }) -join "`n")" }) # Run commands on first boot runcmd: - echo "Cloud-init provisioning complete at `$(date)" >> /var/log/cloud-init-custom.log - echo "Hostname: $Hostname" >> /var/log/cloud-init-custom.log # Final message final_message: "Cloud-init completed for $VMName in \$UPTIME seconds" "@ New-VergeCloudInitFile -VMId $vm.Key -Name "/user-data" -Contents $userData -Render No Write-Host " /user-data created (user: $Username, packages: $($Packages -join ', '))" -ForegroundColor Green # --- meta-data: Instance identification --- $metaData = @" instance-id: $($vm.Key)-$Hostname local-hostname: $Hostname "@ New-VergeCloudInitFile -VMId $vm.Key -Name "/meta-data" -Contents $metaData -Render No Write-Host " /meta-data created (instance-id: $($vm.Key)-$Hostname)" -ForegroundColor Green # --- network-config: Network configuration (DHCP) --- $networkConfig = @" network: version: 2 ethernets: eth0: dhcp4: true dhcp6: false "@ New-VergeCloudInitFile -VMId $vm.Key -Name "/network-config" -Contents $networkConfig -Render No Write-Host " /network-config created (DHCP enabled)" -ForegroundColor Green Write-Host "" #endregion #region Power On VM # ============================================================================ # STEP 5: START THE VIRTUAL MACHINE # ============================================================================ Write-Host "Starting VM '$VMName'..." -ForegroundColor Cyan Start-VergeVM -VM $vm Write-Host " VM powered on - cloud-init will run on first boot" -ForegroundColor Green Write-Host "" #endregion #region Summary # ============================================================================ # DEPLOYMENT SUMMARY # ============================================================================ Write-Host ("=" * 60) -ForegroundColor Cyan Write-Host "CLOUD-INIT DEPLOYMENT COMPLETE" -ForegroundColor Green Write-Host ("=" * 60) -ForegroundColor Cyan Write-Host "" Write-Host "VM Configuration:" -ForegroundColor White Write-Host " Name: $VMName" Write-Host " CPU: $CPUCores cores" Write-Host " RAM: $($RAMSizeMB / 1024) GB" Write-Host " Image: $CloudImageName" Write-Host " Network: $NetworkName (DHCP)" Write-Host "" Write-Host "Cloud-Init Configuration:" -ForegroundColor White Write-Host " Hostname: $Hostname" Write-Host " Username: $Username" Write-Host " Packages: $($Packages -join ', ')" Write-Host "" # List created cloud-init files Write-Host "Cloud-Init Files:" -ForegroundColor White Get-VergeCloudInitFile -VMId $vm.Key | ForEach-Object { Write-Host " $($_.Name) ($($_.FileSize) bytes)" } Write-Host "" # Get console URL $consoleUrl = Get-VergeVMConsole -VM $vm if ($consoleUrl) { Write-Host "Console URL:" -ForegroundColor White Write-Host " $consoleUrl" -ForegroundColor Cyan } Write-Host "" Write-Host "The VM is booting. Cloud-init will:" -ForegroundColor Yellow Write-Host " 1. Set hostname to '$Hostname'" Write-Host " 2. Create user '$Username' with sudo access" Write-Host " 3. Configure DHCP networking" Write-Host " 4. Update packages and install: $($Packages -join ', ')" Write-Host "" Write-Host "Check cloud-init status after boot:" -ForegroundColor Yellow Write-Host " cloud-init status --wait" Write-Host " cat /var/log/cloud-init-output.log" #endregion #region Cleanup Helper # ============================================================================ # CLEANUP FUNCTION (Run manually if needed) # ============================================================================ <# # To remove the VM and its cloud-init files: $vmToRemove = Get-VergeVM -Name "pstest-cloudinit" if ($vmToRemove) { # Stop the VM first Stop-VergeVM -VM $vmToRemove -Force -Confirm:$false # Remove cloud-init files Get-VergeCloudInitFile -VMId $vmToRemove.Key | Remove-VergeCloudInitFile -Confirm:$false # Remove the VM Remove-VergeVM -VM $vmToRemove -Confirm:$false Write-Host "VM and cloud-init files removed." } #> #endregion |