feat: massive refactoring...
This commit is contained in:
49
modules/containers-nixos-logging.nix
Normal file
49
modules/containers-nixos-logging.nix
Normal file
@@ -0,0 +1,49 @@
|
||||
{
|
||||
config,
|
||||
tools,
|
||||
container,
|
||||
def,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
mergeConf = c: (lib.foldl' (acc: e: lib.recursiveUpdate acc e) { } c);
|
||||
in
|
||||
{
|
||||
services.alloy = {
|
||||
enable = true;
|
||||
extraFlags = [
|
||||
"--server.http.listen-addr=0.0.0.0:12345"
|
||||
"--disable-reporting"
|
||||
];
|
||||
};
|
||||
environment.etc = mergeConf (
|
||||
[
|
||||
{
|
||||
"alloy/config.alloy".text = (import ../config/alloy/config.alloy.nix { inherit config tools; }).out;
|
||||
"alloy/metrics.alloy".text =
|
||||
if (def.logging.metricsEnable) then
|
||||
(import ../config/alloy/metrics.alloy.nix { inherit config tools container; }).out
|
||||
else
|
||||
"";
|
||||
}
|
||||
]
|
||||
++ (lib.mapAttrsToList (filename: file: {
|
||||
"alloy/${filename}.alloy".text = (import file { inherit config tools container; }).out;
|
||||
}) def.logging.alloyConfig)
|
||||
++ (lib.mapAttrsToList (service: additional_stages: {
|
||||
"alloy/${container}-${service}.alloy".text =
|
||||
import ../config/alloy/default-journal-logger.alloy.nix
|
||||
{
|
||||
inherit
|
||||
tools
|
||||
container
|
||||
service
|
||||
additional_stages
|
||||
;
|
||||
};
|
||||
}) def.logging.journalLoggers)
|
||||
);
|
||||
|
||||
}
|
||||
8
modules/containers-terraform-authentik.nix
Normal file
8
modules/containers-terraform-authentik.nix
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
config,
|
||||
tools,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
{
|
||||
}
|
||||
35
modules/containers-terraform-postgres.nix
Normal file
35
modules/containers-terraform-postgres.nix
Normal file
@@ -0,0 +1,35 @@
|
||||
{ config, lib, ... }:
|
||||
let
|
||||
cfg = config.my-lxc;
|
||||
in
|
||||
{
|
||||
postgresql_role = lib.filterAttrs (_: v: v != { }) (
|
||||
lib.mapAttrs (
|
||||
containerName: def:
|
||||
lib.optionalAttrs (def.db.enable) {
|
||||
name = containerName;
|
||||
login = true;
|
||||
password = def.db.password;
|
||||
}
|
||||
) cfg
|
||||
);
|
||||
postgresql_database = lib.foldl' (acc: elem: acc // elem) { } (
|
||||
lib.mapAttrsToList (
|
||||
containerName: def:
|
||||
lib.optionalAttrs (def.db.enable) (
|
||||
# mkIf ?
|
||||
lib.listToAttrs (
|
||||
lib.map (db: {
|
||||
name = db;
|
||||
value = {
|
||||
name = db;
|
||||
owner = containerName;
|
||||
lc_ctype = "C";
|
||||
lc_collate = "C";
|
||||
};
|
||||
}) (def.db.additionalDB ++ [ containerName ])
|
||||
)
|
||||
)
|
||||
) cfg
|
||||
);
|
||||
}
|
||||
45
modules/containers-terraform-proxmox.nix
Normal file
45
modules/containers-terraform-proxmox.nix
Normal file
@@ -0,0 +1,45 @@
|
||||
{
|
||||
config,
|
||||
tools,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
cfg = config.my-lxc;
|
||||
in
|
||||
{
|
||||
proxmox_lxc = lib.mapAttrs (
|
||||
name: def:
|
||||
let
|
||||
c = def.container;
|
||||
in
|
||||
lib.mkIf (c.enable) {
|
||||
hostname = name;
|
||||
memory = c.memory;
|
||||
cores = c.cores;
|
||||
ostemplate = "local:vztmpl/\${var.ostemplate}.tar.xz";
|
||||
unprivileged = true;
|
||||
password = "changeme";
|
||||
features.nesting = true;
|
||||
target_node = "\${var.pve_node}";
|
||||
network = {
|
||||
name = "eth0";
|
||||
bridge = "vmbr0";
|
||||
ip = tools.build_ip_cidr name;
|
||||
gw = config.globals.gateway;
|
||||
type = "veth";
|
||||
};
|
||||
protection = c.protection;
|
||||
onboot = true;
|
||||
rootfs = {
|
||||
storage = "local-lvm";
|
||||
size = c.disk;
|
||||
};
|
||||
swap = c.swap;
|
||||
vmid = config.id.${name};
|
||||
tags = lib.strings.join ";" ([ "terraform" ] ++ c.tags);
|
||||
}
|
||||
// c.overrides
|
||||
) cfg;
|
||||
|
||||
}
|
||||
364
modules/containers.nix
Normal file
364
modules/containers.nix
Normal file
@@ -0,0 +1,364 @@
|
||||
{
|
||||
config,
|
||||
system,
|
||||
nixpkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
lib = pkgs.lib;
|
||||
inherit (lib) types mkOption mkEnableOption;
|
||||
cfg = config.my-lxc or { };
|
||||
realcfg = config;
|
||||
nixosTemplate = import ./lxc-template.nix { inherit pkgs; };
|
||||
tools = import ./tools.nix { inherit config lib; };
|
||||
mergeConf = c: (lib.foldl' (acc: e: lib.recursiveUpdate acc e) { } c);
|
||||
|
||||
secrets = import ../secrets/secrets.nix;
|
||||
in
|
||||
{
|
||||
options = with types; {
|
||||
# Inputs
|
||||
my-lxc = mkOption {
|
||||
type = attrsOf (submodule {
|
||||
options = {
|
||||
container = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkOption {
|
||||
type = bool;
|
||||
description = "Enable the container terraform generation";
|
||||
default = true;
|
||||
};
|
||||
cores = mkOption {
|
||||
type = int;
|
||||
description = "Number of CPU";
|
||||
default = 1;
|
||||
};
|
||||
memory = mkOption {
|
||||
type = int;
|
||||
description = "Ram in MB";
|
||||
default = 512;
|
||||
};
|
||||
unprivileged = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
description = "Make an unprivileged container";
|
||||
};
|
||||
disk = mkOption {
|
||||
type = str;
|
||||
description = "Disk size";
|
||||
default = "4G";
|
||||
};
|
||||
swap = mkOption {
|
||||
type = nullOr int;
|
||||
description = "Optional swap size in MB";
|
||||
default = null;
|
||||
};
|
||||
tags = mkOption {
|
||||
type = listOf str;
|
||||
description = "Container tags (terraform is automatically added)";
|
||||
default = [ ];
|
||||
};
|
||||
overrides = mkOption {
|
||||
type = attrs;
|
||||
description = "Overrides to the Proxmox LXC Terraform resource";
|
||||
default = { };
|
||||
};
|
||||
protection = mkOption {
|
||||
type = bool;
|
||||
description = "Whether container should be protected against changes.";
|
||||
default = true;
|
||||
};
|
||||
# TODO: Device passthrough & mount points => use overrides for now - or do it manually...
|
||||
# => in /etc/pve/lxc/{id}.conf
|
||||
# mp{number}: /pve/path,mp=/container/path # <- for bind-mount
|
||||
# dev{number}: /dev/{...} # <- for device pass-through
|
||||
};
|
||||
};
|
||||
};
|
||||
system = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
port = mkOption {
|
||||
type = nullOr int;
|
||||
description = "Main exposed HTTP port";
|
||||
default = null;
|
||||
};
|
||||
additionalPorts = mkOption {
|
||||
type = listOf int;
|
||||
description = "TCP ports to open";
|
||||
default = [ ];
|
||||
};
|
||||
udpPorts = mkOption {
|
||||
type = listOf int;
|
||||
description = "UDP ports to open";
|
||||
default = [ ];
|
||||
};
|
||||
services = mkOption {
|
||||
type = attrs;
|
||||
description = "NixOS services to enable";
|
||||
default = { };
|
||||
};
|
||||
packages = mkOption {
|
||||
type = listOf package;
|
||||
description = "NixOS packages to add";
|
||||
default = [ ];
|
||||
};
|
||||
etcFiles = mkOption {
|
||||
type = attrs;
|
||||
description = "Files to create on NixOS (=> environment.etc)";
|
||||
default = { };
|
||||
};
|
||||
additional = mkOption {
|
||||
type = attrs;
|
||||
description = "Additional NixOS definitions to be merged to nixosModule";
|
||||
default = { };
|
||||
};
|
||||
importConfig = mkOption {
|
||||
type = listOf path;
|
||||
description = "Modules to import and merge to NixOS module";
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
db = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Create a DB";
|
||||
password = mkOption { type = str; };
|
||||
additionalDB = mkOption {
|
||||
type = listOf str;
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
default = { };
|
||||
};
|
||||
logging = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
enable = mkEnableOption "Whether to enable default logs collection";
|
||||
metricsEnable = mkEnableOption "Whether to enable default metrics collection";
|
||||
prometheusPorts = mkOption {
|
||||
type = listOf int;
|
||||
description = "Ports of Prometheus Exporters";
|
||||
default = [ ];
|
||||
};
|
||||
alloyConfig = mkOption {
|
||||
type = attrsOf path;
|
||||
description = "Name => paths to add to Alloy";
|
||||
default = { };
|
||||
};
|
||||
journalLoggers = mkOption {
|
||||
type = attrsOf (nullOr str);
|
||||
description = "Service => routing stages (if any) as str";
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
private = mkOption {
|
||||
type = bool;
|
||||
description = "Should be only exposed to the private network";
|
||||
default = true;
|
||||
};
|
||||
auth = mkOption {
|
||||
type = bool;
|
||||
description = "Should be accessed through the auth middleware";
|
||||
default = true;
|
||||
};
|
||||
otherDomains = mkOption {
|
||||
type = listOf (submodule {
|
||||
options = {
|
||||
subdomain = mkOption { type = str; };
|
||||
port = mkOption { type = int; };
|
||||
private = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
auth = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
customRule = mkOption {
|
||||
type = nullOr str;
|
||||
default = null;
|
||||
};
|
||||
raw_tcp = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [ ];
|
||||
};
|
||||
sso = mkOption {
|
||||
type = attrs;
|
||||
description = "SSO parameters (TBD)";
|
||||
default = { };
|
||||
};
|
||||
secrets = mkOption {
|
||||
type = attrs;
|
||||
description = "Secrets to import {name}: {path}";
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
# in _id.nix
|
||||
id = mkOption {
|
||||
type = attrsOf int;
|
||||
};
|
||||
# in _config.nix
|
||||
globals = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
ip_prefix = mkOption { type = str; };
|
||||
cidr = mkOption { type = int; };
|
||||
gateway = mkOption { type = str; };
|
||||
domains = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
internal = mkOption { type = str; };
|
||||
external = mkOption { type = str; };
|
||||
};
|
||||
};
|
||||
};
|
||||
master = mkOption {
|
||||
type = submodule {
|
||||
options = {
|
||||
login = mkOption { type = str; };
|
||||
email = mkOption { type = str; };
|
||||
public_ssh_key = mkOption { type = str; };
|
||||
initial_htpasswd = mkOption { type = str; };
|
||||
};
|
||||
};
|
||||
};
|
||||
default_tz = mkOption { type = str; };
|
||||
country_code = mkOption { type = str; };
|
||||
currency = mkOption { type = str; };
|
||||
services = mkOption {
|
||||
type = submodule {
|
||||
log_sink = mkOption { type = str; }; # ip:port
|
||||
metrics_sink = mkOption { type = str; }; # ip:port
|
||||
};
|
||||
};
|
||||
|
||||
dns_provider = mkOption { type = str; };
|
||||
|
||||
other_hosts = mkOption {
|
||||
type = listOf (submodule {
|
||||
options = {
|
||||
hostname = mkOption { type = str; };
|
||||
private = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
auth = mkOption {
|
||||
type = bool;
|
||||
default = true;
|
||||
};
|
||||
addr = mkOption {
|
||||
type = str;
|
||||
description = "ip:port for the service";
|
||||
};
|
||||
useCustomCA = mkOption {
|
||||
type = bool;
|
||||
default = false;
|
||||
description = "Whether to use a custom CA (pretty much hardcoded)";
|
||||
};
|
||||
};
|
||||
});
|
||||
default = [ ];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Outputs
|
||||
tf = mkOption {
|
||||
type = types.attrs;
|
||||
description = "Terraform resources";
|
||||
default = { };
|
||||
};
|
||||
nixosModule = mkOption {
|
||||
type = types.attrs;
|
||||
description = "NixOS system";
|
||||
default = { };
|
||||
};
|
||||
};
|
||||
|
||||
config = {
|
||||
|
||||
tf.resource = mergeConf [
|
||||
(import ./containers-terraform-postgres.nix { inherit config tools lib; })
|
||||
(import ./containers-terraform-proxmox.nix { inherit config tools lib; })
|
||||
(import ./containers-terraform-authentik.nix { inherit config tools lib; })
|
||||
];
|
||||
|
||||
nixosModule = lib.mapAttrs (
|
||||
container: def:
|
||||
{ config, pkgs, ... }:
|
||||
let
|
||||
keys = import ../config/_keys.nix;
|
||||
ownKey = if (lib.hasAttr container keys) then keys.${container} else null;
|
||||
in
|
||||
mergeConf [
|
||||
(mergeConf (
|
||||
lib.attrValues (
|
||||
lib.mapAttrs (
|
||||
secretName': _:
|
||||
let
|
||||
secretName = lib.removeSuffix ".age" secretName';
|
||||
in
|
||||
{
|
||||
age.secrets.${secretName}.file = ../secrets/${secretName'};
|
||||
}
|
||||
) (lib.filterAttrs (_: entry: builtins.elem ownKey entry.publicKeys) secrets)
|
||||
)
|
||||
))
|
||||
nixosTemplate
|
||||
(lib.optionalAttrs (def.logging.enable) import ./containers-nixos-logging.nix {
|
||||
inherit
|
||||
config
|
||||
tools
|
||||
container
|
||||
def
|
||||
pkgs
|
||||
;
|
||||
})
|
||||
{
|
||||
networking.hostName = container;
|
||||
networking.firewall = {
|
||||
enable = true;
|
||||
allowedTCPPorts =
|
||||
def.system.additionalPorts
|
||||
++ (if (def.system.port != null) then [ def.system.port ] else [ ])
|
||||
++ (if (def.logging.enable) then [ 12345 ] else [ ]);
|
||||
allowedUDPPorts = def.system.udpPorts;
|
||||
};
|
||||
services = def.system.services;
|
||||
environment.etc = def.system.etcFiles;
|
||||
environment.systemPackages = def.system.packages;
|
||||
}
|
||||
def.system.additional
|
||||
(mergeConf (
|
||||
map (
|
||||
p:
|
||||
import p {
|
||||
inherit pkgs tools;
|
||||
config = mergeConf [
|
||||
realcfg
|
||||
config
|
||||
];
|
||||
}
|
||||
) def.system.importConfig
|
||||
))
|
||||
]
|
||||
|
||||
) cfg;
|
||||
};
|
||||
}
|
||||
53
modules/lxc-template.nix
Normal file
53
modules/lxc-template.nix
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
modulesPath = pkgs.path + "/nixos/modules";
|
||||
config = import ../config/_globals.nix { };
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/virtualisation/proxmox-lxc.nix")
|
||||
];
|
||||
|
||||
boot.isContainer = true;
|
||||
|
||||
systemd.suppressedSystemUnits = [
|
||||
"dev-mqueue.mount"
|
||||
"sys-kernel-debug.mount"
|
||||
"sys-fs-fuse-connections.mount"
|
||||
];
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
openssl
|
||||
coreutils
|
||||
];
|
||||
services.openssh.enable = true;
|
||||
nix.settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
auto-optimise-store = true;
|
||||
};
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
|
||||
time.timeZone = config.globals.default_tz;
|
||||
|
||||
users.users.root = {
|
||||
openssh.authorizedKeys.keys = [
|
||||
config.globals.master.public_ssh_key
|
||||
];
|
||||
initialPassword = "nixos";
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
}
|
||||
53
modules/nixos-kiosk-iso.nix
Normal file
53
modules/nixos-kiosk-iso.nix
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
let
|
||||
lib = pkgs.lib;
|
||||
modulesPath = pkgs.path + "/nixos/modules";
|
||||
config = import ../config/_globals.nix { };
|
||||
in
|
||||
{
|
||||
imports = [
|
||||
(modulesPath + "/virtualisation/proxmox-lxc.nix")
|
||||
];
|
||||
|
||||
boot.isContainer = true;
|
||||
|
||||
systemd.suppressedSystemUnits = [
|
||||
"dev-mqueue.mount"
|
||||
"sys-kernel-debug.mount"
|
||||
"sys-fs-fuse-connections.mount"
|
||||
];
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
openssl
|
||||
coreutils
|
||||
];
|
||||
services.openssh.enable = true;
|
||||
nix.settings = {
|
||||
experimental-features = [
|
||||
"nix-command"
|
||||
"flakes"
|
||||
];
|
||||
auto-optimise-store = true;
|
||||
};
|
||||
nix.gc = {
|
||||
automatic = true;
|
||||
dates = "weekly";
|
||||
options = "--delete-older-than 7d";
|
||||
};
|
||||
|
||||
time.timeZone = config.globals.default_tz;
|
||||
|
||||
users.users.root = {
|
||||
openssh.authorizedKeys.keys = [
|
||||
config.globals.master.public_ssh_key
|
||||
];
|
||||
initialPassword = "nixos";
|
||||
};
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
|
||||
system.stateVersion = "25.11";
|
||||
}
|
||||
42
modules/terraform-base.nix
Normal file
42
modules/terraform-base.nix
Normal file
@@ -0,0 +1,42 @@
|
||||
{ lib, ... }:
|
||||
{
|
||||
terraform.required_providers = {
|
||||
proxmox = {
|
||||
source = "Telmate/proxmox";
|
||||
version = "~> 2.9.11";
|
||||
};
|
||||
|
||||
postgresql = {
|
||||
source = "cyrilgdn/postgresql";
|
||||
version = "~> 1.26.0";
|
||||
};
|
||||
};
|
||||
|
||||
provider.proxmox = {
|
||||
pm_api_url = "\${var.pm_api_url}";
|
||||
pm_api_token_id = "\${var.pm_api_token_id}";
|
||||
pm_api_token_secret = "\${var.pm_api_token_secret}";
|
||||
pm_tls_insecure = "\${var.pm_tls_insecure}";
|
||||
};
|
||||
|
||||
variable.pm_api_url.type = "string";
|
||||
variable.pm_api_token_id.type = "string";
|
||||
variable.pm_api_token_secret.type = "string";
|
||||
variable.pm_tls_insecure.type = "bool";
|
||||
variable.pve_node.type = "string";
|
||||
variable.ostemplate.type = "string";
|
||||
|
||||
provider.postgresql = {
|
||||
host = "\${var.pg_host}";
|
||||
port = 5432;
|
||||
database = "postgres";
|
||||
username = "\${var.pg_user}";
|
||||
password = "\${var.pg_pass}";
|
||||
sslmode = "disable";
|
||||
connect_timeout = 15;
|
||||
};
|
||||
|
||||
variable.pg_host.type = "string";
|
||||
variable.pg_user.type = "string";
|
||||
variable.pg_pass.type = "string";
|
||||
}
|
||||
31
modules/tools.nix
Normal file
31
modules/tools.nix
Normal file
@@ -0,0 +1,31 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
...
|
||||
}:
|
||||
let
|
||||
build_ip =
|
||||
arg:
|
||||
(
|
||||
if (!lib.strings.isString arg) then
|
||||
"${config.globals.ip_prefix}${toString arg}"
|
||||
else
|
||||
let
|
||||
id = config.id.${arg};
|
||||
ip = if (id > 1000) then id - 1000 else id;
|
||||
in
|
||||
"${config.globals.ip_prefix}${toString ip}"
|
||||
);
|
||||
build_ip_cidr = arg: "${build_ip arg}/${toString config.globals.cidr}";
|
||||
mask_cidr = build_ip_cidr 0;
|
||||
build_hostname = arg: "${arg}${config.globals.domains.external}";
|
||||
in
|
||||
{
|
||||
build_ip = build_ip;
|
||||
build_ip_cidr = build_ip_cidr;
|
||||
mask_cidr = mask_cidr;
|
||||
build_hostname = build_hostname;
|
||||
|
||||
loki_addr = "${build_ip "monitoring"}:3100";
|
||||
metrics_addr = "${build_ip "metrics"}:9090";
|
||||
}
|
||||
Reference in New Issue
Block a user