Effortless Config is the pattern for managing your Chef Infra workloads. It uses Chef Habitat and Chef Policyfiles to build an artifact that contains the cookbooks and their dependencies alongside the scripts necessary to run them on your systems.
hab setup
This pattern uses the chef-repo to store and organize everything you need to define your infrastructure with Chef Infra, including:
The Chef Effortless GitHub repository has an example chef-repo for you to explore.
To use this pattern, navigate to the chef-repo directory that you want to use:
cd chef-repo
Create a habitat directory from the command line with:
mkdir habitat
Make a plan file
Make a plan.ps1 for a cookbook that targets Microsoft Windows systems and a plan.sh for a cookbook that targets Linux systems. You can have both a plan.ps1 and a plan.sh in the habitat directory for cookbooks that target both systems. Create a Linux plan:
touch plan.sh
Add information about the cookbook to the plan
Add this information to the plan.sh file:
pkg_name=<my_policyfile>
pkg_origin=<my_origin>
pkg_version="0.1.0"
pkg_maintainer="My Name and Email"
pkg_license=("Apache-2.0")
pkg_scaffolding="chef/scaffolding-chef-infra"
pkg_svc_user=("root")
scaffold_policy_name="<my_policyfile>"
If you do not have a policyfiles directory in your chef-repo, create one:
mkdir policyfiles
Generate a Policyfile:
chef generate policyfile policyfiles/my_policyfile
Example of a policyfile.rb:
# Policyfile.rb - Describe how Chef Infra should build your system.
#
# For more information on the Policyfile feature, visit
# https://docs.chef.io/policyfile.html
name "base"
# Where to find external cookbooks
default_source :supermarket
default_source :chef_repo, "../"
# run_list: run these recipes in the order specified.
run_list [
"patching::default",
"hardening::default"
]
# attributes: set attributes from your cookbooks
default['hardening'] = {}
default['patching'] = {}
Build the package:
Run the following command to build the package:
hab pkg build .
Edit the kitchen.yml file to look similar to this:
---driver:name:vagrantsynced_folders:- ["./results","/tmp/results"]provisioner:name:shellverifier:name:inspecplatforms:- name:centos-7.6suites:- name:baseprovisioner:arguments:["<my_origin>","<my_package_name>"]verifier:inspec_tests:test/integration/baseCreate a bootstrap.sh script and include:
#!/bin/bash
export HAB_LICENSE="accept-no-persist"
export CHEF_LICENSE="accept-no-persist"
if [ ! -e "/bin/hab" ]; then
curl https://raw.githubusercontent.com/habitat-sh/habitat/main/components/hab/install.sh | sudo bash
fi
if grep "^hab:" /etc/passwd > /dev/null; then
echo "Hab user exists"
else
useradd hab && true
fi
if grep "^hab:" /etc/group > /dev/null; then
echo "Hab group exists"
else
groupadd hab && true
fi
pkg_origin=$1
pkg_name=$2
echo "Starting $pkg_origin/$pkg_name"
latest_hart_file=$(ls -la /tmp/results/$pkg_origin-$pkg_name* | tail -n 1 | cut -d " " -f 9)
echo "Latest hart file is $latest_hart_file"
echo "Installing $latest_hart_file"
hab pkg install $latest_hart_file
echo "Determining pkg_prefix for $latest_hart_file"
pkg_prefix=$(find /hab/pkgs/$pkg_origin/$pkg_name -maxdepth 2 -mindepth 2 | sort | tail -n 1)
echo "Found $pkg_prefix"
echo "Running chef for $pkg_origin/$pkg_name"
cd $pkg_prefix
hab pkg exec $pkg_origin/$pkg_name chef-client -z -c $pkg_prefix/config/bootstrap-config.rb
Run Test Kitchen to ensure the cookbook works
Use this command to spin up a CentOS 7 virtual machine (VM) locally and run the cookbook using the latest Chef Infra Client:
kitchen converge base-centos
If you experience errors in this Chef run, you may need to supply attributes or make modifications to your Policyfile, so that your cookbook can run using the latest Chef Infra Client.
When ready, delete the VM instance by running:
kitchen destroy
Upload the Policyfile pkg to Chef Habitat builder by running the following commands:
source results/lastbuild.env
hab pkg upload results/$pkg_artifact
To run the Policyfile on a system, install Chef Habitat services and run:
hab svc load <my_origin>/<my_policyfile_name>
This pattern builds a Chef Habitat artifact for the Policyfile cookbook. You can find an example Policyfile cookbook in the Chef Effortless GitHub repository.
To use this pattern, navigate to the cookbook you want to use:
cd chef-repo/cookbooks/my_cookbook
Create a habitat directory from the command line with:
mkdir habitat
Make a plan file
Use a plan.ps1 for a cookbook targeting Windows. Use a plan.sh for a cookbook targeting Linux. If the cookbook targets both Windows and Linux, you can have both a plan.ps1 and a plan.sh in the habitat directory. Create a plan in Linux with the following command:
touch plan.sh
Add some information about the cookbook to the plan
plan.sh
pkg_name=<Name of my_cookbook artifact>
pkg_origin=<my_origin>
pkg_version="<Cookbook version>"
pkg_maintainer="<My Name>"
pkg_license=("<License for my_cookbook example Apache-2.0>")
pkg_scaffolding="chef/scaffolding-chef-infra"
scaffold_policy_name="Policyfile"
scaffold_policyfile_path="$PLAN_CONTEXT/../" # habitat/../Policyfile.rb
Make a Policyfile in the cookbook directory
Example of a policyfile.rb file:
# Policyfile.rb - Describe how you want Chef to build your system.
#
# For more information on the Policyfile feature, visit
# https://docs.chef.io/policyfile.html
# A name that describes what the system you're building with Chef does.
name '<my_cookbook_name>'
# Where to find external cookbooks:
default_source :supermarket
# run_list: chef-client will run these recipes in the order specified.
run_list '<my_cookbook_name>::default'
# Specify a custom source for a single cookbook:
cookbook '<my_cookbook_name>', path: '.'
Build the package:
hab pkg build <my_cookbook>
Edit the kitchen.yml file to look similar to this:
---driver:name:vagrantsynced_folders:- ["./results","/tmp/results"]provisioner:name:shellverifier:name:inspecplatforms:- name:centos-7.6suites:- name:baseprovisioner:arguments:["<my_origin>","<my_cookbook>"]verifier:inspec_tests:test/integration/baseCreate a bootstrap.sh script and include:
#!/bin/bash
export HAB_LICENSE="accept-no-persist"
export CHEF_LICENSE="accept-no-persist"
if [ ! -e "/bin/hab" ]; then
curl https://raw.githubusercontent.com/habitat-sh/habitat/main/components/hab/install.sh | sudo bash
fi
if grep "^hab:" /etc/passwd > /dev/null; then
echo "Hab user exists"
else
useradd hab && true
fi
if grep "^hab:" /etc/group > /dev/null; then
echo "Hab group exists"
else
groupadd hab && true
fi
pkg_origin=$1
pkg_name=$2
echo "Starting $pkg_origin/$pkg_name"
latest_hart_file=$(ls -la /tmp/results/$pkg_origin-$pkg_name* | tail -n 1 | cut -d " " -f 9)
echo "Latest hart file is $latest_hart_file"
echo "Installing $latest_hart_file"
hab pkg install $latest_hart_file
echo "Determining pkg_prefix for $latest_hart_file"
pkg_prefix=$(find /hab/pkgs/$pkg_origin/$pkg_name -maxdepth 2 -mindepth 2 | sort | tail -n 1)
echo "Found $pkg_prefix"
echo "Running chef for $pkg_origin/$pkg_name"
cd $pkg_prefix
hab pkg exec $pkg_origin/$pkg_name chef-client -z -c $pkg_prefix/config/bootstrap-config.rb
Run Test Kitchen to ensure the cookbook works on Linux
Use this command to spin up a CentOS 7 virtual machine (VM) locally and run the cookbook using the latest Chef Infra Client:
kitchen converge base-centos
If you experience errors in this Chef run, you may need to supply attributes or make modifications to your Policyfile, so that your cookbook can run using the latest Chef Infra Client.
When ready, delete the VM instance by running:
kitchen destroy
Upload the habitat pkg to Chef Habitat builder by running the following commands:
source results/lastbuild.env
hab pkg upload results/$pkg_artifact
To run the cookbook on a system, install Chef Habitat services and run:
hab svc load my_origin/my_cookbook
© Chef Software, Inc.
Licensed under the Creative Commons Attribution 3.0 Unported License.
The Chef™ Mark and Chef Logo are either registered trademarks/service marks or trademarks/servicemarks of Chef, in the United States and other countries and are used with Chef Inc's permission.
We are not affiliated with, endorsed or sponsored by Chef Inc.
https://docs.chef.io/effortless/effortless_config/