Policyfiles & environments
Pin exactly what a node runs.
Roles and Berkshelf resolve dependencies at upload time, which can let a node pick up newer cookbook versions than you tested — a reproducibility gap. Policyfiles close it: a Policyfile.rb declares a run-list and resolves the entire dependency graph to an exact, locked set of versions in a Policyfile.lock.json. A node running that policy runs precisely the cookbooks you tested, nothing floating.
name 'web'default_source :supermarketrun_list 'base', 'nginx', 'web'cookbook 'web', path: '.'cookbook 'nginx', '~> 11.0'# `chef install` writes Policyfile.lock.json pinning EXACT versions
Policy groups as environments
You push a policy to named policy groups — dev, staging, prod — so the same policy can be promoted through environments, and each group can run a different revision. This replaces the older environments + roles approach with a single, version-locked artifact per environment, giving you tested-then-promoted releases of infrastructure code instead of a shared, mutable role that everything reads live.
$ chef install # resolve + write the lock file$ chef push dev # upload the locked policy to the dev group# after testing in dev, promote the exact same revision:$ chef push prod