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
+196
-43
No files matched your search
+2
-6
@@ -13,12 +13,8 @@
|
|||||||
crash.log
|
crash.log
|
||||||
crash.*.log
|
crash.*.log
|
||||||
|
|
||||||
# Exclude all .tfvars files, which are likely to contain sensitive data, such as
|
# Secrets (API token, SSH user); see secrets.auto.tfvars.example
|
||||||
# password, private keys, and other secrets. These should not be part of version
|
secrets.auto.tfvars
|
||||||
# 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
|
# Ignore override files as they are usually used to override resources locally and so
|
||||||
# are not checked in
|
# are not checked in
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
# Learning Plattform for Students
|
# Learning Platform for Students
|
||||||
|
|
||||||
## init
|
## init
|
||||||
|
|
||||||
@@ -21,47 +21,32 @@ Build a reliable platform on a pve host to teach students Linux/Windows server a
|
|||||||
|
|
||||||
## User Management
|
## User Management
|
||||||
|
|
||||||
Apart from the pve host, the main core of the environment will be a _FreeIPA_ Server which combines
|
A Windows Server DC/AD is the identity and DNS server of the lab. Each student gets an AD account and is in the group `linux_students` (further groups: `linux_admins`, `linux_users`). Student VMs join the domain.
|
||||||
|
|
||||||
- identity management server (ldap, sso, acl, ...) via a 389 directory server
|
Additional DCs and firewalls/routers are built by the students as exercises.
|
||||||
- DNS server (bind)
|
|
||||||
- NTP server
|
|
||||||
- Kerberos
|
|
||||||
- Dogtag for certificate management
|
|
||||||
- NFS server or 'advertise' one for home folders of all users and other userful shares when needed in an exercise
|
|
||||||
|
|
||||||
|
## Repo layout
|
||||||
|
|
||||||
We will setup user accounts for each student on the ipa server and a home folder for each one which are shared via nfs
|
- `exercises/`: exercise sheets
|
||||||
and automatically mounted on user login on any device in the domain/realm.
|
- `infra/pve/`: PVE host facts, IP plan, one-time setup
|
||||||
The student will always have their files available no matter the device they login with their own account.
|
- `infra/tofu/<role>/`: one OpenTofu root module (and state) per role, e.g. `student-vms`
|
||||||
|
- `infra/sandbox/`: throwaway test VMs (template clones, no OpenTofu)
|
||||||
Define designated groups, `linux_admins`, `linux_students`, `linux_users`, with each its own ACLs mediated via the ipa server.
|
|
||||||
|
|
||||||
|
|
||||||
## Facts
|
## Facts
|
||||||
|
|
||||||
**Domain:**
|
**Domain:** `lab.softbox.net`
|
||||||
|
|
||||||
- domain: `lab.softbox.net`
|
|
||||||
- realm: `LAB.SOFTBOX.NET`
|
|
||||||
- ipa:
|
|
||||||
- hostname: `ipa.lab.softox.net`
|
|
||||||
- ip address: `10.11.12.65/24`
|
|
||||||
|
|
||||||
|
|
||||||
**Students:**
|
**Students:**
|
||||||
|
|
||||||
- username: `firstname.surname`
|
- username: `firstname.surname`
|
||||||
- mail: `firstname.surname@softbox.de`
|
- mail: `firstname.surname@softbox.de`
|
||||||
- user_ssh_public_key: Created in exercise sheet-00
|
- user_ssh_public_key: created in exercise sheet-00
|
||||||
- uid: `1000-1020`
|
- groups: `linux_students`
|
||||||
- gid: `1000-1020`
|
|
||||||
- groups: `linux_students`
|
|
||||||
|
|
||||||
**VMs:**
|
**VMs:**
|
||||||
|
|
||||||
- hostname: `vm_00`
|
- hostname: `vm-00` … `vm-20`
|
||||||
- IP addresses: `10.11.12.200-220`
|
- IP addresses: `10.100.200.80-100` (see [infra/pve/README.md](infra/pve/README.md))
|
||||||
|
|
||||||
## Schedule
|
## Schedule
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,6 @@
|
|||||||
## TODOs
|
## TODOs
|
||||||
|
|
||||||
- [ ] change hostnames and correspondingly the dns entries of the student hosts to `vm_00` -> manage dns via opentofu
|
- [ ] set up the Windows DC/AD `dc01` (`10.100.200.70`, 2 vCPU, 4-8 GB) as identity and DNS server
|
||||||
- [ ] include all users to freeipa and integrate freeipa as main identity and dns server. Deprecate current bind servers -> automate client installation
|
- [ ] switch the student VMs' DNS to the DC and join them to the domain
|
||||||
- [ ] migrate dns zone to freeipa and manage its bind server with opentofu
|
- [ ] create AD accounts and home folders for all students
|
||||||
- [ ] create nfs shares for the home folder of each user
|
|
||||||
- [ ] write loop for student_vm deployment -> they are similar
|
|
||||||
|
|
||||||
- [ ] include automation which install freeipa-client on each vm via opentofu or ansible executed via opentofu
|
|
||||||
- [ ] write nice markdown template for sheets. With better code highlighting and better text formatting
|
- [ ] write nice markdown template for sheets. With better code highlighting and better text formatting
|
||||||
|
|
||||||
@@ -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