Begin geting terraform working
This commit is contained in:
parent
eba2f6adf9
commit
2f725ca3ea
15 changed files with 945 additions and 21 deletions
199
flake.lock
generated
199
flake.lock
generated
|
@ -1,5 +1,37 @@
|
||||||
{
|
{
|
||||||
"nodes": {
|
"nodes": {
|
||||||
|
"bats-assert": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1636059754,
|
||||||
|
"narHash": "sha256-ewME0l27ZqfmAwJO4h5biTALc9bDLv7Bl3ftBzBuZwk=",
|
||||||
|
"owner": "bats-core",
|
||||||
|
"repo": "bats-assert",
|
||||||
|
"rev": "34551b1d7f8c7b677c1a66fc0ac140d6223409e5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "bats-core",
|
||||||
|
"repo": "bats-assert",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bats-support": {
|
||||||
|
"flake": false,
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1548869839,
|
||||||
|
"narHash": "sha256-Gr4ntadr42F2Ks8Pte2D4wNDbijhujuoJi4OPZnTAZU=",
|
||||||
|
"owner": "bats-core",
|
||||||
|
"repo": "bats-support",
|
||||||
|
"rev": "d140a65044b2d6810381935ae7f0c94c7023c8c3",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "bats-core",
|
||||||
|
"repo": "bats-support",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"disko": {
|
"disko": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
@ -58,6 +90,27 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"terranix",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1736143030,
|
||||||
|
"narHash": "sha256-+hu54pAoLDEZT9pjHlqL9DNzWz0NbUn8NEAHP7PQPzU=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "b905f6fc23a9051a6e1b741e1438dbfc0634c6de",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-utils": {
|
"flake-utils": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"systems": "systems"
|
"systems": "systems"
|
||||||
|
@ -95,6 +148,36 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"flake-utils_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1634851050,
|
||||||
|
"narHash": "sha256-N83GlSGPJJdcqhUxSCS/WwW5pksYf3VP1M13cDRTSVA=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c91f3de5adaf1de973b797ef7485e441a65b8935",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-utils_3": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1634851050,
|
||||||
|
"narHash": "sha256-N83GlSGPJJdcqhUxSCS/WwW5pksYf3VP1M13cDRTSVA=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"rev": "c91f3de5adaf1de973b797ef7485e441a65b8935",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "flake-utils",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1751582995,
|
"lastModified": 1751582995,
|
||||||
|
@ -111,11 +194,28 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"nixpkgs_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1636273007,
|
||||||
|
"narHash": "sha256-eb6HcZNacO9vIP/KcJ5CoCRYSGfD+VxzYs2cCafEo4Y=",
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "c69c6533c820c55c3f1d924b399d8f6925a1e41a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nixos",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
"flake-base": "flake-base",
|
"flake-base": "flake-base",
|
||||||
"nixpkgs": "nixpkgs"
|
"nixpkgs": "nixpkgs",
|
||||||
|
"terranix": "terranix",
|
||||||
|
"terranix-hcloud": "terranix-hcloud"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"snowfall-lib": {
|
"snowfall-lib": {
|
||||||
|
@ -156,6 +256,103 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"systems_2": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1681028828,
|
||||||
|
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-systems",
|
||||||
|
"repo": "default",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"terranix": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"systems": "systems_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1749381683,
|
||||||
|
"narHash": "sha256-16z7tXZch12SAd3d8tbAiEOamyq3zFbw1oUq/ipmTkM=",
|
||||||
|
"owner": "terranix",
|
||||||
|
"repo": "terranix",
|
||||||
|
"rev": "9d2370279d595be9e728b68d29ff0b546d88e619",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "terranix",
|
||||||
|
"repo": "terranix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"terranix-examples": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1633465925,
|
||||||
|
"narHash": "sha256-BfXRW1ZHpK5jh5CVcw7eFpGsWE1CyVxL8R+V7uXemaU=",
|
||||||
|
"owner": "terranix",
|
||||||
|
"repo": "terranix-examples",
|
||||||
|
"rev": "70bf5d5a1ad4eabef1e4e71c1eb101021decd5a4",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "terranix",
|
||||||
|
"repo": "terranix-examples",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"terranix-hcloud": {
|
||||||
|
"inputs": {
|
||||||
|
"flake-utils": "flake-utils_2",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"terranix": "terranix_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1745572802,
|
||||||
|
"narHash": "sha256-Zk2vdO5JSsOJ+WVpBauGvKHF+i8+YZGsn9EHNyLLUhw=",
|
||||||
|
"owner": "terranix",
|
||||||
|
"repo": "terranix-hcloud",
|
||||||
|
"rev": "5e380bf5f8cbc43de134a24d97097a972986bd6e",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "terranix",
|
||||||
|
"repo": "terranix-hcloud",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"terranix_2": {
|
||||||
|
"inputs": {
|
||||||
|
"bats-assert": "bats-assert",
|
||||||
|
"bats-support": "bats-support",
|
||||||
|
"flake-utils": "flake-utils_3",
|
||||||
|
"nixpkgs": "nixpkgs_2",
|
||||||
|
"terranix-examples": "terranix-examples"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1636274023,
|
||||||
|
"narHash": "sha256-HDiyJGgyDUoLnpL8N+wDm3cM/vEfYYc/p4N1kKH/kLk=",
|
||||||
|
"owner": "terranix",
|
||||||
|
"repo": "terranix",
|
||||||
|
"rev": "342ec8490bc948c8589414eb89f26b265cbfd62a",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "terranix",
|
||||||
|
"ref": "develop",
|
||||||
|
"repo": "terranix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"treefmt-nix": {
|
"treefmt-nix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
|
39
flake.nix
39
flake.nix
|
@ -11,18 +11,32 @@
|
||||||
url = "github:nix-community/disko";
|
url = "github:nix-community/disko";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
terranix = {
|
||||||
|
url = "github:terranix/terranix";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
terranix-hcloud = {
|
||||||
|
url = "github:terranix/terranix-hcloud";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
inputs@{ self, nixpkgs, ... }:
|
inputs@{ self, ... }:
|
||||||
let
|
let
|
||||||
|
dirsInPath =
|
||||||
|
path:
|
||||||
|
let
|
||||||
|
files = builtins.readDir path;
|
||||||
|
dirs = builtins.filterAttrs (name: kind: kind == "directory") files;
|
||||||
|
in
|
||||||
|
builtins.attrNames dirs;
|
||||||
profileArgs = { inherit self; };
|
profileArgs = { inherit self; };
|
||||||
profiles = builtins.readDir ./nix/profiles;
|
profileNames = dirsInPath ./nix/profiles;
|
||||||
profilesDirs = nixpkgs.lib.filterAttrs (name: kind: kind == "directory") profiles;
|
nixosModules = dirsInPath ./nix/modules/nixos;
|
||||||
profileNames = builtins.attrNames profilesDirs;
|
|
||||||
inputModules = [ inputs.disko.nixosModules.disko ];
|
inputModules = [ inputs.disko.nixosModules.disko ];
|
||||||
in
|
in
|
||||||
inputs.flake-base.lib.mkFlake {
|
(inputs.flake-base.lib.mkFlake {
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
src = ./.;
|
src = ./.;
|
||||||
systems.modules.nixos = inputModules;
|
systems.modules.nixos = inputModules;
|
||||||
|
@ -37,14 +51,7 @@
|
||||||
modules.nixos = {
|
modules.nixos = {
|
||||||
default =
|
default =
|
||||||
{
|
{
|
||||||
imports = [
|
imports = builtins.map (m: self.nixosModules.${m}) nixosModules ++ inputModules;
|
||||||
self.nixosModules.hetzner
|
|
||||||
self.nixosModules.sshd
|
|
||||||
self.nixosModules.sshd
|
|
||||||
self.nixosModules.systemd-boot
|
|
||||||
self.nixosModules.qemu-guest
|
|
||||||
inputs.disko.nixosModules.disko
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
// (builtins.listToAttrs (
|
// (builtins.listToAttrs (
|
||||||
builtins.map (n: {
|
builtins.map (n: {
|
||||||
|
@ -53,5 +60,11 @@
|
||||||
}) profileNames
|
}) profileNames
|
||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
})
|
||||||
|
// {
|
||||||
|
terranixModules.cloudflare = import ./nix/modules/terranix/cloudflare {
|
||||||
|
inherit inputs;
|
||||||
|
khscodesLib = inputs.self.lib;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
71
nix/lib/mkBwEnv/default.nix
Normal file
71
nix/lib/mkBwEnv/default.nix
Normal file
|
@ -0,0 +1,71 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
mkBwEnv =
|
||||||
|
{
|
||||||
|
items,
|
||||||
|
pkgs,
|
||||||
|
name ? "bw-env",
|
||||||
|
exe,
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
assertMsg = pred: msg: pred || builtins.throw msg;
|
||||||
|
concatLines = builtins.concatStringsSep "\n";
|
||||||
|
itemNames = builtins.attrNames items;
|
||||||
|
exports = builtins.map (
|
||||||
|
itemName:
|
||||||
|
let
|
||||||
|
item = items.${itemName};
|
||||||
|
varNames = builtins.attrNames item;
|
||||||
|
vars = builtins.map (
|
||||||
|
varName:
|
||||||
|
let
|
||||||
|
var = item.${varName};
|
||||||
|
script =
|
||||||
|
if var == "login.password" || var == "login.username" then
|
||||||
|
"jq -r '.${var}'"
|
||||||
|
else
|
||||||
|
"jq -r --arg name '${var}' \"$JQ_FIELD_SCRIPT\"";
|
||||||
|
in
|
||||||
|
assert assertMsg (builtins.match "^[a-zA-Z0-9_]+$" != null) "Invalid variable name: ${varName}";
|
||||||
|
''
|
||||||
|
${varName}="$(${script} <<< "$item")"
|
||||||
|
if [[ "''$${varName}" == "null" ]]; then
|
||||||
|
echo "Could not read ${varName} from ${itemName}" 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
export ${varName}
|
||||||
|
''
|
||||||
|
) varNames;
|
||||||
|
in
|
||||||
|
''
|
||||||
|
item="$(bw get item '${itemName}')"
|
||||||
|
${concatLines vars}
|
||||||
|
''
|
||||||
|
) itemNames;
|
||||||
|
in
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
inherit name;
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.jq
|
||||||
|
pkgs.bitwarden-cli
|
||||||
|
];
|
||||||
|
meta = {
|
||||||
|
mainProgram = name;
|
||||||
|
};
|
||||||
|
text = ''
|
||||||
|
if [ "''${DEBUG:-0}" == "1" ]; then
|
||||||
|
set -x
|
||||||
|
fi
|
||||||
|
if [ -z "''${BW_SESSION+x}" ]; then
|
||||||
|
BW_SESSION="$(bw unlock --raw)"
|
||||||
|
echo "Bitwarden session (export as BW_SESSION to avoid repeating entries): $BW_SESSION" 1>&2
|
||||||
|
export BW_SESSION
|
||||||
|
fi
|
||||||
|
|
||||||
|
JQ_FIELD_SCRIPT='.fields | map(select(.name == $'"name))[0].value"
|
||||||
|
${concatLines exports}
|
||||||
|
|
||||||
|
exec "${exe}" "$@"
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
}
|
13
nix/lib/mkSubmodule/default.nix
Normal file
13
nix/lib/mkSubmodule/default.nix
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
mkSubmodule =
|
||||||
|
{
|
||||||
|
options,
|
||||||
|
description,
|
||||||
|
}:
|
||||||
|
lib.types.submoduleWith {
|
||||||
|
description = description;
|
||||||
|
shorthandOnlyDefinesConfig = true;
|
||||||
|
modules = lib.toList { inherit options; };
|
||||||
|
};
|
||||||
|
}
|
29
nix/modules/nixos/fqdn/default.nix
Normal file
29
nix/modules/nixos/fqdn/default.nix
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.khscodes.fqdn;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.khscodes.fqdn = lib.mkOption {
|
||||||
|
type = lib.types.nullOr lib.types.str;
|
||||||
|
default = null;
|
||||||
|
description = "Sets the FQDN of the machine. This is a prerequisite for many modules to be used";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf (cfg != null) (
|
||||||
|
let
|
||||||
|
hostname = builtins.head (lib.strings.splitString "." cfg);
|
||||||
|
domain = if hostname == cfg then null else (lib.strings.removePrefix "${hostname}." cfg);
|
||||||
|
in
|
||||||
|
{
|
||||||
|
networking.hostName = hostname;
|
||||||
|
networking.domain = domain;
|
||||||
|
boot.kernel.sysctl = {
|
||||||
|
"kernel.hostname" = cfg;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
|
@ -1,4 +1,11 @@
|
||||||
{ config, lib, ... }:
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.khscodes.sshd;
|
||||||
|
in
|
||||||
{
|
{
|
||||||
|
options.khscodes.sshd.enable = lib.mkEnableOption "Enables sshd for the instance";
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.sshd.enable = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
283
nix/modules/nixos/terraform-hetzner/default.nix
Normal file
283
nix/modules/nixos/terraform-hetzner/default.nix
Normal file
|
@ -0,0 +1,283 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.khscodes.terraform-hetzner;
|
||||||
|
fqdn = config.khscodes.fqdn;
|
||||||
|
hostPkgs = import inputs.nixpkgs {
|
||||||
|
system = pkgs.buildPlatform.system;
|
||||||
|
overlays = [ inputs.self.overlays.bitwarden-cli ];
|
||||||
|
};
|
||||||
|
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;
|
||||||
|
mapRdns = cfg.mapRdns;
|
||||||
|
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.terraform-hetzner = {
|
||||||
|
enable = lib.mkEnableOption "enables generating a terraform 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 terraform 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;
|
||||||
|
};
|
||||||
|
config = inputs.terranix.lib.terranixConfiguration {
|
||||||
|
system = pkgs.hostPlatform.system;
|
||||||
|
modules = [
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
inputs.self.terranixModules.cloudflare
|
||||||
|
inputs.terranix-hcloud.terranixModules.hcloud
|
||||||
|
];
|
||||||
|
|
||||||
|
hcloud.enable = true;
|
||||||
|
terraform.required_providers.hcloud.version = "~> 1.45.0";
|
||||||
|
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;
|
||||||
|
};
|
||||||
|
|
||||||
|
data.hcloud_ssh_key.khs = {
|
||||||
|
name = "ca.kaareskovgaard.net";
|
||||||
|
};
|
||||||
|
|
||||||
|
resource.hcloud_primary_ip.ipv4 = {
|
||||||
|
inherit labels;
|
||||||
|
name = "${fqdn} ipv4";
|
||||||
|
datacenter = cfg.datacenter;
|
||||||
|
type = "ipv4";
|
||||||
|
assignee_type = "server";
|
||||||
|
auto_delete = false;
|
||||||
|
};
|
||||||
|
resource.hcloud_primary_ip.ipv6 = {
|
||||||
|
inherit labels;
|
||||||
|
name = "${fqdn} ipv6";
|
||||||
|
datacenter = cfg.datacenter;
|
||||||
|
type = "ipv6";
|
||||||
|
assignee_type = "server";
|
||||||
|
auto_delete = false;
|
||||||
|
};
|
||||||
|
khscodes.cloudflare = {
|
||||||
|
enable = true;
|
||||||
|
dns = {
|
||||||
|
enable = true;
|
||||||
|
zone_name = tldFromFqdn fqdn;
|
||||||
|
aRecords = [
|
||||||
|
{
|
||||||
|
inherit fqdn;
|
||||||
|
content = "\${ hcloud_server.compute.ipv4_address }";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
aaaaRecords = [
|
||||||
|
{
|
||||||
|
inherit fqdn;
|
||||||
|
content = "\${ hcloud_server.compute.ipv6_address }";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
resource.hcloud_firewall.fw = lib.mkIf firewallEnable {
|
||||||
|
inherit labels;
|
||||||
|
name = fqdn;
|
||||||
|
apply_to = {
|
||||||
|
server = "\${ hcloud_server.compute.id }";
|
||||||
|
};
|
||||||
|
rule = firewallRules;
|
||||||
|
};
|
||||||
|
resource.hcloud_server.compute = {
|
||||||
|
inherit (cfg) server_type datacenter;
|
||||||
|
inherit labels;
|
||||||
|
name = fqdn;
|
||||||
|
image = "debian-12";
|
||||||
|
public_net = {
|
||||||
|
ipv4_enabled = true;
|
||||||
|
ipv4 = "\${ hcloud_primary_ip.ipv4.id }";
|
||||||
|
ipv6_enabled = true;
|
||||||
|
ipv6 = "\${ hcloud_primary_ip.ipv6.id }";
|
||||||
|
};
|
||||||
|
ssh_keys = [ "\${ data.hcloud_ssh_key.khs.id }" ];
|
||||||
|
lifecycle = {
|
||||||
|
ignore_changes = [
|
||||||
|
"ssh_keys"
|
||||||
|
"public_net"
|
||||||
|
"image"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
output.ipv4_address = {
|
||||||
|
value = "\${ hcloud_server.compute.ipv4_address }";
|
||||||
|
sensitive = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
output.ipv6_address = {
|
||||||
|
value = "\${ hcloud_server.compute.ipv6_address }";
|
||||||
|
sensitive = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
(
|
||||||
|
{ lib, ... }:
|
||||||
|
{
|
||||||
|
config = lib.mkIf mapRdns {
|
||||||
|
resource.hcloud_rdns.ipv4 = {
|
||||||
|
primary_ip_id = "\${ hcloud_primary_ip.ipv4.id }";
|
||||||
|
ip_address = "\${ hcloud_server.compute.ipv4_address }";
|
||||||
|
dns_ptr = fqdn;
|
||||||
|
};
|
||||||
|
resource.hcloud_rdns.ipv6 = {
|
||||||
|
primary_ip_id = "\${ hcloud_primary_ip.ipv6.id }";
|
||||||
|
ip_address = "\${ hcloud_server.compute.ipv6_address }";
|
||||||
|
dns_ptr = fqdn;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
assertions = [
|
||||||
|
{
|
||||||
|
assertion = config.khscodes.fqdn != null;
|
||||||
|
message = "Must set config.khscodes.fqdn when using terraform";
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
khscodes.terraform-hetzner.output = config;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
172
nix/modules/terranix/cloudflare/default.nix
Normal file
172
nix/modules/terranix/cloudflare/default.nix
Normal file
|
@ -0,0 +1,172 @@
|
||||||
|
{ inputs, khscodesLib }:
|
||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.khscodes.cloudflare;
|
||||||
|
nameFromFQDNAndZone =
|
||||||
|
fqdn: zone:
|
||||||
|
let
|
||||||
|
stripped = lib.strings.removeSuffix ".${zone}" fqdn;
|
||||||
|
in
|
||||||
|
if stripped != fqdn then
|
||||||
|
stripped
|
||||||
|
else if fqdn == zone then
|
||||||
|
"@"
|
||||||
|
else
|
||||||
|
fqdn;
|
||||||
|
fqdnToTFname = fqdn: builtins.replaceStrings [ "." ] [ "_" ] fqdn;
|
||||||
|
dnsARecordModule = khscodesLib.mkSubmodule {
|
||||||
|
description = "Module for defining dns A/AAAA record";
|
||||||
|
options = {
|
||||||
|
fqdn = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The FQDN of the A/AAAA record to create";
|
||||||
|
};
|
||||||
|
content = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The content of the A/AAAA record (IPv4/IPv6 address)";
|
||||||
|
};
|
||||||
|
proxied = lib.mkOption {
|
||||||
|
type = lib.types.bool;
|
||||||
|
description = "Creates a proxied record in cloudflare";
|
||||||
|
default = false;
|
||||||
|
};
|
||||||
|
ttl = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
description = "Time to Live for the A/AAAA record";
|
||||||
|
default = 600;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
dnsTxtRecordModule = khscodesLib.mkSubmodule {
|
||||||
|
description = "Module for defining dns TXT record";
|
||||||
|
options = {
|
||||||
|
fqdn = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The FQDN of the TXT record to create";
|
||||||
|
};
|
||||||
|
content = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The content of the TXT record";
|
||||||
|
};
|
||||||
|
ttl = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
description = "Time to Live for the TXT record";
|
||||||
|
default = 600;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
dnsMxRecordModule = khscodesLib.mkSubmodule {
|
||||||
|
description = "Module for defining dns MX record";
|
||||||
|
options = {
|
||||||
|
fqdn = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The FQDN of the MX record to create";
|
||||||
|
};
|
||||||
|
content = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The content of the MX record";
|
||||||
|
};
|
||||||
|
priority = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
description = "Priority for the MX record";
|
||||||
|
};
|
||||||
|
ttl = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
description = "Time to Live for the MX record";
|
||||||
|
default = 600;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.khscodes.cloudflare = {
|
||||||
|
enable = lib.mkEnableOption "Enables khscodes cloudflare terranix integration";
|
||||||
|
dns = {
|
||||||
|
enable = lib.mkEnableOption "Enables setting up DNS records";
|
||||||
|
zone_name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The dns zone name (TLD)";
|
||||||
|
};
|
||||||
|
aRecords = lib.mkOption {
|
||||||
|
type = lib.types.listOf dnsARecordModule;
|
||||||
|
default = [ ];
|
||||||
|
description = "A records to create in the zone";
|
||||||
|
};
|
||||||
|
aaaaRecords = lib.mkOption {
|
||||||
|
type = lib.types.listOf dnsARecordModule;
|
||||||
|
default = [ ];
|
||||||
|
description = "AAAA records to create in the zone";
|
||||||
|
};
|
||||||
|
txtRecords = lib.mkOption {
|
||||||
|
type = lib.types.listOf dnsTxtRecordModule;
|
||||||
|
default = [ ];
|
||||||
|
description = "TXT Records to create";
|
||||||
|
};
|
||||||
|
mxRecords = lib.mkOption {
|
||||||
|
type = lib.types.listOf dnsMxRecordModule;
|
||||||
|
default = [ ];
|
||||||
|
description = "MX records to create";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
provider.cloudflare.api_token = "\${ var.cloudflare_token }";
|
||||||
|
variable.cloudflare_token = {
|
||||||
|
type = "string";
|
||||||
|
sensitive = true;
|
||||||
|
};
|
||||||
|
terraform.required_providers.cloudflare = {
|
||||||
|
source = "cloudflare/cloudflare";
|
||||||
|
version = "~> 4.0";
|
||||||
|
};
|
||||||
|
|
||||||
|
data.cloudflare_zone.dns_zone = lib.attrsets.optionalAttrs cfg.dns.enable {
|
||||||
|
name = cfg.dns.zone_name;
|
||||||
|
};
|
||||||
|
resource.cloudflare_record = lib.attrsets.optionalAttrs cfg.dns.enable (
|
||||||
|
lib.listToAttrs (
|
||||||
|
(lib.lists.map (record: {
|
||||||
|
name = "${fqdnToTFname record.fqdn}_a";
|
||||||
|
value = {
|
||||||
|
inherit (record) content ttl proxied;
|
||||||
|
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||||
|
type = "A";
|
||||||
|
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||||
|
comment = "app=${cfg.dns.zone_name}";
|
||||||
|
};
|
||||||
|
}) cfg.dns.aRecords)
|
||||||
|
++ (lib.lists.map (record: {
|
||||||
|
name = "${fqdnToTFname record.fqdn}_aaaa";
|
||||||
|
value = {
|
||||||
|
inherit (record) content ttl proxied;
|
||||||
|
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||||
|
type = "AAAA";
|
||||||
|
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||||
|
comment = "app=${cfg.dns.zone_name}";
|
||||||
|
};
|
||||||
|
}) cfg.dns.aaaaRecords)
|
||||||
|
++ (lib.lists.map (record: {
|
||||||
|
name = "${fqdnToTFname record.fqdn}_txt";
|
||||||
|
value = {
|
||||||
|
inherit (record) content ttl;
|
||||||
|
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||||
|
type = "TXT";
|
||||||
|
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||||
|
comment = "app=${cfg.dns.zone_name}";
|
||||||
|
};
|
||||||
|
}) cfg.dns.txtRecords)
|
||||||
|
++ (lib.lists.map (record: {
|
||||||
|
name = "${fqdnToTFname record.fqdn}_mx";
|
||||||
|
value = {
|
||||||
|
inherit (record) content priority;
|
||||||
|
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||||
|
type = "MX";
|
||||||
|
zone_id = "\${ data.cloudflare_zone.dns_zone.id }";
|
||||||
|
comment = "app=${cfg.dns.zone_name}";
|
||||||
|
};
|
||||||
|
}) cfg.dns.mxRecords)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
12
nix/overlays/bitwarden-cli/default.nix
Normal file
12
nix/overlays/bitwarden-cli/default.nix
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{ ... }:
|
||||||
|
final: prev: {
|
||||||
|
bitwarden-cli =
|
||||||
|
if final.lib.strings.hasSuffix "-darwin" final.system then
|
||||||
|
# Bitwarden-cli is broken on darwin with the newer llvm
|
||||||
|
(prev.bitwarden-cli.overrideAttrs (oldAttrs: {
|
||||||
|
nativeBuildInputs = (oldAttrs.nativeBuildInputs or [ ]) ++ [ final.llvmPackages_18.stdenv.cc ];
|
||||||
|
stdenv = final.llvmPackages_18.stdenv;
|
||||||
|
}))
|
||||||
|
else
|
||||||
|
prev.bitwarden-cli;
|
||||||
|
}
|
51
nix/packages/bw-opentofu/default.nix
Normal file
51
nix/packages/bw-opentofu/default.nix
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{ pkgs, lib, ... }:
|
||||||
|
let
|
||||||
|
opentofu = pkgs.opentofu;
|
||||||
|
bw-opentofu = lib.khscodes.mkBwEnv {
|
||||||
|
inherit pkgs;
|
||||||
|
name = "bw-opentofu";
|
||||||
|
items = {
|
||||||
|
"KHS Openstack" = {
|
||||||
|
TF_VAR_openstack_username = "login.username";
|
||||||
|
TF_VAR_openstack_password = "login.password";
|
||||||
|
TF_VAR_openstack_tenant_name = "Project Name";
|
||||||
|
TF_VAR_openstack_auth_url = "Auth URL";
|
||||||
|
TF_VAR_openstack_endpoint_type = "Interface";
|
||||||
|
TF_VAR_openstack_region = "Region Name";
|
||||||
|
};
|
||||||
|
"Cloudflare" = {
|
||||||
|
TF_VAR_cloudflare_token = "DNS API Token";
|
||||||
|
TF_VAR_cloudflare_email = "login.username";
|
||||||
|
AWS_ACCESS_KEY_ID = "BW Terraform access key id";
|
||||||
|
AWS_SECRET_ACCESS_KEY = "BW Terraform secret access key";
|
||||||
|
};
|
||||||
|
"Hetzner Cloud" = {
|
||||||
|
TF_VAR_hcloud_api_token = "Terraform API Token";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
exe = lib.getExe opentofu;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "bw-opentofu";
|
||||||
|
runtimeInputs = [
|
||||||
|
bw-opentofu
|
||||||
|
pkgs.uutils-coreutils-noprefix
|
||||||
|
pkgs.bitwarden-cli
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
fqdn="$1"
|
||||||
|
config="$2"
|
||||||
|
lockHcl="$3"
|
||||||
|
dir="$(mktemp -d --tmpdir -t "terraform-hetzher-''${fqdn}.XXXXXXXXXX")"
|
||||||
|
cp "$lockHcl" "$dir/.terraform.lock.hcl"
|
||||||
|
cp "''${config}" "$dir/config.tf.json"
|
||||||
|
if [ "''${BW_SESSION:-}" == "" ]; then
|
||||||
|
BW_SESSION="$(bw unlock --raw)"
|
||||||
|
export BW_SESSION
|
||||||
|
trap "bw lock" EXIT
|
||||||
|
fi
|
||||||
|
bw-opentofu -chdir="$dir" init
|
||||||
|
bw-opentofu -chdir="$dir" apply
|
||||||
|
'';
|
||||||
|
}
|
16
nix/packages/opentofu-hetzner/default.nix
Normal file
16
nix/packages/opentofu-hetzner/default.nix
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
}:
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "opentofu-hetzner";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.nix
|
||||||
|
pkgs.khscodes.bw-opentofu
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
hostname="$1"
|
||||||
|
config="$(nix build --no-link --print-out-paths '${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.terraform-hetzner.output')"
|
||||||
|
bw-opentofu "$hostname" "$config" "${./terraform.lock.hcl}"
|
||||||
|
'';
|
||||||
|
}
|
47
nix/packages/opentofu-hetzner/terraform.lock.hcl
Normal file
47
nix/packages/opentofu-hetzner/terraform.lock.hcl
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# This file is maintained automatically by "tofu init".
|
||||||
|
# Manual edits may be lost in future updates.
|
||||||
|
|
||||||
|
provider "registry.opentofu.org/cloudflare/cloudflare" {
|
||||||
|
version = "4.52.0"
|
||||||
|
constraints = "~> 4.0"
|
||||||
|
hashes = [
|
||||||
|
"h1:Pi5M+GeoMSN2eJ6QnIeXjBf19O+rby/74CfB2ocpv20=",
|
||||||
|
"zh:19be1a91c982b902c42aba47766860dfa5dc151eed1e95fd39ca642229381ef0",
|
||||||
|
"zh:1de451c4d1ecf7efbe67b6dace3426ba810711afdd644b0f1b870364c8ae91f8",
|
||||||
|
"zh:352b4a2120173298622e669258744554339d959ac3a95607b117a48ee4a83238",
|
||||||
|
"zh:3c6f1346d9154afbd2d558fabb4b0150fc8d559aa961254144fe1bc17fe6032f",
|
||||||
|
"zh:4c4c92d53fb535b1e0eff26f222bbd627b97d3b4c891ec9c321268676d06152f",
|
||||||
|
"zh:53276f68006c9ceb7cdb10a6ccf91a5c1eadd1407a28edb5741e84e88d7e29e8",
|
||||||
|
"zh:7925a97773948171a63d4f65bb81ee92fd6d07a447e36012977313293a5435c9",
|
||||||
|
"zh:7dfb0a4496cfe032437386d0a2cd9229a1956e9c30bd920923c141b0f0440060",
|
||||||
|
"zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
|
||||||
|
"zh:8d4aa79f0a414bb4163d771063c70cd991c8fac6c766e685bac2ee12903c5bd6",
|
||||||
|
"zh:a67540c13565616a7e7e51ee9366e88b0dc60046e1d75c72680e150bd02725bb",
|
||||||
|
"zh:a936383a4767f5393f38f622e92bf2d0c03fe04b69c284951f27345766c7b31b",
|
||||||
|
"zh:d4887d73c466ff036eecf50ad6404ba38fd82ea4855296b1846d244b0f13c380",
|
||||||
|
"zh:e9093c8bd5b6cd99c81666e315197791781b8f93afa14fc2e0f732d1bb2a44b7",
|
||||||
|
"zh:efd3b3f1ec59a37f635aa1d4efcf178734c2fcf8ddb0d56ea690bec342da8672",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
provider "registry.opentofu.org/hetznercloud/hcloud" {
|
||||||
|
version = "1.45.0"
|
||||||
|
constraints = "~> 1.45.0"
|
||||||
|
hashes = [
|
||||||
|
"h1:dh2iL5GHfDui5DbZFD/kcWlwzmC6slgUirA0FbZBK7g=",
|
||||||
|
"zh:1c4b44a698cfaca215bdbadaf92669dd23533210c3cbf32895fbf4ff7acf6c24",
|
||||||
|
"zh:2915f8385559694e5097d8d0df16358200e9f0d9efb80559e9ea0bd072d792b9",
|
||||||
|
"zh:3a6b37b0bba50d263bd3dba26185bde13c825e59b6b301ab3f9f45686a21456b",
|
||||||
|
"zh:3e3910fa22a3a8d73d1aed38cc479c3e1958e9168b5f4a7d0da6cf03c2dfc155",
|
||||||
|
"zh:3f8d7d09e5c93162a1e9e6c89acac0799fb55765b44b7d1d020763c814263c57",
|
||||||
|
"zh:40bc5e94bff495440e1b4f797165d7f0dcee2282a86a61b158f47fe4bc57e9fb",
|
||||||
|
"zh:473f51d464b897d0e8e3d5ca2eb175b37e2f7ce03c8b26f47cc35885cf620946",
|
||||||
|
"zh:6fdd4bf71c19cfad78d7e1d2336be873eb8567a139d53e672e78ebcbc36a4d7d",
|
||||||
|
"zh:9e08638cbfc90d69f1c21ee34191db077d58d040cf7a9eed07a1dc335d463e97",
|
||||||
|
"zh:b1ed5ea81bc6d2c88efdefaeb244322874508d90d8217ac2e3541445254bdadc",
|
||||||
|
"zh:ced05776c27d550d15d4a71360243740ecb4ea1e65e67229fb2273a27353b00c",
|
||||||
|
"zh:da79b8a1a982a1d365ea206a2654e8b5003aeba9ccdc9c8751bb6ee3f40d8c49",
|
||||||
|
"zh:fabbad25bab09dd74f2b819992ab99b939c642374d6ca080b18d6e2a91d8d487",
|
||||||
|
"zh:fb0e083d2925f289999dc561ef1c2f84a9e0ab11388c40162ca8b470f50f71f5",
|
||||||
|
]
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
{ self }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
|
config.khscodes = {
|
||||||
|
hetzner.enable = true;
|
||||||
|
sshd.enable = true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
15
nix/systems/x86_64-linux/khs.codes/default.nix
Normal file
15
nix/systems/x86_64-linux/khs.codes/default.nix
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
imports = [ "${inputs.self}/nix/profiles/hetzner-server.nix" ];
|
||||||
|
khscodes.terraform-hetzner = {
|
||||||
|
enable = true;
|
||||||
|
mapRdns = true;
|
||||||
|
server_type = "cax11";
|
||||||
|
secretsSource = "bitwarden";
|
||||||
|
};
|
||||||
|
khscodes.fqdn = "khs.codes";
|
||||||
|
system.stateVersion = "25.05";
|
||||||
|
}
|
|
@ -1,5 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
{
|
|
||||||
khscodes.hetzner.enable = true;
|
|
||||||
system.stateVersion = "25.05";
|
|
||||||
}
|
|
Loading…
Add table
Add a link
Reference in a new issue