Setting up chef dev environment
Building a Practical Chef Lab on KVM and Vagrant
Most configuration-management tutorials assume you are running VirtualBox on a laptop. That works until you start dealing with real workloads or anything that resembles datacenter networking. For realistic testing, KVM on a Linux host behaves much closer to production. Combine it with Vagrant and you get reproducible provisioning without babysitting virtual machine definitions.
This write-up walks through setting up a Chef Server, a Workstation, and multiple Nodes using KVM, Vagrant, and libvirt.
Install KVM and libvirt:
dnf install -y qemu-kvm libvirt libvirt-daemon libvirt-daemon-driver-qemu virt-install bridge-utils
systemctl enable --now libvirtd
Verify virtualization support:
egrep -c '(vmx|svm)' /proc/cpuinfo
Example isolated network definition:
<network>
<name>chef-net</name>
<bridge name='virbr50'/>
<ip address='192.168.56.1' netmask='255.255.255.0'/>
</network>Activate it:
virsh net-define chef-net.xml
virsh net-start chef-net
virsh net-autostart chef-net
Install Vagrant and the libvirt provider:
dnf install -y vagrant
vagrant plugin install vagrant-libvirt
Verify detection:
vagrant plugin list
vagrant up --provider=libvirt
A minimal Rocky Linux image built using Packer and QEMU provides consistency across all Chef nodes.
After building the VM, export it as a Vagrant box:
vagrant package --base rocky8-kvm --output rocky8-chef.box
vagrant box add rocky8-chef.box --name rocky8-chef
Controlling the base image avoids dependency drift and ensures reproducibility.
A clean layout helps as the lab grows:
chef-lab/
Vagrantfile
cookbooks/
roles/
environments/
data_bags/
chef_repo/
Vagrant.configure("2") do |config|
config.vm.box = "rocky8-chef"
nodes = {
"chef-server" => "192.168.56.10",
"workstation" => "192.168.56.20",
"node01" => "192.168.56.21",
"node02" => "192.168.56.22"
}
nodes.each do |name, ip|
config.vm.define name do |node|
node.vm.hostname = name
node.vm.network "private_network", ip: ip
node.vm.provider :libvirt do |lv|
lv.cpus = 2
lv.memory = 2048
end
end
end
endInstall Chef Server:
dnf install -y chef-server-core
chef-server-ctl reconfigure
Create the first user and organization:
chef-server-ctl user-create admin Admin User admin@example.com 'Password123' --filename admin.pem
chef-server-ctl org-create homelab "HomeLab Org" --association_user admin --filename homelab-validator.pem
Install Chef Workstation:
dnf install -y chef-workstation
Copy keys from the server:
scp admin.pem homelab-validator.pem workstation:/home/vagrant/chef-repo/.chef/
Configure Knife:
knife configure
Test communication:
knife user list
knife node list
Bootstrap each node from the workstation:
knife bootstrap 192.168.56.21 --ssh-user vagrant --sudo --node-name node01
knife bootstrap 192.168.56.22 --ssh-user vagrant --sudo --node-name node02
Nodes should appear in:
knife node list
Generate a new cookbook:
chef generate cookbook apache_demo
Upload it:
knife cookbook upload apache_demo
Add it to a node’s runlist:
knife node run_list add node01 "recipe[apache_demo]"
Trigger a run:
sudo chef-client
Destroy the environment:
vagrant destroy -f
Recreate it:
vagrant up
This guarantees a fresh environment for every test cycle.
A Chef lab built on KVM and Vagrant mirrors real infrastructure far better than desktop hypervisors. You get proper virtio networking, efficient CPU virtualization, and the ability to scale without friction. This setup provides a reliable, repeatable environment for experimenting with Chef cookbooks, policyfiles, CI pipelines, and infrastructure automation concepts.
Related Articles
Setting up chef dev environment
Building a Practical Chef Lab on KVM and Vagrant that mirrors real infrastructure far better than desktop hypervisors.
Modular vagrant file
How to structure a modular Vagrantfile using separate .rb config files for resources, disks, and networks.
How We Set Up Our KVM Hypervisor: From Bare Metal to Production-Ready VM Host
Detailed walkthrough of building a dedicated KVM/libvirt hypervisor with XFS tuning, hugepages, 10GbE tuning, and automation.