First PoC on provisioning instance end to end on openstack
This commit is contained in:
parent
1e8460c2ec
commit
1945038c90
24 changed files with 479 additions and 44 deletions
178
flake.lock
generated
178
flake.lock
generated
|
@ -83,6 +83,28 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"disko_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixos-anywhere",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1748225455,
|
||||||
|
"narHash": "sha256-AzlJCKaM4wbEyEpV3I/PUq5mHnib2ryEy32c+qfj6xk=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "disko",
|
||||||
|
"rev": "a894f2811e1ee8d10c50560551e50d6ab3c392ba",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"ref": "master",
|
||||||
|
"repo": "disko",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"flake-base": {
|
"flake-base": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
|
@ -122,6 +144,27 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"flake-parts": {
|
"flake-parts": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs-lib": [
|
||||||
|
"nixos-anywhere",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1743550720,
|
||||||
|
"narHash": "sha256-hIshGgKZCgWh6AYJpJmRgFdR3WUbkY04o82X05xqQiY=",
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"rev": "c621e8422220273271f52058f618c94e405bb0f5",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "hercules-ci",
|
||||||
|
"repo": "flake-parts",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"flake-parts_2": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"nixpkgs-lib": [
|
"nixpkgs-lib": [
|
||||||
"terranix",
|
"terranix",
|
||||||
|
@ -209,6 +252,116 @@
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"home-manager": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1751810233,
|
||||||
|
"narHash": "sha256-kllkNbIqQi3VplgTMeGzuh1t8Gk8TauvkTRt93Km+tQ=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"rev": "9b0873b46c9f9e4b7aa01eb634952c206af53068",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"ref": "release-25.05",
|
||||||
|
"repo": "home-manager",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nix-vm-test": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixos-anywhere",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1748765518,
|
||||||
|
"narHash": "sha256-vftOR+7zwnMWl5UpG32GL1VBeNGTDZZT0hv+2uNuBGw=",
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "nix-vm-test",
|
||||||
|
"rev": "d6642fbaf42fc98883d84bab66cd0ec720d9dd0c",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "Mic92",
|
||||||
|
"repo": "nix-vm-test",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-anywhere": {
|
||||||
|
"inputs": {
|
||||||
|
"disko": "disko_2",
|
||||||
|
"flake-parts": "flake-parts",
|
||||||
|
"nix-vm-test": "nix-vm-test",
|
||||||
|
"nixos-images": "nixos-images",
|
||||||
|
"nixos-stable": "nixos-stable",
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixpkgs"
|
||||||
|
],
|
||||||
|
"treefmt-nix": "treefmt-nix_2"
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1749105224,
|
||||||
|
"narHash": "sha256-hVTCvMnwywxQ6rGgO7ytBiSpVuLOHNgm3w3vE8UNaQY=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixos-anywhere",
|
||||||
|
"rev": "55fc48f9677822393cd9585b6742e1194accf365",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"ref": "1.11.0",
|
||||||
|
"repo": "nixos-anywhere",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-images": {
|
||||||
|
"inputs": {
|
||||||
|
"nixos-stable": [
|
||||||
|
"nixos-anywhere",
|
||||||
|
"nixos-stable"
|
||||||
|
],
|
||||||
|
"nixos-unstable": [
|
||||||
|
"nixos-anywhere",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1748481078,
|
||||||
|
"narHash": "sha256-jwKRF2EDzlv0VBF8pImPFT7DAJma7stDun25utHtwBw=",
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixos-images",
|
||||||
|
"rev": "191a461dc38313ff41bd3df4b82e49f74a56560d",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "nix-community",
|
||||||
|
"repo": "nixos-images",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nixos-stable": {
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1748437600,
|
||||||
|
"narHash": "sha256-hYKMs3ilp09anGO7xzfGs3JqEgUqFMnZ8GMAqI6/k04=",
|
||||||
|
"owner": "NixOS",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"rev": "7282cb574e0607e65224d33be8241eae7cfe0979",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "NixOS",
|
||||||
|
"ref": "nixos-25.05",
|
||||||
|
"repo": "nixpkgs",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1751582995,
|
"lastModified": 1751582995,
|
||||||
|
@ -246,6 +399,8 @@
|
||||||
"crane": "crane",
|
"crane": "crane",
|
||||||
"disko": "disko",
|
"disko": "disko",
|
||||||
"flake-base": "flake-base",
|
"flake-base": "flake-base",
|
||||||
|
"home-manager": "home-manager",
|
||||||
|
"nixos-anywhere": "nixos-anywhere",
|
||||||
"nixpkgs": "nixpkgs",
|
"nixpkgs": "nixpkgs",
|
||||||
"rust-overlay": "rust-overlay",
|
"rust-overlay": "rust-overlay",
|
||||||
"terranix": "terranix",
|
"terranix": "terranix",
|
||||||
|
@ -327,7 +482,7 @@
|
||||||
},
|
},
|
||||||
"terranix": {
|
"terranix": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-parts": "flake-parts",
|
"flake-parts": "flake-parts_2",
|
||||||
"nixpkgs": [
|
"nixpkgs": [
|
||||||
"nixpkgs"
|
"nixpkgs"
|
||||||
],
|
],
|
||||||
|
@ -427,6 +582,27 @@
|
||||||
"repo": "treefmt-nix",
|
"repo": "treefmt-nix",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"treefmt-nix_2": {
|
||||||
|
"inputs": {
|
||||||
|
"nixpkgs": [
|
||||||
|
"nixos-anywhere",
|
||||||
|
"nixpkgs"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"locked": {
|
||||||
|
"lastModified": 1748243702,
|
||||||
|
"narHash": "sha256-9YzfeN8CB6SzNPyPm2XjRRqSixDopTapaRsnTpXUEY8=",
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"rev": "1f3f7b784643d488ba4bf315638b2b0a4c5fb007",
|
||||||
|
"type": "github"
|
||||||
|
},
|
||||||
|
"original": {
|
||||||
|
"owner": "numtide",
|
||||||
|
"repo": "treefmt-nix",
|
||||||
|
"type": "github"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"root": "root",
|
"root": "root",
|
||||||
|
|
10
flake.nix
10
flake.nix
|
@ -15,6 +15,10 @@
|
||||||
url = "github:terranix/terranix";
|
url = "github:terranix/terranix";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
|
home-manager = {
|
||||||
|
url = "github:nix-community/home-manager/release-25.05";
|
||||||
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
terranix-hcloud = {
|
terranix-hcloud = {
|
||||||
url = "github:terranix/terranix-hcloud";
|
url = "github:terranix/terranix-hcloud";
|
||||||
inputs.nixpkgs.follows = "nixpkgs";
|
inputs.nixpkgs.follows = "nixpkgs";
|
||||||
|
@ -30,6 +34,12 @@
|
||||||
nixpkgs.follows = "nixpkgs";
|
nixpkgs.follows = "nixpkgs";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
nixos-anywhere = {
|
||||||
|
url = "github:nix-community/nixos-anywhere/1.11.0";
|
||||||
|
inputs = {
|
||||||
|
nixpkgs.follows = "nixpkgs";
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
snowfallorg.user.name = "khs";
|
||||||
|
home.stateVersion = "25.05";
|
||||||
|
}
|
53
nix/lib/disko-root-lvm-bios/default.nix
Normal file
53
nix/lib/disko-root-lvm-bios/default.nix
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
{ ... }:
|
||||||
|
{
|
||||||
|
disko-root-lvm-bios =
|
||||||
|
{
|
||||||
|
diskName,
|
||||||
|
device,
|
||||||
|
mbrSize ? "1M",
|
||||||
|
bootPartName ? "mbr",
|
||||||
|
rootPartName ? "primary",
|
||||||
|
volumeGroupName ? "mainpool",
|
||||||
|
rootLvName ? "root",
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
devices.disk = {
|
||||||
|
"${diskName}" = {
|
||||||
|
inherit device;
|
||||||
|
type = "disk";
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
"${bootPartName}" = {
|
||||||
|
size = mbrSize;
|
||||||
|
type = "EF02";
|
||||||
|
};
|
||||||
|
"${rootPartName}" = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "lvm_pv";
|
||||||
|
vg = volumeGroupName;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
devices.lvm_vg = {
|
||||||
|
"${volumeGroupName}" = {
|
||||||
|
type = "lvm_vg";
|
||||||
|
lvs = {
|
||||||
|
"${rootLvName}" = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "ext4";
|
||||||
|
mountpoint = "/";
|
||||||
|
mountOptions = [ "defaults" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{ ... }:
|
{ ... }:
|
||||||
{
|
{
|
||||||
disko-root-lvm =
|
disko-root-lvm-uefi =
|
||||||
{
|
{
|
||||||
diskName,
|
diskName,
|
||||||
device,
|
device,
|
|
@ -24,7 +24,7 @@ in
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
disko = lib.khscodes.disko-root-lvm {
|
disko = lib.khscodes.disko-root-lvm-uefi {
|
||||||
device = "/dev/sda";
|
device = "/dev/sda";
|
||||||
diskName = cfg.diskName;
|
diskName = cfg.diskName;
|
||||||
};
|
};
|
||||||
|
|
|
@ -184,11 +184,18 @@ in
|
||||||
khscodes.openstack.compute_instance.compute = {
|
khscodes.openstack.compute_instance.compute = {
|
||||||
inherit tags;
|
inherit tags;
|
||||||
name = fqdn;
|
name = fqdn;
|
||||||
initial_image = "Ubuntu-22.04";
|
initial_image = "debian-12";
|
||||||
flavor = cfg.flavor;
|
flavor = cfg.flavor;
|
||||||
ssh_public_key = cfg.ssh_key;
|
ssh_public_key = cfg.ssh_key;
|
||||||
firewall_rules = firewallRules;
|
firewall_rules = firewallRules;
|
||||||
};
|
};
|
||||||
|
khscodes.unifi.enable = true;
|
||||||
|
khscodes.unifi.static_route.compute = {
|
||||||
|
name = fqdn;
|
||||||
|
network = config.khscodes.openstack.output.compute_instance.compute.ipv6_cidr;
|
||||||
|
distance = 1;
|
||||||
|
next_hop = config.khscodes.openstack.output.compute_instance.compute.ipv6_external_gateway;
|
||||||
|
};
|
||||||
khscodes.cloudflare = {
|
khscodes.cloudflare = {
|
||||||
enable = true;
|
enable = true;
|
||||||
dns = {
|
dns = {
|
||||||
|
@ -230,15 +237,18 @@ in
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
khscodes.provisioning.pre = {
|
khscodes.provisioning = {
|
||||||
modules = modules;
|
pre = {
|
||||||
secretsSource = cfg.secretsSource;
|
modules = modules;
|
||||||
endpoints = [
|
secretsSource = cfg.secretsSource;
|
||||||
"aws"
|
endpoints = [
|
||||||
"cloudflare"
|
"aws"
|
||||||
"openstack"
|
"cloudflare"
|
||||||
"unifi"
|
"openstack"
|
||||||
];
|
"unifi"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
preImageUsername = "debian";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
|
@ -16,11 +16,12 @@ in
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
disko = lib.khscodes.disko-root-lvm {
|
disko = lib.khscodes.disko-root-lvm-bios {
|
||||||
device = "/dev/sda";
|
device = "/dev/sda";
|
||||||
diskName = cfg.diskName;
|
diskName = cfg.diskName;
|
||||||
};
|
};
|
||||||
khscodes.systemd-boot.enable = lib.mkDefault true;
|
boot.loader.grub.efiSupport = false;
|
||||||
|
boot.loader.timeout = 1;
|
||||||
khscodes.qemu-guest.enable = true;
|
khscodes.qemu-guest.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,11 @@ in
|
||||||
type = lib.types.nullOr lib.types.path;
|
type = lib.types.nullOr lib.types.path;
|
||||||
description = "The generated config for the pre provisioning, if any was specified";
|
description = "The generated config for the pre provisioning, if any was specified";
|
||||||
};
|
};
|
||||||
|
preImageUsername = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The username for the image being deployed before being swapped for NixOS";
|
||||||
|
default = "root";
|
||||||
|
};
|
||||||
postConfig = lib.mkOption {
|
postConfig = lib.mkOption {
|
||||||
type = lib.types.nullOr lib.types.path;
|
type = lib.types.nullOr lib.types.path;
|
||||||
description = "The generated config for the post provisioning, if any was specified";
|
description = "The generated config for the post provisioning, if any was specified";
|
||||||
|
|
20
nix/modules/nixos/services/openssh/default.nix
Normal file
20
nix/modules/nixos/services/openssh/default.nix
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
{ config, lib, ... }:
|
||||||
|
let
|
||||||
|
cfg = config.khscodes.services.openssh;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.khscodes.services.openssh = {
|
||||||
|
enable = lib.mkEnableOption "Enables openssh service for the instance";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
services.openssh = {
|
||||||
|
enable = true;
|
||||||
|
settings = {
|
||||||
|
PasswordAuthentication = false;
|
||||||
|
PermitRootLogin = "no";
|
||||||
|
KbdInteractiveAuthentication = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1,11 +0,0 @@
|
||||||
{ config, lib, ... }:
|
|
||||||
let
|
|
||||||
cfg = config.khscodes.sshd;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
options.khscodes.sshd.enable = lib.mkEnableOption "Enables sshd for the instance";
|
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
|
||||||
services.sshd.enable = true;
|
|
||||||
};
|
|
||||||
}
|
|
|
@ -21,6 +21,10 @@ let
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
description = "The IPv6 external gateway for the network. This is useful to eg. create static routes in Unifi";
|
description = "The IPv6 external gateway for the network. This is useful to eg. create static routes in Unifi";
|
||||||
};
|
};
|
||||||
|
ipv6_cidr = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "IPv6 cidr";
|
||||||
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in
|
in
|
||||||
|
@ -44,6 +48,7 @@ in
|
||||||
ipv4_address = "\${ openstack_networking_floatingip_v2.${sanitizedName}.address }";
|
ipv4_address = "\${ openstack_networking_floatingip_v2.${sanitizedName}.address }";
|
||||||
ipv6_address = "\${ data.openstack_networking_port_v2.${sanitizedName}.all_fixed_ips[1] }";
|
ipv6_address = "\${ data.openstack_networking_port_v2.${sanitizedName}.all_fixed_ips[1] }";
|
||||||
ipv6_external_gateway = "\${ [for ip in openstack_networking_router_v2.${sanitizedName}.external_fixed_ip : ip.ip_address if replace(ip.ip_address, \":\", \"\") != ip.ip_address][0] }";
|
ipv6_external_gateway = "\${ [for ip in openstack_networking_router_v2.${sanitizedName}.external_fixed_ip : ip.ip_address if replace(ip.ip_address, \":\", \"\") != ip.ip_address][0] }";
|
||||||
|
ipv6_cidr = "\${ openstack_networking_subnet_v2.${sanitizedName}_ip6.cidr }";
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
) cfg.compute_instance;
|
) cfg.compute_instance;
|
||||||
|
|
|
@ -5,19 +5,65 @@ let
|
||||||
modules = [
|
modules = [
|
||||||
./output.nix
|
./output.nix
|
||||||
];
|
];
|
||||||
|
unifiStaticRouteModule = khscodesLib.mkSubmodule {
|
||||||
|
description = "Unifi static route";
|
||||||
|
options = {
|
||||||
|
network = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The network to make a static route for";
|
||||||
|
};
|
||||||
|
name = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "Human friendly name of the static route";
|
||||||
|
};
|
||||||
|
distance = lib.mkOption {
|
||||||
|
type = lib.types.int;
|
||||||
|
description = "The distance of the hop";
|
||||||
|
};
|
||||||
|
next_hop = lib.mkOption {
|
||||||
|
type = lib.types.str;
|
||||||
|
description = "The router that can route the network";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.khscodes.unifi = {
|
options.khscodes.unifi = {
|
||||||
enable = lib.mkEnableOption "Enables the unifi provider";
|
enable = lib.mkEnableOption "Enables the unifi provider";
|
||||||
bucket = {
|
static_route = lib.mkOption {
|
||||||
key = lib.mkOption {
|
type = lib.types.attrsOf unifiStaticRouteModule;
|
||||||
type = lib.types.str;
|
description = "Static routes";
|
||||||
description = "key for the bucket to use";
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
imports = lib.lists.map (m: import m { inherit khscodesLib inputs; }) modules;
|
imports = lib.lists.map (m: import m { inherit khscodesLib inputs; }) modules;
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable { };
|
config = lib.mkIf cfg.enable {
|
||||||
|
terraform.required_providers.unifi = {
|
||||||
|
source = "paultyng/unifi";
|
||||||
|
version = "= 0.42.0-prerelease";
|
||||||
|
};
|
||||||
|
provider.unifi = {
|
||||||
|
allow_insecure = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
resource.unifi_static_route = lib.mapAttrs' (
|
||||||
|
name: value:
|
||||||
|
let
|
||||||
|
sanitizedName = khscodesLib.sanitize-terraform-name name;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
name = sanitizedName;
|
||||||
|
value = {
|
||||||
|
inherit (value)
|
||||||
|
network
|
||||||
|
name
|
||||||
|
distance
|
||||||
|
next_hop
|
||||||
|
;
|
||||||
|
type = "nexthop-route";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
) cfg.static_route;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,8 @@
|
||||||
TF_VAR_hcloud_api_token = "Terraform API Token";
|
TF_VAR_hcloud_api_token = "Terraform API Token";
|
||||||
};
|
};
|
||||||
"Ubiquiti" = {
|
"Ubiquiti" = {
|
||||||
TF_VAR_unifi_username = "Terraform username";
|
UNIFI_USERNAME = "Terraform username";
|
||||||
TF_VAR_unifi_password = "Terraform password";
|
UNIFI_PASSWORD = "Terraform password";
|
||||||
TF_VAR_unifi_url = "Terraform URL";
|
UNIFI_API = "Terraform URL";
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
9
nix/packages/create-instance/default.nix
Normal file
9
nix/packages/create-instance/default.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "create-instance";
|
||||||
|
runtimeInputs = [ pkgs.khscodes.pre-provisioning ];
|
||||||
|
text = ''
|
||||||
|
instance="''${1:-}"
|
||||||
|
pre-provisioning "$instance" apply
|
||||||
|
'';
|
||||||
|
}
|
9
nix/packages/destroy-instance/default.nix
Normal file
9
nix/packages/destroy-instance/default.nix
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "destroy-instance";
|
||||||
|
runtimeInputs = [ pkgs.khscodes.pre-provisioning ];
|
||||||
|
text = ''
|
||||||
|
instance="''${1:-}"
|
||||||
|
pre-provisioning "$instance" destroy
|
||||||
|
'';
|
||||||
|
}
|
27
nix/packages/nixos-install/default.nix
Normal file
27
nix/packages/nixos-install/default.nix
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
{
|
||||||
|
inputs,
|
||||||
|
pkgs,
|
||||||
|
}:
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "nixos-install";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.nix
|
||||||
|
pkgs.nixos-anywhere
|
||||||
|
];
|
||||||
|
# TODO: Use secret source and required secrets to set up the correct env variables
|
||||||
|
text = ''
|
||||||
|
hostname="$1"
|
||||||
|
# Build the configuration to ensure it doesn't fail when trying to install it on the host
|
||||||
|
nix build --no-link '${inputs.self}#nixosConfigurations."'"$hostname"'".config.system.build.toplevel'
|
||||||
|
# Allow overriding the host to connec tto, this is useful when testing and the DNS entries are stale with older IPs.
|
||||||
|
host="''${2:-$1}"
|
||||||
|
baseAttr='${inputs.self}#nixosConfigurations."'"$hostname"'".config.khscodes.provisioning'
|
||||||
|
config="$(nix build --no-link --print-out-paths "''${baseAttr}.preConfig")"
|
||||||
|
username="$(nix eval --raw "''${baseAttr}.preImageUsername")"
|
||||||
|
if [[ "$config" == "null" ]]; then
|
||||||
|
echo "No preprovisioning needed"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
nixos-anywhere --flake "${inputs.self}#$hostname" --target-host "$username@$host"
|
||||||
|
'';
|
||||||
|
}
|
|
@ -5,7 +5,7 @@ pkgs.terraform-providers.mkProvider {
|
||||||
owner = "paultyng";
|
owner = "paultyng";
|
||||||
repo = "terraform-provider-unifi";
|
repo = "terraform-provider-unifi";
|
||||||
rev = "ff9c041b3dc4dc6cf6db4c824a43ed6d3ae408d1";
|
rev = "ff9c041b3dc4dc6cf6db4c824a43ed6d3ae408d1";
|
||||||
version = "v0.42.0-prerelease";
|
version = "0.42.0-prerelease";
|
||||||
spdx = "MPL-2.0";
|
spdx = "MPL-2.0";
|
||||||
vendorHash = null;
|
vendorHash = null;
|
||||||
}
|
}
|
||||||
|
|
10
nix/packages/update-instance/default.nix
Normal file
10
nix/packages/update-instance/default.nix
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
{ inputs, pkgs, ... }:
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "update-instance";
|
||||||
|
runtimeInputs = [ pkgs.nixos-rebuild ];
|
||||||
|
text = ''
|
||||||
|
instance="''${1:-}"
|
||||||
|
connect_host="''${2:-$1}"
|
||||||
|
nixos-rebuild switch --flake "${inputs.self}#$instance" --target-host "$connect_host" --build-host "localhost"
|
||||||
|
'';
|
||||||
|
}
|
54
nix/packages/upload-openstack-base-debian-image/default.nix
Normal file
54
nix/packages/upload-openstack-base-debian-image/default.nix
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
{ pkgs, ... }:
|
||||||
|
let
|
||||||
|
image = pkgs.fetchurl {
|
||||||
|
url = "https://cdimage.debian.org/images/cloud/bookworm/20250703-2162/debian-12-genericcloud-amd64-20250703-2162.qcow2";
|
||||||
|
hash = "sha256-hfcP4INSfyP90f9DWDqMLXsZa7teXMhePwK6Vyk+dG4=";
|
||||||
|
};
|
||||||
|
script = pkgs.writeShellApplication {
|
||||||
|
name = "upload-openstack-base-debian-image-wrapped";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.openstackclient
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
export OS_AUTH_URL="''${TF_VAR_openstack_auth_url:-}"
|
||||||
|
# With the addition of Keystone we have standardized on the term **project**
|
||||||
|
# as the entity that owns the resources.
|
||||||
|
# export OS_PROJECT_ID=4840ee3bdd0e4285bc46586b8e14aafb
|
||||||
|
export OS_PROJECT_NAME="khs"
|
||||||
|
export OS_USER_DOMAIN_NAME="Default"
|
||||||
|
export OS_PROJECT_DOMAIN_ID="default"
|
||||||
|
# In addition to the owning entity (tenant), OpenStack stores the entity
|
||||||
|
# performing the action as the **user**.
|
||||||
|
export OS_USERNAME="''${TF_VAR_openstack_username:-}"
|
||||||
|
export OS_PASSWORD="''${TF_VAR_openstack_password:-}"
|
||||||
|
# If your configuration has multiple regions, we set that information here.
|
||||||
|
# OS_REGION_NAME is optional and only valid in certain environments.
|
||||||
|
export OS_REGION_NAME="''${TF_VAR_openstack_region:-}"
|
||||||
|
export OS_INTERFACE="''${TF_VAR_endpoint_type:-}"
|
||||||
|
export OS_IDENTITY_API_VERSION=3
|
||||||
|
|
||||||
|
|
||||||
|
openstack image create \
|
||||||
|
--container-format bare \
|
||||||
|
--disk-format qcow2 \
|
||||||
|
--property hw_disk_bus=scsi \
|
||||||
|
--property hw_scsi_model=virtio-scsi \
|
||||||
|
--property os_type=linux \
|
||||||
|
--property os_distro=debian \
|
||||||
|
--property os_admin_user=debian \
|
||||||
|
--property os_version='12.0.0' \
|
||||||
|
--file ${image} \
|
||||||
|
debian-12
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
in
|
||||||
|
pkgs.writeShellApplication {
|
||||||
|
name = "upload-openstack-base-debian-image";
|
||||||
|
runtimeInputs = [
|
||||||
|
pkgs.khscodes.openbao-helper
|
||||||
|
script
|
||||||
|
];
|
||||||
|
text = ''
|
||||||
|
openbao-helper wrap-program -e openstack -- upload-openstack-base-debian-image-wrapped
|
||||||
|
'';
|
||||||
|
}
|
|
@ -2,6 +2,6 @@
|
||||||
{
|
{
|
||||||
config.khscodes = {
|
config.khscodes = {
|
||||||
hetzner.enable = true;
|
hetzner.enable = true;
|
||||||
sshd.enable = true;
|
services.openssh.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
{
|
{
|
||||||
config.khscodes = {
|
config.khscodes = {
|
||||||
openstack.enable = true;
|
openstack.enable = true;
|
||||||
sshd.enable = true;
|
services.openssh.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,13 @@
|
||||||
flavor = "m.medium";
|
flavor = "m.medium";
|
||||||
secretsSource = "vault";
|
secretsSource = "vault";
|
||||||
};
|
};
|
||||||
|
snowfallorg.users.khs.admin = true;
|
||||||
|
users.users.khs = {
|
||||||
|
initialPassword = "test";
|
||||||
|
openssh.authorizedKeys.keys = [
|
||||||
|
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAACAQCqY0FHnWFKfLG2yfgr4qka5sR9CK+EMAhzlHUkaQyWHTKD+G0/vC/fNPyL1VV3Dxc/ajxGuPzVE+mBMoyxazL3EtuCDOVvHJ5CR+MUSEckg/DDwcGHqy6rC8BvVVpTAVL04ByQdwFnpE1qNSBaQLkxaFVdtriGKkgMkc7+UNeYX/bv7yn+APqfP1a3xr6wdkSSdO8x4N2jsSygOIMx10hLyCV4Ueu7Kp8Ww4rGY8j5o7lKJhbgfItBfSOuQHdppHVF/GKYRhdnK6Y2fZVYbhq4KipUtclbZ6O/VYd8/sOO98+LMm7cOX+K35PQjUpYgcoNy5+Sw3CNS/NHn4JvOtTaUEYP7fK6c9LhMULOO3T7Cm6TMdiFjUKHkyG+s2Mu/LXJJoilw571zwuh6chkeitW8+Ht7k0aPV96kNEvTdoXwLhBifVEaChlAsLAzSUjUq+YYCiXVk0VIXCZQWKj8LoVNTmaqDksWwbcT64fw/FpVC0N18WHbKcFUEIW/O4spJMa30CQwf9FeqpoWoaF1oRClCSDPvX0AauCu0JcmRinz1/JmlXljnXWbSfm20/V+WyvktlI0wTD0cdpNuSasT9vS77YfJ8nutcWWZKSkCj4R4uHeCNpDTX5YXzapy7FxpM9ANCXLIvoGX7Yafba2Po+er7SSsUIY1AsnBBr8ZoDVw=="
|
||||||
|
];
|
||||||
|
};
|
||||||
khscodes.fqdn = "test.kaareskovgaard.net";
|
khscodes.fqdn = "test.kaareskovgaard.net";
|
||||||
system.stateVersion = "25.05";
|
system.stateVersion = "25.05";
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,9 +281,9 @@ struct UnifiData {
|
||||||
|
|
||||||
impl UnifiData {
|
impl UnifiData {
|
||||||
pub fn read_from_env() -> anyhow::Result<Self> {
|
pub fn read_from_env() -> anyhow::Result<Self> {
|
||||||
let username = common::env::read_env("TF_VAR_unifi_username")?;
|
let username = common::env::read_env("UNIFI_USERNAME")?;
|
||||||
let password = common::env::read_env("TF_VAR_unifi_password")?;
|
let password = common::env::read_env("UNIFI_PASSWORD")?;
|
||||||
let url = common::env::read_env("TF_VAR_unifi_url")?;
|
let url = common::env::read_env("UNIFI_API")?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
username,
|
username,
|
||||||
password,
|
password,
|
||||||
|
@ -298,9 +298,9 @@ impl UnifiData {
|
||||||
|
|
||||||
pub fn into_env_data(self) -> Vec<(&'static str, String)> {
|
pub fn into_env_data(self) -> Vec<(&'static str, String)> {
|
||||||
vec![
|
vec![
|
||||||
("TF_VAR_unifi_username", self.username),
|
("UNIFI_USERNAME", self.username),
|
||||||
("TF_VAR_unifi_password", self.password),
|
("UNIFI_PASSWORD", self.password),
|
||||||
("TF_VAR_unifi_url", self.url),
|
("UNIFI_API", self.url),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue