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;
|
||||
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 {
|
||||
system = pkgs.hostPlatform.system;
|
||||
modules = [
|
||||
(
|
||||
{ config, ... }:
|
||||
{
|
||||
imports = [
|
||||
inputs.self.terranixModules.cloudflare
|
||||
inputs.terranix-hcloud.terranixModules.hcloud
|
||||
inputs.self.terranixModules.hcloud
|
||||
];
|
||||
|
||||
hcloud.enable = true;
|
||||
terraform.required_providers.hcloud.version = "~> 1.45.0";
|
||||
config = {
|
||||
terraform.backend.s3 = {
|
||||
bucket = "bw-terraform";
|
||||
key = cfg.bucket.key;
|
||||
|
@ -172,25 +172,17 @@ in
|
|||
skip_s3_checksum = true;
|
||||
};
|
||||
|
||||
data.hcloud_ssh_key.khs = {
|
||||
khscodes.hcloud.data.ssh_key.khs = {
|
||||
name = "ca.kaareskovgaard.net";
|
||||
};
|
||||
|
||||
resource.hcloud_primary_ip.ipv4 = {
|
||||
khscodes.hcloud.enable = true;
|
||||
khscodes.hcloud.server.compute = {
|
||||
inherit (cfg) server_type datacenter;
|
||||
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;
|
||||
name = fqdn;
|
||||
initial_image = "debian-12";
|
||||
rdns = fqdn;
|
||||
ssh_keys = [ config.khscodes.hcloud.output.data.ssh_key.khs.id ];
|
||||
};
|
||||
khscodes.cloudflare = {
|
||||
enable = true;
|
||||
|
@ -200,13 +192,13 @@ in
|
|||
aRecords = [
|
||||
{
|
||||
inherit fqdn;
|
||||
content = "\${ hcloud_server.compute.ipv4_address }";
|
||||
content = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
||||
}
|
||||
];
|
||||
aaaaRecords = [
|
||||
{
|
||||
inherit fqdn;
|
||||
content = "\${ hcloud_server.compute.ipv6_address }";
|
||||
content = config.khscodes.hcloud.output.server.compute.ipv6_address;
|
||||
}
|
||||
];
|
||||
};
|
||||
|
@ -215,54 +207,19 @@ in
|
|||
inherit labels;
|
||||
name = fqdn;
|
||||
apply_to = {
|
||||
server = "\${ hcloud_server.compute.id }";
|
||||
server = config.khscodes.hcloud.output.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 }";
|
||||
value = config.khscodes.hcloud.output.server.compute.ipv4_address;
|
||||
sensitive = false;
|
||||
};
|
||||
|
||||
output.ipv6_address = {
|
||||
value = "\${ hcloud_server.compute.ipv6_address }";
|
||||
value = config.khscodes.hcloud.output.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;
|
||||
};
|
||||
};
|
||||
}
|
||||
)
|
||||
|
|
|
@ -13,7 +13,6 @@ let
|
|||
"@"
|
||||
else
|
||||
fqdn;
|
||||
fqdnToTFname = fqdn: builtins.replaceStrings [ "." ] [ "_" ] fqdn;
|
||||
dnsARecordModule = khscodesLib.mkSubmodule {
|
||||
description = "Module for defining dns A/AAAA record";
|
||||
options = {
|
||||
|
@ -127,7 +126,7 @@ in
|
|||
resource.cloudflare_record = lib.attrsets.optionalAttrs cfg.dns.enable (
|
||||
lib.listToAttrs (
|
||||
(lib.lists.map (record: {
|
||||
name = "${fqdnToTFname record.fqdn}_a";
|
||||
name = "${khscodesLib.sanitize-terraform-name record.fqdn}_a";
|
||||
value = {
|
||||
inherit (record) content ttl proxied;
|
||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||
|
@ -137,7 +136,7 @@ in
|
|||
};
|
||||
}) cfg.dns.aRecords)
|
||||
++ (lib.lists.map (record: {
|
||||
name = "${fqdnToTFname record.fqdn}_aaaa";
|
||||
name = "${khscodesLib.sanitize-terraform-name record.fqdn}_aaaa";
|
||||
value = {
|
||||
inherit (record) content ttl proxied;
|
||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||
|
@ -147,7 +146,7 @@ in
|
|||
};
|
||||
}) cfg.dns.aaaaRecords)
|
||||
++ (lib.lists.map (record: {
|
||||
name = "${fqdnToTFname record.fqdn}_txt";
|
||||
name = "${khscodesLib.sanitize-terraform-name record.fqdn}_txt";
|
||||
value = {
|
||||
inherit (record) content ttl;
|
||||
name = nameFromFQDNAndZone record.fqdn cfg.dns.zone_name;
|
||||
|
@ -157,7 +156,7 @@ in
|
|||
};
|
||||
}) cfg.dns.txtRecords)
|
||||
++ (lib.lists.map (record: {
|
||||
name = "${fqdnToTFname record.fqdn}_mx";
|
||||
name = "${khscodesLib.sanitize-terraform-name record.fqdn}_mx";
|
||||
value = {
|
||||
inherit (record) content priority;
|
||||
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