Automating Infrastructure That Sticks: Practical Patterns with Progress Chef

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:

  1. Express desired state in a recipe
  2. Parameterize with attributes
  3. Lock dependencies with Policyfiles
  4. 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.

Tags:

Jayamathan S

Jayamathan is a Senior Product Manager at Progress, currently responsible for Infra Server, Automate and Declarative State Management (DSM). He has nine years of industry experience and have expertise B2B SaaS,  low-code/no-code and developer platforms. Jayamathan has previously worked with o9 Solutions, Kissflow and Verizon, and he actively contributes to product management and developer communities.

 

Joanna Smith

Joanna Smith is a product manager at Progress.