cooking perl with chef
DESCRIPTION
Reliable and scalable applications need repeatable, automated application deployment. Configuration management tools like Chef, Puppet and others make it easy to deploy an entire application stack, but support for Perl applications has lagged behind other popular, dynamic languages. The Perl community has responded to these challenges with tools like perlbrew, local::lib, carton and others to make it easier to manage an application and its dependencies in isolation. This presentation will show you how to make those tools work with Chef for complete automation of Perl application deployment.TRANSCRIPT
![Page 2: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/2.jpg)
ConfigurationManagement
(e.g. chef, puppet, cfengine, ...)
![Page 3: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/3.jpg)
Unknown state
↓Target state
![Page 4: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/4.jpg)
New machine
↓Deployed app
![Page 5: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/5.jpg)
Infrastructure as code
automated!repeatable!
testable!
(no manual steps, checklist, etc.)
![Page 6: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/6.jpg)
One tool to deploythe whole stack
(DB, caching, messaging, ...)
![Page 7: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/7.jpg)
But wait!Isn't that hard to do for Perl apps?
![Page 8: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/8.jpg)
Perl applications are complex
![Page 9: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/9.jpg)
Dependency hell
![Page 10: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/10.jpg)
App = perl + CPAN + your code
![Page 11: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/11.jpg)
App = perl + CPAN + your code
CHIDateTimeDBIJSONMoosePlackPOETry::Tiny...
![Page 12: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/12.jpg)
App = perl + CPAN + your code
CHIDateTimeDBIJSONMoosePlackPOETry::Tiny...
your application is the versioned set of all its compontents
![Page 13: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/13.jpg)
App = perl + CPAN + your code
CHIDateTimeDBIJSONMoosePlackPOETry::Tiny...
v1.0.0
your application is the versioned set of all its compontents
![Page 14: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/14.jpg)
App = Perl + CPAN + your code
CHIDateTimeDBIJSONMoosePlackPOETry::Tiny...
v1.0.0 v5.14.2
your application is the versioned set of all its compontents
![Page 15: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/15.jpg)
App = Perl + CPAN + your code
0.550.761.6222.532.06030.99891.3540.11...
v1.0.0 v5.14.2
your application is the versioned set of all its compontents
![Page 16: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/16.jpg)
App = Perl + CPAN + your code
0.550.761.6222.532.06030.99891.3540.11...
v1.0.0 v5.14.2 v1.0
your application is the versioned set of all its compontents
![Page 17: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/17.jpg)
App = Perl + CPAN + your code
0.550.761.6222.532.06030.99891.3540.11...
v1.0.0 v5.14.2 v1.0
change one piece...
![Page 18: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/18.jpg)
App = Perl + CPAN + your code
0.550.761.6222.532.06030.99891.3540.11...
v1.0.0 v5.16.0 v1.0
change one piece...
![Page 19: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/19.jpg)
App = Perl + CPAN + your code
0.550.761.6222.532.06030.99891.3540.11...
v1.0.1 v5.16.0 v1.0
… and you have a new version of your application
![Page 20: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/20.jpg)
Repeatable deployment means...
![Page 21: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/21.jpg)
Repeatable deployment means...
... the same Perl
![Page 22: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/22.jpg)
Repeatable deployment means...
... the same Perl
... the same modules
![Page 23: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/23.jpg)
Repeatable deployment means...
... the same Perl
... the same modules
... the same code
![Page 24: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/24.jpg)
Repeatable deployment means...
... the same Perl
... the same modules
... the same code
... on demand
![Page 25: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/25.jpg)
Easy...
![Page 26: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/26.jpg)
If we have the right tools
![Page 27: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/27.jpg)
Use one-size fits all distribution packagers like apt, yum, etc...?
(How much do you like your system perl?!)
![Page 28: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/28.jpg)
This problem is notunique to Perl
![Page 29: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/29.jpg)
Let's be inspired by Larry
![Page 30: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/30.jpg)
[larry hat pic]
![Page 31: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/31.jpg)
Or better yet, Paul
![Page 32: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/32.jpg)
![Page 33: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/33.jpg)
YARRR!
![Page 34: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/34.jpg)
Great hackers steal!
![Page 35: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/35.jpg)
Great hackers steal ideas
![Page 36: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/36.jpg)
Consider Chef...
![Page 37: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/37.jpg)
(written in ruby; various ruby app stacks)
Chef ❤ Ruby
![Page 38: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/38.jpg)
(virtualenv; pip; django apps)
Chef ❤ Python
![Page 39: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/39.jpg)
Common patterns emerge
![Page 40: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/40.jpg)
python → virtualenv + pipruby → rvm + Bundler
![Page 41: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/41.jpg)
We've built tools like these, too
![Page 42: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/42.jpg)
Kang-min Liu (gugod)
Matt S Trout (mst)
Tatsuhiko Miyagawa
(and a big community helping them)
![Page 43: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/43.jpg)
perlbrew – multiple perl manager
Matt S Trout (mst)
Tatsuhiko Miyagawa
(and a big community helping them)
![Page 44: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/44.jpg)
perlbrew – multiple perl manager
local::lib – custom @INC manager
Tatsuhiko Miyagawa
(and a big community helping them)
![Page 45: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/45.jpg)
perlbrew – multiple perl manager
local::lib – custom @INC manager
carton – versioned dependency installer
(and a big community helping them)
![Page 46: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/46.jpg)
So we have the pieces
![Page 47: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/47.jpg)
Repeatable deployment in five parts
![Page 48: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/48.jpg)
Repeatable deployment in five parts
application-specific Perl
application-specific @INC path
versioned application code
versioned module dependencies
automate the previous four
![Page 49: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/49.jpg)
Repeatable deployment in five parts
perlbrew
application-specific @INC path
versioned application code
versioned module dependencies
automate the previous four
![Page 50: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/50.jpg)
Repeatable deployment in five parts
perlbrew
local::lib
versioned application code
versioned module dependencies
automate the previous four
![Page 51: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/51.jpg)
Repeatable deployment in five parts
perlbrew
local::lib
git
versioned module dependencies
automate the previous four
![Page 52: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/52.jpg)
Repeatable deployment in five parts
perlbrew
local::lib
git
carton
automate the previous four
![Page 53: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/53.jpg)
Repeatable deployment in five parts
perlbrew
local::lib
git
carton
@&$%!
![Page 54: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/54.jpg)
[swedish chef FAIL pic]
![Page 55: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/55.jpg)
No support in Chef...
![Page 56: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/56.jpg)
So I implemented it
![Page 57: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/57.jpg)
(In Ruby)
![Page 58: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/58.jpg)
(After I learned some Ruby)
![Page 59: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/59.jpg)
(perlbrew; local::lib; carton)
Chef ❤ Perl
Now...
![Page 61: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/61.jpg)
“Cookbook”
A collection of components to configurea particular application
Typically includes recipes, providers, templates, etc.
(CPAN analogy → “distribution”)
![Page 62: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/62.jpg)
“Recipe”
Component applied that deploys an application or service
Typically declarative, specifying desired resources and associated configuration
![Page 63: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/63.jpg)
“Resource”
An abstraction of something to be deployed
![Page 64: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/64.jpg)
“Provider”
Platform-specific implementation to deliver a resource
![Page 65: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/65.jpg)
“Node”
A host computer managed with Chef
Often means the configuration file that defines recipes, attributes and roles that define the target state of a host
![Page 66: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/66.jpg)
“Attribute”
A variable used in a recipe and/or provider that customizes the configuration of a resource
Attributes have defaults, but can be customized for nodes or roles
![Page 67: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/67.jpg)
“Role”
A collection of recipes and attributes used to apply common configuration across multiple nodes
![Page 68: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/68.jpg)
Summary...
cookbooks include recipes and providers
roles, recipes and attributes get applied to nodes
recipes specify desired resources and customize them with attributes
providers do the work of deploying resources
![Page 69: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/69.jpg)
I wrote two Perl Chef cookbooksfor the Chef community repository
(which is like CPAN circa 1996 or so)
http://community.opscode.com/
![Page 70: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/70.jpg)
1. perlbrew – for managing perls
2. carton – for deploying apps
Also available here: https://github.com/dagolden/perl-chef
![Page 71: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/71.jpg)
perlbrew cookbook resources:
perlbrew_perl – install a perl
perlbrew_lib – create a local::lib
perlbrew_cpanm – install modules to perl or lib
perlbrew_run – run shell commands under aparticular perlbrew and/or lib
![Page 72: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/72.jpg)
carton cookbook resource:
carton_app – deploy an app with carton
– start in directory with the app source– configure for a specific perlbrew perl– install versioned dependencies with carton– create a runit service for the app– start the app
![Page 73: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/73.jpg)
Time for an example:
Deploying a “Hello World” Plack app
https://github.com/dagolden/zzz-hello-world
![Page 74: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/74.jpg)
1. Write the application
2. Use carton to create a carton.lock file with versioned dependency info
3. Write a simple cookbook for the application
4. Check it all into git
5. Deploy the application with Chef
Steps for creating Hello World
![Page 75: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/75.jpg)
$ tree.├── Changes├── Makefile.PL├── app.psgi├── carton.lock├── cookbook│ └── hello-world│ ├── README.md│ ├── attributes│ │ └── default.rb│ ├── metadata.rb│ └── recipes│ └── default.rb└── lib └── ZZZ └── Hello └── World.pm
![Page 76: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/76.jpg)
$ tree.├── Changes├── Makefile.PL├── app.psgi├── carton.lock├── cookbook│ └── hello-world│ ├── README.md│ ├── attributes│ │ └── default.rb│ ├── metadata.rb│ └── recipes│ └── default.rb└── lib └── ZZZ └── Hello └── World.pm
![Page 77: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/77.jpg)
use strict;use warnings;use ZZZ::Hello::World;my $app = sub { ZZZ::Hello::World->run_psgi(@_) };
(this Plack app just invokes a simple module)
![Page 78: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/78.jpg)
$ tree.├── Changes├── Makefile.PL├── app.psgi├── carton.lock├── cookbook│ └── hello-world│ ├── README.md│ ├── attributes│ │ └── default.rb│ ├── metadata.rb│ └── recipes│ └── default.rb└── lib └── ZZZ └── Hello └── World.pm
![Page 79: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/79.jpg)
use 5.008001;use strict;use warnings;
package ZZZ::Hello::World;our $VERSION = "1.0";
use Plack::Request;
sub run_psgi { my $self = shift; my $req = Plack::Request->new(shift); my $res = $req->new_response(200); $res->content_type('text/html'); $res->body(<<"HERE");<html><head><title>Hello World</title></head><body><p>Hello World. It is @{[scalar localtime]}</p>...</body></html>HERE return $res->finalize;}
1;(the module just returns some dynamic HTML)
![Page 80: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/80.jpg)
$ tree.├── Changes├── Makefile.PL├── app.psgi├── carton.lock├── cookbook│ └── hello-world│ ├── README.md│ ├── attributes│ │ └── default.rb│ ├── metadata.rb│ └── recipes│ └── default.rb└── lib └── ZZZ └── Hello └── World.pm
![Page 81: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/81.jpg)
use inc::Module::Install;name 'ZZZ-Hello-World';version '1.0'; requires 'Plack';requires 'Starman'; WriteAll;
(the Makefile.PL also includes deployment dependencies like Starman)
![Page 82: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/82.jpg)
During development, carton installs dependencies locally and creates a versioned dependency file called carton.lock
$ carton install# installs dependencies into a local directory# creates carton.lock if it doesn't exist# carton.lock is a JSON file of dependency info
![Page 83: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/83.jpg)
During deployment, carton installs dependencies from carton.lock and runs the app with them
$ carton install# installs dependencies into a local directory
$ carton exec Ilib starman p 8080 app.psgi# runs the app using carton installed deps
![Page 84: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/84.jpg)
$ tree.├── Changes├── Makefile.PL├── app.psgi├── carton.lock├── cookbook│ └── hello-world│ ├── README.md│ ├── attributes│ │ └── default.rb│ ├── metadata.rb│ └── recipes│ └── default.rb└── lib └── ZZZ └── Hello └── World.pm
![Page 85: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/85.jpg)
# carton.lock JSON{ "modules" : { "Class::Inspector" : { "dist" : "Class-Inspector-1.27", "module" : "Class::Inspector", "pathname" : "A/AD/ADAMK/Class-Inspector-1.27.tar.gz", ... }. "Data::Dump" : { ... }, "Devel::StackTrace" : { ... }, "Encode::Locale" : { ... }, ...}
(carton.lock associates module names to specific versions of those module)
![Page 86: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/86.jpg)
$ tree.├── Changes├── Makefile.PL├── app.psgi├── carton.lock├── cookbook│ └── hello-world│ ├── README.md│ ├── attributes│ │ └── default.rb│ ├── metadata.rb│ └── recipes│ └── default.rb└── lib └── ZZZ └── Hello └── World.pm
![Page 87: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/87.jpg)
# perlbrew to execute withdefault['hello-world']['perl_version'] = 'perl-5.16.0'
# Install directory, repo and tagdefault['hello-world']['deploy_dir'] = '/opt/hello-world'default['hello-world']['deploy_repo'] =
'https://github.com/dagolden/zzz-hello-world.git'default['hello-world']['deploy_tag'] = 'master'
# Service user/group/portdefault['hello-world']['user'] = "nobody"default['hello-world']['group'] = "nogroup"default['hello-world']['port'] = 8080
(attributes are variables used in the recipe; can be customized per-node during deployment)
![Page 88: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/88.jpg)
$ tree.├── Changes├── Makefile.PL├── app.psgi├── carton.lock├── cookbook│ └── hello-world│ ├── README.md│ ├── attributes│ │ └── default.rb│ ├── metadata.rb│ └── recipes│ └── default.rb└── lib └── ZZZ └── Hello └── World.pm
![Page 89: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/89.jpg)
include_recipe 'carton'
package 'git-core'
git node['hello-world']['deploy_dir'] do repository node['hello-world']['deploy_repo'] reference node['hello-world']['deploy_tag'] notifies :restart, "carton_app[hello-world]"end
carton_app "hello-world" do perlbrew node['hello-world']['perl_version'] command "starman -p #{node['hello-world']['port']} app.psgi" cwd node['hello-world']['deploy_dir'] user node['hello-world']['user'] group node['hello-world']['group']end
carton_app "hello-world" do action :startend
(recipe ensures carton and git are available...)
![Page 90: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/90.jpg)
include_recipe 'carton'
package 'git-core'
git node['hello-world']['deploy_dir'] do repository node['hello-world']['deploy_repo'] reference node['hello-world']['deploy_tag'] notifies :restart, "carton_app[hello-world]"end
carton_app "hello-world" do perlbrew node['hello-world']['perl_version'] command "starman -p #{node['hello-world']['port']} app.psgi" cwd node['hello-world']['deploy_dir'] user node['hello-world']['user'] group node['hello-world']['group']end
carton_app "hello-world" do action :startend
(git resource specifies where application code goes...)
![Page 91: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/91.jpg)
include_recipe 'carton'
package 'git-core'
git node['hello-world']['deploy_dir'] do repository node['hello-world']['deploy_repo'] reference node['hello-world']['deploy_tag'] notifies :restart, "carton_app[hello-world]"end
carton_app "hello-world" do perlbrew node['hello-world']['perl_version'] command "starman -p #{node['hello-world']['port']} app.psgi" cwd node['hello-world']['deploy_dir'] user node['hello-world']['user'] group node['hello-world']['group']end
carton_app "hello-world" do action :startend
(attributes parameterize the resource statement...)
![Page 92: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/92.jpg)
include_recipe 'carton'
package 'git-core'
git node['hello-world']['deploy_dir'] do repository node['hello-world']['deploy_repo'] reference node['hello-world']['deploy_tag'] notifies :restart, "carton_app[hello-world]"end
carton_app "hello-world" do perlbrew node['hello-world']['perl_version'] command "starman -p #{node['hello-world']['port']} app.psgi" cwd node['hello-world']['deploy_dir'] user node['hello-world']['user'] group node['hello-world']['group']end
carton_app "hello-world" do action :startend
(carton_app resources installs deps and sets up runit service...)
![Page 93: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/93.jpg)
include_recipe 'carton'
package 'git-core'
git node['hello-world']['deploy_dir'] do repository node['hello-world']['deploy_repo'] reference node['hello-world']['deploy_tag'] notifies :restart, "carton_app[hello-world]"end
carton_app "hello-world" do perlbrew node['hello-world']['perl_version'] command "starman -p #{node['hello-world']['port']} app.psgi" cwd node['hello-world']['deploy_dir'] user node['hello-world']['user'] group node['hello-world']['group']end
carton_app "hello-world" do action :startend
(again, attributes parameterize the resource...)
![Page 94: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/94.jpg)
include_recipe 'carton'
package 'git-core'
git node['hello-world']['deploy_dir'] do repository node['hello-world']['deploy_repo'] reference node['hello-world']['deploy_tag'] notifies :restart, "carton_app[hello-world]"end
carton_app "hello-world" do perlbrew node['hello-world']['perl_version'] command "starman -p #{node['hello-world']['port']} app.psgi" cwd node['hello-world']['deploy_dir'] user node['hello-world']['user'] group node['hello-world']['group']end
carton_app "hello-world" do action :startend
(finally, the resource is idempotently started...)
![Page 95: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/95.jpg)
These files – and the Perl Chefcookbooks – are all you need
![Page 96: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/96.jpg)
Enough code... let's see how to deploy it
![Page 97: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/97.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 98: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/98.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 100: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/100.jpg)
Vagrant is a tool for managing virtual machines
“Can I have a VirtualBox now, please?”
![Page 101: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/101.jpg)
Vagrant is a tool for managing virtual machines
$ vagrant box add base \ http://files.vagrantup.com/lucid32.box
$ vagrant init
$ vagrant up
![Page 102: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/102.jpg)
Vagrant is great for testing Chef deployment
(and other things, besides)
![Page 103: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/103.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 104: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/104.jpg)
Chef Solo is Chef without a centralconfiguration server
(good for demos and smaller deployments)
![Page 105: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/105.jpg)
Chef – you push config data to Chef Server – nodes run Chef Client to pull config
from Chef Server and execute it
Chef Solo – you push config data to nodes– you run Chef Solo remotely
![Page 106: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/106.jpg)
![Page 107: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/107.jpg)
One advantage of Chef Solo...
Your config repo is canonical
(i.e. you don't have to track what you've pushed to the central server)
![Page 108: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/108.jpg)
One dis-advantage of Chef Solo...
Manual rsync/ssh required (yuck!)
![Page 109: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/109.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 110: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/110.jpg)
Pantry is a tool for automating Chef Solo
![Page 111: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/111.jpg)
Pantry is a tool for automating Chef Solo
$ pantry create node server.example.com
$ pantry apply node server.example.com \ --role web --recipe myapp
$ pantry sync node server.example.com
![Page 112: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/112.jpg)
Pantry is written in Perl and available on CPAN
(Similar to pocketknife [Ruby] and littlechef [Python])
![Page 113: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/113.jpg)
Finally, a demonstration...
Screencast available athttp://youtu.be/H93rt-KtwBE
![Page 114: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/114.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 115: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/115.jpg)
$ vagrant init# create config file
$ vim Vagrantfile# edit to forward local port 8080 to# virtual machine port 8080
$ vagrant up# launch it
$ vagrant ssh# check that it's up, then exit
![Page 116: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/116.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 117: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/117.jpg)
$ pantry init# create directories to hold Chef Solo config
$ pantry create node vagrant \ host localhost \ port 8080 \ user vagrant# create a node config file
$ sshadd ~/.vagrant.d/insecure_private_key# allow pantry to ssh to vagrant machine
(Important tip: remove the insecure_private_key after you no longer need it because Github chokes on it.)
![Page 118: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/118.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 119: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/119.jpg)
Four cookbooks must be downloadedand copied to the 'cookbooks' directory
– hello-world– carton– perlbrew– runit
![Page 120: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/120.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 121: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/121.jpg)
$ pantry apply node vagrant recipe helloworld# apply recipe to node configuration
$ pantry apply node vagrant default \ helloworld.perl_version=perl5.14.2# override a default attribute
$ pantry show node vagrant# see the resulting JSON config file{ "helloworld" : { "perl_version" : "perl5.14.2" }, "run_list" : [ "recipe[helloworld]" ], "name" : "vagrant", "pantry_user" : "vagrant", "pantry_port" : "2222", "pantry_host" : "localhost"}
![Page 122: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/122.jpg)
1. Set up a Vagrant virtual machine
2. Prepare Pantry to manage Chef Solo
3. Get Hello World cookbook and dependencies
4. Configure virtual machine for Hello World
5. Deploy
Steps for deployment of Hello World
![Page 123: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/123.jpg)
$ pantry sync node vagrant# ... wait for everything to deploy ...# then load browser and test it!
![Page 124: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/124.jpg)
It works
![Page 125: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/125.jpg)
You can do this, too
![Page 126: Cooking Perl with Chef](https://reader033.vdocuments.us/reader033/viewer/2022060107/554a3360b4c90520578b5354/html5/thumbnails/126.jpg)
Don't be afraid. Try it out. Get involved.
tutorial and screencast → http://perlchef.com
mailing list → [email protected]