240 lines
6 KiB
Nix
240 lines
6 KiB
Nix
{ lib }:
|
|
|
|
let
|
|
inherit (lib) concatStringsSep genAttrs mkIf;
|
|
|
|
clusterName = "ultracloud-vm-cluster";
|
|
clusterId = clusterName;
|
|
environment = "dev";
|
|
bgpAsn = 64512;
|
|
|
|
bootstrapToken = "vm-cluster-bootstrap-token";
|
|
adminToken = "vm-cluster-admin-token";
|
|
|
|
chainfireApiPort = 2379;
|
|
chainfireRaftPort = 2380;
|
|
flaredbApiPort = 2479;
|
|
flaredbRaftPort = 2480;
|
|
iamPort = 50080;
|
|
|
|
controlPlaneLabels = {
|
|
tier = "control-plane";
|
|
platform = "vm-cluster";
|
|
};
|
|
|
|
controlPlaneNodes = {
|
|
node01 = {
|
|
ip = "192.168.100.11";
|
|
failureDomain = "rack-a";
|
|
};
|
|
node02 = {
|
|
ip = "192.168.100.12";
|
|
failureDomain = "rack-b";
|
|
};
|
|
node03 = {
|
|
ip = "192.168.100.13";
|
|
failureDomain = "rack-c";
|
|
};
|
|
};
|
|
|
|
controlPlaneNodeNames = builtins.attrNames controlPlaneNodes;
|
|
bootstrapNodeName = builtins.head controlPlaneNodeNames;
|
|
|
|
mkEndpoint = nodeName: port:
|
|
let
|
|
node = controlPlaneNodes.${nodeName};
|
|
in
|
|
"${node.ip}:${toString port}";
|
|
|
|
chainfireInitialPeers =
|
|
map (nodeName: "${nodeName}=${mkEndpoint nodeName chainfireRaftPort}") controlPlaneNodeNames;
|
|
|
|
flaredbInitialPeers =
|
|
map (nodeName: "${nodeName}=${mkEndpoint nodeName flaredbRaftPort}") controlPlaneNodeNames;
|
|
|
|
chainfireControlPlaneAddrs =
|
|
concatStringsSep "," (map (nodeName: mkEndpoint nodeName chainfireApiPort) controlPlaneNodeNames);
|
|
|
|
flaredbControlPlaneAddrs =
|
|
concatStringsSep "," (map (nodeName: mkEndpoint nodeName flaredbApiPort) controlPlaneNodeNames);
|
|
|
|
sharedDesiredSystem = {
|
|
healthCheckCommand = [ "systemctl" "is-system-running" "--wait" ];
|
|
rollbackOnFailure = true;
|
|
};
|
|
|
|
mkInstallPlan = nodeName: {
|
|
nixosConfiguration = nodeName;
|
|
diskoConfigPath = "nix/nodes/vm-cluster/${nodeName}/disko.nix";
|
|
targetDisk = "/dev/vda";
|
|
};
|
|
|
|
mkClusterNode = nodeName:
|
|
let
|
|
node = controlPlaneNodes.${nodeName};
|
|
in
|
|
{
|
|
role = "control-plane";
|
|
ip = node.ip;
|
|
services = [ "chainfire" "flaredb" "iam" ];
|
|
labels = controlPlaneLabels;
|
|
pool = "control";
|
|
nodeClass = "control-plane";
|
|
failureDomain = node.failureDomain;
|
|
nixProfile = "profiles/control-plane";
|
|
installPlan = mkInstallPlan nodeName;
|
|
desiredSystem = sharedDesiredSystem;
|
|
raftPort = chainfireRaftPort;
|
|
apiPort = chainfireApiPort;
|
|
};
|
|
|
|
clusterNodes = genAttrs controlPlaneNodeNames mkClusterNode;
|
|
|
|
nodeConfigurationPaths = {
|
|
node01 = ./node01/configuration.nix;
|
|
node02 = ./node02/configuration.nix;
|
|
node03 = ./node03/configuration.nix;
|
|
};
|
|
|
|
nodeDiskoPaths = {
|
|
node01 = ./node01/disko.nix;
|
|
node02 = ./node02/disko.nix;
|
|
node03 = ./node03/disko.nix;
|
|
};
|
|
in
|
|
{
|
|
inherit
|
|
adminToken
|
|
bgpAsn
|
|
bootstrapNodeName
|
|
bootstrapToken
|
|
chainfireApiPort
|
|
chainfireControlPlaneAddrs
|
|
chainfireInitialPeers
|
|
chainfireRaftPort
|
|
clusterId
|
|
clusterName
|
|
clusterNodes
|
|
controlPlaneLabels
|
|
controlPlaneNodeNames
|
|
controlPlaneNodes
|
|
environment
|
|
flaredbApiPort
|
|
flaredbControlPlaneAddrs
|
|
flaredbInitialPeers
|
|
flaredbRaftPort
|
|
iamPort
|
|
nodeConfigurationPaths
|
|
nodeDiskoPaths
|
|
sharedDesiredSystem
|
|
;
|
|
|
|
controlPlaneNodeClass = {
|
|
description = "Control-plane VM cluster nodes";
|
|
nixProfile = "profiles/control-plane";
|
|
roles = [ "control-plane" ];
|
|
labels = controlPlaneLabels;
|
|
};
|
|
|
|
controlPlanePool = {
|
|
description = "VM cluster control-plane pool";
|
|
nodeClass = "control-plane";
|
|
labels = {
|
|
plane = "control";
|
|
cluster = "vm-cluster";
|
|
};
|
|
};
|
|
|
|
hostDeployments = {
|
|
control-plane-canary = {
|
|
selector.nodeIds = [ bootstrapNodeName ];
|
|
nixosConfiguration = bootstrapNodeName;
|
|
flakeRef = "github:centra/cloud";
|
|
batchSize = 1;
|
|
maxUnavailable = 1;
|
|
healthCheckCommand = sharedDesiredSystem.healthCheckCommand;
|
|
switchAction = "switch";
|
|
rollbackOnFailure = sharedDesiredSystem.rollbackOnFailure;
|
|
};
|
|
};
|
|
|
|
mkControlPlaneNodeModule = nodeName:
|
|
{ lib, ... }:
|
|
{
|
|
imports = [
|
|
./cluster.nix
|
|
nodeDiskoPaths.${nodeName}
|
|
];
|
|
|
|
networking.hostName = nodeName;
|
|
networking.useDHCP = lib.mkDefault true;
|
|
|
|
boot.loader.grub = {
|
|
enable = true;
|
|
devices = [ "/dev/vda" ];
|
|
efiSupport = true;
|
|
efiInstallAsRemovable = true;
|
|
};
|
|
|
|
services.chainfire = {
|
|
enable = true;
|
|
nodeId = nodeName;
|
|
apiAddr = mkEndpoint nodeName chainfireApiPort;
|
|
raftAddr = mkEndpoint nodeName chainfireRaftPort;
|
|
initialPeers = chainfireInitialPeers;
|
|
};
|
|
|
|
services.flaredb = {
|
|
enable = true;
|
|
nodeId = nodeName;
|
|
apiAddr = mkEndpoint nodeName flaredbApiPort;
|
|
raftAddr = mkEndpoint nodeName flaredbRaftPort;
|
|
initialPeers = flaredbInitialPeers;
|
|
};
|
|
|
|
services.iam = {
|
|
enable = true;
|
|
port = iamPort;
|
|
chainfireAddr = chainfireControlPlaneAddrs;
|
|
flaredbAddr = flaredbControlPlaneAddrs;
|
|
};
|
|
|
|
services.openssh.enable = true;
|
|
users.users.root.openssh.authorizedKeys.keys = [ ];
|
|
|
|
system.stateVersion = "24.05";
|
|
};
|
|
|
|
mkBootstrapServicesModule =
|
|
{ self
|
|
, nodeName
|
|
, enableDeployer ? false
|
|
,
|
|
}:
|
|
{ pkgs, lib, ... }:
|
|
{
|
|
services.nix-agent = {
|
|
enable = true;
|
|
chainfireEndpoint = "http://${mkEndpoint bootstrapNodeName chainfireApiPort}";
|
|
clusterId = clusterId;
|
|
nodeId = nodeName;
|
|
flakeRoot = self.outPath;
|
|
intervalSecs = 30;
|
|
apply = true;
|
|
};
|
|
|
|
services.deployer = mkIf enableDeployer {
|
|
enable = true;
|
|
bindAddr = "0.0.0.0:8088";
|
|
chainfireEndpoints = [ "http://${mkEndpoint bootstrapNodeName chainfireApiPort}" ];
|
|
clusterId = clusterId;
|
|
requireChainfire = true;
|
|
allowUnknownNodes = false;
|
|
allowUnauthenticated = false;
|
|
bootstrapToken = bootstrapToken;
|
|
adminToken = adminToken;
|
|
bootstrapFlakeBundle = pkgs.ultracloudFlakeBundle;
|
|
seedClusterState = true;
|
|
};
|
|
};
|
|
}
|