machines/nix/modules/terranix/hcloud/default.nix

189 lines
5.2 KiB
Nix

{ inputs, khscodesLib }:
{ config, lib, ... }:
let
cfg = config.khscodes.hcloud;
serversWithRdns = lib.filterAttrs (_: value: value.rdns != null) cfg.server;
mapSanitizedAttrs =
f: list:
lib.listToAttrs (
lib.map (
{ name, value }:
let
sanitizedName = khscodesLib.sanitize-terraform-name name;
in
{
name = sanitizedName;
value = f {
inherit value;
name = sanitizedName;
};
}
) (lib.attrsToList list)
);
hcloudServerModule = khscodesLib.mkSubmodule {
description = "Module for defining hcloud server";
options = {
name = lib.mkOption {
type = lib.types.str;
description = "Name of the server";
};
server_type = lib.mkOption {
type = lib.types.str;
description = "Server type for the instance";
};
datacenter = lib.mkOption {
type = lib.types.str;
description = "Data center for the instance";
};
initial_image = lib.mkOption {
type = lib.types.str;
description = "Initial image of the server";
};
ssh_keys = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "The ssh keys added to the server";
};
labels = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
};
rdns = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
description = "FQDN to map rDNS to";
};
};
};
hcloudDataSshKeys = khscodesLib.mkSubmodule {
description = "SSH Keys";
options = {
name = lib.mkOption {
type = lib.types.str;
description = "The name of the ssh keys";
};
id = lib.mkOption {
type = lib.types.str;
description = "A terraform expression for the ssh keys";
};
};
};
in
{
options.khscodes.hcloud = {
enable = lib.mkEnableOption "Enables khscodes hcloud terranix integration";
server = lib.mkOption {
type = lib.types.attrsOf hcloudServerModule;
description = "Defines an hcloud server";
default = { };
};
data.ssh_key = lib.mkOption {
type = lib.types.attrsOf hcloudDataSshKeys;
description = "Reads ssh keys as data source from hcloud";
default = { };
};
};
imports = [
inputs.terranix-hcloud.terranixModules.hcloud
(import ./output.nix { inherit inputs khscodesLib; })
];
config = lib.mkIf cfg.enable {
hcloud.enable = true;
terraform.required_providers.hcloud.version = "~> 1.45.0";
resource.hcloud_server = mapSanitizedAttrs (
{ name, value }:
{
inherit (value)
server_type
datacenter
labels
ssh_keys
name
;
image = value.initial_image;
public_net = {
ipv4_enabled = true;
ipv4 = "\${ hcloud_primary_ip.${name}_ipv4.id }";
ipv6_enabled = true;
ipv6 = "\${ hcloud_primary_ip.${name}_ipv6.id }";
};
lifecycle = {
ignore_changes = [
"ssh_keys"
"public_net"
"image"
];
};
}
) cfg.server;
resource.hcloud_primary_ip =
(lib.mapAttrs' (
name: value:
let
sanitizedName = khscodesLib.sanitize-terraform-name name;
in
{
name = "${sanitizedName}_ipv4";
value = {
inherit (value) labels;
name = "${value.name} ipv4";
datacenter = value.datacenter;
type = "ipv4";
assignee_type = "server";
auto_delete = false;
};
}
) cfg.server)
// (lib.mapAttrs' (
name: value:
let
sanitizedName = khscodesLib.sanitize-terraform-name name;
in
{
name = "${sanitizedName}_ipv6";
value = {
inherit (value) labels;
name = "${value.name} ipv6";
datacenter = value.datacenter;
type = "ipv6";
assignee_type = "server";
auto_delete = false;
};
}
) cfg.server);
resource.hcloud_rdns =
(lib.mapAttrs' (
name: value:
let
sanitizedName = khscodesLib.sanitize-terraform-name name;
in
{
name = "${sanitizedName}_ipv4";
value = {
primary_ip_id = "\${ hcloud_primary_ip.${sanitizedName}_ipv4.id }";
ip_address = "\${ hcloud_server.${sanitizedName}.ipv4_address }";
dns_ptr = value.rdns;
};
}
) serversWithRdns)
// (lib.mapAttrs' (
name: value:
let
sanitizedName = khscodesLib.sanitize-terraform-name name;
in
{
name = "${sanitizedName}_ipv6";
value = {
primary_ip_id = "\${ hcloud_primary_ip.${sanitizedName}_ipv6.id }";
ip_address = "\${ hcloud_server.${sanitizedName}.ipv6_address }";
dns_ptr = value.rdns;
};
}
) serversWithRdns);
data.hcloud_ssh_key = mapSanitizedAttrs (
{ value, ... }:
{
name = value.name;
}
) cfg.data.ssh_key;
};
}