Chef did not make a clean transition into the immutable world. Chef Client was great for persistent infrastructure, but the options got dicier once we started talking about pre-provisioned infrastructure like image building:<p>1. Chef Solo (how I last used it when attempting this), which felt intentionally hobbled. All you needed was one poorly-behaved cookbook that called `search` and the bets were off.<p>2. Chef Zero, which was unnecessarily complicated for being Chef Solo that wasn't intentionally hobbled, so much so that I kept using Solo for awhile after its deprecation.<p>3. Chef Client, against a Chef Server that was run either for your other persistent infrastructure, or just to have a place to put the cookbooks. Heaven forbid you weren't cleaning up all of those dynamically-created nodes, though...<p>I still think Chef's Ruby DSL is much more natural than the YAML manifests used by Ansible, and the ability to integrate at the source level with custom Ruby code is a killer feature as soon as any complexity enters the mix. But I almost certainly would not be using Chef in a greenfield deployment these days.