Add first attempt at libvirt project
parent
c0f20a18fc
commit
4fbbcb99b2
|
|
@ -0,0 +1,71 @@
|
||||||
|
# Local .terraform directories
|
||||||
|
**/.terraform/*
|
||||||
|
|
||||||
|
# .tfstate files
|
||||||
|
*.tfstate
|
||||||
|
*.tfstate.*
|
||||||
|
|
||||||
|
# Crash log files
|
||||||
|
crash.log
|
||||||
|
crash.*.log
|
||||||
|
|
||||||
|
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
|
||||||
|
# password, private keys, and other secrets. These should not be part of version
|
||||||
|
# control as they are data points which are potentially sensitive and subject
|
||||||
|
# to change depending on the environment.
|
||||||
|
*.tfvars
|
||||||
|
*.tfvars.json
|
||||||
|
|
||||||
|
# Ignore override files as they are usually used to override resources locally and so
|
||||||
|
# are not checked in
|
||||||
|
override.tf
|
||||||
|
override.tf.json
|
||||||
|
*_override.tf
|
||||||
|
*_override.tf.json
|
||||||
|
|
||||||
|
# Include override files you do wish to add to version control using negated pattern
|
||||||
|
# !example_override.tf
|
||||||
|
|
||||||
|
# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan
|
||||||
|
# example: *tfplan*
|
||||||
|
|
||||||
|
# Ignore CLI configuration files
|
||||||
|
.terraformrc
|
||||||
|
terraform.rc
|
||||||
|
|
||||||
|
# OpenTofu specific
|
||||||
|
.tofu/
|
||||||
|
*.tofu.lock.hcl
|
||||||
|
|
||||||
|
# IDE and Editor files
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# SSH keys (if any are generated locally)
|
||||||
|
*.pem
|
||||||
|
*.key
|
||||||
|
id_rsa*
|
||||||
|
*.pub
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# Backup files
|
||||||
|
*.backup
|
||||||
|
*.bak
|
||||||
|
|
||||||
|
# Temporary files
|
||||||
|
*.tmp
|
||||||
|
*.temp
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
# This file is maintained automatically by "tofu init".
|
||||||
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
|
provider "registry.opentofu.org/dmacvicar/libvirt" {
|
||||||
|
version = "0.7.6"
|
||||||
|
constraints = "~> 0.7.0"
|
||||||
|
hashes = [
|
||||||
|
"h1:mmbm4vTyC/DCGO4Ed/vbp5AKvy1gmVn/94fzB9VmR08=",
|
||||||
|
"zh:0bde54f6f658b20b620b875daf106b5b25b1bae4d15408d6c5f06d58360e254d",
|
||||||
|
"zh:0c97c6930015918b8a34b6d7a2b0c3d17a649c226fcd1874fcba5bbbc0f35972",
|
||||||
|
"zh:1bdd7aa0011c5f024a09a124836ee9bc8e71b05a6ece810c61824275fd3f695f",
|
||||||
|
"zh:2b0cc7c794e4caf395d84ffff0b380d17e4b3219a4696264271bfe5059450efe",
|
||||||
|
"zh:2f8633f7fe07f76c188836ed6f93321ec5fbf5c004bc7699e1741d9b21ed5f37",
|
||||||
|
"zh:5bf47eed286ce55ed10a5cf657de49a34ab21cc8677c56fef3aab69cdde41a27",
|
||||||
|
"zh:7dca790fc5fd1d42bc4bc7170be003a7093602026d0f95c8aab84ad551fdf2a4",
|
||||||
|
"zh:80476b68bc84e3d661d1390025f83879b88f9cdc836de9751af09bd5716089cb",
|
||||||
|
"zh:82f3e2f3f50176cd6041c8ba36e295cbda1b289ef52ab75b5eceb0f921f64f7b",
|
||||||
|
"zh:a179b165f3b9bb9a67ebbbf9d73157ded33f02d476b2f58906389dca03b653c9",
|
||||||
|
"zh:acae54a5d0616f22b3180ddd8e8aad39af664e604394fdacf1f7b337bca2d5b4",
|
||||||
|
"zh:da4406a2428a9a7e98272c032cb93431c3919253af2fe9934b532d26c0deab09",
|
||||||
|
"zh:f63dbd8e579ab5268d01ffab4503b8a8e736b70d1a04e4f271559ba8dd133dcd",
|
||||||
|
"zh:f85c1d9e51a94ecde137435c9d6b0fb7be590437ea8a725334d1577eebbc550c",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
# VM Infrastructure with OpenTofu + LibVirt
|
||||||
|
|
||||||
|
This project provisions virtual machines using OpenTofu and LibVirt.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Initialize OpenTofu
|
||||||
|
tofu init
|
||||||
|
|
||||||
|
# Plan deployment
|
||||||
|
tofu plan
|
||||||
|
|
||||||
|
# Deploy VMs
|
||||||
|
tofu apply
|
||||||
|
|
||||||
|
# Get VM IPs
|
||||||
|
tofu output vm_ips
|
||||||
|
|
||||||
|
# Destroy infrastructure when done
|
||||||
|
tofu destroy
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
- **VMs**: 3 Ubuntu 22.04 VMs with 4GB RAM, 2 vCPUs, 30GB disk each
|
||||||
|
- **Authentication**: SSH key-based (no password auth)
|
||||||
|
- **User**: `ubuntu` with sudo access
|
||||||
|
- **Network**: Default libvirt network with DHCP
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
- `main.tf` - Main infrastructure configuration
|
||||||
|
- `variables.tf` - Input variables
|
||||||
|
- `outputs.tf` - Output values (VM IPs and names)
|
||||||
|
- `terraform.tfvars` - Variable values
|
||||||
|
- `cloud-init/` - VM initialization configuration
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
1. Install LibVirt and OpenTofu (see main PLAN.md)
|
||||||
|
2. Ensure your SSH public key is in `cloud-init/user-data.yaml`
|
||||||
|
3. User must be in `libvirt` group
|
||||||
|
|
||||||
|
## Accessing VMs
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# SSH to VM (replace with actual IP)
|
||||||
|
ssh ubuntu@192.168.122.100
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
instance-id: vm-instance
|
||||||
|
local-hostname: vm-host
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
#cloud-config
|
||||||
|
users:
|
||||||
|
- name: ubuntu
|
||||||
|
groups: sudo
|
||||||
|
shell: /bin/bash
|
||||||
|
sudo: ['ALL=(ALL) NOPASSWD:ALL']
|
||||||
|
ssh_authorized_keys:
|
||||||
|
- ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDE0jo1NZHqhXNPmWZ8x0wdFDfDiloSLfZL0NK/DbukhF3WN5hSn/6Vv6Qa6USpq1S3XiaBL7pA+zrTZGr/ZH6iZKDelYufU1a22dWx6OYKVX84d/wIc+3PHAFm1A5g3+787pT+6HHH4g7GKmf1/zYJlfqPr5zyGVBdQkzglDadC7wdfwGE7Q3gjHflhAIyGvcBfAQ/hYQSgWAMdsYhthh1DCMvPQIqA0E2tslgD1AtpDhjE72a+pLAsGxDjiBcuKW4SEAjcxt+Jcu10brrXAbt5bHg9SNk/NNwwMZVy0siAJRRcg6Dv41VqMa2MvIGoDUiDju4kRwjJMcxorwxAa8n jlkenyon@helios.local
|
||||||
|
|
||||||
|
packages:
|
||||||
|
- curl
|
||||||
|
- wget
|
||||||
|
- git
|
||||||
|
- htop
|
||||||
|
|
||||||
|
package_update: true
|
||||||
|
package_upgrade: true
|
||||||
|
|
||||||
|
# Set timezone
|
||||||
|
timezone: UTC
|
||||||
|
|
||||||
|
# Enable SSH
|
||||||
|
ssh_pwauth: false
|
||||||
|
|
||||||
|
# Run commands on first boot
|
||||||
|
runcmd:
|
||||||
|
- systemctl enable ssh
|
||||||
|
- systemctl start ssh
|
||||||
|
- echo "VM provisioned successfully" > /tmp/provision-complete
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
libvirt = {
|
||||||
|
source = "dmacvicar/libvirt"
|
||||||
|
version = "~> 0.7.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Configure the LibVirt Provider
|
||||||
|
provider "libvirt" {
|
||||||
|
uri = "qemu:///system"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Download Ubuntu cloud image
|
||||||
|
resource "libvirt_volume" "base_image" {
|
||||||
|
name = "ubuntu-22.04-base.qcow2"
|
||||||
|
pool = var.pool_name
|
||||||
|
source = "https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img"
|
||||||
|
format = "qcow2"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create cloud-init disk
|
||||||
|
resource "libvirt_cloudinit_disk" "cloudinit" {
|
||||||
|
name = "cloudinit.iso"
|
||||||
|
pool = var.pool_name
|
||||||
|
user_data = file("${path.module}/cloud-init/user-data.yaml")
|
||||||
|
meta_data = file("${path.module}/cloud-init/meta-data.yaml")
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create VM volumes from base image
|
||||||
|
resource "libvirt_volume" "vm_disk" {
|
||||||
|
count = var.vm_count
|
||||||
|
name = "vm-${count.index + 1}-disk.qcow2"
|
||||||
|
pool = var.pool_name
|
||||||
|
base_volume_id = libvirt_volume.base_image.id
|
||||||
|
size = var.disk_size
|
||||||
|
}
|
||||||
|
|
||||||
|
# Create VMs
|
||||||
|
resource "libvirt_domain" "vm" {
|
||||||
|
count = var.vm_count
|
||||||
|
name = "vm-${count.index + 1}"
|
||||||
|
memory = var.memory
|
||||||
|
vcpu = var.vcpu
|
||||||
|
|
||||||
|
cloudinit = libvirt_cloudinit_disk.cloudinit.id
|
||||||
|
|
||||||
|
network_interface {
|
||||||
|
network_name = "default"
|
||||||
|
wait_for_lease = true
|
||||||
|
}
|
||||||
|
|
||||||
|
disk {
|
||||||
|
volume_id = libvirt_volume.vm_disk[count.index].id
|
||||||
|
}
|
||||||
|
|
||||||
|
console {
|
||||||
|
type = "pty"
|
||||||
|
target_port = "0"
|
||||||
|
target_type = "serial"
|
||||||
|
}
|
||||||
|
|
||||||
|
graphics {
|
||||||
|
type = "spice"
|
||||||
|
listen_type = "address"
|
||||||
|
autoport = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
output "vm_ips" {
|
||||||
|
description = "IP addresses of the created VMs"
|
||||||
|
value = {
|
||||||
|
for i, vm in libvirt_domain.vm : vm.name => vm.network_interface[0].addresses[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output "vm_names" {
|
||||||
|
description = "Names of the created VMs"
|
||||||
|
value = libvirt_domain.vm[*].name
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
variable "pool_name" {
|
||||||
|
description = "Name of the storage pool"
|
||||||
|
type = string
|
||||||
|
default = "vm-pool"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "pool_path" {
|
||||||
|
description = "Path to the storage pool"
|
||||||
|
type = string
|
||||||
|
default = "/var/lib/libvirt/images/vm-pool"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vm_count" {
|
||||||
|
description = "Number of VMs to create"
|
||||||
|
type = number
|
||||||
|
default = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "memory" {
|
||||||
|
description = "Memory allocation for each VM (MB)"
|
||||||
|
type = number
|
||||||
|
default = 2048
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "vcpu" {
|
||||||
|
description = "Number of vCPUs for each VM"
|
||||||
|
type = number
|
||||||
|
default = 2
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "disk_size" {
|
||||||
|
description = "Disk size for each VM (bytes)"
|
||||||
|
type = number
|
||||||
|
default = 21474836480 # 20GB
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue