merge with tf-debian-vm

This commit is contained in:
Pim Kunis 2023-05-08 16:06:48 +02:00
parent 124350a906
commit 79b1eed55a
4 changed files with 221 additions and 22 deletions

53
debian/files/cloud_init.cfg.tftpl vendored Normal file
View file

@ -0,0 +1,53 @@
#cloud-config
hostname: "${name}"
manage_etc_hosts: true
disable_root: false
timezone: Europe/Amsterdam
ssh_authorized_keys:
%{ for key in admin_authorized_keys ~}
- "${key}"
%{ endfor ~}
%{ if insecure_password }
chpasswd:
list: |
root:root
expire: False
ssh_pwauth: true
%{ else }
ssh_pwauth: 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
%{ if data_share != "" }
mounts:
- ["data", "${data_share}", "9p", "trans=virtio,rw", "0", "0"]
%{ endif }
%{ if fixed_dns != "" }
manage_resolv_conf: true
resolv_conf:
nameservers:
- "${fixed_dns}"
%{ endif }

17
debian/files/get_cert.sh vendored Executable file
View file

@ -0,0 +1,17 @@
#!/bin/bash
set -euo pipefail
IFS=$'\n\t'
eval "$(jq -r '@sh "PUBKEY=\(.pubkey) HOST=\(.host) CAHOST=\(.cahost) CASCRIPT=\(.cascript) CAKEY=\(.cakey)"')"
# TODO: Can this be done more eye-pleasingly?
set +e
CERT=$(ssh -o ConnectTimeout=3 -o ConnectionAttempts=1 root@$CAHOST '"'"$CASCRIPT"'" host "'"$CAKEY"'" "'"$PUBKEY"'" "'"$HOST"'".dmz')
retval=$?
set -e
if [ retval -neq 0 ]; then
CERT=""
fi
jq -n --arg cert "$CERT" '{"cert":$cert}'

16
debian/files/network_config.cfg.tftpl vendored Normal file
View file

@ -0,0 +1,16 @@
version: 2
ethernets:
ens:
match:
name: ens*
%{ if fixed_address != "" }
dhcp4: false
addresses:
- "${fixed_address}"
%{ else }
dhcp4: true
%{ endif }
dhcp4: true
routes:
- to: 0.0.0.0/0
via: 192.168.30.1

147
debian/main.tf vendored
View file

@ -10,27 +10,140 @@ module "invariants" {
source = "git::https://git.pim.kunis.nl/home/tf-modules.git//invariants"
}
module "tf_debian_vm" {
source = "git::https://git.pim.kunis.nl/pim/tf-debian-vm.git"
name = var.name
domain_name = var.domain_name
locals {
admin_authorized_keys = coalesce(var.admin_authorized_keys, module.invariants.admin_authorized_keys)
insecure_password = var.insecure_password
use_host_cert = var.use_host_cert
cloudinit_user_data = templatefile("${path.module}/files/cloud_init.cfg.tftpl", {
name = var.name,
admin_authorized_keys = local.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,
fixed_dns = var.fixed_dns
data_share = var.data_share
})
cloudinit_network_config = templatefile("${path.module}/files/network_config.cfg.tftpl", {
fixed_address = var.fixed_address
})
domain_name = coalesce(var.domain_name, var.name)
disk_pool = coalesce(var.disk_pool, module.invariants.disk_pool)
disk_base = coalesce(var.disk_base, module.invariants.disk_base)
disk_base_pool = coalesce(var.disk_base_pool, module.invariants.disk_base_pool)
cloudinit_pool = coalesce(var.cloudinit_pool, module.invariants.cloudinit_pool)
bridge_name = coalesce(var.bridge_name, module.invariants.bridge_name)
ca_host = module.invariants.ca_host
ca_script = module.invariants.ca_script
ca_key = var.ca_key
memory = var.memory
fixed_address = var.fixed_address
ansible_command = var.ansible_command
mac = var.mac
fixed_dns = var.fixed_dns
disk_size = var.disk_size
data_share = var.data_share
hypervisor_host = var.hypervisor_host
}
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
cahost = module.invariants.ca_host
cascript = module.invariants.ca_script
cakey = var.ca_key
}
}
resource "null_resource" "cert" {
triggers = {
cert = data.external.cert.result["cert"]
}
lifecycle {
ignore_changes = [
triggers
]
postcondition {
condition = data.external.cert.result["cert"] != "" || !var.use_host_cert
error_message = "Error retrieving host certificate."
}
}
}
resource "libvirt_volume" "debian" {
name = "${local.domain_name}.iso"
pool = local.disk_pool
size = var.disk_size
base_volume_name = local.disk_base
base_volume_pool = local.disk_base_pool
lifecycle {
replace_triggered_by = [
libvirt_cloudinit_disk.debian.id
]
}
}
resource "libvirt_cloudinit_disk" "debian" {
name = "${local.domain_name}.iso"
pool = local.cloudinit_pool
user_data = local.cloudinit_user_data
network_config = local.cloudinit_network_config
}
resource "null_resource" "data_share" {
connection {
type = "ssh"
user = "root"
host = var.hypervisor_host
}
provisioner "remote-exec" {
inline = [
"if [ \"${var.data_share}\" != \"\"; then mkdir -p --mode=og=rwx /data/${local.domain_name}; fi"
]
}
}
resource "libvirt_domain" "debian" {
name = local.domain_name
memory = var.memory
vcpu = 4
autostart = true
disk {
volume_id = libvirt_volume.debian.id
}
dynamic "filesystem" {
for_each = var.data_share != "" ? [1] : []
content {
source = "/data/${local.domain_name}"
target = "data"
readonly = false
}
}
network_interface {
bridge = local.bridge_name
hostname = var.name
mac = var.mac
}
cloudinit = libvirt_cloudinit_disk.debian.id
provisioner "local-exec" {
command = var.ansible_command
}
lifecycle {
replace_triggered_by = [
libvirt_cloudinit_disk.debian.id
]
}
depends_on = [
null_resource.data_share
]
}