diff --git a/Kconfig b/Kconfig
index 988782a9dc83..2b8363aeaccd 100644
--- a/Kconfig
+++ b/Kconfig
@@ -67,18 +67,26 @@ menu "Bring up methods"
 source "kconfigs/Kconfig.bringup"
 endmenu
 
+if KDEVOPS_SUPPORTS_BRINGUP
 menu "Bring up goals"
 source "kconfigs/Kconfig.bringup.goals"
 endmenu
+endif
 
+if KDEVOPS_SUPPORTS_SYSCTL
 menu "Node sysctl configuration"
 source "kconfigs/Kconfig.sysctl"
 endmenu
+endif
 
+if KDEVOPS_SUPPORTS_WORKFLOWS
 menu "Target workflows"
 source "kconfigs/workflows/Kconfig"
 endmenu
+endif
 
+if KDEVOPS_SUPPORTS_CONFIG
 menu "Kdevops configuration"
 source "kconfigs/Kconfig.kdevops"
 endmenu
+endif
diff --git a/kconfigs/Kconfig.bringup b/kconfigs/Kconfig.bringup
index a9aefc56e3fa..77493a5cec8d 100644
--- a/kconfigs/Kconfig.bringup
+++ b/kconfigs/Kconfig.bringup
@@ -1,6 +1,31 @@
 config BRINGUP_SUPPORTS_CXL
 	bool
 
+config KDEVOPS_SUPPORTS_BRINGUP
+	bool
+
+config KDEVOPS_SUPPORTS_SYSCTL
+	bool
+
+config KDEVOPS_SUPPORTS_WORKFLOWS
+	bool
+
+config KDEVOPS_SUPPORTS_CONFIG
+	bool
+
+config KDEVOPS_SUPPORTS_LEGACY_KERNELCI
+	bool
+
+config KDEVOPS_NODE_PATH
+	string
+	output yaml
+	default "{{ guestfs_path }}" if KDEVOPS_ENABLE_GUESTFS
+	default "{{ nixos_path }}" if KDEVOPS_ENABLE_NIXOS
+
+config KDEVOPS_GENERATE_NODES
+	bool
+	output yaml
+
 config KDEVOPS_ENABLE_GUESTFS
 	bool
 	output yaml
@@ -13,6 +38,12 @@ config GUESTFS
 	bool "Use guestfs-tools for local virtualization via KVM and libvirt"
 	select KDEVOPS_ENABLE_GUESTFS
 	select EXTRA_STORAGE_SUPPORTS_LARGEIO
+	select KDEVOPS_GENERATE_NODES
+	select KDEVOPS_SUPPORTS_BRINGUP
+	select KDEVOPS_SUPPORTS_SYSCTL
+	select KDEVOPS_SUPPORTS_WORKFLOWS
+	select KDEVOPS_SUPPORTS_CONFIG
+	select KDEVOPS_SUPPORTS_LEGACY_KERNELCI
 	help
 	  This option will use libguestfs utilities instead of Vagrant to build
 	  guest images and spin them up using libvirt with KVM.
@@ -23,6 +54,10 @@ config TERRAFORM
 	select EXTRA_STORAGE_SUPPORTS_1K
 	select EXTRA_STORAGE_SUPPORTS_2K
 	select EXTRA_STORAGE_SUPPORTS_4K
+	select KDEVOPS_SUPPORTS_BRINGUP
+	select KDEVOPS_SUPPORTS_SYSCTL
+	select KDEVOPS_SUPPORTS_WORKFLOWS
+	select KDEVOPS_SUPPORTS_CONFIG
 	help
 	  This option will enable use of Vagrant. Enable this if you want to
 	  use terraform to create nodes on a cloud environment such as:
@@ -39,6 +74,18 @@ config TERRAFORM
 
 	  If you are not using a cloud environment just disable this.
 
+config KDEVOPS_ENABLE_NIXOS
+	bool "Nix OS setup"
+	output yaml
+	select EXTRA_STORAGE_SUPPORTS_512
+	select EXTRA_STORAGE_SUPPORTS_1K
+	select EXTRA_STORAGE_SUPPORTS_2K
+	select EXTRA_STORAGE_SUPPORTS_4K
+	select KDEVOPS_GENERATE_NODES
+	select KDEVOPS_SUPPORTS_CONFIG
+	help
+	  Select this if you want to experiment with Nix OS.
+
 config SKIP_BRINGUP
 	bool "Skip bring up - bare metal or existing nodes"
 	select EXTRA_STORAGE_SUPPORTS_512
diff --git a/kconfigs/Kconfig.kdevops b/kconfigs/Kconfig.kdevops
index c613ff20c193..685abd4e3ce3 100644
--- a/kconfigs/Kconfig.kdevops
+++ b/kconfigs/Kconfig.kdevops
@@ -192,6 +192,8 @@ menu "Ansible post-bring up provisioning configuration"
 source "kconfigs/Kconfig.ansible_provisioning"
 endmenu
 
+if KDEVOPS_SUPPORTS_LEGACY_KERNELCI
 menu "Kernel continous integration configuration"
 source "kconfigs/Kconfig.kernel-ci"
 endmenu
+endif
diff --git a/playbooks/roles/gen_nodes/defaults/main.yml b/playbooks/roles/gen_nodes/defaults/main.yml
index 8ff9b87993a7..5d420dc5e6b3 100644
--- a/playbooks/roles/gen_nodes/defaults/main.yml
+++ b/playbooks/roles/gen_nodes/defaults/main.yml
@@ -1,5 +1,7 @@
 # SPDX-License-Identifier GPL-2.0+
 ---
+kdevops_generate_nodes: False
+kdevops_enable_nixos: False
 kdevops_enable_guestfs: False
 kdevops_enable_terraform: False
 kdevops_enable_vagrant: False
@@ -19,6 +21,10 @@ kdevops_smbd_enable: False
 kdevops_krb5_enable: False
 kdevops_enable_iscsi: false
 
+
+kdevops_node_path: ""
+nixos_path: "{{ topdir_path }}/nixos"
+
 virtualbox_provider: False
 libvirt_provider: False
 
diff --git a/playbooks/roles/gen_nodes/tasks/main.yml b/playbooks/roles/gen_nodes/tasks/main.yml
index 8c6a1f705ee2..7f5b64bcd68f 100644
--- a/playbooks/roles/gen_nodes/tasks/main.yml
+++ b/playbooks/roles/gen_nodes/tasks/main.yml
@@ -18,6 +18,18 @@
   command: "id -g -n"
   register: my_group
 
+- name: Create NixOS directory
+  ansible.builtin.file:
+    path: "{{ kdevops_nix_path }}"
+    state: directory
+  when: kdevops_enable_nixos|bool
+
+- name: Generate NixOS devshell.nix
+  template:
+    src: devshell.nix.j2
+    dest: "{{ kdevops_nix_path }}"
+  when: kdevops_enable_nixos|bool
+
 - name: Fail if kdevops_host_prefix contains a dash
   fail:
     msg: "Invalid kdevops_host_prefix '{{ kdevops_host_prefix }}'. The prefix cannot contain a dash ('-')."
@@ -544,7 +556,14 @@
   include_vars: "{{ topdir_path }}/{{ kdevops_nodes }}"
   ignore_errors: yes
   when:
-    - kdevops_enable_guestfs|bool
+    - kdevops_generate_nodes|bool
+
+- name: Create local directories for each of the guests
+  ansible.builtin.file:
+    path: "{{ kdevops_node_path }}/{{ item.name }}"
+    state: directory
+  with_items: "{{ guestfs_nodes }}"
+  when: kdevops_enable_guestfs|bool
 
 - name: Create local directories for each of the guests
   ansible.builtin.file:
diff --git a/playbooks/roles/gen_nodes/templates/nixos.nix.j2 b/playbooks/roles/gen_nodes/templates/nixos.nix.j2
new file mode 100644
index 000000000000..40eb59853e90
--- /dev/null
+++ b/playbooks/roles/gen_nodes/templates/nixos.nix.j2
@@ -0,0 +1,34 @@
+{ config, pkgs, ... }:
+
+{
+  imports = [ ./hardware-configuration.nix ];
+
+  networking.hostName = "{{ guest_hostname }}";
+  networking.useDHCP = false;
+
+  networking.interfaces.enp1s0.ipv4.addresses = [{
+    address = "{{ guest_ip }}";
+    prefixLength = 24;
+  }];
+  networking.defaultGateway = "{{ guest_gateway }}";
+  networking.nameservers = [ "{{ guest_dns }}" ];
+
+  time.timeZone = "UTC";
+
+  environment.systemPackages = with pkgs; [
+    git
+    htop
+    sysbench
+    docker
+  ];
+
+  services.openssh.enable = true;
+
+  users.users.kdevops = {
+    isNormalUser = true;
+    extraGroups = [ "wheel" ];
+    password = "kdevops"; # for testing only; better to use hashedPassword
+  };
+
+  system.stateVersion = "24.05";
+}
diff --git a/scripts/nixos.Makefile b/scripts/nixos.Makefile
new file mode 100644
index 000000000000..65eec5efa8d0
--- /dev/null
+++ b/scripts/nixos.Makefile
@@ -0,0 +1,77 @@
+# SPDX-License-Identifier: copyleft-next-0.3.1
+
+NIXOIS_ARGS :=
+
+KDEVOPS_NODES_TEMPLATE :=	$(KDEVOPS_NODES_ROLE_TEMPLATE_DIR)/nixos_nodes.j2
+KDEVOPS_NODES :=		$(KDEVOPS_NODE_PATH)/kdevops_nodes.yaml
+
+export KDEVOPS_PROVISIONED_SSH := $(KDEVOPS_PROVISIONED_SSH_DEFAULT_GUARD)
+
+NIXOS_ARGS += data_home_dir=/home/kdevops
+NIXOS_ARGS += kdevops_storage_pool_user='$(USER)'
+
+NIXOS_ARGS += libvirt_provider=True
+
+QEMU_GROUP:=$(subst ",,$(CONFIG_LIBVIRT_QEMU_GROUP))
+NIXOS_ARGS += kdevops_storage_pool_group='$(QEMU_GROUP)'
+NIXOS_ARGS += storage_pool_group='$(QEMU_GROUP)'
+
+ANSIBLE_EXTRA_ARGS += $(NIXOS_ARGS)
+
+NIXOS_BRINGUP_DEPS :=
+NIXOS_BRINGUP_DEPS +=  install_nixos
+
+KDEVOPS_PROVISION_METHOD		:= bringup_nixos
+KDEVOPS_PROVISION_STATUS_METHOD		:= status_nixos
+KDEVOPS_PROVISION_DESTROY_METHOD	:= destroy_nixos
+
+$(KDEVOPS_PROVISIONED_SSH):
+	$(Q)if [[ "$(CONFIG_KDEVOPS_SSH_CONFIG_UPDATE)" == "y" ]]; then \
+		ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+			--inventory localhost, \
+			playbooks/update_ssh_config_nixos.yml \
+			--extra-vars=@./extra_vars.yaml \
+			-e 'ansible_python_interpreter=/usr/bin/python3' ;\
+		LIBVIRT_DEFAULT_URI=$(CONFIG_LIBVIRT_URI) $(TOPDIR)/scripts/update_ssh_config_nixos.py; \
+	fi
+	$(Q)ansible $(ANSIBLE_VERBOSE) -i hosts all -e 'ansible_python_interpreter=/usr/bin/python3' -m wait_for_connection
+	$(Q)touch $(KDEVOPS_PROVISIONED_SSH)
+
+install_nixos:
+	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+		--inventory localhost, \
+		playbooks/bringup_nixos.yml \
+		-e 'ansible_python_interpreter=/usr/bin/python3' \
+		--extra-vars=@./extra_vars.yaml \
+		--tags install-deps
+
+bringup_nixos: $(NIXOS_BRINGUP_DEPS)
+	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+		--inventory localhost, \
+		playbooks/bringup_nixos.yml \
+		-e 'ansible_python_interpreter=/usr/bin/python3' \
+		--extra-vars=@./extra_vars.yaml \
+		--tags bringup
+PHONY += bringup_nixos
+
+status_nixos:
+	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+		--inventory localhost, \
+		playbooks/bringup_nixos.yml \
+		-e 'ansible_python_interpreter=/usr/bin/python3' \
+		--extra-vars=@./extra_vars.yaml \
+		--tags status
+PHONY += status_nixos
+
+destroy_nixos:
+	$(Q)ansible-playbook $(ANSIBLE_VERBOSE) --connection=local \
+		--inventory localhost, \
+		playbooks/bringup_nixos.yml \
+		-e 'ansible_python_interpreter=/usr/bin/python3' \
+		--extra-vars=@./extra_vars.yaml \
+		--tags destroy
+	$(Q)rm -f $(KDEVOPS_PROVISIONED_SSH) $(KDEVOPS_PROVISIONED_DEVCONFIG)
+PHONY += destroy_nixos
+
+cleancache:
+	$(Q)echo fixme
