Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up
for free
Automate your Infrastructure with Chef
Christian Joudrey
February 28, 2013
Programming
9
500
Automate your Infrastructure with Chef
Talk given at ConFoo 2013 on February 28th, 2013.
Christian Joudrey
February 28, 2013
Tweet
Share
More Decks by Christian Joudrey
See All by Christian Joudrey
cjoudrey
1
440
cjoudrey
3
410
cjoudrey
6
4.6k
cjoudrey
2
490
cjoudrey
3
490
cjoudrey
3
190
cjoudrey
4
320
Other Decks in Programming
See All in Programming
nbkouhou
1
1.1k
trajchevska
0
150
akatsukinewgrad
0
150
aratayokoyama
0
200
ippey
0
170
standfm
0
220
kyonmm
2
2.1k
ajstarks
2
550
cwozaki
1
1.7k
nbkouhou
0
790
blendthink
0
400
azdaroth
0
160
Featured
See All Featured
myddelton
109
11k
cassininazir
347
20k
tammielis
237
23k
philnash
8
490
imathis
478
150k
keavy
106
14k
bermonpainter
342
26k
smashingmag
229
18k
trishagee
20
2k
cromwellryan
101
5.9k
morganepeng
92
13k
jnunemaker
PRO
40
4.5k
Transcript
Automate your Infrastructure with Chef
cjoudrey @
None
c #
c # # # # # # # in minutes
# d # d c # # # # #
d in minutes
w Manual setup takes time
# ruby 1.9.3 # ruby 1.9.2 != and error-prone
# ruby 1.9.3 # ruby 1.9.2 != Oops! and error-prone
What is ?! Chef
1 Manage servers with ruby code
instead of $ ssh root@app1 Last login: Thu Feb 28
... # apt-get install nginx ... # vim /etc/nginx/nginx.conf ... # apt-get install ruby ...
client server
# node # node # node # chef server (server1
to server3.example.com) (chef.example.com) knife ! (local machine)
# node # node # node # chef server (server1
to server3.example.com) (chef.example.com) knife ! (local machine)
# node # node # node # chef server (server1
to server3.example.com) (chef.example.com) knife ! (local machine)
# node # node # node # chef server chef-client
(server1 to server3.example.com) knife ! (local machine)
2terminology Chef
2recipe Ruby file that contains Chef commands
2cookbook Collection of Chef recipes
Getting started with Chef 2
git clone opscode/chef-repo https://github.com/opscode/chef-repo !
! $ ls confoo ... cookbooks/ data_bags/ environments/ roles/
Install Chef on local machine !
! gem install chef
# Hosted* Chef server from Opscode * free up to
5 nodes
#
#
Setup Knife on local machine !
# node # node # node # chef server (server1
to server3.example.com) (chef.example.com) knife ! (local machine)
! $ ls confoo/.chef confoo-demo-validator.pem confoo-demo.pem knife.rb Copy files to
REPO/.chef
! $ cd confoo $ knife user list confoo-demo Test
Knife
8 Create your first cookbook $ cd confoo $ knife
cookbook create nginx
8 $ ls cookbooks/nginx ... attributes/ providers/ recipes/ resources/ templates/
package "nginx" cookbooks/nginx/recipes/default.rb
package installs using system’s package mgr
cookbooks/nginx/recipes/default.rb package "nginx" service "nginx"
service defines an available service
cookbooks/nginx/recipes/default.rb package "nginx" service "nginx" do supports :status => true,
:restart => true, :reload => true end
cookbooks/nginx/recipes/default.rb package "nginx" service "nginx" do supports :status => true,
:restart => true, :reload => true action [:enable, :start] end
:enable start on server boot
:start start when Chef runs
8 Upload cookbook $ knife cookbook upload nginx Uploading nginx
[0.1.0]
Let’s test it on a node #
! $ knife bootstrap \ server1.example.com Bootstrap a node
!
2run list Ordered list of recipes and roles that get
run on the node
! $ knife node edit \ server1.example.com Edit a node
{ "name": "server1.example.com", "run_list": [ ] }
{ "name": "server1.example.com", "run_list": [ "recipe[nginx::default]" ] }
recipe[nginx::default] means default recipe of nginx cookbook
$ ssh server1.example.com server1:~# chef-client Run Chef on the node
#
#
#
# Let’s configure nginx
copy from server to nginx cookbook templates/default/nginx.conf.erb /etc/nginx/nginx.conf !
cookbooks/nginx/recipes/default.rb package "nginx" service "nginx" do supports :status => true,
:restart => true, :reload => true action [:enable, :start] end template "/etc/nginx/nginx.conf" do source "nginx.conf.erb" notifies :reload, "service[nginx]" end
cookbooks/nginx/recipes/default.rb package "nginx" service "nginx" do supports :status => true,
:restart => true, :reload => true action [:enable, :start] end template "/etc/nginx/nginx.conf" do source "nginx.conf.erb" notifies :reload, "service[nginx]" end
cookbooks/nginx/recipes/default.rb package "nginx" service "nginx" do supports :status => true,
:restart => true, :reload => true action [:enable, :start] end template "/etc/nginx/nginx.conf" do source "nginx.conf.erb" notifies :reload, "service[nginx]" end
cookbooks/nginx/recipes/default.rb package "nginx" service "nginx" do supports :status => true,
:restart => true, :reload => true action [:enable, :start] end template "/etc/nginx/nginx.conf" do source "nginx.conf.erb" notifies :reload, "service[nginx]" end
! Upload the cookbook and run chef-client on node
#
2 Chef is idempotent
! What if we edit templates/default/nginx.conf.erb and run Chef
#
#
#
Let’s run Chef one more time #
#
2Attributes
nginx/templates/default/nginx.conf.erb user www-data; worker_processes 2; pid /var/run/nginx.pid; ...
nginx/attributes/nginx.rb default['nginx']['worker_processes'] = 2
nginx/templates/default/nginx.conf.erb user www-data; worker_processes <%= node['nginx'] ['worker_processes'] %>; pid /var/run/nginx.pid;
...
# Override for a specific node
{ "name": "server1.example.com", "run_list": [ "recipe[nginx::default]" ] }
{ "name": "server1.example.com", "normal": { "nginx": { "worker_processes": 4 },
}, "run_list": [ "recipe[nginx::default]" ] }
2Roles
roles/app-server.rb name 'app-server' description 'app-server stuff' run_list( 'recipe[nginx::default]' ) override_attributes(
'nginx' => { 'worker_processes' => 2 } )
! $ knife role from file \ app-server.rb Upload a
role
Apply the role on a node #
{ "name": "server1.example.com", "run_list": [ "role[app-server]" ] }
#
{ "name": "server1.example.com", "run_list": [ "role[base]", "role[app-server]" ] }
2 Environments
environments/production.rb name 'production' cookbook_versions 'nginx' => '= 0.1.0'
{ "name": "server1.example.com", "chef_environment": "production", "run_list": [ "recipe[nginx::default]" ] }
! Searching for nodes $ knife search node \ role:app-server
2
8 Searching can be done in recipes too!
8 Searching can be done in recipes too! OMFG!
backend app balance roundrobin server app1 10.10.0.1 check port 80
server app2 10.10.0.2 check port 80 server app3 10.10.0.3 check port 80
nodes = search( :node, 'role:app-server' ) template "/etc/haproxy.conf" do source
"haproxy.conf.erb" variables :nodes => nodes end
backend www balance roundrobin <% @nodes.each do |n| %> server
<%= n[:hostname] %> <%= n[:ipaddress] %> check port <% end %>
2Goodies
None
None
None
None
None
Automation is important
# staging/CI # production ! development = =
Thanks!
cjoudrey @