Chef Sugar
CHEF SUGAR DEPRECATION WARNING
Chef Sugar functionality has been migrated into Chef Infra Client 16. There is no longer a need for this cookbook and gem for most use cases and we will not be maintaining the project further at this point. No issues or patches are being accepted at this time.
Requirements
Platforms
- any platform
Chef
- Chef 13.0+
Cookbooks
- none
Installation
If you want to develop/hack on chef-sugar, please see the CONTRIBUTING.md.
If you are using Berkshelf, add chef-sugar
to your Berksfile
:
cookbook 'chef-sugar'
Otherwise, you can use knife
or download the tarball directly from the community site:
knife cookbook site install chef-sugar
Usage
Simply depend on this cookbook in the metadata of your cookbook and the gem will be installed and required..
Requiring the Chef Sugar Gem will automatically extend the Recipe DSL, Chef::Resource
, and Chef::Provider
with helpful convenience methods.
Module Method
If you are working outside of the Recipe DSL, you can use the module methods instead of the Recipe DSL. In general, the module methods have the same name as their Recipe-DSL counterparts, but require the node object as a parameter. For example:
In a Recipe:
# cookbook/recipes/default.rb
do_something if windows?
In a Library as a singleton:
# cookbook/libraries/default.rb
def only_on_windows(&block)
yield if Chef::Sugar::PlatformFamily.windows?(@node)
end
In a Library as a Mixin:
# cookbook/libraries/default.rb
include Chef::Sugar::PlatformFamily
def only_on_windows(&block)
yield if windows?(@node)
end
API
Note: For the most extensive API documentation, please see the YARD documentation.
Architecture
Note: Some of the architecture commands begin with an underscore (_
) because Ruby does not permit methods to start with a numeric.
_64_bit?
_32_bit?
intel?
sparc?
ppc64?
ppc64le?
powerpc?
Examples
execute 'build[my binary]' do
command '...'
not_if { _64_bit? }
end
Cloud
azure?
cloud?
digitalocean?
ec2?
eucalyptus?
gce?
linode?
openstack?
cloudstack?
rackspace?
softlayer?
Examples
template '/tmp/config' do
variables(
# See also: best_ip_for
ipaddress: cloud? ? node['local_ipv4'] : node['public_ipv4']
)
end
Core Extensions
Note: Core extensions are not included by default. You must require the chef/sugar/core_extensions
module manually to gain access to these APIs:
require 'chef/sugar/core_extensions'
String#satisfies?
String#satisfied_by?
Array#satisfied_by?
Object#blank?
Examples
# Checking version constraints
'1.0.0'.satisfies?('~> 1.0') #=> true
'~> 1.0'.satisfied_by?('1.0') #=> true
# Check for an object's presence
''.blank? #=> true
['hello'].blank? #=> false
Data Bag
-
encrypted_data_bag_item
- a handy DSL method for loading encrypted data bag items the same way you load a regular data bag item; this requiresChef::Config[:encrypted_data_bag_secret]
is set! -
encrypted_data_bag_item_for_environment
- find the encrypted data bag entry for the current node's Chef environment. -
data_bag_item_for_environment
- find the data bag entry for the current node's Chef environment.
Examples
encrypted_data_bag_item('accounts', 'hipchat')
encrypted_data_bag_item_for_environment('accounts', 'github')
data_bag_item_for_environment('accounts', 'github')
Docker
Chef Sugar looks for hints to see if the node being converged is a Docker container. When Ohai supports checking other nodes, Chef Sugar will automatically pick up the information.
docker?
Examples
template '/runme' do
only_if { docker?(node) }
end
Attributes
Chef Sugar adds more Chef-like DSL to attribute definitions. Instead of using the Ruby hash syntax, you can define attributes using nested namespaces. This DSL may be more friendly to non-Ruby developers. It can safely be mixed-and-matched with the standard syntax.
# This is functionally the same as default['apache2']['config']['root'] = '/var/www'
namespace 'apache2' do
namespace 'config' do
root '/var/www'
end
end
# Specify multiple keys instead of nesting namespaces
namespace 'apache2', 'config' do
root '/var/www'
end
# Specify different nested precedence levels
namespace 'apache2', precedence: normal do
namespace 'config', precedence: override do
root '/var/www' #=> override['apache2']['config']['root'] = '/var/www'
end
end
Constraints
-
constraints
- create a new constraint (or requirement) that can be used to test version validations. -
chef_version
- (DSL only) a wrapper forversion(Chef::VERSION)
-
version
- create a new version that can be used to test constraint validation.
Examples
# Check if a version is satisfied by a constraint
version('1.2.3').satisfies?('~> 1.2.0')
# Check if a constraint is satisfied by a version
constraint('~> 1.2.0').satisfied_by?('1.2.3')
# Support multiple constraints
version('1.2.3').satisfies?('> 1.2', '< 2.0')
constraint('> 1.2', '< 2.0').satisfied_by?('1.2.3')
# Only perform an operation if Chef is at a certain version
package 'apache2' do
not_if { chef_version.satisfies?('~> 11.0') } # Ignore Chef 11
end
Kernel
-
require_chef_gem
- "safely" require a gem. Loading a gem with Chef is sometimes difficult and confusing. The errors that Chef produces are also sometimes not very intuitive. In the event you require a gem to exist on the system, you can userequire_chef_gem
, which will attempt to require the gem and then produce helpful output if the gem is not installed:Chef could not load the gem `#{name}'! You may need to install the gem manually with `gem install #{name}', or include a recipe before you can use this resource. Please consult the documentation for this cookbook for proper usage.
Examples
# LWRP
require_chef_gem 'pry'
class Chef
class Provider
class MyProvider > Provider
require_chef_gem 'pry'
end
end
end
Init
-
systemd?
- detect if init system is systemd -
upstart?
- detect if init system is upstart -
runit?
- detect if init system is runit
Examples
systemd_service 'my-service' do
description 'My Service'
install do
wanted_by 'multi-user.target'
end
service do
exec_start '/usr/bin/myserviced'
end
action [:create, :enable, :start]
only_if { systemd? }
end
cookbook_file '/etc/init/my-service.conf' do
source 'my-service.conf'
only_if { upstart? }
end
IP
-
best_ip_for
- determine the best IP address for the given "other" node, preferring local IP addresses over public ones.
Examples
redis = search('node', 'role:redis').first
template '/tmp/config' do
variables(
ipaddress: best_ip_for(redis)
)
end
Node
Additional methods for the node
object
-
deep_fetch
- safely fetch a nested attribute. -
deep_fetch!
- fetch a nested attribute, raising a more semantic error if the key does not exist. -
in?
- determine if the node is in the given Chef environment.
Examples
credentials = if node.in?('production')
Chef::EncryptedDataBag.new('...')
else
data_bag('...')
end
node.deep_fetch('apache2', 'config', 'root') => node['apache2']['config']['root']
Platform
amazon_linux?
centos?
linux_mint?
oracle_linux?
redhat_enterprise_linux?
scientific_linux?
ubuntu?
solaris2?
aix?
smartos?
omnios?
raspbian?
nexus?
ios_xr?
There are also a series of dynamically defined matchers that map named operating system release versions and comparison operators in the form "#{platform}#{operator}#{name}?". For example:
debian_after_squeeze?
linuxmint_after_or_at_olivia?
mac_os_x_lion?
centos_final?
ubuntu_before_lucid?
ubuntu_before_or_at_maverick?
solaris_10?
solaris_11?
To get a full list, run the following in IRB:
require 'chef/sugar'
puts Chef::Sugar::Platform.instance_methods
Examples
if ubuntu?
execute 'apt-get update'
end
Platform Family
arch_linux?
debian?
fedora?
freebsd?
gentoo?
linux?
mac_os_x?
openbsd?
rhel?
slackware?
suse?
windows?
wrlinux?
Examples
node['attribute'] = if windows?
'C:\Foo\BarDrive'
else
'/foo/bar_drive'
end
Ruby
Note: The applies to the Ruby found at node['languages']['ruby']
.
ruby_20?
ruby_19?
Examples
log 'This has been known to fail on Ruby 2.0' if ruby_20?
Run Context
-
includes_recipe?
- determines if the current run context includes the recipe
if includes_recipe?('apache2::default')
apache_module 'my_module' do
# ...
end
end
Shell
which
dev_null
installed?
installed_at_version?
version_for
Examples
log "Using `mongo` at `#{which('mongo')}`"
if installed?('apt')
execute 'apt-get update'
end
execute 'install[thing]' do
command "... 2>&1 #{dev_null}"
not_if { installed_at_version?('thing', node['thing']['version']) }
end
log "Skipping git install, version is at #{version_for('mongo', '-v')}"
Vagrant
vagrant?
Examples
http_request 'http://...' do
not_if { vagrant? }
end
Virtualization
kvm?
lxc?
parallels?
virtualbox?
vmware?
openvz?
Examples
service 'ntpd' do
action [:enable, :start]
not_if { lxc? }
end
Filters
-
at_compile_time
- accepts a block of resources to run at compile time -
before
- insert resource in the collection before the given resource -
after
- insert resource in the collection after the given resource
Examples
at_compile_time do
package 'apache2'
end
# This is equivalent to
package 'apache2' do
action :nothing
end.run_action(:install)
before 'service[apache2]' do
log 'I am before the apache 2 service fires!'
end
after 'service[apache2]' do
log 'I am after the apache 2 service fires!'
end
License & Authors
- Author: Seth Vargo (sethvargo@gmail.com)
Copyright 2013-2015 Seth Vargo
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.