Compare commits

..

10 commits

Author SHA1 Message Date
d482fd0694 flake file rearranging 2026-02-08 14:02:12 -03:00
6d28510dca reformat programs 2026-02-07 10:00:06 -03:00
0112637288 move common/users.nix into users/ 2026-02-07 09:49:52 -03:00
c6fbd21009 move podmand security options to podman aspect 2026-02-07 09:33:55 -03:00
d83172f487 eza uses --git by default 2026-02-07 09:31:14 -03:00
ab69b26b40 this shouldn't ever have been commited 2026-02-07 08:21:02 -03:00
4bbf14f750 terranix: import flakeModule once in flake.nix
Fixes duplicate module declaration error by importing terranix
flakeModule once at the top level instead of in each config file.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 08:18:49 -03:00
c7757c139f terranix: convert to self-contained flake-parts modules
Each terranix configuration now exports its own flake output as a
self-contained module. Flattened directory structure and removed
centralized terranixConfigurations.nix in favor of import-tree.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 08:16:58 -03:00
f8478a75eb shells: convert to self-contained flake-parts module
Move devShells.nix to shells/default.nix as a flake-parts module
and use import-tree for automatic module discovery.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 08:11:55 -03:00
124d414359 packages/overlays: use builtins.readDir for dynamic package discovery
Instead of manually listing packages, the overlay now reads the
packages/ directory and automatically includes all .nix files
(except overlays.nix itself) as overlay attributes.

This makes adding new packages simpler - just add the file and it
will automatically be included in the overlay.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-07 08:08:59 -03:00
30 changed files with 856 additions and 832 deletions

View file

@ -1,41 +1,43 @@
{ ... }: { ... }:
{ {
flake.modules.nixos.common-programs = { lib, pkgs, ... }: { flake.modules.nixos.common-programs =
environment = { { lib, pkgs, ... }:
systemPackages = with pkgs; [ {
### Dev Tools ### environment = {
git systemPackages = with pkgs; [
### System Utilities ### ### Dev Tools ###
btop git
fastfetch ### System Utilities ###
helix btop
nixos-firewall-tool fastfetch
nvd helix
sysz nixos-firewall-tool
tmux nvd
wget sysz
yazi tmux
]; wget
shellAliases = { yazi
cat = "${lib.getExe pkgs.bat} --paging=never --style=plain"; ];
ls = "${lib.getExe pkgs.eza} --icons --group-directories-first"; shellAliases = {
tree = "ls --tree"; cat = "${lib.getExe pkgs.bat} --paging=never --style=plain";
ls = "${lib.getExe pkgs.eza} --git --icons --group-directories-first";
tree = "ls --tree";
};
}; };
};
programs = { programs = {
command-not-found.enable = false; command-not-found.enable = false;
fish = { fish = {
enable = true; enable = true;
interactiveShellInit = '' interactiveShellInit = ''
set fish_greeting set fish_greeting
if set -q SSH_CONNECTION if set -q SSH_CONNECTION
export TERM=xterm-256color export TERM=xterm-256color
clear clear
fastfetch fastfetch
end end
''; '';
};
}; };
}; };
};
} }

View file

@ -1,14 +1,13 @@
{ ... }: { ... }:
{ {
flake.modules.nixos.common-security = { ... }: { flake.modules.nixos.common-security =
security = { { ... }:
unprivilegedUsernsClone = true; # Needed for rootless podman {
sudo = { security.sudo = {
wheelNeedsPassword = false; wheelNeedsPassword = false;
extraConfig = '' extraConfig = ''
Defaults lecture = never Defaults lecture = never
''; '';
}; };
}; };
};
} }

View file

@ -1,25 +0,0 @@
{ ... }:
{
flake.modules.nixos.common-users = { pkgs, ... }: {
users.users = {
user = {
isNormalUser = true;
shell = pkgs.fish;
extraGroups = [
"networkmanager"
"wheel"
];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam"
];
hashedPassword = "$6$Pj7v/CpstyuWQQV0$cNujVDhfMBdwlGVEnnd8t71.kZPixbo0u25cd.874iaqLTH4V5fa1f98V5zGapjQCz5JyZmsR94xi00sUrntT0";
};
root = {
shell = pkgs.fish;
hashedPassword = "!";
};
};
};
}

View file

@ -6,7 +6,12 @@
modules = [ modules = [
inputs.agenix.nixosModules.default inputs.agenix.nixosModules.default
{ networking.hostName = "alexandria"; } { networking.hostName = "alexandria"; }
{ nixpkgs.overlays = [ inputs.agenix.overlays.default inputs.self.overlays.default ]; } {
nixpkgs.overlays = [
inputs.agenix.overlays.default
inputs.self.overlays.default
];
}
# Common aspects (always included) # Common aspects (always included)
inputs.self.modules.nixos.common-boot inputs.self.modules.nixos.common-boot
@ -19,7 +24,10 @@
inputs.self.modules.nixos.common-security inputs.self.modules.nixos.common-security
inputs.self.modules.nixos.common-services inputs.self.modules.nixos.common-services
inputs.self.modules.nixos.common-tailscale inputs.self.modules.nixos.common-tailscale
inputs.self.modules.nixos.common-users
# User aspects
inputs.self.modules.nixos.user
inputs.self.modules.nixos.root
# Server aspects # Server aspects
inputs.self.modules.nixos.server-boot inputs.self.modules.nixos.server-boot

View file

@ -6,7 +6,12 @@
modules = [ modules = [
inputs.agenix.nixosModules.default inputs.agenix.nixosModules.default
{ networking.hostName = "io"; } { networking.hostName = "io"; }
{ nixpkgs.overlays = [ inputs.agenix.overlays.default inputs.self.overlays.default ]; } {
nixpkgs.overlays = [
inputs.agenix.overlays.default
inputs.self.overlays.default
];
}
# Common aspects (always included) # Common aspects (always included)
inputs.self.modules.nixos.common-boot inputs.self.modules.nixos.common-boot
@ -19,7 +24,10 @@
inputs.self.modules.nixos.common-security inputs.self.modules.nixos.common-security
inputs.self.modules.nixos.common-services inputs.self.modules.nixos.common-services
inputs.self.modules.nixos.common-tailscale inputs.self.modules.nixos.common-tailscale
inputs.self.modules.nixos.common-users
# User aspects
inputs.self.modules.nixos.user
inputs.self.modules.nixos.root
# Desktop aspects # Desktop aspects
inputs.self.modules.nixos.desktop-boot inputs.self.modules.nixos.desktop-boot

View file

@ -6,7 +6,12 @@
modules = [ modules = [
inputs.agenix.nixosModules.default inputs.agenix.nixosModules.default
{ networking.hostName = "rotterdam"; } { networking.hostName = "rotterdam"; }
{ nixpkgs.overlays = [ inputs.agenix.overlays.default inputs.self.overlays.default ]; } {
nixpkgs.overlays = [
inputs.agenix.overlays.default
inputs.self.overlays.default
];
}
# Common aspects (always included) # Common aspects (always included)
inputs.self.modules.nixos.common-boot inputs.self.modules.nixos.common-boot
@ -19,7 +24,10 @@
inputs.self.modules.nixos.common-security inputs.self.modules.nixos.common-security
inputs.self.modules.nixos.common-services inputs.self.modules.nixos.common-services
inputs.self.modules.nixos.common-tailscale inputs.self.modules.nixos.common-tailscale
inputs.self.modules.nixos.common-users
# User aspects
inputs.self.modules.nixos.user
inputs.self.modules.nixos.root
# Desktop aspects # Desktop aspects
inputs.self.modules.nixos.desktop-boot inputs.self.modules.nixos.desktop-boot

View file

@ -6,7 +6,12 @@
modules = [ modules = [
inputs.agenix.nixosModules.default inputs.agenix.nixosModules.default
{ networking.hostName = "trantor"; } { networking.hostName = "trantor"; }
{ nixpkgs.overlays = [ inputs.agenix.overlays.default inputs.self.overlays.default ]; } {
nixpkgs.overlays = [
inputs.agenix.overlays.default
inputs.self.overlays.default
];
}
# Common aspects (always included) # Common aspects (always included)
inputs.self.modules.nixos.common-boot inputs.self.modules.nixos.common-boot
@ -19,7 +24,10 @@
inputs.self.modules.nixos.common-security inputs.self.modules.nixos.common-security
inputs.self.modules.nixos.common-services inputs.self.modules.nixos.common-services
inputs.self.modules.nixos.common-tailscale inputs.self.modules.nixos.common-tailscale
inputs.self.modules.nixos.common-users
# User aspects
inputs.self.modules.nixos.user
inputs.self.modules.nixos.root
# Server aspects # Server aspects
inputs.self.modules.nixos.server-boot inputs.self.modules.nixos.server-boot

View file

@ -1,15 +1,24 @@
{ ... }: { ... }:
{ {
flake.modules.nixos.podman = { config, lib, pkgs, ... }: { flake.modules.nixos.podman =
virtualisation.podman = { {
enable = true; config,
autoPrune.enable = true; lib,
extraPackages = [ pkgs.podman-compose ]; pkgs,
}; ...
}:
{
virtualisation.podman = {
enable = true;
autoPrune.enable = true;
extraPackages = [ pkgs.podman-compose ];
};
systemd = { security.unprivilegedUsernsClone = true; # Needed for rootless podman
services.podman-auto-update.enable = true;
timers.podman-auto-update.enable = true; systemd = {
services.podman-auto-update.enable = true;
timers.podman-auto-update.enable = true;
};
}; };
};
} }

View file

@ -1,27 +1,25 @@
{ ... }: { ... }:
{ {
flake.modules.nixos.programs-graphics = { pkgs, ... }: { flake.modules.nixos.programs-graphics =
environment.systemPackages = with pkgs; [ { pkgs, ... }:
# Image Editing {
gimp environment.systemPackages = with pkgs; [
inkscape gimp
# CAD & 3D Modeling inkscape
plasticity plasticity
]; ];
services.flatpak.packages = [ services.flatpak.packages = [
# Vector Graphics "com.boxy_svg.BoxySVG"
"com.boxy_svg.BoxySVG" rec {
# 3D Printing / Slicing appId = "io.github.softfever.OrcaSlicer";
rec { sha256 = "0hdx5sg6fknj1pfnfxvlfwb5h6y1vjr6fyajbsnjph5gkp97c6p1";
appId = "io.github.softfever.OrcaSlicer"; bundle = "${pkgs.fetchurl {
sha256 = "0hdx5sg6fknj1pfnfxvlfwb5h6y1vjr6fyajbsnjph5gkp97c6p1"; url = "https://github.com/SoftFever/OrcaSlicer/releases/download/v2.3.0/OrcaSlicer-Linux-flatpak_V2.3.0_x86_64.flatpak";
bundle = "${pkgs.fetchurl { inherit sha256;
url = "https://github.com/SoftFever/OrcaSlicer/releases/download/v2.3.0/OrcaSlicer-Linux-flatpak_V2.3.0_x86_64.flatpak"; }}";
inherit sha256; }
}}"; ];
} };
];
};
} }

View file

@ -2,28 +2,28 @@
{ {
flake.modules = { flake.modules = {
nixos.programs-media = { pkgs, ... }: { nixos.programs-media =
environment.systemPackages = with pkgs; [ { pkgs, ... }:
# Audio {
decibels environment.systemPackages = with pkgs; [
# Video decibels
showtime loupe
# Image Viewer obs-studio
loupe showtime
# Recording & Streaming
obs-studio
];
};
homeManager.programs-media = { pkgs, ... }: {
programs.obs-studio = {
enable = true;
plugins = with pkgs.obs-studio-plugins; [
obs-vkcapture
obs-backgroundremoval
obs-pipewire-audio-capture
]; ];
}; };
};
homeManager.programs-media =
{ pkgs, ... }:
{
programs.obs-studio = {
enable = true;
plugins = with pkgs.obs-studio-plugins; [
obs-vkcapture
obs-backgroundremoval
obs-pipewire-audio-capture
];
};
};
}; };
} }

View file

@ -1,25 +1,22 @@
{ ... }: { ... }:
{ {
flake.modules.nixos.programs-office = { pkgs, ... }: { flake.modules.nixos.programs-office =
environment.systemPackages = with pkgs; [ { pkgs, ... }:
# Spelling {
aspell environment.systemPackages = with pkgs; [
aspellDicts.de aspell
aspellDicts.en aspellDicts.de
aspellDicts.en-computers aspellDicts.en
aspellDicts.pt_BR aspellDicts.en-computers
# Document Viewing aspellDicts.pt_BR
papers papers
# Presentations presenterm
presenterm rnote
# Note Taking & Drawing ];
rnote
];
services.flatpak.packages = [ services.flatpak.packages = [
# Office Suite "com.collabora.Office"
"com.collabora.Office" ];
]; };
};
} }

View file

@ -2,64 +2,61 @@
{ {
flake.modules = { flake.modules = {
nixos.programs-utilities = { pkgs, ... }: { nixos.programs-utilities =
environment.systemPackages = with pkgs; [ { pkgs, ... }:
# Terminal {
ghostty environment.systemPackages = with pkgs; [
# File Management ghostty
nautilus gnome-disk-utility
gnome-disk-utility mission-center
# Archive Tools nautilus
p7zip p7zip
unrar rclone
# Cloud & Remote unrar
rclone # Desktop Integration
# System Monitoring adwaita-icon-theme
mission-center junction
# Desktop Integration libfido2
adwaita-icon-theme toggleaudiosink
junction # Xwayland Support
libfido2 xwayland-satellite
toggleaudiosink ];
# Xwayland Support
xwayland-satellite
];
services.flatpak.packages = [ services.flatpak.packages = [
# Flatpak Management "com.github.tchx84.Flatseal"
"com.github.tchx84.Flatseal" "com.rustdesk.RustDesk"
# Remote Desktop ];
"com.rustdesk.RustDesk" };
];
};
homeManager.programs-utilities = { pkgs, ... }: { homeManager.programs-utilities =
programs = { { pkgs, ... }:
ghostty = { {
enable = true; programs = {
settings = { ghostty = {
cursor-style = "block"; enable = true;
shell-integration-features = "no-cursor"; settings = {
cursor-style-blink = false; cursor-style = "block";
custom-shader = "${builtins.fetchurl { shell-integration-features = "no-cursor";
url = "https://raw.githubusercontent.com/hackr-sh/ghostty-shaders/cb6eb4b0d1a3101c869c62e458b25a826f9dcde3/cursor_blaze.glsl"; cursor-style-blink = false;
sha256 = "sha256:0g2lgqjdrn3c51glry7x2z30y7ml0y61arl5ykmf4yj0p85s5f41"; custom-shader = "${builtins.fetchurl {
}}"; url = "https://raw.githubusercontent.com/hackr-sh/ghostty-shaders/cb6eb4b0d1a3101c869c62e458b25a826f9dcde3/cursor_blaze.glsl";
bell-features = ""; sha256 = "sha256:0g2lgqjdrn3c51glry7x2z30y7ml0y61arl5ykmf4yj0p85s5f41";
gtk-titlebar-style = "tabs"; }}";
keybind = [ "shift+enter=text:\\x1b\\r" ]; bell-features = "";
gtk-titlebar-style = "tabs";
keybind = [ "shift+enter=text:\\x1b\\r" ];
};
};
password-store = {
enable = true;
package = pkgs.pass-wayland;
}; };
}; };
password-store = { home.sessionVariables = {
enable = true; TERMINAL = "ghostty";
package = pkgs.pass-wayland;
}; };
}; };
home.sessionVariables = {
TERMINAL = "ghostty";
};
};
}; };
} }

View file

@ -1,18 +1,21 @@
{ ... }: { ... }:
{ {
flake.modules.nixos.programs-web = { inputs, pkgs, system, ... }: { flake.modules.nixos.programs-web =
environment.systemPackages = with pkgs; [ {
# Browsers inputs,
inputs.zen-browser.packages."${system}".default pkgs,
tor-browser system,
# Communication ...
vesktop }:
# Cloud & Sync {
bitwarden-desktop environment.systemPackages = with pkgs; [
nextcloud-client inputs.zen-browser.packages."${system}".default
# Downloads bitwarden-desktop
fragments fragments
]; nextcloud-client
}; tor-browser
vesktop
];
};
} }

12
aspects/users/root.nix Normal file
View file

@ -0,0 +1,12 @@
{ ... }:
{
flake.modules.nixos.root =
{ pkgs, ... }:
{
users.root = {
shell = pkgs.fish;
hashedPassword = "!";
};
};
}

View file

@ -1,91 +1,118 @@
# aspects/users/user.nix
{ inputs, ... }: { inputs, ... }:
{ {
flake.homeConfigurations = { flake = {
"user@rotterdam" = inputs.home-manager.lib.homeManagerConfiguration { modules.nixos.user =
pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux; { pkgs, ... }:
extraSpecialArgs = { inherit inputs; hostname = "rotterdam"; }; {
modules = [ users.users.user = {
{ nixpkgs.overlays = [ inputs.self.overlays.default ]; } isNormalUser = true;
shell = pkgs.fish;
extraGroups = [
"networkmanager"
"wheel"
];
openssh.authorizedKeys.keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam"
];
hashedPassword = "$6$Pj7v/CpstyuWQQV0$cNujVDhfMBdwlGVEnnd8t71.kZPixbo0u25cd.874iaqLTH4V5fa1f98V5zGapjQCz5JyZmsR94xi00sUrntT0";
};
};
# CLI aspects (common module included) homeConfigurations = {
inputs.self.modules.homeManager.cli-base "user@rotterdam" = inputs.home-manager.lib.homeManagerConfiguration {
inputs.self.modules.homeManager.cli-btop pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
inputs.self.modules.homeManager.cli-comma extraSpecialArgs = {
inputs.self.modules.homeManager.cli-direnv inherit inputs;
inputs.self.modules.homeManager.cli-helix hostname = "rotterdam";
inputs.self.modules.homeManager.cli-starship };
inputs.self.modules.homeManager.cli-tmux modules = [
{ nixpkgs.overlays = [ inputs.self.overlays.default ]; }
# Shell # CLI aspects (common module included)
inputs.self.modules.homeManager.shell-fish inputs.self.modules.homeManager.cli-base
inputs.self.modules.homeManager.shell-bash inputs.self.modules.homeManager.cli-btop
inputs.self.modules.homeManager.cli-comma
inputs.self.modules.homeManager.cli-direnv
inputs.self.modules.homeManager.cli-helix
inputs.self.modules.homeManager.cli-starship
inputs.self.modules.homeManager.cli-tmux
# Desktop # Shell
inputs.self.modules.homeManager.desktop-desktop inputs.self.modules.homeManager.shell-fish
inputs.self.modules.homeManager.desktop-niri inputs.self.modules.homeManager.shell-bash
# Gaming # Desktop
inputs.self.modules.homeManager.gaming-mangohud inputs.self.modules.homeManager.desktop-desktop
inputs.self.modules.homeManager.desktop-niri
# Programs # Gaming
inputs.self.modules.homeManager.programs-media # for obs-studio inputs.self.modules.homeManager.gaming-mangohud
# Stylix # Programs
inputs.self.modules.homeManager.stylix inputs.self.modules.homeManager.programs-media # for obs-studio
# User-specific (from _user/) # Stylix
./_user/git.nix inputs.self.modules.homeManager.stylix
# Home configuration # User-specific (from _user/)
{ ./_user/git.nix
home = {
username = "user";
homeDirectory = "/home/user";
stateVersion = "22.05";
};
}
];
};
"user@io" = inputs.home-manager.lib.homeManagerConfiguration { # Home configuration
pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux; {
extraSpecialArgs = { inherit inputs; hostname = "io"; }; home = {
modules = [ username = "user";
{ nixpkgs.overlays = [ inputs.self.overlays.default ]; } homeDirectory = "/home/user";
stateVersion = "22.05";
};
}
];
};
# CLI aspects (common module included) "user@io" = inputs.home-manager.lib.homeManagerConfiguration {
inputs.self.modules.homeManager.cli-base pkgs = inputs.nixpkgs.legacyPackages.x86_64-linux;
inputs.self.modules.homeManager.cli-btop extraSpecialArgs = {
inputs.self.modules.homeManager.cli-comma inherit inputs;
inputs.self.modules.homeManager.cli-direnv hostname = "io";
inputs.self.modules.homeManager.cli-helix };
inputs.self.modules.homeManager.cli-starship modules = [
inputs.self.modules.homeManager.cli-tmux { nixpkgs.overlays = [ inputs.self.overlays.default ]; }
# Shell # CLI aspects (common module included)
inputs.self.modules.homeManager.shell-fish inputs.self.modules.homeManager.cli-base
inputs.self.modules.homeManager.shell-bash inputs.self.modules.homeManager.cli-btop
inputs.self.modules.homeManager.cli-comma
inputs.self.modules.homeManager.cli-direnv
inputs.self.modules.homeManager.cli-helix
inputs.self.modules.homeManager.cli-starship
inputs.self.modules.homeManager.cli-tmux
# Desktop # Shell
inputs.self.modules.homeManager.desktop-desktop inputs.self.modules.homeManager.shell-fish
inputs.self.modules.homeManager.desktop-niri inputs.self.modules.homeManager.shell-bash
# Stylix # Desktop
inputs.self.modules.homeManager.stylix inputs.self.modules.homeManager.desktop-desktop
inputs.self.modules.homeManager.desktop-niri
# User-specific (from _user/) # Stylix
./_user/git.nix inputs.self.modules.homeManager.stylix
# Home configuration # User-specific (from _user/)
{ ./_user/git.nix
home = {
username = "user"; # Home configuration
homeDirectory = "/home/user"; {
stateVersion = "22.05"; home = {
}; username = "user";
} homeDirectory = "/home/user";
]; stateVersion = "22.05";
};
}
];
};
}; };
}; };
} }

View file

@ -2,58 +2,52 @@
description = "My nix hosts"; description = "My nix hosts";
inputs = { inputs = {
# nix tools
flake-parts.url = "github:hercules-ci/flake-parts"; flake-parts.url = "github:hercules-ci/flake-parts";
import-tree.url = "github:vic/import-tree"; import-tree.url = "github:vic/import-tree";
# nixos/hm
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.11"; nixpkgs-stable.url = "github:nixos/nixpkgs/nixos-25.11";
home-manager = { home-manager = {
url = "github:nix-community/home-manager/master"; url = "github:nix-community/home-manager/master";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
# nixos/hm functionality modules
agenix = { agenix = {
url = "github:ryantm/agenix"; url = "github:ryantm/agenix";
inputs.nixpkgs.follows = "nixpkgs-stable"; inputs.nixpkgs.follows = "nixpkgs-stable";
}; };
disko.url = "github:nix-community/disko"; disko.url = "github:nix-community/disko";
impermanence.url = "github:nix-community/impermanence";
noctalia = { nixos-cli.url = "github:nix-community/nixos-cli";
url = "github:noctalia-dev/noctalia-shell"; nix-flatpak.url = "github:gmodena/nix-flatpak/main";
inputs.nixpkgs.follows = "nixpkgs";
};
stylix.url = "github:danth/stylix"; stylix.url = "github:danth/stylix";
nixos-cli.url = "github:nix-community/nixos-cli"; # nixos/hm program modules
nix-flatpak.url = "github:gmodena/nix-flatpak/main";
zen-browser.url = "github:0xc000022070/zen-browser-flake";
impermanence.url = "github:nix-community/impermanence";
deploy-rs.url = "github:serokell/deploy-rs";
niri-flake.url = "github:sodiboo/niri-flake"; niri-flake.url = "github:sodiboo/niri-flake";
nix-ai-tools.url = "github:numtide/llm-agents.nix";
niri.url = "github:baduhai/niri/auto-center-when-space-available";
nix-index-database = { nix-index-database = {
url = "github:nix-community/nix-index-database"; url = "github:nix-community/nix-index-database";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
noctalia = {
url = "github:noctalia-dev/noctalia-shell";
inputs.nixpkgs.follows = "nixpkgs";
};
vicinae.url = "github:vicinaehq/vicinae";
zen-browser.url = "github:0xc000022070/zen-browser-flake";
# stand-alone tools
deploy-rs.url = "github:serokell/deploy-rs";
terranix = { terranix = {
url = "github:terranix/terranix"; url = "github:terranix/terranix";
inputs.nixpkgs.follows = "nixpkgs"; inputs.nixpkgs.follows = "nixpkgs";
}; };
nix-ai-tools.url = "github:numtide/llm-agents.nix"; # others
niri.url = "github:baduhai/niri/auto-center-when-space-available";
vicinae.url = "github:vicinaehq/vicinae";
}; };
outputs = outputs =
@ -61,6 +55,8 @@
let let
aspectsModule = import-tree ./aspects; aspectsModule = import-tree ./aspects;
packagesModule = import-tree ./packages; packagesModule = import-tree ./packages;
shellsModule = import-tree ./shells;
terranixModule = import-tree ./terranix;
in in
flake-parts.lib.mkFlake { inherit inputs; } { flake-parts.lib.mkFlake { inherit inputs; } {
systems = [ systems = [
@ -70,12 +66,14 @@
imports = [ imports = [
flake-parts.flakeModules.modules flake-parts.flakeModules.modules
] ++ aspectsModule.imports inputs.terranix.flakeModule
++ packagesModule.imports ]
++ [ ++ aspectsModule.imports
./deploy.nix ++ packagesModule.imports
./devShells.nix ++ shellsModule.imports
./terranixConfigurations.nix ++ terranixModule.imports
]; ++ [
./deploy.nix
];
}; };
} }

View file

@ -1,12 +1,22 @@
{ inputs, ... }: { inputs, ... }:
let
packageDir = builtins.readDir ./.;
# Filter to .nix files, excluding overlays.nix
isPackageFile = name:
name != "overlays.nix" && builtins.match ".*\\.nix$" name != null;
# Extract package name from filename (e.g., "foo-bar.nix" -> "foo-bar")
toPackageName = filename:
builtins.head (builtins.match "(.+)\\.nix$" filename);
packageNames = map toPackageName (builtins.filter isPackageFile (builtins.attrNames packageDir));
in
{ {
flake.overlays.default = final: prev: { flake.overlays.default = final: prev:
base16-schemes = inputs.self.packages.${final.system}.base16-schemes; builtins.listToAttrs (map (name: {
claude-desktop = inputs.self.packages.${final.system}.claude-desktop; inherit name;
fastfetch = inputs.self.packages.${final.system}.fastfetch; value = inputs.self.packages.${final.system}.${name};
hm-cli = inputs.self.packages.${final.system}.hm-cli; }) packageNames);
kwrite = inputs.self.packages.${final.system}.kwrite;
toggleaudiosink = inputs.self.packages.${final.system}.toggleaudiosink;
};
} }

89
plan.md
View file

@ -1,89 +0,0 @@
# Current structure:
```
 hosts
├──  alexandria
│ ├──  hardware-configuration.nix
│ ├──  jellyfin.nix
│ ├──  kanidm.nix
│ ├──  nextcloud.nix
│ ├──  nginx.nix
│ ├──  unbound.nix
│ └──  vaultwarden.nix
├──  io
│ ├──  boot.nix
│ ├──  disko.nix
│ ├──  hardware-configuration.nix
│ ├──  programs.nix
│ └──  services.nix
├──  modules
│ ├──  common
│ │ ├──  boot.nix
│ │ ├──  console.nix
│ │ ├──  firewall.nix
│ │ ├──  locale.nix
│ │ ├──  nix.nix
│ │ ├──  openssh.nix
│ │ ├──  programs.nix
│ │ ├──  security.nix
│ │ ├──  services.nix
│ │ ├──  tailscale.nix
│ │ └──  users.nix
│ ├──  desktop
│ │ ├──  boot.nix
│ │ ├──  desktop.nix
│ │ ├──  nix.nix
│ │ └──  services.nix
│ ├──  server
│ │ ├──  boot.nix
│ │ ├──  nix.nix
│ │ └──  tailscale.nix
│ ├──  ai.nix
│ ├──  bluetooth.nix
│ ├──  dev.nix
│ ├──  ephemeral.nix
│ ├──  fwupd.nix
│ ├──  gaming.nix
│ ├──  libvirtd.nix
│ ├──  networkmanager.nix
│ └──  podman.nix
├──  rotterdam
│ ├──  boot.nix
│ ├──  hardware-configuration.nix
│ ├──  hardware.nix
│ ├──  programs.nix
│ └──  services.nix
└──  trantor
├──  boot.nix
├──  disko.nix
├──  fail2ban.nix
├──  forgejo.nix
├──  hardware-configuration.nix
├──  networking.nix
├──  nginx.nix
├──  openssh.nix
└──  unbound.nix
 modules
└──  ephemeral.nix
 users
├──  modules
│ ├──  common
│ │ ├──  bash.nix
│ │ ├──  fish.nix
│ │ └──  hm-cli.nix
│ ├──  desktop
│ │ ├──  desktop.nix
│ │ └──  niri.nix
│ ├──  btop.nix
│ ├──  comma.nix
│ ├──  direnv.nix
│ ├──  gaming.nix
│ ├──  helix.nix
│ ├──  obs-studio.nix
│ ├──  starship.nix
│ ├──  stylix.nix
│ └──  tmux.nix
└──  user
└──  git.nix
```

113
terranix/baduhai.dev.nix Normal file
View file

@ -0,0 +1,113 @@
# Required environment variables:
# CLOUDFLARE_API_TOKEN - API token with "Edit zone DNS" permissions
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ ... }:
{
perSystem =
{ pkgs, ... }:
{
terranix.terranixConfigurations.cloudflare-baduhaidev = {
terraformWrapper.package = pkgs.opentofu;
modules = [
(
{ config, lib, ... }:
let
sharedData = import ../data/services.nix;
# Enrich services with host IPs
services = map (
svc:
let
hostInfo = sharedData.hosts.${svc.host} or { };
in
svc
// {
lanIP = hostInfo.lanIP or null;
tailscaleIP = hostInfo.tailscaleIP or null;
}
) sharedData.services;
# Helper to extract subdomain from full domain (e.g., "git.baduhai.dev" -> "git")
getSubdomain = domain: lib.head (lib.splitString "." domain);
# Generate DNS records for services
# Public services point to trantor's public IP
# Private services point to their tailscale IP
mkServiceRecords = lib.listToAttrs (
lib.imap0 (
i: svc:
let
subdomain = getSubdomain svc.domain;
targetIP =
if svc.public or false then
config.data.terraform_remote_state.trantor "outputs.instance_public_ip"
else
svc.tailscaleIP;
in
{
name = "service_${toString i}";
value = {
zone_id = config.variable.zone_id.default;
name = subdomain;
type = "A";
content = targetIP;
proxied = false;
ttl = 3600;
};
}
) services
);
in
{
terraform.required_providers.cloudflare = {
source = "cloudflare/cloudflare";
version = "~> 5.0";
};
terraform.backend.s3 = {
bucket = "terraform-state";
key = "cloudflare/baduhai.dev.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
variable = {
zone_id = {
default = "c63a8332fdddc4a8e5612ddc54557044";
type = "string";
};
};
data = {
terraform_remote_state.trantor = {
backend = "s3";
config = {
bucket = "terraform-state";
key = "oci/trantor.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
};
};
resource.cloudflare_dns_record = mkServiceRecords;
}
)
];
};
};
}

View file

@ -1,94 +0,0 @@
# Required environment variables:
# CLOUDFLARE_API_TOKEN - API token with "Edit zone DNS" permissions
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ config, lib, ... }:
let
sharedData = import ../../data/services.nix;
# Enrich services with host IPs
services = map (svc:
let hostInfo = sharedData.hosts.${svc.host} or {};
in svc // {
lanIP = hostInfo.lanIP or null;
tailscaleIP = hostInfo.tailscaleIP or null;
}
) sharedData.services;
# Helper to extract subdomain from full domain (e.g., "git.baduhai.dev" -> "git")
getSubdomain = domain: lib.head (lib.splitString "." domain);
# Generate DNS records for services
# Public services point to trantor's public IP
# Private services point to their tailscale IP
mkServiceRecords = lib.listToAttrs (
lib.imap0 (
i: svc:
let
subdomain = getSubdomain svc.domain;
targetIP =
if svc.public or false then
config.data.terraform_remote_state.trantor "outputs.instance_public_ip"
else
svc.tailscaleIP;
in
{
name = "service_${toString i}";
value = {
zone_id = config.variable.zone_id.default;
name = subdomain;
type = "A";
content = targetIP;
proxied = false;
ttl = 3600;
};
}
) services
);
in
{
terraform.required_providers.cloudflare = {
source = "cloudflare/cloudflare";
version = "~> 5.0";
};
terraform.backend.s3 = {
bucket = "terraform-state";
key = "cloudflare/baduhai.dev.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
variable = {
zone_id = {
default = "c63a8332fdddc4a8e5612ddc54557044";
type = "string";
};
};
data = {
terraform_remote_state.trantor = {
backend = "s3";
config = {
bucket = "terraform-state";
key = "oci/trantor.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
};
};
resource.cloudflare_dns_record = mkServiceRecords;
}

View file

@ -0,0 +1,17 @@
# Cloudflare kernelpanic.space configuration placeholder
{ ... }:
{
perSystem =
{ pkgs, ... }:
{
terranix.terranixConfigurations.cloudflare-kernelpanicspace = {
terraformWrapper.package = pkgs.opentofu;
modules = [
({ config, ... }: {
# Terraform config goes here
})
];
};
};
}

View file

@ -1,258 +0,0 @@
# Required environment variables:
# instead of OCI variables, ~/.oci/config may also be used
# OCI_TENANCY_OCID - Oracle tenancy OCID (or use TF_VAR_* to override variables)
# OCI_USER_OCID - Oracle user OCID
# OCI_FINGERPRINT - API key fingerprint
# OCI_PRIVATE_KEY_PATH - Path to OCI API private key
# AWS variables are required
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ config, ... }:
{
terraform.required_providers.oci = {
source = "oracle/oci";
version = "~> 7.0";
};
provider.oci.region = "sa-saopaulo-1";
terraform.backend.s3 = {
bucket = "terraform-state";
key = "oci/trantor.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
variable = {
tenancy_ocid = {
default = "ocid1.tenancy.oc1..aaaaaaaap3vfdz4piygqza6e6zqunbcuso43ddqfo3ydmpmnomidyghh7rvq";
type = "string";
};
compartment_name = {
default = "trantor";
type = "string";
};
vcn_cidr = {
default = "10.0.0.0/24";
type = "string";
};
instance_name = {
default = "trantor";
type = "string";
};
ssh_public_keys = {
default = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam"
];
type = "list(string)";
};
};
data = {
oci_identity_availability_domains.ads = {
compartment_id = config.variable.tenancy_ocid.default;
};
oci_core_images.ubuntu_arm = {
compartment_id = config.variable.tenancy_ocid.default;
operating_system = "Canonical Ubuntu";
operating_system_version = "24.04";
shape = "VM.Standard.A1.Flex";
sort_by = "TIMECREATED";
sort_order = "DESC";
};
};
resource = {
oci_identity_compartment.trantor = {
compartment_id = config.variable.tenancy_ocid.default;
description = "trantor infrastructure compartment";
name = config.variable.compartment_name.default;
};
oci_core_vcn.vcn = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
cidr_blocks = [ config.variable.vcn_cidr.default ];
display_name = "trantor-vcn";
dns_label = "trantor";
};
oci_core_internet_gateway.ig = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
vcn_id = config.resource.oci_core_vcn.vcn "id";
display_name = "trantor-ig";
enabled = true;
};
oci_core_route_table.rt = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
vcn_id = config.resource.oci_core_vcn.vcn "id";
display_name = "trantor-rt";
route_rules = [
{
network_entity_id = config.resource.oci_core_internet_gateway.ig "id";
destination = "0.0.0.0/0";
destination_type = "CIDR_BLOCK";
}
];
};
oci_core_security_list.sl = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
vcn_id = config.resource.oci_core_vcn.vcn "id";
display_name = "trantor-sl";
egress_security_rules = [
{
destination = "0.0.0.0/0";
protocol = "all";
stateless = false;
}
];
ingress_security_rules = [
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 22;
max = 22;
};
}
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 80;
max = 80;
};
}
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 443;
max = 443;
};
}
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 25565;
max = 25565;
};
}
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 19132;
max = 19133;
};
}
{
protocol = "17"; # UDP
source = "0.0.0.0/0";
stateless = false;
udp_options = {
min = 19132;
max = 19133;
};
}
];
};
oci_core_subnet.subnet = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
vcn_id = config.resource.oci_core_vcn.vcn "id";
cidr_block = config.variable.vcn_cidr.default;
display_name = "trantor-subnet";
dns_label = "subnet";
route_table_id = config.resource.oci_core_route_table.rt "id";
security_list_ids = [ (config.resource.oci_core_security_list.sl "id") ];
prohibit_public_ip_on_vnic = false;
};
oci_core_instance.trantor = {
availability_domain = config.data.oci_identity_availability_domains.ads "availability_domains[0].name";
compartment_id = config.resource.oci_identity_compartment.trantor "id";
display_name = config.variable.instance_name.default;
shape = "VM.Standard.A1.Flex";
shape_config = {
ocpus = 2;
memory_in_gbs = 12;
};
source_details = {
source_type = "image";
source_id = config.data.oci_core_images.ubuntu_arm "images[0].id";
boot_volume_size_in_gbs = 100;
};
create_vnic_details = {
subnet_id = config.resource.oci_core_subnet.subnet "id";
display_name = "trantor-vnic";
assign_public_ip = true;
hostname_label = config.variable.instance_name.default;
};
metadata = {
ssh_authorized_keys = builtins.concatStringsSep "\n" config.variable.ssh_public_keys.default;
};
preserve_boot_volume = false;
};
oci_budget_budget.trantor_budget = {
compartment_id = config.variable.tenancy_ocid.default;
targets = [ (config.resource.oci_identity_compartment.trantor "id") ];
amount = 1;
reset_period = "MONTHLY";
display_name = "trantor-budget";
description = "Monthly budget for trantor compartment";
target_type = "COMPARTMENT";
};
oci_budget_alert_rule.daily_spend_alert = {
budget_id = config.resource.oci_budget_budget.trantor_budget "id";
type = "ACTUAL";
threshold = 5;
threshold_type = "PERCENTAGE";
display_name = "daily-spend-alert";
recipients = "baduhai@proton.me";
description = "Alert when daily spending exceeds $0.05";
message = "Daily spending has exceeded $0.05 in the trantor compartment";
};
};
output = {
compartment_id = {
value = config.resource.oci_identity_compartment.trantor "id";
};
instance_public_ip = {
value = config.resource.oci_core_instance.trantor "public_ip";
};
};
}

57
terranix/tailnet.nix Normal file
View file

@ -0,0 +1,57 @@
# Required environment variables:
# TAILSCALE_API_KEY - Tailscale API key with appropriate permissions
# TAILSCALE_TAILNET - Your tailnet name (e.g., "user@example.com" or "example.org.github")
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ ... }:
{
perSystem =
{ pkgs, ... }:
{
terranix.terranixConfigurations.tailscale-tailnet = {
terraformWrapper.package = pkgs.opentofu;
modules = [
(
{ config, ... }:
{
terraform.required_providers.tailscale = {
source = "tailscale/tailscale";
version = "~> 0.17";
};
terraform.backend.s3 = {
bucket = "terraform-state";
key = "tailscale/tailnet.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
variable = {
trantor_tailscale_ip = {
default = "100.108.5.90";
type = "string";
};
};
resource = {
tailscale_dns_nameservers.global = {
nameservers = [
config.variable.trantor_tailscale_ip.default
"1.1.1.1"
"1.0.0.1"
];
};
};
}
)
];
};
};
}

View file

@ -1,43 +0,0 @@
# Required environment variables:
# TAILSCALE_API_KEY - Tailscale API key with appropriate permissions
# TAILSCALE_TAILNET - Your tailnet name (e.g., "user@example.com" or "example.org.github")
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ config, ... }:
{
terraform.required_providers.tailscale = {
source = "tailscale/tailscale";
version = "~> 0.17";
};
terraform.backend.s3 = {
bucket = "terraform-state";
key = "tailscale/tailnet.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
variable = {
trantor_tailscale_ip = {
default = "100.108.5.90";
type = "string";
};
};
resource = {
tailscale_dns_nameservers.global = {
nameservers = [
config.variable.trantor_tailscale_ip.default
"1.1.1.1"
"1.0.0.1"
];
};
};
}

17
terranix/terminus.nix Normal file
View file

@ -0,0 +1,17 @@
# OCI Terminus configuration placeholder
{ ... }:
{
perSystem =
{ pkgs, ... }:
{
terranix.terranixConfigurations.oci-terminus = {
terraformWrapper.package = pkgs.opentofu;
modules = [
({ config, ... }: {
# Terraform config goes here
})
];
};
};
}

272
terranix/trantor.nix Normal file
View file

@ -0,0 +1,272 @@
# Required environment variables:
# instead of OCI variables, ~/.oci/config may also be used
# OCI_TENANCY_OCID - Oracle tenancy OCID (or use TF_VAR_* to override variables)
# OCI_USER_OCID - Oracle user OCID
# OCI_FINGERPRINT - API key fingerprint
# OCI_PRIVATE_KEY_PATH - Path to OCI API private key
# AWS variables are required
# AWS_ACCESS_KEY_ID - Cloudflare R2 access key for state storage
# AWS_SECRET_ACCESS_KEY - Cloudflare R2 secret key for state storage
{ ... }:
{
perSystem =
{ pkgs, ... }:
{
terranix.terranixConfigurations.oci-trantor = {
terraformWrapper.package = pkgs.opentofu;
modules = [
(
{ config, ... }:
{
terraform.required_providers.oci = {
source = "oracle/oci";
version = "~> 7.0";
};
provider.oci.region = "sa-saopaulo-1";
terraform.backend.s3 = {
bucket = "terraform-state";
key = "oci/trantor.tfstate";
region = "auto";
endpoint = "https://fcdf920bde00c3d013ee541f984da70e.r2.cloudflarestorage.com";
skip_credentials_validation = true;
skip_metadata_api_check = true;
skip_region_validation = true;
skip_requesting_account_id = true;
use_path_style = true;
};
variable = {
tenancy_ocid = {
default = "ocid1.tenancy.oc1..aaaaaaaap3vfdz4piygqza6e6zqunbcuso43ddqfo3ydmpmnomidyghh7rvq";
type = "string";
};
compartment_name = {
default = "trantor";
type = "string";
};
vcn_cidr = {
default = "10.0.0.0/24";
type = "string";
};
instance_name = {
default = "trantor";
type = "string";
};
ssh_public_keys = {
default = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAICQPkAyy+Du9Omc2WtnUF2TV8jFAF4H6mJi2D4IZ1nzg user@himalia"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIO3Y0PVpGfJHonqDS7qoCFhqzUvqGq9I9sax+F9e/5cs user@io"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIA1v3+q3EaruiiStWjubEJWvtejam/r41uoOpCdwJtLL user@rotterdam"
];
type = "list(string)";
};
};
data = {
oci_identity_availability_domains.ads = {
compartment_id = config.variable.tenancy_ocid.default;
};
oci_core_images.ubuntu_arm = {
compartment_id = config.variable.tenancy_ocid.default;
operating_system = "Canonical Ubuntu";
operating_system_version = "24.04";
shape = "VM.Standard.A1.Flex";
sort_by = "TIMECREATED";
sort_order = "DESC";
};
};
resource = {
oci_identity_compartment.trantor = {
compartment_id = config.variable.tenancy_ocid.default;
description = "trantor infrastructure compartment";
name = config.variable.compartment_name.default;
};
oci_core_vcn.vcn = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
cidr_blocks = [ config.variable.vcn_cidr.default ];
display_name = "trantor-vcn";
dns_label = "trantor";
};
oci_core_internet_gateway.ig = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
vcn_id = config.resource.oci_core_vcn.vcn "id";
display_name = "trantor-ig";
enabled = true;
};
oci_core_route_table.rt = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
vcn_id = config.resource.oci_core_vcn.vcn "id";
display_name = "trantor-rt";
route_rules = [
{
network_entity_id = config.resource.oci_core_internet_gateway.ig "id";
destination = "0.0.0.0/0";
destination_type = "CIDR_BLOCK";
}
];
};
oci_core_security_list.sl = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
vcn_id = config.resource.oci_core_vcn.vcn "id";
display_name = "trantor-sl";
egress_security_rules = [
{
destination = "0.0.0.0/0";
protocol = "all";
stateless = false;
}
];
ingress_security_rules = [
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 22;
max = 22;
};
}
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 80;
max = 80;
};
}
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 443;
max = 443;
};
}
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 25565;
max = 25565;
};
}
{
protocol = "6"; # TCP
source = "0.0.0.0/0";
stateless = false;
tcp_options = {
min = 19132;
max = 19133;
};
}
{
protocol = "17"; # UDP
source = "0.0.0.0/0";
stateless = false;
udp_options = {
min = 19132;
max = 19133;
};
}
];
};
oci_core_subnet.subnet = {
compartment_id = config.resource.oci_identity_compartment.trantor "id";
vcn_id = config.resource.oci_core_vcn.vcn "id";
cidr_block = config.variable.vcn_cidr.default;
display_name = "trantor-subnet";
dns_label = "subnet";
route_table_id = config.resource.oci_core_route_table.rt "id";
security_list_ids = [ (config.resource.oci_core_security_list.sl "id") ];
prohibit_public_ip_on_vnic = false;
};
oci_core_instance.trantor = {
availability_domain = config.data.oci_identity_availability_domains.ads "availability_domains[0].name";
compartment_id = config.resource.oci_identity_compartment.trantor "id";
display_name = config.variable.instance_name.default;
shape = "VM.Standard.A1.Flex";
shape_config = {
ocpus = 2;
memory_in_gbs = 12;
};
source_details = {
source_type = "image";
source_id = config.data.oci_core_images.ubuntu_arm "images[0].id";
boot_volume_size_in_gbs = 100;
};
create_vnic_details = {
subnet_id = config.resource.oci_core_subnet.subnet "id";
display_name = "trantor-vnic";
assign_public_ip = true;
hostname_label = config.variable.instance_name.default;
};
metadata = {
ssh_authorized_keys = builtins.concatStringsSep "\n" config.variable.ssh_public_keys.default;
};
preserve_boot_volume = false;
};
oci_budget_budget.trantor_budget = {
compartment_id = config.variable.tenancy_ocid.default;
targets = [ (config.resource.oci_identity_compartment.trantor "id") ];
amount = 1;
reset_period = "MONTHLY";
display_name = "trantor-budget";
description = "Monthly budget for trantor compartment";
target_type = "COMPARTMENT";
};
oci_budget_alert_rule.daily_spend_alert = {
budget_id = config.resource.oci_budget_budget.trantor_budget "id";
type = "ACTUAL";
threshold = 5;
threshold_type = "PERCENTAGE";
display_name = "daily-spend-alert";
recipients = "baduhai@proton.me";
description = "Alert when daily spending exceeds $0.05";
message = "Daily spending has exceeded $0.05 in the trantor compartment";
};
};
output = {
compartment_id = {
value = config.resource.oci_identity_compartment.trantor "id";
};
instance_public_ip = {
value = config.resource.oci_core_instance.trantor "public_ip";
};
};
}
)
];
};
};
}

View file

@ -1,27 +0,0 @@
{ inputs, ... }:
{
imports = [
inputs.terranix.flakeModule
];
perSystem =
{ pkgs, ... }:
{
terranix.terranixConfigurations = {
oci-trantor = {
modules = [ ./terranix/oci/trantor.nix ];
terraformWrapper.package = pkgs.opentofu;
};
cloudflare-baduhaidev = {
modules = [ ./terranix/cloudflare/baduhai.dev.nix ];
terraformWrapper.package = pkgs.opentofu;
};
tailscale-tailnet = {
modules = [ ./terranix/tailscale/tailnet.nix ];
terraformWrapper.package = pkgs.opentofu;
};
};
};
}