Upgrade one non-critical machine first. Pick a machine whose loss of connectivity will not lock you out, and make sure you have an SSH fallback that does not go over ZeroTier.
Keep config changes minimal. If your network worked before the bump, do not rewrite your inventory.
The only edits required are the ones in Required config updates below, and only if they apply to you.
A machine can now join several ZeroTier networks. Each network is a single inventory.instances.<name> entry with module.name = "zerotier". Previously
there was effectively one ZeroTier network per clan. Multiple instances where not natively possible.
Renaming a ZeroTier instance creates a new, disconnected network. Keep the instance names you already have.
If you want to rename your zerotier instances do so before the migration runs.
Bump clan-core in your flake.nix and update the lock
(nix flake update clan-core).
Run clan vars generate. Before evaluating any generator, clan runs an
automatic, value-preserving migration that moves your existing ZeroTier
vars into the new layout. It does not regenerate anything: identities,
network IDs, and IPs are preserved, and the migration is robust to an
interrupted prior run. You should see only file moves under vars/.
Verify the values did not change. Confirm each machine kept the same IP and network ID, for example:
clan vars get <machine> zerotier-ip-<machine>-<instance>/ip
clan vars get <controller> zerotier-network-<instance>/network-idDeploy one test machine, confirm ZeroTier connectivity, then roll out to the rest.
The old zerotier generator no longer exists. If your code references clan.core.vars.generators.zerotier you need to update it.
targetHostIf you set clan.core.networking.targetHost
clan.core.networking.targetHost =
"root@[${config.clan.core.vars.generators.zerotier.files.zerotier-ip.value}]"; Prefer removing the manual setting entirely. This is now handled by the networking module.
If you still want to keep it, rename:
clan.core.networking.targetHost =
"root@[${config.clan.core.vars.generators."zerotier-ip-<machine>-<instance>".files.ip.value}]"; If you need a NixOS-module that works on any machine:
{ config, ... }:
let
# Auto-derived; no need to hardcode the machine name.
machineName = config.clan.core.settings.machine.name;
# Your inventory.instances.<name> key (e.g. "net-a"). Not the module name.
instanceName = "<instance>";
ztIp = config.clan.core.vars.generators."zerotier-ip-${machineName}-${instanceName}".files.ip.value;
in
{
environment.etc."zerotier-ip".text = ztIp;
} allowedIdsIf you authorized external devices with
zerotier-members allow <node-id>
move those node IDs into the controller settings and delete the tool call.
On the controller:
roles.controller.machines."<controller>".settings.allowedIds = [
"deadbeef00" # node ID from `zerotier-cli info` on the external device
]; allowedIds is preferred. Because the node ID is stable per device.allowedIps still works if you prefer to authorize by ZeroTier IP, but be aware that the IP depends on the network.In case of any problems reach us on matrix