Update design.md
This commit is contained in:
parent
f4023c47b0
commit
b5c1a43863
1 changed files with 23 additions and 13 deletions
36
design.md
36
design.md
|
|
@ -1,12 +1,12 @@
|
||||||
# Metanix: Design Document (WIP)
|
# Metanix: Design Document (WIP)
|
||||||
|
|
||||||
_Declarative infrastructure, but with fewer repeated DSL war crimes._
|
_Declare your infrastructure!_
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## 1. High-Level Overview
|
## 1. High-Level Overview
|
||||||
|
|
||||||
**Metanix** is a Nix library / flake that generates NixOS configurations and related infrastructure from a higher-level “world description” file, `meta.nix`, plus a `policy` section.
|
**Metanix** is a Nix library / flake that generates NixOS configurations and related infrastructure from a higher-level “world description” file, `meta.nix`.
|
||||||
|
|
||||||
Instead of hand-writing:
|
Instead of hand-writing:
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ Metanix then:
|
||||||
- builds NixOS configs for each system
|
- builds NixOS configs for each system
|
||||||
- wires DNS, DHCP, WireGuard, firewalls, and home-manager for users where applicable
|
- wires DNS, DHCP, WireGuard, firewalls, and home-manager for users where applicable
|
||||||
|
|
||||||
You still _can_ hand-write Nix when you care about specifics. You just don’t have to for the 90% of boilerplate that machines are objectively better at than you.
|
You still _can_ hand-write Nix when you care about specifics. You just don't have to for the 90% of boilerplate that machines are objectively better at than you.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -61,10 +61,10 @@ You still _can_ hand-write Nix when you care about specifics. You just don’t h
|
||||||
### Non-Goals
|
### Non-Goals
|
||||||
|
|
||||||
- Replacing NixOS modules
|
- Replacing NixOS modules
|
||||||
Metanix composes and configures them; it doesn’t rewrite them.
|
Metanix composes and configures them; it doesn't rewrite them.
|
||||||
|
|
||||||
- Being a one-click magic box
|
- Being a one-click magic box
|
||||||
This is not “paste YAML, receive Kubernetes.” You’re still expected to understand your network and your systems.
|
This is not “paste YAML, receive Kubernetes.” You're still expected to understand your network and your systems.
|
||||||
|
|
||||||
- Hiding complexity at all costs
|
- Hiding complexity at all costs
|
||||||
The complexity is still there. Metanix just centralizes it so you can reason about it.
|
The complexity is still there. Metanix just centralizes it so you can reason about it.
|
||||||
|
|
@ -82,7 +82,6 @@ You still _can_ hand-write Nix when you care about specifics. You just don’t h
|
||||||
domain = "kasear.net";
|
domain = "kasear.net";
|
||||||
locations = { ... };
|
locations = { ... };
|
||||||
systems = { ... };
|
systems = { ... };
|
||||||
consumers = { ... }; # global defaults for resources
|
|
||||||
policy = { ... }; # identity, RBAC, shared configs
|
policy = { ... }; # identity, RBAC, shared configs
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
@ -93,7 +92,7 @@ Metanix is the flake; `meta.nix` is the data.
|
||||||
|
|
||||||
## 4. Locations, Subnets, Hosts
|
## 4. Locations, Subnets, Hosts
|
||||||
|
|
||||||
Locations describe _where_ things live. Subnets describe _how_ they’re sliced. Hosts are the concrete entries inside those subnets.
|
Locations describe _where_ things live. Subnets describe _how_ they're sliced. Hosts are the concrete entries inside those subnets.
|
||||||
|
|
||||||
### 4.1 Locations
|
### 4.1 Locations
|
||||||
|
|
||||||
|
|
@ -134,7 +133,7 @@ Actual presence/privilege on a given system is resolved later via hosts and syst
|
||||||
Shape:
|
Shape:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
locations.<location>.<subnet> = {
|
locations.networks.<location>.subnets.<subnet> = {
|
||||||
vlan = 10; # optional
|
vlan = 10; # optional
|
||||||
dhcp = { start = 1; end = 250; }; # optional
|
dhcp = { start = 1; end = 250; }; # optional
|
||||||
|
|
||||||
|
|
@ -159,7 +158,7 @@ Hosts are **interfaces into contexts**, not necessarily 1:1 machines.
|
||||||
Shape:
|
Shape:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
locations.<location>.<subnet>.hosts.<hostname> = {
|
locations.networks.<location>.subnets.<subnet>.hosts.<hostname> = {
|
||||||
role = "router" | "server" | "adminWorkstation" | "coreServer" | ...;
|
role = "router" | "server" | "adminWorkstation" | "coreServer" | ...;
|
||||||
hw-address = "aa:bb:cc:dd:ee:ff"; # optional
|
hw-address = "aa:bb:cc:dd:ee:ff"; # optional
|
||||||
aliases = [ "fqdn" ... ]; # optional
|
aliases = [ "fqdn" ... ]; # optional
|
||||||
|
|
@ -184,7 +183,7 @@ Examples:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
# Home DMZ view of deimos
|
# Home DMZ view of deimos
|
||||||
locations.home.dmz.hosts.deimos = {
|
locations.networks.home.subnets.dmz.hosts.deimos = {
|
||||||
role = "server";
|
role = "server";
|
||||||
hw-address = "10:98:36:a0:2c:b2";
|
hw-address = "10:98:36:a0:2c:b2";
|
||||||
interface = "eno2";
|
interface = "eno2";
|
||||||
|
|
@ -194,7 +193,7 @@ locations.home.dmz.hosts.deimos = {
|
||||||
};
|
};
|
||||||
|
|
||||||
# Cloud DMZ view of same system
|
# Cloud DMZ view of same system
|
||||||
locations.cloud.dmz.hosts.deimos-cloud = {
|
locations.networks.cloud.subnets.dmz.hosts.deimos-cloud = {
|
||||||
role = "server";
|
role = "server";
|
||||||
interface = "wg0";
|
interface = "wg0";
|
||||||
users = [ "analytics" ]; # non-admin plane
|
users = [ "analytics" ]; # non-admin plane
|
||||||
|
|
@ -300,7 +299,7 @@ These serve as:
|
||||||
Consumers describe what this system **depends on**:
|
Consumers describe what this system **depends on**:
|
||||||
|
|
||||||
```nix
|
```nix
|
||||||
consumers = {
|
systems.<name>.consumers = {
|
||||||
dns = { provider = "eris"; };
|
dns = { provider = "eris"; };
|
||||||
dhcp = { provider = "phobos"; };
|
dhcp = { provider = "phobos"; };
|
||||||
wireguard = { provider = "frontend.kasear.net"; };
|
wireguard = { provider = "frontend.kasear.net"; };
|
||||||
|
|
@ -311,7 +310,6 @@ Resolution order:
|
||||||
|
|
||||||
- `systems.<name>.consumers.<res>.provider`
|
- `systems.<name>.consumers.<res>.provider`
|
||||||
overrides
|
overrides
|
||||||
- top-level `consumers.<res>.provider` defaults
|
|
||||||
|
|
||||||
Providers can be:
|
Providers can be:
|
||||||
|
|
||||||
|
|
@ -778,3 +776,15 @@ Because you’re not done tormenting yourself yet:
|
||||||
- error on users referenced in locations but missing from `policy.users`
|
- error on users referenced in locations but missing from `policy.users`
|
||||||
- error on groups referenced but missing from `policy.groups`
|
- error on groups referenced but missing from `policy.groups`
|
||||||
- warn when `adminWorkstation` has random non-admin users unless explicitly allowed
|
- warn when `adminWorkstation` has random non-admin users unless explicitly allowed
|
||||||
|
|
||||||
|
## 11. Putting It All Together!
|
||||||
|
|
||||||
|
Metanix needs to turn the meta.nix file and whatever it might include into full, valid NixOS configurations. It does this in multiple stages.
|
||||||
|
|
||||||
|
1. Compiler - This parses the meta.nix, generates "facts" such as IP addresses, IDs, zones, hostnames, and so forth, and produces an internal attribute set/dictionary.
|
||||||
|
|
||||||
|
2. Dictionary - This carries what is supposed to be all the specifics of what Metanix should generate in terms of configuration to be consumed by emitters.
|
||||||
|
|
||||||
|
3. Emitters?!?!?!! - Emitters are bits of Nix libraries and modules used to use the dictionary and expand it into protocol, service, or system specifics. Ultimately the emitters are what actually turn the meta.nix information processed by the compiler into actual chunks of NixOS configuration.
|
||||||
|
|
||||||
|
4. Processor - This zips all the generated NixOS/home-manager configuration snippets into the actual flake outputs that will be used by tools like nixos-rebuild or, preferably, deploy-rs.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue