Configuration Management in the Cloud
Puppet and Chef
Let’s talk• What is Configuration Management• diff cloud.txt physical.txt > painful.out• Why is it painful?• Infrastructure as Code• Puppet• Chef• Examples
What is Configuration Management
My own definition:“The art of keeping everything under control”
Wikipedia:“Configuration management (CM) is a
systems engineering process for establishing and maintaining consistency of a product’s performance, functional and physical attributes with its requirements, design and operational information throughout its life.”
diff cloud.txt physical.txt > painful.out
• Physical:o Resources stay there “forever”o Attributes / properties are static (ips / hostnames / macaddress)o Some cases is possible to recover the same system
• Cloud:o Resources are dynamic and in constant change
“Some times they just disappear, WTF is the cloud it should be always there”
o Attributes / properties change without noticeo Once a system is done, its done
Why is it painful?• Config management systems where design for
static/physical environments.• Most of them use certs/keys based on hostnames.• With things as “bursting into the cloud” the config
management server that supported 100 servers now it has to support 1K, 2K 15K servers.
• Most cloud environments cloud instances come and go.
• In physical environments you don’t need completely automation from 0 to app
• Most CMS’s don’t have rollbacks.
Infrastructure as Code in the Cloud
• Keep your CM code in repositories (git/svn)
• Replicate… replicate… replicate…
• The CM system wont do everything by itself
• Have your Dev, Test and Prod environments
• If something fails… destroy and rebuild
• Go Masterless whenever possible
Puppet• Pros
o Ruby basedo Easy to read and learno You can do pretty much anything
• Conso Custom changes require you to build specific prividers, resources and
the DSL is not as good as you would likeo Based on certs using hostnames to generate themo Master/Client communicationo Does not scale very well
Chef• Pros
o Ruby basedo You literally can code in ito You can apply order to the things he will executeo Provides an encrypted way to pass sensitive datao Provides more utilities (knife and search)
• Chefo Master server requires more componentso Syntax a little bit more complexo You need to learn ruby to get the good out of ito Master/Client communication
Puppet Arch• Semi Masterless• Architecture:
Chef Arch• Master/Client• Architecture
Puppet Module• Apache
o Files• Cert.key• Ca.key
o Templates• Vhost.erb
o Manifests• Init.pp• Redhat
o Install.ppo Config.ppo Postconfig.ppo Service.pp
Puppet Code – init.pp• Init.ppClass apache ( $servername = “myserver”, $port = 80, $serveradmin = “[email protected]”) { case @::operatingsystem { “redhat”, “centos”: { require apache::redhat::service } “ubuntu”: { require apache::ubuntu::service } default: { require apache::redhat::service } }}
Puppet Code – install.pp
Class apache::redhat::install (
) {
package { “httpd”:
ensure => “latest”; }
}
Puppet Code – config.pp
Class apache::redhat::config (
$servername = $apache::servername, $serveradmin = $apache::serveradmin, $serverport = $apache::serverport
) {
require apache::redhat::install
file { “/etc/httpd/conf.d/myvhost.conf”: owner => “apache”,
group => “apache”,content => template(‘apache/vhost.erb’);
}}
Puppet Code – service.pp
Class apache::redhat::service (
) {
require apache::redhat::config
service { “httpd”:
ensure => “running”; }
}
Puppet Masterless• Create bootstrap script that:• Download Repository into the Cloud instance• Create a manifest.pp with the contents of the node
definition• Call puppet apply -vd
--modulepath=/location/modules/ manifest.pp• Example manifest.pp
import “whatever”class { “apache”:
servername => “myserver.com”,serveradmin =>
“[email protected]”,port => 8080
}
Chef Code• Roles
o Webserver.json
• Cookbookso Attributes
• Default.rbo Files
• Cert.key• Ca.key
o Templates• Vhost.erb
o Librarieso Providerso Resourceso Recipes
• Default.rb• install.rb• Config.rb• Vhost.rb
Chef Roles{ "name": ”webserver", "default_attributes": { "service": ”httpd”, “port”: “80”, "packages": { "extras": [ ”httpd" ] } }, "chef_type": "role", "env_run_lists": { }, "run_list": [ "recipe[[email protected]]", "recipe[[email protected]]", "recipe[[email protected]]", "recipe[[email protected]]", "recipe[[email protected]]", "recipe[[email protected]]”, “recipe[[email protected]]” ], "override_attributes": { }, "description": ”webserver", "json_class": "Chef::Role"}
Chef Cookbook - Attributes
default['dns']['subdomains'] = ['production', 'test', 'development']default['dns']['basedomain'] = 'demiops.com.'default['dns']['route53']['register'] = truedefault['dns']['route53']['default_ttl'] = '300'default['resolver']['options'] = ['rotate', 'attempts:5']default['resolver']['nameservers'] = ['127.0.0.1']default[‘web’][‘port’] = ‘80’default[‘web’][‘servername’] = ‘myserver.com’default[‘web’][‘serveradmin’] = ‘[email protected]’
Chef Cookbook - Recipes
Default.rbinclude_recipe “apache::install"include_recipe ”apache::config"include_recipe “apache::vhost"include_recipe ”apache::authorized_keys”
Authorized_keys.rbcookbook_file "/root/.ssh/authorized_keys" do group "root" owner "root" mode 0600 source "authorized_keys"end
Chef in the Cloud• Create a bootstrap script that:• Download the chef repository into the cloud
instance• Use minitests to check everything worked• Install chef-client and knife in the instance• Use knife to search chef-client inventory and
update dynamically config files• Use ohai
Questions ?