Chef Conditional Prgramming Tutorials

There are certain attributes that can be used to evaluate the state of a node during the
execution process of a chef-client run. Based on the result of the evaluation, the attribute
is used to tell chef-client whether it should continue the execution of that specific
resource or not.

These attributes are referred to as guard attributes or conditionals.
A guard attribute either accepts

  1. A string or - If a string is supplied as a value, the string is considered as a command,if the execution of the concerned command yields 0 as the return value the guard is applied or else not.
  2. A block of Ruby code as a value. - If a Ruby block is supplied as a value, the block is executed as Ruby code. The block
    must return either true or false.

Guard attributes are typically used to ensure that the Chef resource is idempotent. It checks whether the desired state is present or not. If the state is already present, the chef-client run does nothing for the concerned resource.

The following attributes can be used to define a guard:

Attribute Description
not_if This prevents a resource from being executed if the condition is true
only_if This ensures that a resource is executed only if the condition is true

 

 


Example Programs

Condistions Based on if-else statement with Chef Attributes attribute? A useful method that is related to attributes is the attribute? method. This method will check for the existence of an attribute, so that processing can be done in an attributes file or recipe, but only if a specific attribute exists. Using attribute?() in an attributes file: if attribute?('ec2') # ... set stuff related to EC2 end Using attribute?() in a recipe: if node.attribute?('ec2') # ... do stuff on EC2 nodes end Condistions Based on if statement if node[:platform_family].include?("rhel") ... end Condistions Based on if statement

if node['platform'] == 'debian' || node['platform'] == 'ubuntu'
 execute "apt-get update" do
   command "apt-get update"
 end
end	
Condistions Based on include_recipe

include_recipe 'python::repository' if node['python']['installrepo']
Condistions Based on if-else and include_recipe

if node['platform_family'] == 'windows'
  include_recipe 'python::install-windows'
else
  include_recipe 'python::install-linux'
end
Condistions Based on Attributes

if node['platform'] == 'debian' || node['platform'] == 'ubuntu'
 execute "apt-get update" do
   command "apt-get update"
 end
end	

if node['platform'] == 'redhat'
 execute "yum git" do
   command "yum install git -y"
 end
end
not_if

apt_package "apache2" do
 action :install
 not_if { node['platform'] == 'redhat' }
end

file '/tmp/somefile.txt' do
  mode '0755'
  not_if { File.exist?('/etc/passwd' )}
end

execute 'bundle install' do
  cwd '/myapp'
  not_if 'bundle check' # This is run from /myapp
end

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  not_if { node[:some_value] }
end	

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  not_if do
    File.exist?('/etc/passwd')
  end
end

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  not_if { File.exist?('/etc/passwd' )}
end

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  not_if 'test -f /etc/passwd'
end


Example
:user
Specify the user that a command will run as. For example:
not_if 'grep adam /etc/passwd', :user => 'adam'

:group
Specify the group that a command will run as. For example:
not_if 'grep adam /etc/passwd', :group => 'adam'

:environment
Specify a Hash of environment variables to be set. For example:
not_if 'grep adam /etc/passwd', :environment => {
  'HOME' => '/home/adam'
}

:cwd
Set the current working directory before running a command. For example:
not_if 'grep adam passwd', :cwd => '/etc'

:timeout
Set a timeout for a command. For example:
not_if 'sleep 10000', :timeout => 10

apt_package "php5" do
 action :install
 not_if { node['platform'] == 'centos' }
end

# want to ensure that we have the right JAVA_HOME path set before we go about
triggering the command to start the app or check the status.

bash "some_app" do
environment { "JAVA_HOME" => "/usr/java/default" }
code "java /apps/some_app/app start"
not_if "java /apps/some_app/app status"
end

# However, this isn't the right way to go about handling our situation because the
environment variable JAVA_HOME isn't available to the java some_app status
command. One way to do it correctly is this:

bash "some_app" do
environment { "JAVA_HOME" => "/usr/java/default" }
code "java /apps/some_app/app start"
not_if "java /apps/some_app/app status", :environment => {
'JAVA_HOME' => '/usr/java/default' }
end

bash "some_app" do
guard_interpreter :bash
environment { "JAVA_HOME" => "/usr/java/default" }
code "java /apps/some_app/app start"
not_if "java /apps/some_app/app status"
end

# we are installing a package called package_name and
we want to install it only on systems running RHEL 6.x.
package "package_name" do
action :install
not_if { platform_family?('rhel') && node['platform_version'].to_f < 6.0 }
end
only_if

only_if
Allow a resource to execute only if the condition returns true.

file '/tmp/infy.txt' do
    only_if { File.exist?('/etc/passwd2' ) }
end

package "httpd" do
action :install
only_if { platform_family?('rhel') && node['platform_version'].to_f >= 6.0 }
end

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  only_if { node[:some_value] }
end

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  only_if do ! File.exist?('/etc/passwd') end
end

template '/tmp/somefile' do
  mode '0755'
  source 'somefile.erb'
  only_if 'test -f /etc/passwd'
end

file '/var/www/html/login.php' do
    only_if { ::File.exist?('/var/www/html/login.php') }
    action :touch
end

file '/path/foo' do
  action :delete
  only_if { File.exist? '/path/foo' }
end

apt_package "php-pear" do
 action :install
 only_if "which php"
end

# we are installing a package called package_name and
we want to install it only on systems running RHEL 6.x.
package "package_name" do
action :install
only_if { platform_family?('rhel') && node['platform_version'].to_f >= 6.0 }
end

include_recipe "postfix::server" do
  only_if node["defaults"]["postfix_server"] = true
end

Avail Rajesh Kumar as trainer at 50% Discount
Puppet Online Training
Puppet Classroom TrainingEnroll Now