2024-11-12 14:38:34 +01:00
|
|
|
---
|
|
|
|
marp: true
|
|
|
|
# theme: gaia
|
|
|
|
class: invert
|
|
|
|
headingDivider: 1
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
# NixOps4
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
<!--
|
|
|
|
_class: invert lead
|
|
|
|
-->
|
|
|
|
|
|
|
|
- Why
|
|
|
|
- What
|
|
|
|
- How
|
|
|
|
- Demo
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
Robert Hensing
|
|
|
|
@roberth
|
|
|
|
|
|
|
|
fediversity.eu
|
|
|
|
|
2024-11-12 14:38:34 +01:00
|
|
|
|
|
|
|
# Why
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
2013 - 2020
|
|
|
|
|
2024-11-12 14:38:34 +01:00
|
|
|
- NixOps 1 is a tool to deploy NixOS systems
|
2024-11-14 10:45:18 +01:00
|
|
|
- Provisioning, secrets
|
|
|
|
- Also resources, e.g. AWS Route53
|
|
|
|
- Call Nix evaluator twice (bad(TM))
|
2024-11-12 14:38:34 +01:00
|
|
|
|
|
|
|
<!--
|
|
|
|
calling the evaluator twice is not good enough
|
|
|
|
-->
|
|
|
|
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
# Why
|
|
|
|
|
|
|
|
NixOps 2
|
|
|
|
|
|
|
|
2020 - ...
|
|
|
|
|
|
|
|
- Plugins
|
|
|
|
- Polyrepo
|
|
|
|
|
|
|
|
# Why
|
2024-11-12 14:38:34 +01:00
|
|
|
|
|
|
|
NixOps 2
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
2020 - ...
|
2024-11-12 14:38:34 +01:00
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
<!--
|
|
|
|
|
|
|
|
I sincerely apologize to the authors and previous maintainers.
|
|
|
|
They did a good job with the architecture they had.
|
|
|
|
|
|
|
|
- Plugin system
|
|
|
|
- Ossified the architecture
|
|
|
|
-->
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
# Why
|
2024-11-12 14:38:34 +01:00
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
2022
|
|
|
|
|
|
|
|
@roberth
|
|
|
|
|
|
|
|
- Still the only tool that integrates provisioning
|
|
|
|
|
|
|
|
|
|
|
|
# Step back
|
2024-11-12 14:38:34 +01:00
|
|
|
|
|
|
|
Nix
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
┌────────────┐ ┌────────────────────┐
|
|
|
|
│ Nix │---- instantiate ---->│ Derivations │ ↺ store path
|
|
|
|
│ expression │ └────────────────────┘
|
|
|
|
│ language │ ⇑ builds
|
|
|
|
│ │ ┌────────────────────┐
|
|
|
|
│ │ │ Nix sandbox, store │
|
|
|
|
└────────────┘ └────────────────────┘
|
|
|
|
```
|
|
|
|
|
|
|
|
<!--
|
2024-11-14 10:45:18 +01:00
|
|
|
TODO: Explain firmly
|
2024-11-12 14:38:34 +01:00
|
|
|
-->
|
|
|
|
|
|
|
|
# Architecture
|
|
|
|
|
|
|
|
NixOps4
|
|
|
|
|
|
|
|
```
|
|
|
|
┌────────────┐ ┌────────────────────┐
|
|
|
|
│ Nix │---- configure ------>│ Resources │ ↺ nix value
|
|
|
|
│ expression │ └────────────────────┘
|
|
|
|
│ language │ ⇑ run output
|
|
|
|
│ │ ┌────────────────────┐
|
|
|
|
│ │---- instantiate ---->│ Derivations │ ↺ store path
|
|
|
|
│ │ └────────────────────┘
|
|
|
|
│ │ ⇑ builds
|
|
|
|
│ │ ┌────────────────────┐
|
|
|
|
│ │ │ Nix sandbox, store │
|
|
|
|
└────────────┘ └────────────────────┘
|
|
|
|
```
|
|
|
|
|
|
|
|
<!--
|
2024-11-14 10:45:18 +01:00
|
|
|
|
|
|
|
How done is it?
|
|
|
|
|
2024-11-12 14:38:34 +01:00
|
|
|
Adds new layer on top
|
|
|
|
|
|
|
|
Focus on `nix value` => precisely that; no tight coupling between NixOps and its resources
|
|
|
|
|
|
|
|
NixOps4 just manages the data flows generically
|
|
|
|
|
|
|
|
Another benefit
|
|
|
|
- resource can be implemented in any language, with any library
|
|
|
|
|
|
|
|
Not comparable to NixOps 2 architecture image. NixOps 2 is "just a script" that grew until it failed to scale and then ossified with plugins.
|
|
|
|
|
|
|
|
-->
|
|
|
|
|
|
|
|
|
|
|
|
# Resource
|
|
|
|
|
|
|
|
- Declares the existence of a real world object
|
|
|
|
- Operations
|
|
|
|
- Create
|
|
|
|
- Read
|
|
|
|
- Update
|
|
|
|
- Delete
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
# Deployment
|
2024-11-12 14:38:34 +01:00
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
Collection of resources
|
|
|
|
- wired together with Nix expressions
|
|
|
|
- reflecting some area of the real world
|
2024-11-12 14:38:34 +01:00
|
|
|
|
|
|
|
# Operations
|
|
|
|
|
|
|
|
- CRUD
|
|
|
|
|
|
|
|
- "`nix run`"
|
|
|
|
- backup
|
|
|
|
- key rotation
|
|
|
|
|
|
|
|
<!--
|
|
|
|
a. Arbitrary callable methods in resource provider
|
|
|
|
b. Scripts depending on resource outputs
|
|
|
|
-->
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
# Resource Provider
|
|
|
|
|
|
|
|
- Program built with Nix
|
|
|
|
- Called by NixOps
|
|
|
|
- Talks an IPC protocol
|
2024-11-12 14:38:34 +01:00
|
|
|
|
|
|
|
|
|
|
|
# Expressions
|
|
|
|
|
|
|
|
Simplified
|
|
|
|
|
|
|
|
```nix
|
|
|
|
{ # flake.nix
|
|
|
|
outputs = inputs: {
|
|
|
|
nixops4Deployments.default = { resources, ... }: {
|
|
|
|
resources = {
|
2024-11-14 10:45:18 +01:00
|
|
|
<resource name> = {
|
2024-11-12 14:38:34 +01:00
|
|
|
...
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
<!-- These are very abstract. Clarify why. -->
|
|
|
|
|
|
|
|
|
2024-11-12 14:38:34 +01:00
|
|
|
# Expressions
|
|
|
|
|
|
|
|
```nix
|
|
|
|
{ resources, ... }: {
|
|
|
|
resources = {
|
2024-11-14 10:45:18 +01:00
|
|
|
"nixos" = {
|
|
|
|
imports = [ inputs.nixos.modules.nixops4Resource.nixos ];
|
2024-11-12 14:38:34 +01:00
|
|
|
inputs = {
|
2024-11-14 10:45:18 +01:00
|
|
|
ssh.privateKey = resources.sshkeypair.privateKey;
|
|
|
|
ssh.host = resources.host;
|
|
|
|
module = ./configuration.nix;
|
2024-11-12 14:38:34 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# Expressions
|
|
|
|
|
|
|
|
```nix
|
|
|
|
{ resources, ... }: {
|
|
|
|
resources = {
|
2024-11-14 10:45:18 +01:00
|
|
|
"nixos" = ...;
|
|
|
|
"sshkeypair" = {
|
|
|
|
type = "ssh.keypair";
|
2024-11-12 14:38:34 +01:00
|
|
|
inputs = {
|
2024-11-14 10:45:18 +01:00
|
|
|
state = resources.state;
|
2024-11-12 14:38:34 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# Expressions
|
|
|
|
|
|
|
|
```nix
|
|
|
|
{ resources, ... }: {
|
|
|
|
resources = {
|
2024-11-14 10:45:18 +01:00
|
|
|
"nixos" = ...;
|
|
|
|
"sshkeypair" = ...;
|
|
|
|
"state" = {
|
|
|
|
type = "s3.object";
|
2024-11-12 14:38:34 +01:00
|
|
|
inputs = {
|
2024-11-14 10:45:18 +01:00
|
|
|
endpoint = "https://garage.example.com";
|
|
|
|
bucket = "nixops4-my-project";
|
2024-11-12 14:38:34 +01:00
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# Expressions
|
|
|
|
|
|
|
|
```nix
|
2024-11-14 10:45:18 +01:00
|
|
|
{ config, resources, ... }: {
|
2024-11-12 14:38:34 +01:00
|
|
|
options.customers = mkOption {
|
|
|
|
type = attrsOf (submodule ./customer.nix);
|
|
|
|
};
|
|
|
|
config.resources = {
|
|
|
|
"state" = ...;
|
2024-11-14 10:45:18 +01:00
|
|
|
"sshkeypair" = ...;
|
|
|
|
"nixos" = ... (foo config.customers) ...;
|
2024-11-12 14:38:34 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# Expressions
|
|
|
|
|
|
|
|
```nix
|
|
|
|
{ resources, ... }: {
|
|
|
|
imports = [
|
|
|
|
./data-model.nix
|
|
|
|
./applications/pixelfed.nix
|
|
|
|
./applications/mastodon.nix
|
|
|
|
./applications/peertube.nix
|
|
|
|
];
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# Expressions
|
|
|
|
|
|
|
|
- `resources` monoid in the category of endofunctors :wink:
|
|
|
|
- Structural composition like `attrsOf` or `submodule`
|
|
|
|
- `imports` is mix-ins
|
|
|
|
|
|
|
|
```nix
|
|
|
|
top@{ resources, ... }: {
|
|
|
|
resources = {
|
|
|
|
"state" = ...;
|
|
|
|
"my-host" = mkSequence ({ resources, ... }: {
|
2024-11-14 10:45:18 +01:00
|
|
|
"sshkeypair" = ... top.resources.state.handle ...;
|
|
|
|
"nixos" = ... resources.sshkeypair.privateKey ...;
|
2024-11-12 14:38:34 +01:00
|
|
|
});
|
|
|
|
};
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
# Module author benefits
|
|
|
|
|
|
|
|
- All-Nix development experience
|
|
|
|
- No glue code
|
|
|
|
- All declarative
|
|
|
|
|
|
|
|
# Application benefits
|
|
|
|
|
|
|
|
"NixPanel"
|
|
|
|
|
|
|
|
- Structured logging
|
|
|
|
|
|
|
|
- Separate evaluator for stability
|
|
|
|
|
|
|
|
# Operator benefits
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
CLI for the backend
|
2024-11-12 14:38:34 +01:00
|
|
|
|
|
|
|
Integrate arbitrary scripts, no glue code
|
|
|
|
|
2024-11-14 10:45:18 +01:00
|
|
|
# Operator benefits
|
|
|
|
|
|
|
|
# Caveats
|
|
|
|
|
|
|
|
TBD
|
|
|
|
- `mkSequence` nesting / data dependencies
|
|
|
|
- Read, Update, Delete
|
|
|
|
- More resources
|
|
|
|
- OpenTofu
|
|
|
|
|
2024-11-12 14:38:34 +01:00
|
|
|
# Demo?
|
|
|
|
|
|
|
|
# Not discussed
|
|
|
|
|
|
|
|
- Resource naming within the state
|
|
|
|
- read multiple => migrations
|
|
|
|
|
|
|
|
- `resourceProviderSystem`
|
2024-11-14 10:45:18 +01:00
|
|
|
|
|
|
|
# Process Architecture
|
|
|
|
|
|
|
|
- `nixops4`
|
|
|
|
- `nixops4-eval` -> `libnixexpr` etc (internal)
|
|
|
|
- resource providers
|
|
|
|
- `nixops4-resources-local`
|
|
|
|
- `nixops4-resources-opentofu` (planned)
|
|
|
|
- ...
|