space, → | next slide |
← | previous slide |
d | debug mode |
## <ret> | go to slide # |
c | table of contents (vi) |
f | toggle footer |
r | reload slides |
z | toggle help (this) |
sudo apt-get -y install ruby rubygems
sudo gem install --no-rdoc --no-ri puppet
pip freeze
package { "python":
ensure => installed,
provider => apt,
}
package { "python":
ensure => "2.6.6-2ubuntu1",
provider => apt,
}
package { "python":
ensure => latest,
provider => apt,
}
package {
"build-essential":
ensure => installed,
provider => apt;
"python":
ensure => installed,
provider => apt;
"python-dev":
ensure => installed,
provider => apt;
"python-setuptools":
ensure => installed,
provider => apt;
}
package {
"build-essential": ensure => installed;
"python": ensure => installed;
"python-dev": ensure => installed;
"python-setuptools": ensure => installed;
}
group { "rcrowley":
ensure => present,
gid => 1000,
}
user { "rcrowley":
ensure => present,
gid => 1000,
uid => 1000,
}
ssh_authorized_key { "Richard's VM":
ensure => present,
key => "AAAAB3NzaC1yc2EAAAABIwAAAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzIw+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoPkcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NOTd0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcWyLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQ",
type => "ssh-rsa",
user => "rcrowley",
}
service { "apache2":
enable => true,
ensure => running,
hasstatus => true,
}
exec
and file
exec { "easy_install pip":
path => "/usr/local/bin:/usr/bin:/bin",
unless => "which pip",
}
file {
"/root/.pip":
ensure => directory,
group => "root",
mode => 0755,
owner => "root";
"/root/.pip/pip.conf":
content => template("python/pip.conf.erb"),
ensure => file,
group => "root",
mode => 0644,
owner => "root";
}
template
functiontemplate("python/pip.conf.erb")
pip.conf.erb
template[install]
user-mirrors = true
mirrors =
http://pypi.<%= domainname %>
http://pypi.python.org
facter | less
facter factname
sudo puppet apply pathname
--noop
and --verbose
are handy.class python {
package {
"build-essential": ensure => installed;
"python": ensure => installed;
"python-dev": ensure => installed;
"python-setuptools": ensure => installed;
}
exec { "easy_install pip":
path => "/usr/local/bin:/usr/bin:/bin",
unless => "which pip",
}
}
include python
include
is a shorthand function.class { "python": }
class foo($bar = "baz") {}
class { "foo": bar => "quux" }
define pip($ensure = installed) {
case $ensure {
installed: {
exec { "pip install $name":
path => "/usr/local/bin:/usr/bin:/bin",
}
}
latest: {
exec { "pip install --upgrade $name":
path => "/usr/local/bin:/usr/bin:/bin",
}
}
default: {
exec { "pip install $name==$ensure":
path => "/usr/local/bin:/usr/bin:/bin",
}
}
}
}
pip { "mysql-python": ensure => installed }
gem install puppet-pip
puppet-pip
package { "mysql-python":
ensure => installed,
provider => pip,
}
/etc/puppet/
manifests/
nodes.pp
site.pp
modules/
python/
manifests/
init.pp
foo.pp
modules/python/ manifests/init.pp
class python {
# ...
}
modules/python/ manifests/foo.pp
class python::foo {
# ...
}
include python
will expect the python
class in modules/python/manifests/init.pp
.template("python/foo.erb")
will render modules/python/templates/foo.erb
.sudo puppet apply -e "include classname"
--noop
and --verbose
are still handy.node default {
include python
}
node /^www\d+\./ inherits default {
include apache
include django
}
node "mail.example.com" inherits default {
include lamson
}
manifests/nodes.pp
.manifests/site.pp
Exec {
path => "/usr/local/bin:/usr/bin:/bin",
}
import "nodes"
sudo puppet apply /etc/puppet/manifests/site.pp
--noop
and --verbose
are still handy.class django {
package {
"django":
ensure => "1.2.5",
provider => pip;
"mysql-python":
ensure => installed,
provider => pip;
}
}
class django {
package {
"django":
ensure => "1.2.5",
provider => pip;
"mysql-python":
ensure => installed,
provider => pip;
}
}
class django {
package {
"django":
ensure => "1.2.5",
provider => pip;
"libmysqlclient-dev":
ensure => installed;
"mysql-python":
ensure => installed,
provider => pip;
}
}
class django {
package {
"django":
ensure => "1.2.5",
provider => pip;
"libmysqlclient-dev":
ensure => installed;
"mysql-python":
ensure => installed,
provider => pip;
}
}
class django {
package {
"django":
ensure => "1.2.5",
provider => pip;
"libmysqlclient-dev":
ensure => installed;
"mysql-python":
ensure => installed,
provider => pip,
require => Package["libmysqlclient-dev"];
}
}
class python {
package {
"build-essential": ensure => installed;
"python": ensure => installed;
"python-dev": ensure => installed;
"python-setuptools": ensure => installed;
}
exec { "easy_install pip":
path => "/usr/local/bin:/usr/bin:/bin",
require => Package["python-setuptools"],
unless => "which pip",
}
}
class python {
package {
"build-essential": ensure => installed;
"python": ensure => installed;
"python-dev": ensure => installed;
"python-setuptools": ensure => installed;
}
exec { "easy_install pip":
alias => "pip",
path => "/usr/local/bin:/usr/bin:/bin",
require => Package["python-setuptools"],
unless => "which pip",
}
Class["python"] -> Package<| provider == pip |>
}
pip
packages require pip
to be setup.before
and require
require
another.before
another.class django {
package {
"django":
ensure => "1.2.5",
provider => pip;
"libmysqlclient-dev":
before => Package["mysql-python"],
ensure => installed;
"mysql-python":
ensure => installed,
provider => pip;
}
}
libmysqlclient-dev
.class apache {
package {
"apache2-mpm-worker": ensure => installed;
"libapache2-mod-wsgi": ensure => installed;
}
file {
"/etc/apache2/sites-available/mysite":
content => template("apache/mysite.erb"),
ensure => file,
require => Package["apache2-mpm-worker"];
"/etc/apache2/sites-enabled/001-mysite":
ensure =>
"/etc/apache2/sites-available/mysite",
require => Package["apache2-mpm-worker"];
}
# Next slide goes here.
}
service { "apache2":
enable => true,
ensure => running,
hasstatus => true,
require => Package["apache2-mpm-worker"],
subscribe => [
Package[
"apache2-mpm-worker",
"libapache2-mod-wsgi"],
File[
"/etc/apache2/sites-available/mysite",
"/etc/apache2/sites-enabled/001-mysite"]],
}
notify
and subscribe
before
and require
.exec
resources run their command.service
resourcesmodules/apache/templates/mysite.erb
<VirtualHost *:80>
DocumentRoot /usr/local/share/wsgi/mysite/media
Alias /media /usr/local/share/wsgi/mysite/media
WSGIScriptAlias / /usr/local/share/wsgi/mysite/mysite.wsgi
WSGIDaemonProcess mysite processes=2
WSGIProcessGroup mysite
</VirtualHost>
modules/apache/templates/mysite.erb
with one process per core<VirtualHost *:80>
DocumentRoot /usr/local/share/wsgi/mysite/media
Alias /media /usr/local/share/wsgi/mysite/media
WSGIScriptAlias / /usr/local/share/wsgi/mysite/mysite.wsgi
WSGIDaemonProcess mysite processes=<%= processorcount %>
WSGIProcessGroup mysite
</VirtualHost>
from fabric.api import *
from fabric.contrib.project import rsync_project
env.hosts = ['example.com']
def deploy():
rsync_project(remote_dir='/etc/puppet')
sudo('RUBYLIB=/var/lib/gems/1.8/gems/puppet-pip-0.0.5/lib'
'puppet apply /etc/puppet/manifests/site.pp')
sudo puppet master
/etc/puppet/puppet.conf
[main]
server = puppet.example.com
sudo puppet agent --no-daemonize --onetime
sudo puppet cert -l
sudo puppet cert -s hostname
sudo puppet agent --no-daemonize --onetime
--noop
and --verbose
are still handy.[main]
server = puppet.example.com
dbadapter = mysql
dbname = puppet
dbpassword = puppet
dbserver = localhost
dbuser = puppet
[master]
thin_storeconfigs = true
node /^www\d+\./ inherits default {
include apache
include django
@@nagios_host { "$hostname":
address => "$ipaddress",
hostgroups => ["www"],
use => "generic-host",
# ...
}
}
node "ops.example.com" inherits default {
include nagios
Nagios_host<<||>>
}
blueprint
(1) reverse engineers servers to generate Puppet code.