Also begin adding rust building capabilities to be able to write rust binaries for some commands.
242 lines
6.6 KiB
Nix
242 lines
6.6 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
inputs,
|
|
pkgs,
|
|
...
|
|
}:
|
|
let
|
|
cfg = config.khscodes.hetzner-instance;
|
|
fqdn = config.khscodes.fqdn;
|
|
firewallTcpRules = lib.lists.map (p: {
|
|
direction = "in";
|
|
protocol = "tcp";
|
|
port = p;
|
|
source_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
}) config.networking.firewall.allowedTCPPorts;
|
|
firewallUdpRules = lib.lists.map (p: {
|
|
direction = "in";
|
|
protocol = "udp";
|
|
port = p;
|
|
source_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
}) config.networking.firewall.allowedUDPPorts;
|
|
firewallIcmpRules = lib.lists.optional config.networking.firewall.allowPing {
|
|
direction = "in";
|
|
protocol = "icmp";
|
|
source_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "ping";
|
|
};
|
|
firewallRules = firewallTcpRules ++ firewallUdpRules ++ firewallIcmpRules ++ cfg.extraFirewallRules;
|
|
firewallEnable = config.networking.firewall.enable;
|
|
tldFromFqdn =
|
|
fqdn:
|
|
let
|
|
split = lib.strings.splitString "." fqdn;
|
|
in
|
|
if lib.lists.length split < 3 then
|
|
fqdn
|
|
else
|
|
lib.strings.removePrefix "${builtins.head split}." fqdn;
|
|
in
|
|
{
|
|
options.khscodes.hetzner-instance = {
|
|
enable = lib.mkEnableOption "enables generating a opentofu config";
|
|
dnsNames = lib.mkOption {
|
|
type = lib.types.listOf lib.types.str;
|
|
description = "DNS names for the server";
|
|
default = [ fqdn ];
|
|
};
|
|
bucket = {
|
|
key = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Key for use in the bucket";
|
|
default = "${fqdn}.tfstate";
|
|
};
|
|
};
|
|
secretsSource = lib.mkOption {
|
|
type = lib.types.enum [
|
|
"bitwarden"
|
|
"vault"
|
|
];
|
|
description = "Whether to load opentofu secrets from Bitwarden or Vault";
|
|
default = "vault";
|
|
};
|
|
datacenter = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "The Hetzner datacenter to create a server in";
|
|
default = "hel1-dc2";
|
|
};
|
|
output = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.package;
|
|
description = "The terranix package built from the configuration";
|
|
default = null;
|
|
};
|
|
mapRdns = lib.mkOption {
|
|
type = lib.types.bool;
|
|
description = "Sets up RDNS for the server";
|
|
default = false;
|
|
};
|
|
server_type = lib.mkOption {
|
|
type = lib.types.nullOr lib.types.str;
|
|
description = "The server type to create";
|
|
default = null;
|
|
};
|
|
extraFirewallRules = lib.mkOption {
|
|
type = lib.types.listOf lib.types.attrs;
|
|
description = "Extra firewall rules added to the instance";
|
|
default = [
|
|
{
|
|
direction = "out";
|
|
protocol = "tcp";
|
|
port = 80;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "http";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "tcp";
|
|
port = 443;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "https";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "udp";
|
|
port = 443;
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "quic";
|
|
}
|
|
{
|
|
direction = "out";
|
|
protocol = "icmp";
|
|
destination_ips = [
|
|
"0.0.0.0/0"
|
|
"::/0"
|
|
];
|
|
description = "Ping";
|
|
}
|
|
];
|
|
};
|
|
};
|
|
config = lib.mkIf cfg.enable (
|
|
let
|
|
labels = {
|
|
app = fqdn;
|
|
};
|
|
modules = [
|
|
(
|
|
{ config, ... }:
|
|
{
|
|
imports = [
|
|
inputs.self.terranixModules.cloudflare
|
|
inputs.self.terranixModules.hcloud
|
|
];
|
|
config = {
|
|
terraform.backend.s3 = {
|
|
bucket = "bw-terraform";
|
|
key = cfg.bucket.key;
|
|
region = "auto";
|
|
endpoints = {
|
|
s3 = "https://477b394a6a545699445c40953e40f00b.r2.cloudflarestorage.com";
|
|
};
|
|
use_path_style = true;
|
|
skip_credentials_validation = true;
|
|
skip_region_validation = true;
|
|
skip_metadata_api_check = true;
|
|
skip_requesting_account_id = true;
|
|
skip_s3_checksum = true;
|
|
};
|
|
|
|
khscodes.hcloud.data.ssh_key.khs = {
|
|
name = "ca.kaareskovgaard.net";
|
|
};
|
|
khscodes.hcloud.enable = true;
|
|
khscodes.hcloud.server.compute = {
|
|
inherit (cfg) server_type datacenter;
|
|
inherit labels;
|
|
name = fqdn;
|
|
initial_image = "debian-12";
|
|
rdns = fqdn;
|
|
ssh_keys = [ config.khscodes.hcloud.output.data.ssh_key.khs.id ];
|
|
};
|
|
khscodes.cloudflare = {
|
|
enable = true;
|
|
dns = {
|
|
enable = true;
|
|
zone_name = tldFromFqdn fqdn;
|
|
aRecords = [
|
|
{
|
|
inherit fqdn;
|
|
content = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
|
}
|
|
];
|
|
aaaaRecords = [
|
|
{
|
|
inherit fqdn;
|
|
content = config.khscodes.hcloud.output.server.compute.ipv6_address;
|
|
}
|
|
];
|
|
};
|
|
};
|
|
resource.hcloud_firewall.fw = lib.mkIf firewallEnable {
|
|
inherit labels;
|
|
name = fqdn;
|
|
apply_to = {
|
|
server = config.khscodes.hcloud.output.server.compute.id;
|
|
};
|
|
rule = firewallRules;
|
|
};
|
|
output.ipv4_address = {
|
|
value = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
|
sensitive = false;
|
|
};
|
|
|
|
output.ipv6_address = {
|
|
value = config.khscodes.hcloud.output.server.compute.ipv6_address;
|
|
sensitive = false;
|
|
};
|
|
};
|
|
}
|
|
)
|
|
];
|
|
in
|
|
{
|
|
assertions = [
|
|
{
|
|
assertion = config.khscodes.fqdn != null;
|
|
message = "Must set config.khscodes.fqdn when using opentofu";
|
|
}
|
|
];
|
|
|
|
khscodes.provisioning.pre = {
|
|
modules = modules;
|
|
secretsSource = cfg.secretsSource;
|
|
variablesNeeded = [
|
|
"TF_VAR_cloudflare_token"
|
|
"TF_VAR_cloudflare_email"
|
|
"AWS_ACCESS_KEY_ID"
|
|
"AWS_SECRET_ACCESS_KEY"
|
|
"TF_VAR_hcloud_api_token"
|
|
];
|
|
};
|
|
}
|
|
);
|
|
}
|