Modern teams want automation that’s fast to adopt, safe to change, and easy to scale. Progress Chef delivers exactly that: a workflow where you define desired state once, enforce it everywhere, and continuously validate outcomes with policy, testing, and compliance. In this post, we’ll walk through a simple, repeatable approach to infrastructure automation with Chef—using a few code snippets you can lift into your environment today.

Why Chef for Day‑2 Reality
Day‑1 provisioning gets attention, but Day‑2 is where reliability and cost efficiency live: patching, configuration drift control, secure baselines, and ongoing compliance. Chef’s model-driven automation turns these needs into code—versioned, testable, and reusable—so teams avoid “snowflake servers” and manual runbooks.
You’ll see four patterns:
- Express desired state in a recipe
- Parameterize with attributes
- Lock dependencies with Policyfiles
- Continuously validate with Chef InSpec
1) Start Simple: Express Desired State in a Recipe
package ‘nginx’ do
action :install
end
service ‘nginx’ do
action [:enable, :start]
end
file ‘/etc/nginx/conf.d/progress.conf’ do
content <<~CONF
server {
listen 80;
server_name _;
location / {
return 200 ‘Hello from Progress Chef!’;
}
}
CONF
mode ‘0644’
owner ‘root’
group ‘root’
notifies :reload, ‘service[nginx]’, :immediately
end
2) Make It Reusable: Attributes Over Hardcoding
attributes/default.rb
default[‘web_baseline’][‘message’] = ‘Hello from Progress Chef!’
default[‘web_baseline’][‘port’] = 80
Template example
server {
listen <%= @port %>;
server_name _;
location / {
return 200 ‘<%= @message %>’;
}
}
3) Ship Predictably: Policyfiles for Dependency Locking
Policyfile.rb
name ‘web_baseline_policy’
run_list(
‘recipe[web_baseline::default]’
)
default_source :supermarket
cookbook ‘web_baseline’, path: ‘./cookbooks/web_baseline’
default[‘web_baseline’][‘message’] = ‘Welcome to Production (Progress Chef)!’
default[‘web_baseline’][‘port’] = 8080
4) Verify Continuously: Compliance with Chef InSpec
control ‘nginx-1.0’ do
impact 0.7
title ‘NGINX is installed, enabled, and serving expected content’
describe package(‘nginx’) do
it { should be_installed }
end
describe service(‘nginx’) do
it { should be_enabled }
it { should be_running }
end
port_number = input(‘port’, value: 80)
describe port(port_number) do
it { should be_listening }
its(‘protocols’) { should include ‘tcp’ }
end
describe http(“http://localhost:#{port_number}”) do
its(‘status’) { should cmp 200 }
its(‘body’) { should match /Progress Chef/ }
end
end
Contact us to learn more about Chef.