Common Resource Functionality
All resources (including custom resources) share a set of common actions, properties, conditional executions, notifications, and relative path options.
Actions
The following actions may be used with any resource:
:nothing
- This resource block does not act unless notified by another resource to take action. Once notified, this resource block either runs immediately or is queued up to run at the end of a Chef Infra Client run.
Examples
The following examples show how to use common actions in a recipe.
Use the :nothing action
service 'memcached' do
action :nothing
end
Properties
The following properties are common to every resource:
compile_time
Ruby Type: true, false | Default Value:
false
Control the phase during which the resource is run on the node. Set to true to run while the resource collection is being built (the
compile phase
). Set to false to run while Chef Infra Client is configuring the node (theconverge phase
).ignore_failure
Ruby Type: true, false, :quiet | Default Value:
false
Continue running a recipe if a resource fails for any reason.
:quiet
will not display the full stack trace and the recipe will continue to run if a resource fails.retries
Ruby Type: Integer | Default Value:
0
The number of attempts to catch exceptions and retry the resource.
retry_delay
Ruby Type: Integer | Default Value:
2
The delay in seconds between retry attempts.
sensitive
Ruby Type: true, false | Default Value:
false
Ensure that sensitive resource data is not logged by Chef Infra Client.
Examples
The following examples show how to use common properties in a recipe.
Use the ignore_failure common property
gem_package 'syntax' do
action :install
ignore_failure true
end
Use the retries and retry_delay common properties
service 'apache' do
action [ :enable, :start ]
retries 3
retry_delay 5
end
Guards
A guard property can be used to evaluate the state of a node during the execution phase of a Chef Infra Client run. Based on the results of this evaluation, a guard property is then used to tell Chef Infra Client if it should continue executing a resource. A guard property accepts either a string value or a Ruby block value:
- A string is executed as a shell command. If the command returns
0
, the guard is applied. If the command returns any other value, then the guard property is not applied. String guards in a powershell_script run Windows PowerShell commands and may returntrue
in addition to0
. - A block is executed as Ruby code that must return either
true
orfalse
. If the block returnstrue
, the guard property is applied. If the block returnsfalse
, the guard property is not applied.
A guard property is useful for ensuring that a resource is idempotent by allowing that resource to test for the desired state as it is being executed, and then if the desired state is present, for Chef Infra Client to do nothing.
Note
When using the not_if
and only_if
guards with the execute
resource, the guard’s environment is inherited from the resource’s
environment. For example:
execute 'bundle install' do
cwd '/myapp'
not_if 'bundle check' # This is run from /myapp
end
Properties
The following properties can be used to define a guard that is evaluated during the execution phase of a Chef Infra Client run:
not_if
Prevent a resource from executing when the condition returns
true
.only_if
Allow a resource to execute only if the condition returns
true
.
Arguments
The following arguments can be used with the not_if
or only_if
guard
properties:
: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
not_if Examples
Update if not already updated
The following example shows how to use not_if
to guard against running
the apt-get-update
command when a file already exists that is the same
as the updated file:
execute 'apt-get-update' do
command 'apt-get update'
ignore_failure true
not_if { ::File.exist?('/var/lib/apt/periodic/update-success-stamp') }
end
Ensure a node can resolve a host
The following example shows how to use a custom block of Ruby code to ensure that a node can resolve the host. If the node can resolve the host, Chef Infra Client will do nothing. If the node cannot resolve the host, Chef Infra Client will configure the host:
ruby_block 'ensure node can resolve API FQDN' do
block do
fe = Chef::Util::FileEdit.new('/etc/hosts')
fe.insert_line_if_no_match(/#{node['chef-server']['api_fqdn']}/,
"127.0.0.1 #{node['chef-server']['api_fqdn']}")
fe.write_file
end
not_if { Resolv.getaddress(node['chef-server']['api_fqdn']) rescue false }
end
Prevent installs on older versions
The following example shows how to use not_if
to prevent ZeroMQ from
being installed when the node on which the install is to occur has a
version of Red Hat Enterprise Linux that is older than version 6.0:
ark 'test_autogen' do
url 'https://github.com/zeromq/libzmq/tarball/master'
extension 'tar.gz'
action :configure
not_if { platform_family?('rhel') && node['platform_version'].to_f < 6.0 }
end
Set the administrator if not already set
The following example shows how to set the administrator for Nagios on multiple nodes, except when the package already exists on a node:
%w(adminpassword adminpassword-repeat).each do |setting|
execute "debconf-set-selections::#{node['nagios']['server']['vname']}-cgi::#{node['nagios']['server']['vname']}/#{setting}" do
command "echo #{node['nagios']['server']['vname']}-cgi #{node['nagios']['server']['vname']}/#{setting} password #{random_initial_password} | debconf-set-selections"
not_if "dpkg -l #{node['nagios']['server']['vname']}"
end
end
only_if Examples
Install packages only when necessary
The following example shows how to use only_if
with one (or more)
cookbook attributes to ensure that packages are only installed when
necessary. In this case, three attributes exist in the
/attributes/default.rb
file: use_openssl
, use_pcre
, and
use_zlib
. Each of these attributes are defined as false
by default.
The only_if
attributes are used to test for the presence of these
packages on the target node before then asking Chef Infra Client to
complete the process of installing these packages. If the packages are
already present, Chef Infra Client will do nothing.
package 'libpcre3-dev' do
only_if { node['haproxy']['source']['use_pcre'] }
end
package 'libssl-dev' do
only_if { node['haproxy']['source']['use_openssl'] }
end
package 'zlib1g-dev' do
only_if { node['haproxy']['source']['use_zlib'] }
end
Remove a recipe if it belongs to a specific run-list
The following example shows how to use only_if
to only remove a recipe
named recipe[ntp::undo]
, but only when that recipe is part of the
recipe[ntp::default]
run-list:
ruby_block 'remove ntp::undo from run list' do
block do
node.run_list.remove('recipe[ntp::undo]')
end
only_if { node.run_list.include?('recipe[ntp::default]') }
end
Re-register ASP.Net if it is already installed
The following example shows how to use only_if
to ensure that Chef
Infra Client will attempt to register ASP.NET only if the executable is
installed on the system, on both 32- and 64-bit systems:
aspnet_regiis = "#{ENV['WinDir']}\\Microsoft.NET\\Framework\\v4.0.30319\\aspnet_regiis.exe"
execute 'Register ASP.NET v4' do
command "#{aspnet_regiis} -i"
only_if { ::File.exist?(aspnet_regiis) }
action :nothing
end
aspnet_regiis64 = "#{ENV['WinDir']}\\Microsoft.NET\\Framework64\\v4.0.30319\\aspnet_regiis.exe"
execute 'Register ASP.NET v4 (x64)' do
command "#{aspnet_regiis64} -i"
only_if { ::File.exist?(aspnet_regiis64) }
action :nothing
end
Guard Interpreters
Any resource that passes a string command may also specify the interpreter that will be used to evaluate that string command. This is done by using theguard_interpreter
property to specify a
script-based resource.Attributes
The guard_interpreter
property may be set to any of the following
values:
:bash
Evaluates a string command using the bash resource.
:batch
Evaluates a string command using the batch resource. Default value (within a batch resource block):
:batch
.:csh
Evaluates a string command using the csh resource.
:default
Default. Executes the default interpreter as identified by Chef Infra Client.
:perl
Evaluates a string command using the perl resource.
:powershell_script
Evaluates a string command using the powershell_script resource. Default value (within a powershell_script resource block):
:powershell_script
.:python
Evaluates a string command using the python resource.
:ruby
Evaluates a string command using the ruby resource.
Inheritance
The guard_interpreter
property is set to :default
by default for the
bash, csh, perl, python, and ruby resources. When
the guard_interpreter
property is set to :default
, not_if
or
only_if
guard statements do not inherit properties that are
defined by the script-based resource.
Warning
The batch and powershell_script resources inherit properties by
default. The guard_interpreter
property is set to :batch
or
:powershell_script
automatically when using a not_if
or only_if
guard statement within a batch or powershell_script resource,
respectively.
bash 'javatooling' do
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started'
end
and requires adding the environment
property to the not_if
guard
statement so that it may use the JAVA_HOME
path as part of its
evaluation:
bash 'javatooling' do
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started', :environment => 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
end
To inherit properties, add the guard_interpreter
property to the
resource block and set it to the appropriate value:
:bash
for bash:csh
for csh:perl
for perl:python
for python:ruby
for ruby
For example, using the same example as from above, but this time adding
the guard_interpreter
property and setting it to :bash
:
bash 'javatooling' do
guard_interpreter :bash
environment 'JAVA_HOME' => '/usr/lib/java/jdk1.7/home'
code 'java-based-daemon-ctl.sh -start'
not_if 'java-based-daemon-ctl.sh -test-started'
end
The not_if
statement now inherits the environment
property and will
use the JAVA_HOME
path as part of its evaluation.
Examples
For example, the following code block will ensure the command is evaluated using the default interpreter as identified by Chef Infra Client:
resource 'name' do
guard_interpreter :default
# code
end
Lazy Evaluation
In some cases, the value for a property cannot be known until the execution phase of a Chef Infra Client run. In this situation, using lazy evaluation of property values can be helpful. Instead of a property being assigned a value, it may instead be assigned a code block. The syntax for using lazy evaluation is as follows:
property_name lazy { code_block }
where lazy
is used to tell Chef Infra Client to evaluate the contents
of the code block later on in the resource evaluation process (instead
of immediately) and { code_block }
is arbitrary Ruby code that
provides the value.
For example, a resource that is not doing lazy evaluation:
template 'template_name' do
# some properties
path '/foo/bar'
end
and a resource block that is doing lazy evaluation:
template 'template_name' do
# some properties
path lazy { ' some Ruby code ' }
end
In the previous examples, the first resource uses the value /foo/bar
and the second resource uses the value provided by the code block, as
long as the contents of that code block are a valid resource property.
The following example shows how to use lazy evaluation with template variables:
template '/tmp/canvey_island.txt' do
source 'canvey_island.txt.erb'
variables(
lazy do
{ canvey_island: node.run_state['sea_power'] }
end
)
end
Notifications
A notification is a property on a resource that listens to other resources in the resource collection and then takes actions based on the notification type (notifies
or subscribes
).Timers
A timer specifies the point during a Chef Infra Client run at which a notification is run. The following timers are available:
:before
Specifies that the action on a notified resource should be run before processing the resource block in which the notification is located.
:delayed
Default. Specifies that a notification should be queued up, and then executed at the end of a Chef Infra Client run.
:immediate
,:immediately
Specifies that a notification should be run immediately, for each resource notified.
Notifies
A resource may notify another resource to take action when its state
changes. Specify a 'resource[name]'
, the :action
that resource
should take, and then the :timer
for that action. A resource may
notify more than one resource; use a notifies
statement for each
resource to be notified.
If the referenced resource does not exist, an error is raised.
In contrast, subscribes
will not fail if the source
resource is not found.
The syntax for notifies
is:
notifies :action, 'resource[name]', :timer
Changed in Chef Infra Client 12.6 to use :before
timer with the notifies
and subscribes
properties to specify that the action on a notified
resource should be run before processing the resource block in which the
notification is located.
Examples
The following examples show how to use the notifies
notification in a
recipe.
Delay notifications
template '/etc/nagios3/configures-nagios.conf' do
# other parameters
notifies :run, 'execute[test-nagios-config]', :delayed
end
Notify immediately
By default, notifications are :delayed
, that is they are queued up as
they are triggered, and then executed at the end of a Chef Infra
Client run. To run an action immediately, use :immediately
:
template '/etc/nagios3/configures-nagios.conf' do
# other parameters
notifies :run, 'execute[test-nagios-config]', :immediately
end
and then Chef Infra Client would immediately run the following:
execute 'test-nagios-config' do
command 'nagios3 --verify-config'
action :nothing
end
Notify multiple resources
template '/etc/chef/server.rb' do
source 'server.rb.erb'
owner 'root'
group 'root'
mode '0755'
notifies :restart, 'service[chef-elasticsearch]', :delayed
notifies :restart, 'service[chef-server]', :delayed
end
Notify in a specific order
To notify multiple resources, and then have these resources run in a certain order, do something like the following:
execute 'foo' do
command '...'
notifies :create, 'template[baz]', :immediately
notifies :install, 'package[bar]', :immediately
notifies :run, 'execute[final]', :immediately
end
template 'baz' do
...
notifies :run, 'execute[restart_baz]', :immediately
end
package 'bar'
execute 'restart_baz'
execute 'final' do
command '...'
end
where the sequencing will be in the same order as the resources are
listed in the recipe: execute 'foo'
, template 'baz'
,
execute [restart_baz]
, package 'bar'
, and execute 'final'
.
Reload a service
template '/tmp/somefile' do
mode '0755'
source 'somefile.erb'
notifies :reload, 'service[apache]', :immediately
end
Restart a service when a template is modified
template '/etc/www/configures-apache.conf' do
notifies :restart, 'service[apache]', :immediately
end
Send notifications to multiple resources
To send notifications to multiple resources, just use multiple attributes. Multiple attributes will get sent to the notified resources in the order specified.
template '/etc/netatalk/netatalk.conf' do
notifies :restart, 'service[afpd]', :immediately
notifies :restart, 'service[cnid]', :immediately
end
service 'afpd'
service 'cnid'
Execute a command using a template
The following example shows how to set up IPv4 packet forwarding using
the execute resource to run a command named forward_ipv4
that uses
a template defined by the template resource:
execute 'forward_ipv4' do
command 'echo > /proc/.../ipv4/ip_forward'
action :nothing
end
template '/etc/file_name.conf' do
source 'routing/file_name.conf.erb'
notifies :run, 'execute[forward_ipv4]', :delayed
end
where the command
property for the execute resource contains the
command that is to be run and the source
property for the template
resource specifies which template to use. The notifies
property for
the template specifies that the execute[forward_ipv4]
(which is
defined by the execute resource) should be queued up and run at the
end of a Chef Infra Client run.
Restart a service, and then notify a different service
The following example shows how start a service named example_service
and immediately notify the Nginx service to restart.
service 'example_service' do
action :start
notifies :restart, 'service[nginx]', :immediately
end
Restart one service before restarting another
This example uses the :before
notification to restart the php-fpm
service before restarting nginx
:
service 'nginx' do
action :restart
notifies :restart, 'service[php-fpm]', :before
end
With the :before
notification, the action specified for the nginx
resource will not run until action has been taken on the notified
resource (php-fpm
).
Notify when a remote source changes
remote_file '/tmp/couch.png' do
source 'http://couchdb.apache.org/img/sketch.png'
action :nothing
end
http_request 'HEAD http://couchdb.apache.org/img/sketch.png' do
message ''
url 'http://couchdb.apache.org/img/sketch.png'
action :head
if ::File.exist?('/tmp/couch.png')
headers 'If-Modified-Since' => File.mtime('/tmp/couch.png').httpdate
end
notifies :create, 'remote_file[/tmp/couch.png]', :immediately
end
Subscribes
A resource may listen to another resource, and then take action if the
state of the resource being listened to changes. Specify a
'resource[name]'
, the :action
to be taken, and then the :timer
for
that action.
Note that subscribes
does not apply the specified action to the
resource that it listens to - for example:
file '/etc/nginx/ssl/example.crt' do
mode '0600'
owner 'root'
end
service 'nginx' do
subscribes :reload, 'file[/etc/nginx/ssl/example.crt]', :immediately
end
In this case the subscribes
property reloads the nginx
service
whenever its certificate file, located under
/etc/nginx/ssl/example.crt
, is updated. subscribes
does not make any
changes to the certificate file itself, it merely listens for a change
to the file, and executes the :reload
action for its resource (in this
example nginx
) when a change is detected.
If the other resource does not exist, the subscription will not raise an
error. Contrast this with the stricter semantics of notifies
, which
will raise an error if the other resource does not exist.
The syntax for subscribes
is:
subscribes :action, 'resource[name]', :timer
Examples
The following examples show how to use the subscribes
notification in
a recipe.
Verify a configuration update
Use the :nothing
action (common to all resources) to prevent the test
from starting automatically, and then use the subscribes
notification
to run a configuration test when a change to the template is detected:
execute 'test-nagios-config' do
command 'nagios3 --verify-config'
action :nothing
subscribes :run, 'template[/etc/nagios3/configures-nagios.conf]', :immediately
end
Reload a service when a template is updated
To reload a service that is based on a template, use the template and service resources together in the same recipe, similar to the following:
template '/tmp/somefile' do
mode '0755'
source 'somefile.erb'
end
service 'apache' do
action :enable
subscribes :reload, 'template[/tmp/somefile]', :immediately
end
where the subscribes
notification is used to reload the service
whenever the template is modified.
Relative Paths
The following relative paths can be used with any resource:
#{ENV['HOME']}
Use to return the
~
path in Linux and macOS or the%HOMEPATH%
in Windows.
Examples
template "#{ENV['HOME']}/chef-getting-started.txt" do
source 'chef-getting-started.txt.erb'
mode '0755'
end
Run in Compile Phase
Chef Infra Client processes recipes in two phases:
- First, each resource in the node object is identified and a resource collection is built. All recipes are loaded in a specific order, and then the actions specified within each of them are identified. This is also referred to as the “compile phase”.
- Next, Chef Infra Client configures the system based on the order of the resources in the resource collection. Each resource then examines the node and performs the necessary steps to complete the action. This is also referred to as the “execution phase”.
Typically, actions are processed during the execution phase of a Chef Infra Client run. However, sometimes it is necessary to run an action during the compile phase. For example, a resource can be configured to install a package during the compile phase to ensure that application is available to other resources during the execution phase.
Note
Use the chef_gem resource to install gems that are needed by Chef Infra Client during the execution phase.
Using the compile_time property
Use .run_action(:some_action)
at the end of a resource block to run
the specified action during the compile phase. For example:
build_essential 'Install compilers' do
action :nothing
end.run_action(:install)
where action
is set to :nothing
to ensure the run_action
is run
during the compile phase and not later during the execution phase.
This can be simplified by using the compile_time
flag in Chef Infra
Client 16 and later versions:
build_essential 'Install compilers' do
compile_time true
end
That flag both forces the resource to run at compile time and sets the
converge action to :nothing
.
The following examples show when (and when not) to use run_action
.
Using Custom Resources preferred to forcing to compile time
Compile time execution is often used to install gems before requiring them in recipe code.
This is a poor pattern since gems may depend on native gems which may require installing compilers at compile time.
build_essential 'Install compilers' do
compile_time true
end
chef_gem 'aws-dsk' do
compile_time true
end
require 'aws-sdk'
A better strategy is to move the code, which requires the gem, into a custom resource. Since all the actions of custom resources run at converge time, this defers requiring the gem until later in the overall Chef Infra Client execution. Unified mode can also be used in the resource to eliminate compile/converge mode issues entirely:
unified_mode true
action :run do
build_essential 'Install compilers'
chef_gem 'aws-sdk'
require 'aws-sdk'
end
Download and parse a configuration file
A common use case is to download a configuration file, parse it, and then use the values in templates and to control other configuration.
An important distinction to make is that the downloaded configuration file only exists in a temporary state to be used by the Chef Infra Client. It will not be used directly by the system or applications that are managed by the Chef Infra Client.
To download and parse a JSON file and render it in a template, it makes sense to download the file during compile time:
# the remote_file is being downloaded to a temporary file
remote_file "#{Chef::Config[:file_cache_path]}/users.json" do
source "https://jsonplaceholder.typicode.com/users"
compile_time true
end
# this parsing needs to happen after the remote_file is downloaded, but will
# be executed at compile time.
array = JSON.parse(IO.read("#{Chef::Config[:file_cache_path]}/users.json")
# the `array.last["phone"]` expression here will also be evaluated at compile
# time and must be lazied using wrapping the expresssion in `lazy {}`
file "/tmp/phone_number.txt" do
content array.last["phone"]
end
This is considerably cleaner than the alternative of lazy evaluating both the parsing of the
JSON and the rendering of the data into the file template, which will happen if
the remote_file
resource is not run at compile time:
# the execution of this is now deferred
remote_file "#{Chef::Config[:file_cache_path]}/users.json" do
source "https://jsonplaceholder.typicode.com/users"
end
# it is necessary due to lexical scoping issues to create this variable here
array = nil
# the parsing of the JSON is now deferred due to the ruby_block
ruby_block "parse JSON" do
block do
array = JSON.parse(IO.read("#{Chef::Config[:file_cache_path]}/users.json")
end
end
# the argument to the content property must now also be deferred
file "/tmp/phone_number.txt" do
content lazy { array.last["phone"] }
end
This is an example of code that overuses deferred execution, uses more “lazy” evaluation, and is considerably harder to understand and write correctly.
Notifications will not work
Resources that are executed during the compile phase cannot notify other resources. For example:
execute 'ifconfig'
package 'vim-enhanced' do
compile_time true
notifies :run, 'execute[ifconfig]', :immediately
end
A better approach in this type of situation is to install the package before the resource collection is built to ensure that it is available to other resources later on.
The best approach to this problem is to use unified mode
, which eliminates
the compile time and converge time distinction while allowing notifications
to work correctly.
Resources that are forced to compile time by default
The ohai_hint
and hostname
resources run at compile time by default.
This is due to the fact that later resources may consume the node attributes which
are set by those resources leading to excessive use of lazy
in subsequent
resources (and similar issues to the remote_file
example above).
The chef_gem
resource used to execute at compile time by default, but now we
recommend that users move code that executes at compile time to custom resources.
Windows File Security
To support Windows security, the template, file, remote_file, cookbook_file, directory, and remote_directory resources support the use of inheritance and access control lists (ACLs) within recipes.Access Control Lists (ACLs)
The rights
property can be used in a recipe to manage access control
lists (ACLs), which allow permissions to be given to multiple users and
groups. Use the rights
property can be used as many times as
necessary; Chef Infra Client will apply them to the file or directory as
required. The syntax for the rights
property is as follows:
rights permission, principal, option_type => value
where
permission
Use to specify which rights are granted to the
principal
. The possible values are::read
,:write
,read_execute
,:modify
,:full_control
, or an integer.Integers used for permissions must match the following list FileSystemRights Enum fields.
These permissions are cumulative. If
:write
is specified, then it includes:read
. If:full_control
is specified, then it includes both:write
and:read
.(For those who know the Windows API:
:read
corresponds toGENERIC_READ
;:write
corresponds toGENERIC_WRITE
;:read_execute
corresponds toGENERIC_READ
andGENERIC_EXECUTE
;:modify
corresponds toGENERIC_WRITE
,GENERIC_READ
,GENERIC_EXECUTE
, andDELETE
;:full_control
corresponds toGENERIC_ALL
, which allows a user to change the owner and other metadata about a file.)principal
Use to specify a group or user. The principal can be specified by either name or SID. When using name, this is identical to what is entered in the login box for Windows, such as
user_name
,domain\user_name
, oruser_name@fully_qualified_domain_name
. When using a SID, you may use either the standard string representation of a SID (S-R-I-S-S) or one of the SDDL string constants. Chef Infra Client does not need to know if a principal is a user or a group.option_type
A hash that contains advanced rights options. For example, the rights to a directory that only applies to the first level of children might look something like:
rights :write, 'domain\group_name', :one_level_deep => true
.Possible option types:
:applies_to_children
Specify how permissions are applied to children. Possible values:
true
to inherit both child directories and files;false
to not inherit any child directories or files;:containers_only
to inherit only child directories (and not files);:objects_only
to recursively inherit files (and not child directories).:applies_to_self
Indicates whether a permission is applied to the parent directory. Possible values:
true
to apply to the parent directory or file and its children;false
to not apply only to child directories and files.:one_level_deep
Indicates the depth to which permissions will be applied. Possible values:
true
to apply only to the first level of children;false
to apply to all children.
For example:
resource 'x.txt' do
rights :read, 'S-1-1-0'
rights :write, 'domain\group'
rights :full_control, 'group_name_or_user_name'
rights :full_control, 'user_name', applies_to_children: true
end
or:
rights :read, %w(Administrators Everyone)
rights :full_control, 'Users', applies_to_children: true
rights :write, 'Sally', applies_to_children: :containers_only, applies_to_self: false, one_level_deep: true
Some other important things to know when using the rights
attribute:
- Only inherited rights remain. All existing explicit rights on the object are removed and replaced.
- If rights are not specified, nothing will be changed. Chef Infra Client does not clear out the rights on a file or directory if rights are not specified.
- Changing inherited rights can be expensive. Windows will propagate rights to all children recursively due to inheritance. This is a normal aspect of Windows, so consider the frequency with which this type of action is necessary and take steps to control this type of action if performance is the primary consideration.
Use the deny_rights
property to deny specific rights to specific
users. The ordering is independent of using the rights
property. For
example, it doesn’t matter if rights are granted to everyone is placed
before or after deny_rights :read, ['Julian', 'Lewis']
, both Julian
and Lewis will be unable to read the document. For example:
resource 'x.txt' do
rights :read, 'Everyone'
rights :write, 'domain\group'
rights :full_control, 'group_name_or_user_name'
rights :full_control, 'user_name', applies_to_children: true
deny_rights :read, %w(Julian Lewis)
end
or:
deny_rights :full_control, ['Sally']
Inheritance
By default, a file or directory inherits rights from its parent
directory. Most of the time this is the preferred behavior, but
sometimes it may be necessary to take steps to more specifically control
rights. The inherits
property can be used to specifically tell Chef
Infra Client to apply (or not apply) inherited rights from its parent
directory.
For example, the following example specifies the rights for a directory:
directory 'C:\mordor' do
rights :read, 'MORDOR\Minions'
rights :full_control, 'MORDOR\Sauron'
end
and then the following example specifies how to use inheritance to deny access to the child directory:
directory 'C:\mordor\mount_doom' do
rights :full_control, 'MORDOR\Sauron'
inherits false # Sauron is the only person who should have any sort of access
end
If the deny_rights
permission were to be used instead, something could
slip through unless all users and groups were denied.
Another example also shows how to specify rights for a directory:
directory 'C:\mordor' do
rights :read, 'MORDOR\Minions'
rights :full_control, 'MORDOR\Sauron'
rights :write, 'SHIRE\Frodo' # Who put that there I didn't put that there
end
but then not use the inherits
property to deny those rights on a child
directory:
directory 'C:\mordor\mount_doom' do
deny_rights :read, 'MORDOR\Minions' # Oops, not specific enough
end
Because the inherits
property is not specified, Chef Infra Client will
default it to true
, which will ensure that security settings for
existing files remain unchanged.