blip
This commit is contained in:
parent
0dd3b5bdfe
commit
1b9eeb1288
35 changed files with 1274 additions and 0 deletions
33
main.tf
33
main.tf
|
@ -57,3 +57,36 @@ module "poc" {
|
||||||
}
|
}
|
||||||
admin_ssh_public_key = var.ssh_public_key_admin_netboot_server
|
admin_ssh_public_key = var.ssh_public_key_admin_netboot_server
|
||||||
}
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
castopod_domain = "pod.broken-by-design.fr"
|
||||||
|
castopod_upstream_port = 8000
|
||||||
|
}
|
||||||
|
|
||||||
|
module "castopod_config" {
|
||||||
|
source = "./modules/castopod"
|
||||||
|
|
||||||
|
base_url = "https://pod.broken-by-design.fr/"
|
||||||
|
castopod_domain = local.castopod_domain
|
||||||
|
castopod_upstream_port = local.castopod_upstream_port
|
||||||
|
ssh_authorized_keys = [
|
||||||
|
file("/var/home/fmaury/.ssh/fma_ovh_rise2.pub")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
module "caddy_config" {
|
||||||
|
source = "./modules/caddy_reverse"
|
||||||
|
|
||||||
|
vhosts = [
|
||||||
|
{
|
||||||
|
domain = local.castopod_domain
|
||||||
|
upstreams = [
|
||||||
|
"10.109.0.13:${local.castopod_upstream_port}"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
ssh_authorized_keys = [
|
||||||
|
file("/var/home/fmaury/.ssh/fma_ovh_rise2.pub")
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
60
modules/acme_server/main.tf
Normal file
60
modules/acme_server/main.tf
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
proxmox = {
|
||||||
|
source = "bpg/proxmox"
|
||||||
|
version = "~>0.56.1"
|
||||||
|
}
|
||||||
|
ignition = {
|
||||||
|
source = "community-terraform-providers/ignition"
|
||||||
|
version = "2.3.4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required_version = ">=1.6.2"
|
||||||
|
}
|
||||||
|
|
||||||
|
data "ignition_disk" "data" {
|
||||||
|
device = "/dev/disk/by-path/0000:00:0b.0"
|
||||||
|
|
||||||
|
partition {
|
||||||
|
label = "caddy_config"
|
||||||
|
number = 0
|
||||||
|
sizemib = 100
|
||||||
|
startmib = 0
|
||||||
|
type_guid = "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
|
||||||
|
}
|
||||||
|
partition {
|
||||||
|
label = "caddy_data"
|
||||||
|
number = 0
|
||||||
|
sizemib = 1000
|
||||||
|
startmib = 0
|
||||||
|
type_guid = "0FC63DAF-8483-4772-8E79-3D69D8477DE4"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data "ignition_filesystem" "caddy_config" {
|
||||||
|
device = "/dev/disk/by-label/caddy_config"
|
||||||
|
format = "btrfs"
|
||||||
|
wipe_filesystem = true
|
||||||
|
label = "caddy_config"
|
||||||
|
path = "/caddy/config"
|
||||||
|
mount_options = ["nodev", "noexec", "nosuid"]
|
||||||
|
}
|
||||||
|
|
||||||
|
data "ignition_filesystem" "caddy_data" {
|
||||||
|
device = "/dev/disk/by-label/caddy_data"
|
||||||
|
format = "btrfs"
|
||||||
|
wipe_filesystem = true
|
||||||
|
label = "caddy_data"
|
||||||
|
path = "/caddy/data"
|
||||||
|
mount_options = ["nodev", "noexec", "nosuid"]
|
||||||
|
}
|
||||||
|
|
||||||
|
data "ignition_config" "acme_server" {
|
||||||
|
disks = [
|
||||||
|
data.ignition_disk.data.rendered,
|
||||||
|
]
|
||||||
|
filesystems = [
|
||||||
|
data.ignition_filesystem.caddy_config.rendered,
|
||||||
|
data.ignition_filesystem.caddy_data.rendered,
|
||||||
|
]
|
||||||
|
}
|
3
modules/acme_server/outputs.tf
Normal file
3
modules/acme_server/outputs.tf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
output "test" {
|
||||||
|
value = data.ignition_config.acme_server.rendered
|
||||||
|
}
|
5
modules/acme_server/variables.tf
Normal file
5
modules/acme_server/variables.tf
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
variable "fcos_base_vm_id" {
|
||||||
|
type = number
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
25
modules/caddy_reverse/files/Caddyfile.tftpl
Normal file
25
modules/caddy_reverse/files/Caddyfile.tftpl
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
skip_install_trust
|
||||||
|
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
log {
|
||||||
|
output stdout
|
||||||
|
format json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
%{ for vhost in vhosts ~}
|
||||||
|
${vhost.domain} {
|
||||||
|
reverse_proxy {
|
||||||
|
%{ for upstream in vhost.upstreams ~}
|
||||||
|
to https://${upstream}
|
||||||
|
transport http {
|
||||||
|
tls_server_name ${vhost.domain}
|
||||||
|
tls_insecure_skip_verify
|
||||||
|
}
|
||||||
|
%{ endfor ~}
|
||||||
|
%{ for hdr in vhost.headers_down ~}
|
||||||
|
header_down ${hdr.modifier}${hdr.name} "${hdr.value}"
|
||||||
|
%{ endfor ~}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
%{ endfor ~}
|
20
modules/caddy_reverse/files/caddy.container.tftpl
Normal file
20
modules/caddy_reverse/files/caddy.container.tftpl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "Caddy Container"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
ContainerName = caddy
|
||||||
|
Image = docker.io/caddy:${caddy_version}
|
||||||
|
|
||||||
|
Volume = ${caddy_data_volume_name}.volume:/data:z
|
||||||
|
Volume = ${caddy_config_file_path}:/etc/caddy/Caddyfile:ro,z
|
||||||
|
|
||||||
|
Network = ${caddy_network_name}.network
|
||||||
|
|
||||||
|
PublishPort = 80:80
|
||||||
|
PublishPort = 443:443
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
5
modules/caddy_reverse/files/caddy.network.tftpl
Normal file
5
modules/caddy_reverse/files/caddy.network.tftpl
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[Unit]
|
||||||
|
Description = Caddy Network
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
NetworkName = "${caddy_network_name}"
|
11
modules/caddy_reverse/files/caddy_data.volume.tftpl
Normal file
11
modules/caddy_reverse/files/caddy_data.volume.tftpl
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[Unit]
|
||||||
|
Description = Caddy Data Volume
|
||||||
|
|
||||||
|
[Volume]
|
||||||
|
VolumeName = ${caddy_data_volume_name}
|
||||||
|
Device=/dev/disk/by-label/${caddy_data_volume_name}
|
||||||
|
Options=nodev,noexec,nosuid,rootcontext=system_u:object_r:container_file_t:s0
|
||||||
|
Type=ext4
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
151
modules/caddy_reverse/main.tf
Normal file
151
modules/caddy_reverse/main.tf
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
locals {
|
||||||
|
data_device_path = "/dev/vdb"
|
||||||
|
|
||||||
|
caddy_version = "2.8.4-alpine"
|
||||||
|
|
||||||
|
caddy_config_dir_path = "/opt/caddy_config"
|
||||||
|
caddy_data_volume_name = "caddy_data"
|
||||||
|
caddy_network_name = "caddy_net"
|
||||||
|
|
||||||
|
data_disk = {
|
||||||
|
device = local.data_device_path
|
||||||
|
wipeTable = true
|
||||||
|
partitions = [
|
||||||
|
{
|
||||||
|
label = local.caddy_data_volume_name
|
||||||
|
number = 1
|
||||||
|
sizeMiB = 512
|
||||||
|
wipePartitionEntry = true
|
||||||
|
shouldExist = true
|
||||||
|
resize = true
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_data_filesystem = {
|
||||||
|
device = "${local.data_device_path}1"
|
||||||
|
format = "ext4"
|
||||||
|
label = local.caddy_data_volume_name
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_data_volume_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.caddy_data_volume_name}.volume"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/caddy_data.volume.tftpl",
|
||||||
|
{
|
||||||
|
caddy_data_volume_name = local.caddy_data_volume_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_config_directory = {
|
||||||
|
path = local.caddy_config_dir_path
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
}
|
||||||
|
|
||||||
|
caddyfile_file = {
|
||||||
|
path = "${local.caddy_config_dir_path}/Caddyfile"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/Caddyfile.tftpl",
|
||||||
|
{
|
||||||
|
vhosts = var.vhosts
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_network_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.caddy_network_name}.network"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/caddy.network.tftpl",
|
||||||
|
{
|
||||||
|
caddy_network_name = local.caddy_network_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_container_file = {
|
||||||
|
path = "/etc/containers/systemd/caddy.container"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/caddy.container.tftpl",
|
||||||
|
{
|
||||||
|
caddy_version = local.caddy_version
|
||||||
|
caddy_data_volume_name = local.caddy_data_volume_name
|
||||||
|
caddy_config_file_path = "${local.caddy_config_dir_path}/Caddyfile"
|
||||||
|
caddy_network_name = local.caddy_network_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ignition_config = jsonencode({
|
||||||
|
ignition = {
|
||||||
|
version = "3.4.0"
|
||||||
|
}
|
||||||
|
storage = {
|
||||||
|
disks = [
|
||||||
|
local.data_disk,
|
||||||
|
]
|
||||||
|
filesystems = [
|
||||||
|
local.caddy_data_filesystem,
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
local.caddy_data_volume_file,
|
||||||
|
local.caddyfile_file,
|
||||||
|
local.caddy_network_file,
|
||||||
|
local.caddy_container_file,
|
||||||
|
]
|
||||||
|
directories = [
|
||||||
|
local.caddy_config_directory,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
passwd = {
|
||||||
|
users = [
|
||||||
|
{
|
||||||
|
name = "core"
|
||||||
|
sshAuthorizedKeys = var.ssh_authorized_keys
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
3
modules/caddy_reverse/outputs.tf
Normal file
3
modules/caddy_reverse/outputs.tf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
output "config" {
|
||||||
|
value = local.ignition_config
|
||||||
|
}
|
16
modules/caddy_reverse/variables.tf
Normal file
16
modules/caddy_reverse/variables.tf
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
variable "vhosts" {
|
||||||
|
type = list(object({
|
||||||
|
domain = string
|
||||||
|
upstreams = list(string)
|
||||||
|
headers_down = optional(list(object({
|
||||||
|
modifier = optional(string, "")
|
||||||
|
name = string
|
||||||
|
value = string
|
||||||
|
})), [])
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "ssh_authorized_keys" {
|
||||||
|
type = list(string)
|
||||||
|
nullable = false
|
||||||
|
}
|
20
modules/castopod/files/Caddyfile.tftpl
Normal file
20
modules/castopod/files/Caddyfile.tftpl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{
|
||||||
|
skip_install_trust
|
||||||
|
# acme_ca https://acme-staging-v02.api.letsencrypt.org/directory
|
||||||
|
log {
|
||||||
|
output stdout
|
||||||
|
format json
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
${castopod_domain}:8000 {
|
||||||
|
handle_path /media/* {
|
||||||
|
file_server {
|
||||||
|
root /media
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reverse_proxy {
|
||||||
|
to ${castopod_container_name}:8000
|
||||||
|
}
|
||||||
|
tls internal
|
||||||
|
}
|
6
modules/castopod/files/caddy-frontend.network.tftpl
Normal file
6
modules/castopod/files/caddy-frontend.network.tftpl
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[Unit]
|
||||||
|
Description = Caddy Frontend Network
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
NetworkName = "${caddy_frontend_network_name}"
|
||||||
|
Internal = true
|
21
modules/castopod/files/caddy.container.tftpl
Normal file
21
modules/castopod/files/caddy.container.tftpl
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "Caddy Container"
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
ContainerName = "${caddy_container_name}"
|
||||||
|
Image = "docker.io/caddy/caddy:${caddy_version}"
|
||||||
|
|
||||||
|
Volume = ${caddy_config_dir}/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||||
|
Volume = ${castopod_media_volume_name}.volume:/media:z
|
||||||
|
|
||||||
|
Network = ${caddy_frontend_network_name}.network
|
||||||
|
Network = ${castopod_frontend_network_name}.network
|
||||||
|
|
||||||
|
PublishPort=${castopod_upstream_port}:8000
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=on-failure
|
||||||
|
ExecStartPre=/usr/bin/chcon -t container_file_t ${caddy_config_dir}/Caddyfile
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
6
modules/castopod/files/castopod-backend.network.tftpl
Normal file
6
modules/castopod/files/castopod-backend.network.tftpl
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
[Unit]
|
||||||
|
Description = Castopod Backend Network
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
NetworkName = "${castopod_backend_network_name}"
|
||||||
|
Internal = true
|
5
modules/castopod/files/castopod-frontend.network.tftpl
Normal file
5
modules/castopod/files/castopod-frontend.network.tftpl
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
[Unit]
|
||||||
|
Description = Castopod Frontend Network
|
||||||
|
|
||||||
|
[Network]
|
||||||
|
NetworkName = "${castopod_frontend_network_name}"
|
8
modules/castopod/files/castopod-media.volume.tftpl
Normal file
8
modules/castopod/files/castopod-media.volume.tftpl
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "Castopod Media Volume"
|
||||||
|
|
||||||
|
[Volume]
|
||||||
|
VolumeName = ${castopod_media_volume_name}
|
||||||
|
Device=/dev/disk/by-label/${castopod_media_volume_name}
|
||||||
|
Options=nodev,noexec,nosuid,rootcontext=system_u:object_r:container_file_t:s0
|
||||||
|
Type=ext4
|
30
modules/castopod/files/castopod.container.tftpl
Normal file
30
modules/castopod/files/castopod.container.tftpl
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "Castopod Container"
|
||||||
|
|
||||||
|
Wants=generate_secrets.service
|
||||||
|
After=generate_secrets.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
ContainerName = "${castopod_container_name}"
|
||||||
|
Image = "docker.io/castopod/castopod:${castopod_version}"
|
||||||
|
|
||||||
|
Volume = ${castopod_media_volume_name}.volume:/var/www/castopod/public/media:z
|
||||||
|
|
||||||
|
Network = ${castopod_frontend_network_name}.network
|
||||||
|
Network = ${castopod_backend_network_name}.network
|
||||||
|
|
||||||
|
Environment=CP_DATABASE_HOSTNAME=${mariadb_container_name}
|
||||||
|
Environment=CP_DATABASE_NAME=${castopod_db_name}
|
||||||
|
Environment=CP_DATABASE_USERNAME=${castopod_db_user}
|
||||||
|
Environment=CP_BASEURL=${castopod_base_url}
|
||||||
|
Environment=CP_CACHE_HANDLER=redis
|
||||||
|
Environment=CP_REDIS_HOST=${valkey_container_name}
|
||||||
|
EnvironmentFile=${secrets_path}/castopod-mariadb-password.env
|
||||||
|
EnvironmentFile=${secrets_path}/castopod-valkey.env
|
||||||
|
EnvironmentFile=${secrets_path}/castopod-analytics.env
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
20
modules/castopod/files/generate_secrets.service.tftpl
Normal file
20
modules/castopod/files/generate_secrets.service.tftpl
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "Generate Secrets"
|
||||||
|
|
||||||
|
Wants=${secrets_path_escaped}.mount
|
||||||
|
After=${secrets_path_escaped}.mount
|
||||||
|
|
||||||
|
ConditionPathExists=!${secrets_path}/mariadb-root-password.env
|
||||||
|
ConditionPathExists=!${secrets_path}/mariadb-password.env
|
||||||
|
ConditionPathExists=!${secrets_path}/castopod-mariadb-password.env
|
||||||
|
ConditionPathExists=!${secrets_path}/castopod-analytics.env
|
||||||
|
ConditionPathExists=!${secrets_path}/castopod-valkey.env
|
||||||
|
ConditionPathExists=!${secrets_path}/valkey-entrypoint.sh
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
RemainAfterExit=true
|
||||||
|
ExecStart=/bin/bash /var/opt/generate_secrets.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
22
modules/castopod/files/generate_secrets.sh.tftpl
Normal file
22
modules/castopod/files/generate_secrets.sh.tftpl
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -o errexit -o nounset -o pipefail
|
||||||
|
|
||||||
|
umask 7177
|
||||||
|
|
||||||
|
openssl rand -hex 16 | tr -d '\n' > "${secrets_path}/mariadb-root-password.secret"
|
||||||
|
(echo -n 'MARIADB_ROOT_PASSWORD=' ; cat ${secrets_path}/mariadb-root-password.secret) > "${secrets_path}/mariadb-root-password.env"
|
||||||
|
|
||||||
|
openssl rand -hex 16 | tr -d '\n' > "${secrets_path}/castopod-mariadb.secret"
|
||||||
|
(echo -n 'MARIADB_PASSWORD=' ; cat "${secrets_path}/castopod-mariadb.secret") > "${secrets_path}/mariadb-password.env"
|
||||||
|
(echo -n 'CP_DATABASE_PASSWORD=' ; cat "${secrets_path}/castopod-mariadb.secret") > "${secrets_path}/castopod-mariadb-password.env"
|
||||||
|
(echo -n 'CP_ANALYTICS_SALT=' ; openssl rand -base64 16) > "${secrets_path}/castopod-analytics.env"
|
||||||
|
|
||||||
|
openssl rand -hex 16 | tr -d '\n' > "${secrets_path}/castopod-valkey.secret"
|
||||||
|
(echo -n 'CP_REDIS_PASSWORD=' ; cat "${secrets_path}/castopod-valkey.secret") > "${secrets_path}/castopod-valkey.env"
|
||||||
|
|
||||||
|
echo "#!/bin/sh" > '${secrets_path}/valkey-entrypoint.sh'
|
||||||
|
(echo '/usr/local/bin/docker-entrypoint.sh valkey-server --requirepass "' ; cat "${secrets_path}/castopod-valkey.secret" ; echo '"') >> '${secrets_path}/valkey-entrypoint.sh'
|
||||||
|
chown 999 '${secrets_path}/valkey-entrypoint.sh'
|
||||||
|
chmod 700 '${secrets_path}/valkey-entrypoint.sh'
|
||||||
|
chcon -t container_file_t '${secrets_path}/valkey-entrypoint.sh'
|
8
modules/castopod/files/mariadb-data.volume.tftpl
Normal file
8
modules/castopod/files/mariadb-data.volume.tftpl
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "MariaDB data Volume"
|
||||||
|
|
||||||
|
[Volume]
|
||||||
|
VolumeName = ${mariadb_data_volume_name}
|
||||||
|
Device=/dev/disk/by-label/${mariadb_data_volume_name}
|
||||||
|
Options=nodev,noexec,nosuid,rootcontext=system_u:object_r:container_file_t:s0
|
||||||
|
Type=ext4
|
28
modules/castopod/files/mariadb.container.tftpl
Normal file
28
modules/castopod/files/mariadb.container.tftpl
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "MariaDB Container"
|
||||||
|
|
||||||
|
Wants=generate_secrets.service
|
||||||
|
After=generate_secrets.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
ContainerName = "${mariadb_container_name}"
|
||||||
|
Image = "docker.io/mariadb:${mariadb_version}"
|
||||||
|
|
||||||
|
Volume = ${mariadb_data_volume_name}.volume:/var/lib/mysql:z
|
||||||
|
|
||||||
|
Network = ${castopod_backend_network_name}.network
|
||||||
|
|
||||||
|
EnvironmentFile=${secrets_path}/mariadb-root-password.env
|
||||||
|
EnvironmentFile=${secrets_path}/mariadb-password.env
|
||||||
|
Environment=MARIADB_DATABASE=${castopod_db_name}
|
||||||
|
Environment=MARIADB_USER=${castopod_db_user}
|
||||||
|
|
||||||
|
# skips chown that would cause a EPERM on lost+found
|
||||||
|
User=mysql
|
||||||
|
Group=mysql
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
11
modules/castopod/files/secrets.mount.tftpl
Normal file
11
modules/castopod/files/secrets.mount.tftpl
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[Unit]
|
||||||
|
Description = Mountpoint for persistent secrets
|
||||||
|
|
||||||
|
[Mount]
|
||||||
|
What=LABEL=${secrets_part_name}
|
||||||
|
Where=/var/opt/secrets
|
||||||
|
Type=ext4
|
||||||
|
Options=nosuid,nodev
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=local-fs.target
|
25
modules/castopod/files/valkey.container.tftpl
Normal file
25
modules/castopod/files/valkey.container.tftpl
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "Valkey Container"
|
||||||
|
|
||||||
|
Wants=generate_secrets.service
|
||||||
|
After=generate_secrets.service
|
||||||
|
|
||||||
|
[Container]
|
||||||
|
ContainerName = "${valkey_container_name}"
|
||||||
|
Image = "docker.io/valkey/valkey:${valkey_version}"
|
||||||
|
|
||||||
|
Volume = ${secrets_path}/valkey-entrypoint.sh:/usr/local/bin/valkey-entrypoint.sh:ro
|
||||||
|
Volume = ${valkey_cache_volume_name}.volume:/data:z
|
||||||
|
|
||||||
|
Network = ${castopod_backend_network_name}.network
|
||||||
|
Entrypoint=/usr/local/bin/valkey-entrypoint.sh
|
||||||
|
|
||||||
|
# skips find/chown in docker entrypoint which tries to chown lost+found and receive a perm denied
|
||||||
|
User=valkey
|
||||||
|
Group=valkey
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
8
modules/castopod/files/valkey.volume.tftpl
Normal file
8
modules/castopod/files/valkey.volume.tftpl
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
[Unit]
|
||||||
|
Description = "Valkey Cache Volume"
|
||||||
|
|
||||||
|
[Volume]
|
||||||
|
VolumeName = ${valkey_cache_volume_name}
|
||||||
|
Device=/dev/disk/by-label/${valkey_cache_volume_name}
|
||||||
|
Options=nodev,noexec,nosuid,rootcontext=system_u:object_r:container_file_t:s0
|
||||||
|
Type=ext4
|
452
modules/castopod/main.tf
Normal file
452
modules/castopod/main.tf
Normal file
|
@ -0,0 +1,452 @@
|
||||||
|
locals {
|
||||||
|
caddy_frontend_network_name = "caddy-frontend"
|
||||||
|
caddy_container_name = "caddy"
|
||||||
|
caddy_version = "2.9.1-alpine"
|
||||||
|
caddy_config_dir = "/var/opt/caddy"
|
||||||
|
|
||||||
|
castopod_frontend_network_name = "castopod-frontend"
|
||||||
|
castopod_backend_network_name = "castopod-backend"
|
||||||
|
castopod_media_volume_name = "castopod-media"
|
||||||
|
castopod_container_name = "castopod"
|
||||||
|
|
||||||
|
castopod_db_name = "castopod"
|
||||||
|
castopod_db_user = "castopod"
|
||||||
|
castopod_base_url = var.base_url
|
||||||
|
|
||||||
|
valkey_container_name = "valkey"
|
||||||
|
valkey_cache_volume_name = "castopod-cache"
|
||||||
|
|
||||||
|
mariadb_container_name = "mariadb"
|
||||||
|
mariadb_data_volume_name = "castopod-db"
|
||||||
|
mariadb_version = "11.5"
|
||||||
|
|
||||||
|
secrets_part_name = "secrets"
|
||||||
|
secrets_path = "/var/opt/secrets"
|
||||||
|
secrets_path_escaped = "var-opt-secrets"
|
||||||
|
|
||||||
|
data_device_path = "/dev/vdb"
|
||||||
|
|
||||||
|
data_disk = {
|
||||||
|
device = local.data_device_path
|
||||||
|
wipeTable = true
|
||||||
|
partitions = [
|
||||||
|
{
|
||||||
|
label = local.secrets_part_name
|
||||||
|
number = 1
|
||||||
|
sizeMiB = 1024
|
||||||
|
wipePartitionEntry = true
|
||||||
|
shouldExist = true
|
||||||
|
resize = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = local.castopod_media_volume_name
|
||||||
|
number = 2
|
||||||
|
sizeMiB = 20 * 1024
|
||||||
|
wipePartitionEntry = true
|
||||||
|
shouldExist = true
|
||||||
|
resize = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = local.mariadb_data_volume_name
|
||||||
|
number = 3
|
||||||
|
sizeMiB = 5 * 1024
|
||||||
|
wipePartitionEntry = true
|
||||||
|
shouldExist = true
|
||||||
|
resize = true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label = local.valkey_cache_volume_name
|
||||||
|
number = 4
|
||||||
|
sizeMiB = 1024
|
||||||
|
wipePartitionEntry = true
|
||||||
|
shouldExist = true
|
||||||
|
resize = true
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_config_directory = {
|
||||||
|
path = local.caddy_config_dir
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 448 # 0700
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_config_file = {
|
||||||
|
path = "${local.caddy_config_dir}/Caddyfile"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/Caddyfile.tftpl",
|
||||||
|
{
|
||||||
|
castopod_domain = var.castopod_domain
|
||||||
|
castopod_container_name = local.castopod_container_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_frontend_network_file = {
|
||||||
|
path = "/etc/containers/systemd/caddy-frontend.network"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/caddy-frontend.network.tftpl",
|
||||||
|
{
|
||||||
|
caddy_frontend_network_name = local.caddy_frontend_network_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
caddy_container_file = {
|
||||||
|
path = "/etc/containers/systemd/caddy.container"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/caddy.container.tftpl",
|
||||||
|
{
|
||||||
|
caddy_container_name = local.caddy_container_name
|
||||||
|
caddy_version = local.caddy_version
|
||||||
|
caddy_config_dir = local.caddy_config_dir
|
||||||
|
caddy_frontend_network_name = local.caddy_frontend_network_name
|
||||||
|
castopod_frontend_network_name = local.castopod_frontend_network_name
|
||||||
|
castopod_upstream_port = var.castopod_upstream_port
|
||||||
|
castopod_media_volume_name = local.castopod_media_volume_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_secrets_filesystem = {
|
||||||
|
device = "${local.data_device_path}1"
|
||||||
|
format = "ext4"
|
||||||
|
label = local.secrets_part_name
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_secrets_directory = {
|
||||||
|
path = local.secrets_path
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 448 # 0700
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_secrets_mount_unit = {
|
||||||
|
name = "${local.secrets_path_escaped}.mount"
|
||||||
|
enabled = true
|
||||||
|
contents = templatefile(
|
||||||
|
"${path.module}/files/secrets.mount.tftpl",
|
||||||
|
{
|
||||||
|
secrets_part_name = local.secrets_part_name
|
||||||
|
secrets_path = local.secrets_path
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_generate_secrets_script_file = {
|
||||||
|
path = "/var/opt/generate_secrets.sh"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 448 # 0700
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/generate_secrets.sh.tftpl",
|
||||||
|
{
|
||||||
|
secrets_path = local.secrets_path
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_generate_secrets_service_unit = {
|
||||||
|
name = "generate_secrets.service"
|
||||||
|
enabled = true
|
||||||
|
contents = templatefile(
|
||||||
|
"${path.module}/files/generate_secrets.service.tftpl",
|
||||||
|
{
|
||||||
|
secrets_path = local.secrets_path
|
||||||
|
secrets_path_escaped = local.secrets_path_escaped
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_frontend_network_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.castopod_frontend_network_name}.network"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/castopod-frontend.network.tftpl",
|
||||||
|
{
|
||||||
|
castopod_frontend_network_name = local.castopod_frontend_network_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_backend_network_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.castopod_backend_network_name}.network"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/castopod-backend.network.tftpl",
|
||||||
|
{
|
||||||
|
castopod_backend_network_name = local.castopod_backend_network_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_media_volume_filesystem = {
|
||||||
|
device = "${local.data_device_path}2"
|
||||||
|
format = "ext4"
|
||||||
|
label = local.castopod_media_volume_name
|
||||||
|
options = [
|
||||||
|
"-E", "root_owner=33:33",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_media_volume_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.castopod_media_volume_name}.volume"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/castopod-media.volume.tftpl",
|
||||||
|
{
|
||||||
|
castopod_media_volume_name = local.castopod_media_volume_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mariadb_data_volume_filesystem = {
|
||||||
|
device = "${local.data_device_path}3"
|
||||||
|
format = "ext4"
|
||||||
|
label = local.mariadb_data_volume_name
|
||||||
|
options = [
|
||||||
|
"-E", "root_owner=999:999",
|
||||||
|
]
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
mariadb_data_volume_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.mariadb_data_volume_name}.volume"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/mariadb-data.volume.tftpl",
|
||||||
|
{
|
||||||
|
mariadb_data_volume_name = local.mariadb_data_volume_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mariadb_container_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.mariadb_container_name}.container"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/mariadb.container.tftpl",
|
||||||
|
{
|
||||||
|
mariadb_container_name = local.mariadb_container_name
|
||||||
|
mariadb_version = local.mariadb_version
|
||||||
|
mariadb_data_volume_name = local.mariadb_data_volume_name
|
||||||
|
castopod_backend_network_name = local.castopod_backend_network_name
|
||||||
|
castopod_db_name = local.castopod_db_name
|
||||||
|
castopod_db_user = local.castopod_db_user
|
||||||
|
secrets_path = local.secrets_path
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valkey_cache_volume_filesystem = {
|
||||||
|
device = "${local.data_device_path}4"
|
||||||
|
format = "ext4"
|
||||||
|
label = local.valkey_cache_volume_name
|
||||||
|
options = [
|
||||||
|
"-E", "root_owner=999:999",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
valkey_cache_volume_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.valkey_cache_volume_name}.volume"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/valkey.volume.tftpl",
|
||||||
|
{
|
||||||
|
valkey_cache_volume_name = local.valkey_cache_volume_name
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
valkey_container_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.valkey_container_name}.container"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile(
|
||||||
|
"${path.module}/files/valkey.container.tftpl",
|
||||||
|
{
|
||||||
|
valkey_container_name = local.valkey_container_name
|
||||||
|
valkey_version = "8.0-alpine"
|
||||||
|
valkey_cache_volume_name = local.valkey_cache_volume_name
|
||||||
|
castopod_backend_network_name = local.castopod_backend_network_name
|
||||||
|
secrets_path = local.secrets_path
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
castopod_container_file = {
|
||||||
|
path = "/etc/containers/systemd/${local.castopod_container_name}.container"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(
|
||||||
|
templatefile("${path.module}/files/castopod.container.tftpl", {
|
||||||
|
castopod_version = "1.13.2",
|
||||||
|
castopod_container_name = local.castopod_container_name
|
||||||
|
castopod_frontend_network_name = local.castopod_frontend_network_name
|
||||||
|
castopod_backend_network_name = local.castopod_backend_network_name
|
||||||
|
castopod_media_volume_name = local.castopod_media_volume_name
|
||||||
|
castopod_db_name = local.castopod_db_name
|
||||||
|
castopod_db_user = local.castopod_db_user
|
||||||
|
castopod_base_url = var.base_url
|
||||||
|
mariadb_container_name = local.mariadb_container_name
|
||||||
|
valkey_container_name = local.valkey_container_name
|
||||||
|
secrets_path = local.secrets_path
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ignition_config = jsonencode({
|
||||||
|
ignition = {
|
||||||
|
version = "3.4.0"
|
||||||
|
}
|
||||||
|
storage = {
|
||||||
|
disks = [
|
||||||
|
local.data_disk,
|
||||||
|
]
|
||||||
|
filesystems = [
|
||||||
|
local.castopod_secrets_filesystem,
|
||||||
|
local.castopod_media_volume_filesystem,
|
||||||
|
local.mariadb_data_volume_filesystem,
|
||||||
|
local.valkey_cache_volume_filesystem,
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
local.caddy_config_file,
|
||||||
|
local.caddy_frontend_network_file,
|
||||||
|
local.caddy_container_file,
|
||||||
|
local.castopod_generate_secrets_script_file,
|
||||||
|
local.castopod_frontend_network_file,
|
||||||
|
local.castopod_backend_network_file,
|
||||||
|
local.castopod_media_volume_file,
|
||||||
|
local.mariadb_data_volume_file,
|
||||||
|
local.mariadb_container_file,
|
||||||
|
local.valkey_cache_volume_file,
|
||||||
|
local.valkey_container_file,
|
||||||
|
local.castopod_container_file,
|
||||||
|
]
|
||||||
|
directories = [
|
||||||
|
local.caddy_config_directory,
|
||||||
|
local.castopod_secrets_directory,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
systemd = {
|
||||||
|
units = [
|
||||||
|
local.castopod_secrets_mount_unit,
|
||||||
|
local.castopod_generate_secrets_service_unit,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
passwd = {
|
||||||
|
users = [
|
||||||
|
{
|
||||||
|
name = "core"
|
||||||
|
sshAuthorizedKeys = var.ssh_authorized_keys
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
3
modules/castopod/outputs.tf
Normal file
3
modules/castopod/outputs.tf
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
output "config" {
|
||||||
|
value = local.ignition_config
|
||||||
|
}
|
19
modules/castopod/variables.tf
Normal file
19
modules/castopod/variables.tf
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
variable "ssh_authorized_keys" {
|
||||||
|
type = list(string)
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "base_url" {
|
||||||
|
type = string
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "castopod_domain" {
|
||||||
|
type = string
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "castopod_upstream_port" {
|
||||||
|
type = number
|
||||||
|
nullable = false
|
||||||
|
}
|
2
modules/dns_resolver/.gitignore
vendored
Normal file
2
modules/dns_resolver/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
dns_resolver_dhcp_config_*.conf
|
||||||
|
dns_resolver_sftp_script_for_*
|
3
modules/dns_resolver/files/dhcp_config.conf.tftpl
Normal file
3
modules/dns_resolver/files/dhcp_config.conf.tftpl
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
dhcp-host=${mac_address},set:exampletag,${host_ip},example
|
||||||
|
dhcp-option=tag:sampletag,encap:128,2,"${vm_id}.ign"
|
||||||
|
dhcp-option=tag:sampletag,encap:128,3,"/dev/disk/by-path/pci-0000:00:0a.0"
|
168
modules/dns_resolver/main.tf
Normal file
168
modules/dns_resolver/main.tf
Normal file
|
@ -0,0 +1,168 @@
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
proxmox = {
|
||||||
|
source = "bpg/proxmox"
|
||||||
|
version = "~>0.56.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required_version = ">=1.6.2"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
locals {
|
||||||
|
core_user = {
|
||||||
|
name = "core"
|
||||||
|
password_hash = "$6$vDMAZf/yOO6mEbcs$6VE7WD8T9/PeotszMFxatOQxB/rFmLDWsNajg4sI0O47OikSuVpqPjkxRbzcueiXn6rBUY1ubCHlp0nnoZ1VI1"
|
||||||
|
}
|
||||||
|
|
||||||
|
hostname_file = {
|
||||||
|
path = "/etc/hostname"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(var.instance_name)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ignition_configuration = jsonencode({
|
||||||
|
ignition = {
|
||||||
|
version = "3.4.0"
|
||||||
|
}
|
||||||
|
storage = {
|
||||||
|
files = [
|
||||||
|
{
|
||||||
|
path = "/etc/hostname"
|
||||||
|
user = {id = 0}
|
||||||
|
group = {id = 0}
|
||||||
|
mode = 420 # 0644
|
||||||
|
contents = {
|
||||||
|
source = format(
|
||||||
|
"data:text/plain;base64,%s",
|
||||||
|
base64encode(var.instance_name)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
passwd = {
|
||||||
|
users = [
|
||||||
|
local.core_user,
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "random_pet" "config_name" {
|
||||||
|
length = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
locals {
|
||||||
|
generated_ignition_config_file = "${path.module}/dns_resolver_ignition_config_${random_pet.config_name.id}.ign"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "local_file" "sftp_script_for_ignition_file" {
|
||||||
|
content = <<EOT
|
||||||
|
cd writable
|
||||||
|
-rm ${var.pve_vm_id}.ign
|
||||||
|
put ${local.generated_ignition_config_file} ${var.pve_vm_id}.ign
|
||||||
|
EOT
|
||||||
|
filename = "${path.module}/dns_resolver_sftp_script_for_ignition_config_${random_pet.config_name.id}"
|
||||||
|
file_permission = "0644"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "local_file" "dns_resolver_ignition_config" {
|
||||||
|
content = local.ignition_configuration
|
||||||
|
filename = local.generated_ignition_config_file
|
||||||
|
file_permission = "0644"
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = <<EOT
|
||||||
|
sftp -P ${var.netboot_server_sftp_port} \
|
||||||
|
-o ProxyJump=${var.pve_ssh_user}@${var.pve_ssh_host} \
|
||||||
|
-b "${path.module}/dns_resolver_sftp_script_for_ignition_config_${random_pet.config_name.id}" \
|
||||||
|
terraform_ignition@${var.netboot_server_ip_address}
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
lifecycle {
|
||||||
|
replace_triggered_by = [local_file.sftp_script_for_ignition_file]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "local_file" "sftp_script_for_dhcp_config" {
|
||||||
|
content = <<EOT
|
||||||
|
cd writable
|
||||||
|
-rm ${var.pve_vm_id}.conf
|
||||||
|
put ${path.module}/dns_resolver_dhcp_config_${random_pet.config_name.id}.conf ${var.pve_vm_id}.conf
|
||||||
|
EOT
|
||||||
|
filename = "${path.module}/dns_resolver_sftp_script_for_dhcp_config_${random_pet.config_name.id}"
|
||||||
|
file_permission = "0644"
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "local_file" "dhcp_config" {
|
||||||
|
depends_on = [ local_file.sftp_script_for_dhcp_config ]
|
||||||
|
content = templatefile(
|
||||||
|
"${path.module}/files/dhcp_config.conf.tftpl",
|
||||||
|
{
|
||||||
|
vm_id = var.pve_vm_id
|
||||||
|
host_ip = cidrhost(var.prod_network.prefix, var.pve_vm_id)
|
||||||
|
mac_address = var.prod_network.mac_address
|
||||||
|
}
|
||||||
|
)
|
||||||
|
filename = "${path.module}/dns_resolver_dhcp_config_${random_pet.config_name.id}.conf"
|
||||||
|
file_permission = "0644"
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = <<EOT
|
||||||
|
sftp -P ${var.netboot_server_sftp_port} \
|
||||||
|
-o ProxyJump=${var.pve_ssh_user}@${var.pve_ssh_host} \
|
||||||
|
-b "${path.module}/dns_resolver_sftp_script_for_dhcp_config_${random_pet.config_name.id}" \
|
||||||
|
terraform_dhcp@${var.netboot_server_ip_address}
|
||||||
|
EOT
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycle {
|
||||||
|
replace_triggered_by = [local_file.sftp_script_for_dhcp_config ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "proxmox_virtual_environment_vm" "netboot_server" {
|
||||||
|
name = var.instance_name
|
||||||
|
node_name = var.pve_node_name
|
||||||
|
vm_id = var.pve_vm_id
|
||||||
|
|
||||||
|
cpu {
|
||||||
|
architecture = "x86_64"
|
||||||
|
type = "host"
|
||||||
|
sockets = 1
|
||||||
|
cores = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
memory {
|
||||||
|
dedicated = 4096
|
||||||
|
}
|
||||||
|
|
||||||
|
disk {
|
||||||
|
datastore_id = var.pve_storage_id
|
||||||
|
interface = "virtio0"
|
||||||
|
size = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
network_device {
|
||||||
|
bridge = "prod"
|
||||||
|
model = "virtio"
|
||||||
|
mac_address = var.prod_network.mac_address
|
||||||
|
}
|
||||||
|
|
||||||
|
boot_order = ["net0"]
|
||||||
|
|
||||||
|
operating_system {
|
||||||
|
type = "l26"
|
||||||
|
}
|
||||||
|
|
||||||
|
vga {}
|
||||||
|
serial_device{}
|
||||||
|
}
|
0
modules/dns_resolver/outputs.tf
Normal file
0
modules/dns_resolver/outputs.tf
Normal file
70
modules/dns_resolver/variables.tf
Normal file
70
modules/dns_resolver/variables.tf
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
variable "pve_node_name" {
|
||||||
|
type = string
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "pve_storage_id" {
|
||||||
|
type = string
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "pve_vm_id" {
|
||||||
|
type = number
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "pve_ssh_user" {
|
||||||
|
type = string
|
||||||
|
nullable = false
|
||||||
|
default = "root"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "pve_ssh_host" {
|
||||||
|
type = string
|
||||||
|
nullable = false
|
||||||
|
default = "proxmox.broken-by-design.fr"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "netboot_server_ip_address" {
|
||||||
|
type = string
|
||||||
|
nullable = false
|
||||||
|
default = "10.109.0.2"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "netboot_server_sftp_port" {
|
||||||
|
type = number
|
||||||
|
nullable = false
|
||||||
|
default = 2222
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "instance_name" {
|
||||||
|
type = string
|
||||||
|
default = "knot-resolver"
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "admin_network" {
|
||||||
|
type = object({
|
||||||
|
name = string
|
||||||
|
prefix = string
|
||||||
|
mac_address = string
|
||||||
|
})
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "prod_network" {
|
||||||
|
type = object({
|
||||||
|
name = string
|
||||||
|
prefix = string
|
||||||
|
mac_address = string
|
||||||
|
})
|
||||||
|
nullable = false
|
||||||
|
}
|
||||||
|
|
||||||
|
variable "monitoring_network" {
|
||||||
|
type = object({
|
||||||
|
name = string
|
||||||
|
prefix = string
|
||||||
|
mac_address = string
|
||||||
|
})
|
||||||
|
nullable = false
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
output "castopod_config" {
|
||||||
|
value = module.castopod_config.config
|
||||||
|
}
|
||||||
|
|
||||||
|
output "caddy_config" {
|
||||||
|
value = module.caddy_config.config
|
||||||
|
}
|
Loading…
Reference in a new issue