This commit is contained in:
Pim Kunis 2023-04-05 16:48:38 +02:00
commit d41794e65d
5 changed files with 182 additions and 0 deletions

View file

@ -0,0 +1,33 @@
#cloud-config
hostname: "${name}"
manage_etc_hosts: true
ssh_pwauth: ${ssh_pwauth}
disable_root: false
ssh_authorized_keys:
%{ for key in admin_authorized_keys ~}
- "${key}"
%{ endfor ~}
%{ if insecure_password }
chpasswd:
list: |
root:root
expire: False
%{ endif }
%{ if use_host_cert }
ssh_keys:
ed25519_private: |
${indent(4, private_key)}
ed25519_certificate: "${host_cert}"
%{ endif}
write_files:
- path: /etc/default/locale
content: |
LC_ALL=en_US.UTF-8
LANG=en_US.UTF-8
- path: /etc/locale.gen
content: |
en_US.UTF-8 UTF-8
runcmd:
- dhclient -r
- dhclient
- locale-gen

12
files/get_cert.sh Executable file
View file

@ -0,0 +1,12 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
CAHOST=root@hermes.dmz
eval "$(jq -r '@sh "PUBKEY=\(.pubkey) HOST=\(.host)"')"
# TODO: Can this be done more eye-pleasingly?
CERT=$(ssh $CAHOST '/root/ca.sh host "'"$PUBKEY"'" "'"$HOST"'".dmz')
jq -n --arg cert "$CERT" '{"cert":$cert}'

7
files/network_config.cfg Normal file
View file

@ -0,0 +1,7 @@
version: 2
ethernets:
ens3:
dhcp4: true
routes:
- to: 0.0.0.0/0
via: 192.168.30.1

94
main.tf Normal file
View file

@ -0,0 +1,94 @@
terraform {
required_providers {
libvirt = {
source = "dmacvicar/libvirt"
}
}
}
locals {
cloudinit_user_data = templatefile("${path.module}/files/cloud_init.cfg.tftpl", {
name = var.name,
ssh_pwauth = true,
admin_authorized_keys = var.admin_authorized_keys,
insecure_password = var.insecure_password,
use_host_cert = var.use_host_cert,
host_cert = trimspace(null_resource.cert.triggers["cert"]),
private_key = tls_private_key.debian.private_key_openssh
})
}
resource "tls_private_key" "debian" {
algorithm = "ED25519"
}
data "tls_public_key" "debian" {
private_key_pem = tls_private_key.debian.private_key_pem
}
data "external" "cert" {
program = ["bash", "${path.module}/files/get_cert.sh"]
query = {
pubkey = trimspace(data.tls_public_key.debian.public_key_openssh)
host = var.name
}
}
resource "null_resource" "cert" {
triggers = {
cert = data.external.cert.result["cert"]
}
lifecycle {
ignore_changes = [
triggers
]
}
}
resource "libvirt_volume" "debian" {
name = "${var.name}.iso"
pool = "disk"
size = var.disk_size
base_volume_name = "debian-bookworm.qcow2"
base_volume_pool = "iso"
lifecycle {
replace_triggered_by = [
libvirt_cloudinit_disk.debian.id
]
}
}
resource "libvirt_cloudinit_disk" "debian" {
name = "${var.name}.iso"
pool = "init"
user_data = local.cloudinit_user_data
network_config = file("${path.module}/files/network_config.cfg")
}
resource "libvirt_domain" "debian" {
name = var.name
memory = var.memory
vcpu = 4
autostart = true
disk {
volume_id = libvirt_volume.debian.id
}
network_interface {
bridge = "dmzbr"
hostname = var.name
mac = var.mac
}
cloudinit = libvirt_cloudinit_disk.debian.id
lifecycle {
replace_triggered_by = [
libvirt_cloudinit_disk.debian.id
]
}
}

36
variables.tf Normal file
View file

@ -0,0 +1,36 @@
variable "name" {
type = string
}
variable "disk_size" {
type = number
default = 1024 * 1024 * 1024 * 15
}
variable "admin_authorized_keys" {
type = list(string)
default = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOodpLr+FDRyKyHjucHizNLVFHZ5AQmE9GmxMnOsSoaw pimkunis@thinkpadpim",
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAINUZp4BCxf7uLa1QWonx/Crf8tYZ5MKIZ+EuaBa82LrV user@user-laptop"
]
}
variable "memory" {
type = number
default = 1024
}
variable "mac" {
type = string
default = null
}
variable "insecure_password" {
type = bool
default = false
}
variable "use_host_cert" {
type = bool
default = true
}