5.6 KiB
5.6 KiB
marp | class | headingDivider |
---|---|---|
true | invert | 1 |
NixOps4
- Why
- What
- How
- Demo
Why
- NixOps 1 is a tool to deploy NixOS systems
- Provisioning
- Secrets
- Other resources, such as AWS Route53, etc
- Python program
- Call Nix evaluator twice
Architecture
NixOps 2
2013 - 2020 - ...
Architecture
Nix
┌────────────┐ ┌────────────────────┐
│ Nix │---- instantiate ---->│ Derivations │ ↺ store path
│ expression │ └────────────────────┘
│ language │ ⇑ builds
│ │ ┌────────────────────┐
│ │ │ Nix sandbox, store │
└────────────┘ └────────────────────┘
Architecture
NixOps4
┌────────────┐ ┌────────────────────┐
│ Nix │---- configure ------>│ Resources │ ↺ nix value
│ expression │ └────────────────────┘
│ language │ ⇑ run output
│ │ ┌────────────────────┐
│ │---- instantiate ---->│ Derivations │ ↺ store path
│ │ └────────────────────┘
│ │ ⇑ builds
│ │ ┌────────────────────┐
│ │ │ Nix sandbox, store │
└────────────┘ └────────────────────┘
Resource
- Declares the existence of a real world object
- Operations
- Create
- Read
- Update
- Delete
Resource Provider
- Separate process
- executable obtained with Nix.
Operations
-
CRUD
-
"
nix run
"- backup
- key rotation
Process Architecture
- NixOps4
nixops4-eval
->libnixexpr
etc (internal)- resource providers
nixops4-resources-local
nixops4-resources-opentofu
(planned)- ...
Expressions
Simplified
{ # flake.nix
outputs = inputs: {
nixops4Deployments.default = { resources, ... }: {
resources = {
"state" = {
...
};
};
};
};
}
Expressions
{ resources, ... }: {
resources = {
"state" = {
type = "s3.object";
inputs = {
endpoint = "https://garage.example.com";
bucket = "nixops4-my-project";
};
};
};
}
Expressions
{ resources, ... }: {
resources = {
"state" = ...;
};
}
Expressions
{ resources, ... }: {
resources = {
"state" = ...;
"sshkey" = {
type = "ssh.key";
inputs = {
state = resources.state.handle;
};
};
};
}
Expressions
{ resources, ... }: {
resources = {
"state" = ...;
"sshkey" = ...;
"nixos" = {
imports = [ inputs.nixos.modules.nixops4Resource.nixos ];
inputs = {
ssh.privateKey = resources.sshkey.privateKey;
ssh.host = resources.host;
module = ./configuration.nix;
};
};
};
}
Expressions
{ resources, ... }: {
options.customers = mkOption {
type = attrsOf (submodule ./customer.nix);
};
config.resources = {
"state" = ...;
"sshkey" = ...;
"nixos" = ...;
};
}
Expressions
{ resources, ... }: {
imports = [
./data-model.nix
./applications/pixelfed.nix
./applications/mastodon.nix
./applications/peertube.nix
];
}
Expressions
resources
monoid in the category of endofunctors 😉- Structural composition like
attrsOf
orsubmodule
imports
is mix-ins
top@{ resources, ... }: {
resources = {
"state" = ...;
"my-host" = mkSequence ({ resources, ... }: {
"sshkey" = ... top.resources.state.handle ...;
"nixos" = ... resources.sshkey.privateKey ...;
});
};
}
Module author benefits
- All-Nix development experience
- No glue code
- All declarative
Application benefits
"NixPanel"
-
Structured logging
-
Separate evaluator for stability
Operator benefits
CLI interface for the backend
Integrate arbitrary scripts, no glue code
Demo?
Not discussed
-
Resource naming within the state
- read multiple => migrations
-
resourceProviderSystem