Refactor terranix code to be more reusable and maintainable
Hopefully
This commit is contained in:
parent
2f725ca3ea
commit
624508dd14
6 changed files with 337 additions and 115 deletions
|
@ -66,5 +66,9 @@
|
||||||
inherit inputs;
|
inherit inputs;
|
||||||
khscodesLib = inputs.self.lib;
|
khscodesLib = inputs.self.lib;
|
||||||
};
|
};
|
||||||
|
terranixModules.hcloud = import ./nix/modules/terranix/hcloud {
|
||||||
|
inherit inputs;
|
||||||
|
khscodesLib = inputs.self.lib;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
4
nix/lib/sanitize-terraform-name/default.nix
Normal file
4
nix/lib/sanitize-terraform-name/default.nix
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
sanitize-terraform-name = name: builtins.replaceStrings [ "." ] [ "_" ] name;
|
||||||
|
}
|
|
@ -149,14 +149,14 @@ in
|
||||||
config = inputs.terranix.lib.terranixConfiguration {
|
config = inputs.terranix.lib.terranixConfiguration {
|
||||||
system = pkgs.hostPlatform.system;
|
system = pkgs.hostPlatform.system;
|
||||||
modules = [
|
modules = [
|
||||||
|
(
|
||||||
|
{ config, ... }:
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
inputs.self.terranixModules.cloudflare
|
inputs.self.terranixModules.cloudflare
|
||||||
inputs.terranix-hcloud.terranixModules.hcloud
|
inputs.self.terranixModules.hcloud
|
||||||
];
|
];
|
||||||
|
config = {
|
||||||
hcloud.enable = true;
|
|
||||||
terraform.required_providers.hcloud.version = "~> 1.45.0";
|
|
||||||
terraform.backend.s3 = {
|
terraform.backend.s3 = {
|
||||||
bucket = "bw-terraform";
|
bucket = "bw-terraform";
|
||||||
key = cfg.bucket.key;
|
key = cfg.bucket.key;
|
||||||
|
@ -172,25 +172,17 @@ in
|
||||||
skip_s3_checksum = true;
|
skip_s3_checksum = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
data.hcloud_ssh_key.khs = {
|
khscodes.hcloud.data.ssh_key.khs = {
|
||||||
name = "ca.kaareskovgaard.net";
|
name = "ca.kaareskovgaard.net";
|
||||||
};
|
};
|
||||||
|
khscodes.hcloud.enable = true;
|
||||||
resource.hcloud_primary_ip.ipv4 = {
|
khscodes.hcloud.server.compute = {
|
||||||
|
inherit (cfg) server_type datacenter;
|
||||||
inherit labels;
|
inherit labels;
|
||||||
name = "${fqdn} ipv4";
|
name = fqdn;
|
||||||
datacenter = cfg.datacenter;
|
initial_image = "debian-12";
|
||||||
type = "ipv4";
|
rdns = fqdn;
|
||||||
assignee_type = "server";
|
ssh_keys = [ config.khscodes.hcloud.output.data.ssh_key.khs.id ];
|
||||||
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 = {
|
khscodes.cloudflare = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
@ -200,13 +192,13 @@ in
|
||||||
aRecords = [
|
aRecords = [
|
||||||
{
|
{
|
||||||
inherit fqdn;
|
inherit fqdn;
|
||||||
content = "\${ hcloud_server.compute.ipv4_address }";
|
content = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
aaaaRecords = [
|
aaaaRecords = [
|
||||||
{
|
{
|
||||||
inherit fqdn;
|
inherit fqdn;
|
||||||
content = "\${ hcloud_server.compute.ipv6_address }";
|
content = config.khscodes.hcloud.output.server.compute.ipv6_address;
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
@ -215,54 +207,19 @@ in
|
||||||
inherit labels;
|
inherit labels;
|
||||||
name = fqdn;
|
name = fqdn;
|
||||||
apply_to = {
|
apply_to = {
|
||||||
server = "\${ hcloud_server.compute.id }";
|
server = config.khscodes.hcloud.output.server.compute.id;
|
||||||
};
|
};
|
||||||
rule = firewallRules;
|
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 = {
|
output.ipv4_address = {
|
||||||
value = "\${ hcloud_server.compute.ipv4_address }";
|
value = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
||||||
sensitive = false;
|
sensitive = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
output.ipv6_address = {
|
output.ipv6_address = {
|
||||||
value = "\${ hcloud_server.compute.ipv6_address }";
|
value = config.khscodes.hcloud.output.server.compute.ipv6_address;
|
||||||
sensitive = false;
|
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;
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -13,7 +13,6 @@ let
|
||||||
"@"
|
"@"
|
||||||
else
|
else
|
||||||
fqdn;
|
fqdn;
|
||||||
fqdnToTFname = fqdn: builtins.replaceStrings [ "." ] [ "_" ] fqdn;
|
|
||||||
dnsARecordModule = khscodesLib.mkSubmodule {
|
dnsARecordModule = khscodesLib.mkSubmodule {
|
||||||
description = "Module for defining dns A/AAAA record";
|
description = "Module for defining dns A/AAAA record";
|
||||||
options = {
|
options = {
|
||||||
|
@ -127,7 +126,7 @@ in
|
||||||
resource.cloudflare_record = lib.attrsets.optionalAttrs cfg.dns.enable (
|
resource.cloudflare_record = lib.attrsets.optionalAttrs cfg.dns.enable (
|
||||||
lib.listToAttrs (
|
lib.listToAttrs (
|
||||||
(lib.lists.map (record: {
|
(lib.lists.map (record: {
|
||||||
name = "${fqdnToTFname record.fqdn}_a";
|
name = "${khscodesLib.sanitize-terraform-name record.fqdn}_a";
|
||||||
value = {
|
value = {
|
||||||
inherit (record) content ttl proxied;
|
inherit (record) content ttl proxied;
|
||||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||||
|
@ -137,7 +136,7 @@ in
|
||||||
};
|
};
|
||||||
}) cfg.dns.aRecords)
|
}) cfg.dns.aRecords)
|
||||||
++ (lib.lists.map (record: {
|
++ (lib.lists.map (record: {
|
||||||
name = "${fqdnToTFname record.fqdn}_aaaa";
|
name = "${khscodesLib.sanitize-terraform-name record.fqdn}_aaaa";
|
||||||
value = {
|
value = {
|
||||||
inherit (record) content ttl proxied;
|
inherit (record) content ttl proxied;
|
||||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||||
|
@ -147,7 +146,7 @@ in
|
||||||
};
|
};
|
||||||
}) cfg.dns.aaaaRecords)
|
}) cfg.dns.aaaaRecords)
|
||||||
++ (lib.lists.map (record: {
|
++ (lib.lists.map (record: {
|
||||||
name = "${fqdnToTFname record.fqdn}_txt";
|
name = "${khscodesLib.sanitize-terraform-name record.fqdn}_txt";
|
||||||
value = {
|
value = {
|
||||||
inherit (record) content ttl;
|
inherit (record) content ttl;
|
||||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||||
|
@ -157,7 +156,7 @@ in
|
||||||
};
|
};
|
||||||
}) cfg.dns.txtRecords)
|
}) cfg.dns.txtRecords)
|
||||||
++ (lib.lists.map (record: {
|
++ (lib.lists.map (record: {
|
||||||
name = "${fqdnToTFname record.fqdn}_mx";
|
name = "${khscodesLib.sanitize-terraform-name record.fqdn}_mx";
|
||||||
value = {
|
value = {
|
||||||
inherit (record) content priority;
|
inherit (record) content priority;
|
||||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||||
|
|
189
nix/modules/terranix/hcloud/default.nix
Normal file
189
nix/modules/terranix/hcloud/default.nix
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
{ 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;
|
||||||
|
};
|
||||||
|
}
|
69
nix/modules/terranix/hcloud/output.nix
Normal file
69
nix/modules/terranix/hcloud/output.nix
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{ inputs, khscodesLib }:
|
||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.khscodes.hcloud;
|
||||||
|
hcloudOutputServerModule = khscodesLib.mkSubmodule {
|
||||||
|
description = "Module defined when a corresponding server has been defined";
|
||||||
|
options = {
|
||||||
|
id = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "ID of the instance, as a terraform string expression";
|
||||||
|
};
|
||||||
|
ipv4_address = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "IPv4 address of the instance, as a terraform string expression";
|
||||||
|
};
|
||||||
|
ipv6_address = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "IPv6 address of the instance, as a terraform string expression";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
hcloudDataOutputSshKeyModule = khscodesLib.mkSubmodule {
|
||||||
|
description = "Module defined when a corresponding ssh key has ben retrieved";
|
||||||
|
options = {
|
||||||
|
id = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "ID of the ssh key, as a terraform string expression";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.khscodes.hcloud = {
|
||||||
|
output.server = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf hcloudOutputServerModule;
|
||||||
|
description = "Set by this module to be read by other modules when needing results of defining a server";
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
output.data.ssh_key = lib.mkOption {
|
||||||
|
type = lib.types.attrsOf hcloudDataOutputSshKeyModule;
|
||||||
|
description = "Set by this module to be read by other modules when needing the result of the ssh key";
|
||||||
|
default = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
config = {
|
||||||
|
khscodes.hcloud.output.server = lib.attrsets.mapAttrs (
|
||||||
|
name: value:
|
||||||
|
(
|
||||||
|
let
|
||||||
|
sanitizedName = khscodesLib.sanitize-terraform-name name;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
id = "\${ hcloud_server.${sanitizedName}.id }";
|
||||||
|
ipv4_address = "\${ hcloud_server.${sanitizedName}.ipv4_address }";
|
||||||
|
ipv6_address = "\${ hcloud_server.${sanitizedName}.ipv4_address }";
|
||||||
|
}
|
||||||
|
)
|
||||||
|
) cfg.server;
|
||||||
|
khscodes.hcloud.output.data.ssh_key = lib.attrsets.mapAttrs (
|
||||||
|
name: _:
|
||||||
|
let
|
||||||
|
sanitizedName = khscodesLib.sanitize-terraform-name name;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
id = "\${ data.hcloud_ssh_key.${sanitizedName}.id }";
|
||||||
|
}
|
||||||
|
) cfg.data.ssh_key;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue