Skip to content

arnarg/nixidy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

nixidy logo
License Badge Latest Release Badge Checks Passing Badge

Kubernetes GitOps with nix and Argo CD.

Getting Started β€’ Documentation β€’ Features β€’ Examples

Why Nixidy?

Managing Kubernetes configurations at scale is hard. Helm charts require complex value overrides, Kustomize leads to repetitive overlays, and raw YAML becomes unmaintainable. Reviewing changes across environments is nearly impossible.

Nixidy solves this by bringing the power of Nix and the NixOS module system to Kubernetes:

  • Declarative: Define your entire cluster state in one place
  • Typed: Catch configuration errors before deployment
  • Composable: Build complex configurations from reusable modules
  • Reviewable: Generate plain YAML for easy PR reviews
  • Reproducible: Same input always produces the same output

How It Works

Define your Kubernetes resources using Nix:

{
  applications.demo = {
    namespace = "demo";
    createNamespace = true;

    resources = {
      deployments.nginx.spec = {
        replicas = 3;
        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;
      };
    };
  };
}

Build with nixidy:

nixidy build .#prod

Get clean, reviewable YAML:

result/
β”œβ”€β”€ apps/
β”‚   └── Application-demo.yaml
└── demo/
    β”œβ”€β”€ Deployment-nginx.yaml
    β”œβ”€β”€ Namespace-demo.yaml
    └── Service-nginx.yaml

Argo CD picks up the changes, after committing the new manifests to your repository, and deploys to your cluster. That's it.

Features

🎯 Declarative Cluster Management

Define your entire cluster state using Nix. No more scattered YAML files, Helm value overrides, or Kustomize patches. Everything in one place, with one language.

πŸ”’ Strongly-Typed Configuration

Every Kubernetes resource is typed. Catch typos and validate configurations before they hit your cluster.

# This will error at build time, not runtime
resources.deployments.nginx.spec.replicas = "three"; # Type error!

πŸ“¦ First-Class Helm Support

Use existing Helm charts without giving up control. Override values, patch resources, and clean up Helm artifacts.

applications.traefik = {
  namespace = "traefik";

  helm.releases.traefik = {
    chart = lib.helm.downloadHelmChart {
      repo = "https://traefik.github.io/charts/";
      chart = "traefik";
      version = "25.0.0";
      chartHash = "sha256-ua8KnUB6MxY7APqrrzaKKSOLwSjDYkk9tfVkb1bqkVM=";
    };
    values = {
      ingressClass.enabled = true;
    };
  };

  # Patch Helm output with nixidy
  resources.deployments.traefik.spec.replicas = lib.mkForce 5;
};

πŸ”§ Kustomize Integration

Seamlessly incorporate Kustomize applications:

applications.argocd.kustomize.applications.argocd = {
  namespace = "argocd";
  kustomization = {
    src = pkgs.fetchFromGitHub {
      owner = "argoproj";
      repo = "argo-cd";
      rev = "v2.9.3";
      hash = "sha256-GaY4Cw/LlSwy35umbB4epXt6ev8ya19UjHRwhDwilqU=";
    };
    path = "manifests/cluster-install";
  };
};

🌍 Multi-Environment Made Easy

Manage dev, staging, and production with shared base configurations and environment-specific overrides:

# base.nix - shared configuration
{lib, ...}: {
  applications.api.resources.deployments.api.spec = {
    replicas = lib.mkDefault 1;
    selector.matchLabels.app = "api";
    template.spec.containers.api.image = "api:latest";
  };
}

# prod.nix - production overrides
{lib, ...}: {
  imports = [ ./base.nix ];
  applications.api.resources.deployments.api.spec = {
    replicas = lib.mkForce 10;
    template.spec.containers.api.resources = {
      requests.memory = "512Mi";
      limits.memory = "1Gi";
    };
  };
}

πŸ—οΈ Reusable Templates

Create templates for common patterns and reuse them across applications:

templates.webApp = {
  options = {
    image = mkOption {
      type = lib.types.str;
      description = "The image to use in the web application deployment";
    };
    replicas = mkOption {
      type = lib.types.int;
      default = 3;
      description = "The number of replicas for the web application deployment.";
    };
    port = mkOption {
      type = lib.types.port;
      default = 8080;
      description = "The web application's port.";
    };
  };
  output = { name, config, ... }: {
    deployments.${name}.spec = {
      replicas = config.replicas;
      selector.matchLabels.app = name;
      template = {
        metadata.labels.app = name;
        spec.containers.${name} = {
          image = config.image;
          ports.http.containerPort = config.port;
        };
      };
    };
    services.${name}.spec = {
      selector.app = name;
      ports.http.port = config.port;
    };
  };
};

# Use the template
applications.frontend.templates.webApp.frontend = {
  image = "frontend:v1.2.3";
  replicas = 5;
};

πŸ”„ GitOps Ready

Nixidy implements the Rendered Manifests Pattern. Your CI generates plain YAML, you review the exact changes in PRs, and Argo CD deploys them. No surprises.

πŸš€ App-of-Apps Bootstrap

Bootstrap your entire cluster with a single command:

nixidy bootstrap .#prod | kubectl apply -f -

⚑ Direct Apply

Skip GitOps if you want to:

nixidy apply .#dev

Uses kubectl apply --prune for safe, declarative deployments directly to your cluster.

πŸŽ›οΈ CRD Support

Generate typed Nix options from any Custom Resource Definition:

packages.generators.cilium = nixidy.packages.${system}.generators.fromCRD {
  name = "cilium";
  src = pkgs.fetchFromGitHub { /* ... */ };
  crds = [
    "pkg/k8s/apis/cilium.io/client/crds/v2/ciliumnetworkpolicies.yaml"
  ];
};

Then use your CRDs with full type safety:

resources.ciliumNetworkPolicies.allow-dns.spec = {
  endpointSelector = {};
  egress = [{
    toEndpoints = [{ matchLabels."k8s:io.kubernetes.pod.namespace" = "kube-system"; }];
    toPorts = [{ ports = [{ port = "53"; protocol = "UDP"; }]; }];
  }];
};

Quick Start

With Flakes

{
  inputs = {
    nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
    nixidy.url = "github:arnarg/nixidy";
  };

  outputs = { nixpkgs, nixidy, ... }: {
    nixidyEnvs.x86_64-linux = nixidy.lib.mkEnvs {
      pkgs = nixpkgs.legacyPackages.x86_64-linux;
      envs.dev.modules = [ ./env/dev.nix ];
    };
  };
}
{
  nixidy.target.repository = "https://github.com/you/your-repo.git";
  nixidy.target.branch = "main";

  applications.hello = {
    namespace = "hello";
    createNamespace = true;
    resources.deployments.hello.spec = {
      selector.matchLabels.app = "hello";
      template = {
        metadata.labels.app = "hello";
        spec.containers.hello.image = "hello-world:latest";
      };
    };
  };
}

See the Getting Started Guide for detailed setup instructions.

Documentation

Examples

Comparison

Feature nixidy Helm Kustomize Raw YAML
Type Safety βœ… Full ❌ None ❌ None ❌ None
Composability βœ… Modules ⚠️ Subcharts ⚠️ Overlays ❌ Copy/Paste
Helm Integration βœ… Native βœ… Native ⚠️ Inflate ❌ Manual
Reviewable Output βœ… Plain YAML ❌ Templates ⚠️ Patches βœ… Plain YAML
Multi-Environment βœ… Built-in ⚠️ Values files ⚠️ Overlays ❌ Manual
Reproducibility βœ… Guaranteed ⚠️ Depends ⚠️ Depends ⚠️ Depends

Community

Contributing

Contributions are welcome! Whether it's bug reports, feature requests, documentation improvements, or code contributions, please feel free to open an issue or pull request on our GitHub repository.

Acknowledgments

  • nix-kube-generators β€” Used internally for Helm chart rendering
  • kubenix β€” Resource options generator forked from kubenix

License

nixidy is licensed under the MIT License.

About

Kubernetes GitOps with nix and Argo CD.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 10

Languages