nixidy: Ditch the 600-Line Helm Values File, Use Nix Instead
nixidy replaces Helm overrides, Kustomize overlays, and raw YAML with typed Nix expressions — turning Kubernetes manifest authoring into something closer to configuring a NixOS system.
If you've managed a Kubernetes GitOps repo long enough, you've hit the wall: a Helm values override file that has grown to 600 lines, helm template | grep archaeology, and a lingering uncertainty about what actually landed in the cluster. nixidy is a tool written specifically to close that gap — replacing the Helm/Kustomize layer with a single Nix expression per environment whose output is plain, diffable YAML.
The Rendered Manifests Pattern
nixidy implements the Rendered Manifests Pattern: your CI evaluates Nix expressions and commits the resulting YAML to a branch, ArgoCD pulls that YAML and applies it, and you review concrete diffs in pull requests before anything touches a cluster. The deployment side is identical to running ArgoCD against raw YAML — nixidy only changes how that YAML is produced.
The key structural shift is that every Kubernetes resource becomes a typed Nix option, not a freeform string blob. A Deployment has an integer replicas, a string image, and a selector that's a structured attribute set. Set replicas = "two" and the build fails immediately — not 15 minutes into a rollout.
Wiring Up the Flake
The entry point is a flake.nix that pulls in nixidy and declares named environments:
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
flake-utils.url = "github:numtide/flake-utils";
nixidy.url = "github:arnarg/nixidy";
};
outputs = { nixpkgs, flake-utils, nixidy, ... }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = import nixpkgs { inherit system; };
in {
nixidyEnvs = nixidy.lib.mkEnvs {
inherit pkgs;
envs.dev.modules = [ ./env/dev.nix ];
};
});
}
nixidy.lib.mkEnvs produces Nix derivations — one per named environment — that build the full set of YAML manifests. Each environment takes a list of modules using the exact same NixOS module system: imports, lib.mkDefault, lib.mkForce, the whole composition toolkit.
Writing an Environment Module
An environment module looks like this (env/dev.nix):
{
nixidy.target.repository = "https://github.com/YOUR_USERNAME/my-cluster.git";
nixidy.target.branch = "main";
nixidy.target.rootPath = "./manifests/dev";
applications.nginx = {
namespace = "nginx";
createNamespace = true;
resources = {
deployments.nginx.spec = {
replicas = 2;
selector.matchLabels.app = "nginx";
template = {
metadata.labels.app = "nginx";
spec.containers.nginx = {
image = "nginx:1.25.1";
ports.http.containerPort = 80;
};
};
};
services.nginx.spec = {
selector.app = "nginx";
ports.http.port = 80;
};
};
};
}
A few things worth noting here:
nixidy.target.*tells nixidy where to write YAML and what path to embed in the generated ArgoCDApplicationmanifests.applications.nginxis a logical grouping that produces both the Kubernetes resources and an ArgoCDApplicationmanifest pointing at them — no hand-authoredApplicationYAML required.createNamespace = trueemits aNamespacemanifest automatically. Without it, you'd create the namespace out-of-band and pray nothing drifts.
To build:
nix run github:arnarg/nixidy -- build .#dev
The output is a result/ tree with an apps/ directory containing Application-nginx.yaml and a nginx/ directory with the Deployment, Service, and Namespace manifests — ready to commit and push.
Composition Is the Real Payoff
The single biggest advantage over Helm values or Kustomize patches shows up when you add environments. A prod.nix that scales up one application:
{ lib, ... }: {
imports = [ ./dev.nix ];
applications.nginx.resources.deployments.nginx.spec.replicas =
lib.mkForce 10;
}
Two lines. No duplicated YAML, no strategic-merge patch gymnastics, no helm upgrade --set. lib.mkForce is the same override mechanism NixOS uses to let a module win a value conflict — you get it for free because nixidy is built on the NixOS module system.
If you've already internalized how NixOS modules compose, managing a multi-environment Kubernetes fleet with nixidy will feel immediately familiar. If you haven't, this is a compelling reason to learn — the same mental model now scales from your laptop's system config to a production cluster's full workload manifest.
nixidy is an early project, and the source material covers only the introductory setup — but the primitives on display (typed resources, environment composition, automatic ArgoCD manifest generation) address real, daily pain points that Helm and Kustomize have never fully solved.
Discussion 0
Join the discussion
Sign in with GitHub to comment and vote.
No comments yet
Be the first to weigh in.