Add infra/ with student-vms OpenTofu root module
- infra/pve: host facts, IP plan, one-time setup - infra/tofu/student-vms: 3 student VMs via tf-mod-pve v1.0.0 - infra/sandbox: template clones for throwaway test VMs - README/TODO: Windows DC/AD instead of FreeIPA, new network - .gitignore: only ignore secrets.auto.tfvars instead of all tfvars Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2dfa8de5c6
commit
91ed0b300c
12 files changed
+197
-44
No files matched your search
@@ -0,0 +1,41 @@
|
||||
# PVE host
|
||||
|
||||
- Host: `pve` (`10.100.200.50`), Proxmox VE 9.2, 6 cores, 31 GiB RAM
|
||||
- Storage: `local` (dir: ISOs, snippets), `local-lvm` (VM disks)
|
||||
- Network: `vmbr0` on `10.100.200.0/24`, gateway and current DNS `10.100.200.4`
|
||||
- Templates: `903` `temp-debian-13`
|
||||
|
||||
## IP plan (10.100.200.0/24)
|
||||
|
||||
| Address | Use | Size |
|
||||
|---|---|---|
|
||||
| `.4` | Gateway, current DNS | |
|
||||
| `.50` | PVE host | |
|
||||
| `.70` | DC/AD `dc01.lab.softbox.net` (planned) | 2 vCPU, 4-8 GB |
|
||||
| `.80-.100` | Student VMs (`vm-00`, …), VMID `1080-1100`, 5-10 planned | 1 vCPU, 1 GB |
|
||||
| `.101-.211` | In use by other devices (probably DHCP) | |
|
||||
|
||||
## One-time setup (as root, done)
|
||||
|
||||
```bash
|
||||
# 1. Allow snippets on local storage
|
||||
pvesm set local --content iso,vztmpl,backup,import,snippets
|
||||
|
||||
# 2. API user and token for OpenTofu; put the printed value into
|
||||
# infra/tofu/<role>/secrets.auto.tfvars as pve_api_token = "tofu@pve!tofu=<value>"
|
||||
pveum user add tofu@pve --comment "OpenTofu"
|
||||
pveum aclmod / -user tofu@pve -role PVEAdmin
|
||||
pveum user token add tofu@pve tofu --privsep 0
|
||||
|
||||
# 3. sudo for sbxadmin; passwordless rules for the snippet upload of the bpg/proxmox provider
|
||||
usermod -aG sudo sbxadmin
|
||||
cat > /etc/sudoers.d/sbxadmin-tofu <<'EOF'
|
||||
sbxadmin ALL=(root) NOPASSWD: /usr/sbin/pvesm apiinfo
|
||||
sbxadmin ALL=(root) NOPASSWD: /usr/bin/tee ^/var/lib/vz/snippets/[a-zA-Z0-9_][a-zA-Z0-9_.-]*$
|
||||
EOF
|
||||
chmod 440 /etc/sudoers.d/sbxadmin-tofu && visudo -c
|
||||
|
||||
# 4. Templates: tf-mod-pve/scripts/create_template.sh, copied to /root/templates/ with
|
||||
# storage=local-lvm, ssh_keyfile=/root/.ssh/authorized_keys, only temp-debian-13 enabled
|
||||
cd /root/templates && bash create_template.sh
|
||||
```
|
||||
@@ -0,0 +1,13 @@
|
||||
# sandbox
|
||||
|
||||
Throwaway test VMs, not managed by OpenTofu. Clone a template on the PVE host (as root), use VMIDs `9990-9999`:
|
||||
|
||||
```bash
|
||||
qm clone 903 9991 --name test-01 --full
|
||||
qm set 9991 --ipconfig0 ip=dhcp
|
||||
qm start 9991
|
||||
# done testing
|
||||
qm stop 9991 && qm destroy 9991
|
||||
```
|
||||
|
||||
Login: `ssh admin@<ip>` (IP via `qm guest cmd 9991 network-get-interfaces`).
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
# This file is maintained automatically by "tofu init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/bpg/proxmox" {
|
||||
version = "0.118.1"
|
||||
constraints = ">= 0.118.0, ~> 0.118"
|
||||
hashes = [
|
||||
"h1:/tyENGiIdJgBVlcOQOyHaBmLyQEoogFnTTMN+GJ6ayE=",
|
||||
"h1:057hFYAlLv2HcjHR7TVoNnDmm57YWNZDNqhDvv6PS7I=",
|
||||
"h1:CxLdcddSmTqP00oYkvWdN6d+qQSDTOhDzbM2/FzCPbY=",
|
||||
"h1:E1uc/cddGUBfnYyLOxnmqpzd6yLL4RKHqZJVxRMn/DA=",
|
||||
"h1:G34GMrwG/FejGMTxwJYKx4tghadFA+xqtrF40FbyOG8=",
|
||||
"h1:M1nzf28WMPzm4p9sUJGrAUOcqfDyQwRjRIpFMaHzo+Q=",
|
||||
"h1:MeUGboRbtAzb07dgljVCzUmU5hJ8BOfHBQOOtFzNziU=",
|
||||
"h1:OCF6iuMldDOqn52ULPf22IJb0Ni3GFx6HdoiTAPIb3M=",
|
||||
"h1:f46bI0fO0leCFEkYdEVcRrsjAAtSFEN6yZKu2fZymTI=",
|
||||
"h1:fhAY0NwBwBBu/qUeTb1lAd3a7bffgouILhhjUNNNXCk=",
|
||||
"h1:gaCA8Ez8zV/OXIVWIE1B11iQmKH7gILdn7Vm9KSRrbU=",
|
||||
"h1:r52a2cEQ7ftGS1G6vHFMqWI6Bg6o0F/T5BsShH8O2DQ=",
|
||||
"h1:wAD5hFQpgEptQYR5UK8Hbh8WoTcMGnRCxehLqN+3f9w=",
|
||||
"zh:07405857f3dda91d1a065b0349547920f4f9b58ec214b19f7e54a07d776c1f88",
|
||||
"zh:0bd362db77c5971fe0e92b0faf57ed9b50062d4321b5c7a09f492c57dffecb19",
|
||||
"zh:2cb31f9d4ad2ae90f72f87e3cb77c2f745acbe4b17822821c385612647ea178d",
|
||||
"zh:2e63ff741101e173feafb133f96273634831322984939115396763b6f860706b",
|
||||
"zh:787bdda1b4e0924c334acebeb7491966b8e611aaa8e542ec003cb8cbfd9081f4",
|
||||
"zh:7f2ece41d81a24988f5a357684b2b323cc5165022434e7f91e5a29f10a4182c7",
|
||||
"zh:9a1e263e4111105c14ed1dc44a5c4e45f00f0f88cb726d16388771c1cdd9b26d",
|
||||
"zh:a2c1ae4950667bdc0f023f3d12d175fec3cf1a809c4d990cf72f0a200606f6f8",
|
||||
"zh:abd342c9153e712a8542b0fd03f6a0b25f954573184dfe8f5b05b08b1e26e254",
|
||||
"zh:b5cc543d31183a63c782af7fab9a4a203b4eebf782db13af94ae65c9b7d51373",
|
||||
"zh:befeb50e7346802d3c222541e91a06093933990acdfc89cf93364615fdac91c4",
|
||||
"zh:d164da80b3f3339549942a3131b0717f14798ed514e8362c76874b68feba89f8",
|
||||
"zh:dc265c6e4c3e656e014c524b50e0ff02761070cb9db7cb24f7b0ab57c12b9e97",
|
||||
"zh:f26e0763dbe6a6b2195c94b44696f2110f7f55433dc142839be16b9697fa5597",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
# student-vms
|
||||
|
||||
One Debian 13 VM per student (`vm-00`, `vm-01`, …, IPs `10.100.200.80-100`), created with [tf-mod-pve](https://github.com/CubelaPetar/tf-mod-pve). The VM list is in `vms.tf`.
|
||||
|
||||
Prerequisites: host setup from [`../../pve/README.md`](../../pve/README.md) and your SSH key authorized for `sbxadmin` on the host.
|
||||
|
||||
```bash
|
||||
ssh-add ~/.ssh/id_ed25519 # provider uploads snippets via ssh-agent
|
||||
cp secrets.auto.tfvars.example secrets.auto.tfvars # fill in the API token
|
||||
tofu init
|
||||
tofu plan
|
||||
tofu apply
|
||||
```
|
||||
|
||||
State is local (`terraform.tfstate`, gitignored). Back it up.
|
||||
@@ -0,0 +1,11 @@
|
||||
provider "proxmox" {
|
||||
endpoint = "https://10.100.200.50:8006/"
|
||||
api_token = var.pve_api_token
|
||||
insecure = true # self-signed certificate
|
||||
|
||||
# Used to upload the cloud-init snippets, key comes from the ssh-agent
|
||||
ssh {
|
||||
agent = true
|
||||
username = var.pve_ssh_user
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Copy to secrets.auto.tfvars (gitignored) and fill in
|
||||
pve_api_token = "tofu@pve!tofu=<secret>"
|
||||
pve_ssh_user = "sbxadmin"
|
||||
@@ -0,0 +1,16 @@
|
||||
variable "pve_api_token" {
|
||||
type = string
|
||||
description = "Proxmox API token, e.g. tofu@pve!tofu=<secret>"
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "pve_ssh_user" {
|
||||
type = string
|
||||
description = "SSH user on the PVE host for the snippet upload"
|
||||
}
|
||||
|
||||
variable "ssh_public_key_file" {
|
||||
type = string
|
||||
description = "Public key added to the VM user admin"
|
||||
default = "~/.ssh/id_ed25519.pub"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
terraform {
|
||||
required_version = ">= 1.10"
|
||||
|
||||
required_providers {
|
||||
proxmox = {
|
||||
source = "bpg/proxmox"
|
||||
version = "~> 0.118"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
# One VM per student: hostname => VMID and IP (10.100.200.80-100)
|
||||
locals {
|
||||
vms = {
|
||||
"vm-00" = { vm_id = 1080, ip = "10.100.200.80" }
|
||||
"vm-01" = { vm_id = 1081, ip = "10.100.200.81" }
|
||||
"vm-02" = { vm_id = 1082, ip = "10.100.200.82" }
|
||||
}
|
||||
}
|
||||
|
||||
module "vm" {
|
||||
source = "git::https://github.com/CubelaPetar/tf-mod-pve.git?ref=v1.0.0"
|
||||
for_each = local.vms
|
||||
|
||||
node_name = "pve"
|
||||
vm_id = each.value.vm_id
|
||||
template_vm_id = 903 # temp-debian-13
|
||||
hostname = each.key
|
||||
domain = "lab.softbox.net"
|
||||
tags = ["student"]
|
||||
ssh_public_key = file(pathexpand(var.ssh_public_key_file))
|
||||
|
||||
cpu_cores = 1
|
||||
memory = 1024
|
||||
storage = "local-lvm"
|
||||
disk_size = 16
|
||||
|
||||
net_bridge = "vmbr0"
|
||||
ip_address = "${each.value.ip}/24"
|
||||
gateway = "10.100.200.4"
|
||||
# Current resolver until the DC/AD takes over DNS
|
||||
nameservers = ["10.100.200.4"]
|
||||
}
|
||||
Reference in new issue
Block a user