Don't know about simple, but we're using Puppet with Vagrant.
Our Vagrant box uses the exact same setup as production, with minor local tweaks (for example, our internal tool also sets up local DNS resolution so that every app can be invoked from a .dev host name, and we also mount apps from the host machine so you can work on the code and hot-reload it). We use the same tools to deploy apps, inspect status and generally interact with the environment.
Once the developer has downloaded the box, keeping it updated is a manner of running an update command which performs the Puppet magic. The developer doesn't need to know what's going on exactly.
It's not perfect, but it's fairly pain-free, and means we have the exact same software locally as what's on the server.