4. Search
➔
Search for nodes with Roles
➔
Find configuration data
➔
IP addresses
➔
Hostnames
➔
FQDNs
5. Pass Results to Templates
pool_members = search("node","role:webserver”)
template "/etc/haproxy/haproxy.cfg" do
source "haproxy-app_lb.cfg.erb"
owner "root"
group "root"
mode 0644
variables :pool_members => pool_members.uniq
notifies :restart, "service[haproxy]"
end
6. Pass Results to Templates
# Set up application listeners here.
listen application 0.0.0.0:80
balance roundrobin
<% @pool_members.each do |member| -%>
server <%= member[:hostname] %> <%=
member[:ipaddress] %>:> weight 1 maxconn 1
check
<% end -%>
<% if node["haproxy"]["enable_admin"] -%>
listen admin 0.0.0.0:22002
mode http
stats uri /
<% end -%>
7. Attributes
➔
OS attributes provided by ohai
➔
Other attributes are configured by the installed
cookbooks
Attributes are mutable
➔
attributes — variables
➔
recipes — list of instructions (“resources”)
➔
files — files used by resources
➔
templates — ERB templates
➔
definitions — macros of resources
➔
libraries — Ruby to extend Chef DSL
8. recipes/default.rb
template “/tmp/hello_world.txt” do
source “hello_world.txt.erb”
variables :my_name => node[:my_name]
mode 00664
action :create
end
Simple attribute
attributes/my_name.rb
my_name “Juan Vicente”
templates/default/hello_world.txt.erb
Hello, <%= @my_name %>, how are you
today?
Add the recipe to the node’s recipe list
• Invoke chef-client
• Default chef-client setup has client invoked
periodically
9. When chef-client runs
• Node authenticates with server
• Libraries, attributes, definitions & recipes
are synchronized
• Libraries, attributes, definitions & recipes
compiled
• Node state is converged
• Everything happens on the node
May be simply defined, e.g.
my_name “Juan Vicente”
• Allow overriding, e.g. unless attribute?
my_name “Juan Vicente”
(“my_name”)
• List values are regular array
10. Resources
• The steps that make up a recipe
package “git-core” do
action :install
end
• Resources are implemented via Providers
Package
package "tar" do
version "1.16.1-1"
action :install
end
• Action can be install, upgrade, remove,
purge
• Version is optional
11. Remote files
• Copying remote files is easy
remote_file “/tmp/foo.png” do
source “foo.png”
owner “root”
group “root”
mode 0444
action :create
end
• Where does the file live?
12. Files and templates are searched for in the
following order: FQDN, platform-version,
platform, default
• For Ubuntu 12.10:
myhost.example.com
ubuntu-9.04
ubuntu
Default
More remote file fun
• File source can be a URL
source “http://warez.com/thing.tgz”
• Provide SHA256 hash to prevent needless
downloading from chef-server each time
checksum “08da0021”
13. Useful things
Control existence and attributes of a file,not its contents
file “/tmp/whatever” do
owner “root”
group “root”
mode “0644”
action :create
end
• Other actions are touch, delete
directory
— analog of the File resource
remote_directory
— recursive remote
copy
14. Useful things
Control system services from /etc/init.d and friends
• We can en/disable, start, stop & restart
service “my_daemon” do
supports :restart => true
action [ :enable, :start ]
End
User
• Group
• Cron
• Route
• Mount
15. Useful things
Execute arbitrary command
command “mysql-stuff” do
execute “/usr/bin/mysql </tmp/foo.sql”
creates “/tmp/outfile.sql”
environment {‘FOO’ => “bar”}
action :run
end
16. Useful things
bash, perl, python, ruby, csh
bash “install_foo” do
user “root”
cwd “/tmp”
code <<-EOC
wget http://example.org/foo.tgz
tar xvf foo.tgz && cd foo
./configure && make install
EOC
end
17. Notifies
• Chain actions
template “/etc/my_daemon/my.cnf” do
source “my.cnf.erb”
notifies :restart,
resources(:service => “my_daemon”)
end
• By default, notification postponed until end of run, add :immediately as
final argument to override
Action :nothing
• If you want a resource to run only on a notify, specify action
:nothing
execute "index-gem-repository" do
command "gem generate_index -d /srv/
gems"
action :nothing
end
18. Notifies
Useful for connecting to existing services
http_request “say_hello” do
url “http://myserv.local/check_in”
message :node => node[:fqdn]
action :post
end
19. Overriding attributes
• In cookbook, easy enough to set a default
• Per-node customizations can be made in the UI
• To set new defaults, override selectively in site-cookbooks
Conditional resources
• Use only_if and not_if to control resource execution
• Takes either shell commands or Ruby
blocks, e.g.
only_if do
IO.read(“/tmp/foo”).chomp == ‘bar’
end
20. Chef attributes can be overridden at multiple levels of organization, and
we can normalize our configuration items (e.g. node attributes in Chef)
into cookbook, environment, role or node defaults and overrides. Here
is the actual node attribute precedence from low to high:
cookbook default < environment default < role default < node default <
cookbook set < node set < cookbook override < role override <
environment override < node override
By using this precedence rule, we can configure node attributes across
our entire Chef environment with a single configuration change, or
override one specific node’s attribute without making changes to the
rest of the environment.
21. Data Bag
A data bag stores arbitrary information about the infrastructure in a
nested hash structure. Just like any other Chef objects, it can be
accessed via RESTful API. A data bag does not belong to a specific
Chef environment, so it should be used to store truly global
configuration items. You can also encrypt a data bag to store
sensitive information that you need to keep out of your source code
repository.
For example root path for jboss, mysql, tomcat, applications... to
have the same path in all of the nodes
24. Using environments within recipes
To have different behaviour depending on the environment, use
the "chef_environment" method of the node object. This is a
Ruby method, not a Chef attribute. For example:
file "/opt/data/testfile1.txt" do
mode "0644"
content "A sample file."
only_if { node.chef_environment == "dev"}end
25. Author
●
Juan Vicente Herrera Ruiz de Alejo
●
Juan.herrera@lumatagroup.com
●
http://juanvicenteherrera.eu
●
@jvicenteherrera
●
Skype: jvherrera.quimerus.es