fosdem chef-101-app-deploy
TRANSCRIPT
Copyright © 2010 Opscode, Inc - All Rights Reserved
Speaker:
‣ [email protected]‣ @jtimberman‣ www.opscode.com
Joshua Timberman Sr. Technical Evangelist
1
Deploying Apps with Chef
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Speaker:
2
Chef 101
‣ [email protected]‣ @jtimberman‣ www.opscode.com
Joshua Timberman Sr. Technical Evangelist
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 3Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 4Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 5
(They make computers?)
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 6
(Security training/certification)
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 7Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 8Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 9Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 10Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 11Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 12Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 13Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 14Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 15Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 16Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 17Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
http://www.flickr.com/photos/timyates/2854357446/sizes/l/
18
Developers?System administrators?“Business” people?
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 19Sunday, February 6, 2011
At a High Level...
‣ A library for configuration management
‣ A configuration management system
‣ A systems integration platform
‣ An API for your entire Infrastructure
http://www.flickr.com/photos/asten/2159525309/sizes/l/
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 21
Principles
IdempotentData-drivenSane defaultsHackabilityTMTOWTDI
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Multiple applications of an operation do not change the result
22Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
We start with APIs, you supply data
23Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
option :json_attribs, :short => "-j JSON_ATTRIBS", :long => "--json-attributes JSON_ATTRIBS", :description => "Load attributes from a JSON file or URL", :proc => nil
option :node_name, :short => "-N NODE_NAME", :long => "--node-name NODE_NAME", :description => "The node name for this client", :proc => nilDefaults are sane, but
easily changed24
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Open source and community
25Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 26Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
TIMTOWTDI is a Perl motto
27http://www.flickr.com/photos/lidarose/225156612
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
A Tour of Chef
28Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Chef Client runs on your systems
29Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Clients talk to a Chef Server
30Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Clients authenticate with RSA keys
31http://www.flickr.com/photos/debbcollins/3401944550/
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
The Opscode Platform is a Chef Server
32Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Command-line API utility, Knife
33http://www.flickr.com/photos/myklroventine/3474391066/
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved http://www.flickr.com/photos/peterrosbjerg/3913766224/ 34
We call each system you configure a Node
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Nodes have Attributes
35
{ "kernel": { "machine": "x86_64", "name": "Darwin", "os": "Darwin", "version": "Darwin Kernel Version 10.4.0: Fri Apr 23 18:28:53 PDT 2010; root:xnu-1504.7.4~1/RELEASE_I386", "release": "10.4.0" }, "platform_version": "10.6.4", "platform": "mac_os_x", "platform_build": "10F569", "domain": "local", "os": "darwin", "current_user": "jtimberman", "ohai_time": 1278602661.60043, "os_version": "10.4.0", "uptime": "18 days 17 hours 49 minutes 18 seconds", "ipaddress": "10.13.37.116", "hostname": "cider", "fqdn": "cider.local", "uptime_seconds": 1619358 }
Kernel info!
Platform info!
Hostname and IP!
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Attributes are Searchable
36
$ knife search node ‘platform:mac_os_x’
search(:node, ‘platform:mac_os_x’)
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Nodes have a Run List
37
What Roles or Recipes to applyin Order
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Nodes have a Run List
38
{ "run_list": [ "role[production]", "role[webserver]" ]}
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 39
Nodes have Roles
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Roles have a Run List
40
What Roles or Recipes to applyin Order
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 41
name "webserver"description "Systems that serve HTTP traffic"
run_list( "recipe[apache2]", "recipe[apache2::mod_ssl]")
default_attributes( "apache" => { "listen_ports" => [ "80", "443" ] })
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Roles are Searchable
42
$ knife search role ‘listen_ports:80’
search(:role, ‘listen_ports:80’)
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Chef manages Resources on Nodes
43Sunday, February 6, 2011
Resources...
‣ Have a type
‣ Have a name
‣ Have parameters
‣ Take action to put the resource in the declared state
package "apache2" do version "2.2.11-2ubuntu2.6" action :installend
template "/etc/apache2/apache2.conf" do source "apache2.conf.erb" owner "root" group "root" mode 0644 action :createend
Declare a description of the state a part of the node should be in
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Resources take action through Providers
45Sunday, February 6, 2011
Providers...
Multiple providers per resource type.
Know how to actually perform the actions specified by a resource.
Apt, Yum, Rubygems, Portage, Macports, FreeBSD Ports, etc.
Sunday, February 6, 2011
Resources
Platform
Provider
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 48
:ubuntu => { :default => { :package => Chef::Provider::Package::Apt, :service => Chef::Provider::Service::Debian, :cron => Chef::Provider::Cron, :mdadm => Chef::Provider::Mdadm }},
Chef::Platform
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 49
Recipes are lists of Resources
Sunday, February 6, 2011
Recipes...Apply resources in the order they are specified
package "apache2" do version "2.2.11-2ubuntu2.6" action :installend
template "/etc/apache2/apache2.conf" do source "apache2.conf.erb" owner "root" group "root" mode 0644 action :createend
1
2
‣ Evaluates resources in the order they appear
‣ Adds each resource to the Resource Collection
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Recipes are just Ruby!
51
extra_packages = case node[:platform] when "ubuntu","debian" %w{ ruby1.8 ruby1.8-dev rdoc1.8 ri1.8 libopenssl-ruby } end
extra_packages.each do |pkg| package pkg do action :install endend
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Cookbooks are packages for Recipes
52Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 53
Cookbooks are shareable!
cookbooks.opscode.com
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Data bags store arbitrary data
54Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
% knife data bag show users jtimberman{ "comment": "Joshua Timberman", "groups": "sysadmin", "ssh_keys": "ssh-rsa SUPERSEKRATS jtimberman@cider", "files": { ".zshrc": { "mode": "0644", "source": "dot-zshrc" }, ".vimrc": { "mode": "0644", "source": "dot-vimrc" } }, "id": "jtimberman", "uid": 7004, "shell": "/usr/bin/zsh", "openid": "http://jtimberman.myopenid.com/"}
A user data bag item...
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Data Bags are Searchable
56
$ knife search users ‘shell:/bin/bash’
search(:users, ‘/bin/bash’)
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Data bags make recipes awesome-r (that’s
totally a word)
57
bash_users = search(:users, 'shell:/bin/bash')
bash_users.each do |u| user u['id'] do uid u['id'] shell "/usr/bin/zsh" comment u['comment'] supports :manage_home => true home "/home/#{u['id']}" end
directory "/home/#{u['id']}/.ssh" do owner u['id'] group u['id'] mode 0700 end
template "/home/#{u['id']}/.ssh/authorized_keys" do source "authorized_keys.erb" owner u['id'] group u['id'] mode 0600 variables :ssh_keys => u['ssh_keys'] endend
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 58
I can has applications?
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 59Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 60Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 61Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 62Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 63Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 64
Application Deployment
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Application Deployment
65
tar -x -C /app -f app.tarrsync ~/dev/app www:/appcap deploy
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Server Configuration
66Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Server Configuration
Web ServersLoad BalancersDatabase Servers
67Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Server Configuration
68
% vi /etc/mysql/my.cnf#!/bin/bashCapfile
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 69
def install_package(pkg) if pkg.kind_of?(Array) run("apt-get -y install #{pkg.join(' ')}") else run("apt-get -y install #{pkg}") end end
packages = [ "build-essential", "ruby", "ruby1.8-dev", "libopenssl-ruby", "rake", "irb", "zlib1g-dev", "libssl-dev", "git-core" ] logger.info("Installing baseline packages: #{packages.join(' ')}") install_package(packages)
Capistrano anyone?
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Application Deployment
70
Application Repository‣ Source‣ CI / Build
Chef Repositorycider:~/dev/rails-quick-start (ruby-1.9.2-p0)master ✔ % ls -ltotal 16-rw-r--r-- 1 jtimberman staff 3521 Nov 5 13:09 README.md-rw-r--r-- 1 jtimberman staff 2171 Nov 5 13:09 Rakefiledrwxr-xr-x 3 jtimberman staff 102 Nov 5 13:09 certificates/drwxr-xr-x 3 jtimberman staff 102 Nov 5 13:09 config/drwxr-xr-x 26 jtimberman staff 884 Nov 12 08:16 cookbooks/drwxr-xr-x 4 jtimberman staff 136 Nov 5 13:25 data_bags/drwxr-xr-x 9 jtimberman staff 306 Nov 12 08:16 roles/
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Chef Repository
RolesCookbooksApplication Information
‣ Data Bag!
71Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Application Information
Data BagJSONPredefined structure
72Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Walkthrough
73Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 74
knife ec2 server create 'role[production]' 'role[base]' \'role[radiant_database_master]' 'role[radiant]' \'role[radiant_run_migrations]' 'recipe[radiant::db_bootstrap]' \-S rails-quick-start -I ~/.ssh/rails-quick-start.pem -x ubuntu \-G default -i ami-a403f7cd -f m1.small
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 75
knife ec2 server create 'role[production]' 'role[base]' \ 'role[radiant_database_master]' \ -S rails-quick-start -I ~/.ssh/rails-quick-start.pem -x ubuntu \ -G default -i ami-a403f7cd -f m1.small
knife ec2 server create 'role[production]' 'role[base]' \ 'role[radiant]' 'role[radiant_run_migrations]' \ 'recipe[radiant::db_bootstrap]' \ -S rails-quick-start -I ~/.ssh/rails-quick-start.pem -x ubuntu \ -G default -i ami-a403f7cd -f m1.small
knife ec2 server create 'role[production]' 'role[base]' \ 'role[radiant]' \ -S rails-quick-start -I ~/.ssh/rails-quick-start.pem -x ubuntu \ -G default -i ami-a403f7cd -f m1.small
knife ec2 server create 'role[production]' 'role[base]' \ 'role[radiant_load_balancer]' \ -S rails-quick-start -I ~/.ssh/rails-quick-start.pem -x ubuntu \ -G default -i ami-a403f7cd -f m1.small
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 76
{ "id": "radiant", "server_roles": [ "radiant" ], "type": { "radiant": [ "rails", "unicorn" ] }, "database_master_role": [ "radiant_database_master" ], "repository": "git://github.com/radiant/radiant.git", "revision": { "production": "0.9.1" },
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved 77
base.rbproduction.rbradiant.rbradiant_database_master.rbradiant_load_balancer.rbradiant_run_migrations.rb
Server Roles
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Base Role
78
name "base"description "Base role applied to all nodes."run_list( "recipe[apt]", "recipe[git]", "recipe[build-essential]", "recipe[ruby]")
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Production Role
79
name "production"description "Nodes in the production environment."default_attributes( "app_environment" => "production")
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Radiant Role
80
name "radiant"description "radiant front end application server."run_list( "recipe[mysql::client]", "recipe[application]")
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Application Recipe
81
search(:apps) do |app| (app["server_roles"] & node.run_list.roles).each do |app_role| app["type"][app_role].each do |thing| node.run_state[:current_app] = app include_recipe "application::#{thing}" end endend
node.run_state.delete(:current_app)
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Application Rails Recipe
82
app['gems'].each do |gem,ver| gem_package gem do action :install version ver if ver && ver.length > 0 endend
deploy_revision app['id'] do revision app['revision'][node.app_environment] repository app['repository'] user app['owner'] group app['group'] deploy_to app['deploy_to'] environment 'RAILS_ENV' => node.app_environment action app['force'][node.app_environment] ? :force_deploy : :deploy
...
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Radiant Database Master Role
83
name "radiant_database_master"description "Database master for the radiant application."run_list( "recipe[database::master]")
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Database Master Recipe
84
search(:apps) do |app| (app['database_master_role'] & node.run_list.roles).each do |dbm_role| app['databases'].each do |env,db| if env =~ /#{node[:app_environment]}/ root_pw = node["mysql"]["server_root_password"] mysql_database "create #{db['database']}" do host "localhost" username "root" password root_pw database db['database'] action [:create_db] end end end endend
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Radiant Load Balancer Role
85
name "radiant_load_balancer"description "radiant load balancer"run_list( "recipe[haproxy::app_lb]")override_attributes( "haproxy" => { "app_server_role" => "radiant" })
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Haproxy App Load Balancer Recipe
86
pool_members = search("node", "role:#{node['haproxy']['app_server_role']} AND app_environment:#{node['app_environment']}") || []
template "/etc/haproxy/haproxy.cfg" do source "haproxy-app_lb.cfg.erb" owner "root" group "root" mode 0644 variables :pool_members => pool_members notifies :restart, resources(:service => "haproxy")end
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Control Deployment
knife data bag edit apps radiant
87
"force": { "production": false },
"force": { "production": true },
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Control Migrations
data bag item has migrate setting
need an attribute set as well
88
"migrate": { "production": true }
name "radiant_run_migrations"description "Run db:migrate on demand for radiant"override_attributes( "apps" => { "radiant" => { "production" => { "run_migrations" => true } } })
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Add the role and migrations will be run
knife node run list add NODE ‘role[radiant_run_migrations]’
Migrations will run, and the role is removed by Chef automatically.
89
ruby_block "remove_run_migrations" do block do if node.role?("#{app['id']}_run_migrations") Chef::Log.info("Migrations were run, removing role[#{app['id']}_run_migrations]") node.run_list.remove("role[#{app['id']}_run_migrations]") end end end
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Your Application
Your application is different than Radiant.
But not a unique snowflake, right?
Mostly, you will just need to modify the data and create application specific roles...
But wait, I’m using Rails 3!
90Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Use the Gems data
Use bundler or bundler08 in the gems hash of the application data
91
"gems": { "bundler": "1.0.9" },
"gems": { "bundler08": "0.8.5" },
before_migrate do if app['gems'].has_key?('bundler') execute "bundle install" do ignore_failure true cwd release_path end elsif app['gems'].has_key?('bundler08') execute "gem bundle" do ignore_failure true cwd release_path end
Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
How does it scale?
92Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Quick FAQ
93Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Testing
94Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Reporting
95Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
vs [Other tool]
96Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
These slides will be posted
97Sunday, February 6, 2011
Copyright © 2010 Opscode, Inc - All Rights Reserved
Resources/Questions
98
www.opscode.com/chefIRC and Mailing lists‣ irc.freenode.net #chef‣ lists.opscode.com
Twitter:‣ @opscode, #opschef‣ @jtimberman
Questions?
Sunday, February 6, 2011