SlideShare une entreprise Scribd logo
1  sur  126
Télécharger pour lire hors ligne
Cooking Perl with Chef
        David Golden
           @xdg

      http://perlchef.com/

             July 2012
Configuration
    Management
(e.g. chef, puppet, cfengine, ...)
Unknown state

     ↓
 Target state
New machine

    ↓
Deployed app
Infrastructure as code
            automated!
            repeatable!
              testable!

 (no manual steps, checklist, etc.)
One tool to deploy
 the whole stack
(DB, caching, messaging, ...)
But wait!
Isn't that hard to do for Perl apps?
Perl applications are complex
Dependency hell
App = perl + CPAN + your code
CHI
             DateTime
             DBI
             JSON
App = perl + CPAN + your code
             Moose
             Plack
             POE
             Try::Tiny
             ...
CHI
                            DateTime
                            DBI
                            JSON
App = perl + CPAN + your code
                            Moose
                            Plack
                            POE
                            Try::Tiny
                            ...




 your application is the versioned set of all its compontents
CHI
                              DateTime
                              DBI
                              JSON
App
v1.0.0   = perl + CPAN + your code
                              Moose
                              Plack
                              POE
                              Try::Tiny
                              ...




   your application is the versioned set of all its compontents
CHI
                              DateTime
                              DBI
                              JSON
App
v1.0.0   = Perl + CPAN + your code
           v5.14.2            Moose
                              Plack
                              POE
                              Try::Tiny
                              ...




   your application is the versioned set of all its compontents
0.55
                              0.76
                              1.622
                              2.53
App
v1.0.0   = Perl + CPAN + your code
           v5.14.2            2.0603
                              0.9989
                              1.354
                              0.11
                              ...




   your application is the versioned set of all its compontents
0.55
                              0.76
                              1.622
                              2.53
App
v1.0.0   = Perl + CPAN + your code
           v5.14.2       v1.0 2.0603
                              0.9989
                              1.354
                              0.11
                              ...




   your application is the versioned set of all its compontents
0.55
                     0.76
                     1.622
                     2.53
App
v1.0.0   = Perl + CPAN + your code
           v5.14.2       v1.0
                     2.0603
                     0.9989
                     1.354
                     0.11
                     ...




              change one piece...
0.55
                     0.76
                     1.622
                     2.53
App
v1.0.0   = Perl + CPAN + your code
           v5.16.0       v1.0
                     2.0603
                     0.9989
                     1.354
                     0.11
                     ...




              change one piece...
0.55
                              0.76
                              1.622
                              2.53
App
v1.0.1    = Perl + CPAN + your code
            v5.16.0       v1.02.0603
                              0.9989
                              1.354
                              0.11
                              ...




         … and you have a new version of your application
Repeatable deployment means...
Repeatable deployment means...

        ... the same Perl
Repeatable deployment means...

        ... the same Perl
        ... the same modules
Repeatable deployment means...

        ... the same Perl
        ... the same modules
        ... the same code
Repeatable deployment means...

        ... the same Perl
        ... the same modules
        ... the same code
        ... on demand
Easy...
If we have the right tools
Use one-size fits all distribution packagers like
               apt, yum, etc...?

       (How much do you like your system perl?!)
This problem is not
  unique to Perl
Let's be inspired by Larry
[larry hat pic]
Or better yet, Paul
YARRR!
Great hackers steal!
Great hackers steal ideas
Consider Chef...
Chef ❤ Ruby
(written in ruby; various ruby app stacks)
Chef ❤ Python
(virtualenv; pip; django apps)
Common patterns emerge
python → virtualenv + pip
 ruby → rvm + Bundler
We've built tools like these, too
Kang-min Liu (gugod)

 Matt S Trout (mst)

Tatsuhiko Miyagawa
(and a big community helping them)
perlbrew – multiple perl manager

       Matt S Trout (mst)

      Tatsuhiko Miyagawa
      (and a big community helping them)
perlbrew – multiple perl manager

local::lib – custom @INC manager

      Tatsuhiko Miyagawa
      (and a big community helping them)
perlbrew – multiple perl manager

  local::lib – custom @INC manager

carton – versioned dependency installer
         (and a big community helping them)
So we have the pieces
Repeatable deployment in five parts
Repeatable deployment in five parts

      application-specific Perl

      application-specific @INC path

      versioned application code

      versioned module dependencies

      automate the previous four
Repeatable deployment in five parts

      perlbrew

      application-specific @INC path

      versioned application code

      versioned module dependencies

      automate the previous four
Repeatable deployment in five parts

      perlbrew

      local::lib

      versioned application code

      versioned module dependencies

      automate the previous four
Repeatable deployment in five parts

      perlbrew

      local::lib

      git

      versioned module dependencies

      automate the previous four
Repeatable deployment in five parts

      perlbrew

      local::lib

      git

      carton

      automate the previous four
Repeatable deployment in five parts

      perlbrew

      local::lib

      git

      carton

      @&$%!
[swedish chef FAIL pic]
No support in Chef...
So I implemented it
(In Ruby)
(After I learned some Ruby)
Now...


         Chef ❤ Perl
    (perlbrew; local::lib; carton)
Time for a quick Chef glossary...

 (see http://wiki.opscode.com/)
“Cookbook”

A collection of components to configure
a particular application

Typically includes recipes, providers,
templates, etc.

(CPAN analogy → “distribution”)
“Recipe”

Component applied that deploys an
application or service

Typically declarative, specifying desired
resources and associated configuration
“Resource”

An abstraction of something to be deployed
“Provider”

Platform-specific implementation to deliver a
resource
“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
“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
“Role”

A collection of recipes and attributes used to
apply common configuration across multiple
nodes
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
I wrote two Perl Chef cookbooks
for the Chef community repository
     (which is like CPAN circa 1996 or so)


       http://community.opscode.com/
1. perlbrew – for managing perls

2. carton – for deploying apps


Also available here: https://github.com/dagolden/perl-chef
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 a
  particular perlbrew and/or lib
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
Time for an example:

Deploying a “Hello World” Plack app

     https://github.com/dagolden/zzz-hello-world
Steps for creating Hello World

    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
$ 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
$ 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
use strict;
use warnings;
use ZZZ::Hello::World;
my $app = sub { ZZZ::Hello::World->run_psgi(@_) };




                             (this Plack app just invokes a simple module)
$ 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
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)
$ 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
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)
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
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
$ 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
# 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)
$ 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
# perlbrew to execute with
 default['hello-world']['perl_version'] = 'perl-5.16.0'

 # Install directory, repo and tag
 default['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/port
 default['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)
$ 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
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 :start
end



                                (recipe ensures carton and git are available...)
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 :start
end



                          (git resource specifies where application code goes...)
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 :start
end



                              (attributes parameterize the resource statement...)
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 :start
end



                     (carton_app resources installs deps and sets up runit service...)
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 :start
end



                               (again, attributes parameterize the resource...)
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 :start
end



                                (finally, the resource is idempotently started...)
These files – and the Perl Chef
 cookbooks – are all you need
Enough code... let's see how to deploy it
Steps for deployment of Hello World


    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


    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
Vagrant is a tool for managing virtual machines


   “Can I have a VirtualBox now, please?”
Vagrant is a tool for managing virtual machines


$ vagrant box add base 
  http://files.vagrantup.com/lucid32.box

$ vagrant init

$ vagrant up
Vagrant is great for testing Chef deployment

            (and other things, besides)
Steps for deployment of Hello World


    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
Chef Solo is Chef without a central
      configuration server

 (good for demos and smaller deployments)
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
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)
One dis-advantage of Chef Solo...

Manual rsync/ssh required (yuck!)
Steps for deployment of Hello World


    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
Pantry is a tool for automating Chef Solo
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
Pantry is written in Perl and available on CPAN

   (Similar to pocketknife [Ruby] and littlechef [Python])
Finally, a demonstration...



   Screencast available at
http://youtu.be/H93rt-KtwBE
Steps for deployment of Hello World


    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
$ 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
Steps for deployment of Hello World


    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
$ pantry init
# create directories to hold Chef Solo config

$ pantry create node vagrant 
    ­­host localhost 
    ­­port 8080      
    ­­user vagrant
# create a node config file

$ ssh­add ~/.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.)
Steps for deployment of Hello World


    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
Four cookbooks must be downloaded
and copied to the 'cookbooks' directory

 – hello-world
 – carton
 – perlbrew
 – runit
Steps for deployment of Hello World


    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
$ pantry apply node vagrant ­­recipe hello­world
# apply recipe to node configuration

$ pantry apply node vagrant ­­default 
    hello­world.perl_version=perl­5.14.2
# override a default attribute

$ pantry show node vagrant
# see the resulting JSON config file
{
   "hello­world" : {
      "perl_version" : "perl­5.14.2"
   },
   "run_list" : [
      "recipe[hello­world]"
   ],
   "name" : "vagrant",
   "pantry_user" : "vagrant",
   "pantry_port" : "2222",
   "pantry_host" : "localhost"
}
Steps for deployment of Hello World


    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
$ pantry sync node vagrant
# ... wait for everything to deploy ...
# then load browser and test it!
It works
You can do this, too
Don't be afraid. Try it out. Get involved.

   tutorial and screencast → http://perlchef.com

  mailing list → perl-devops-subscribe@perl.org

Contenu connexe

Tendances

From Dev to DevOps - ApacheCON NA 2011
From Dev to DevOps - ApacheCON NA 2011From Dev to DevOps - ApacheCON NA 2011
From Dev to DevOps - ApacheCON NA 2011
Carlos Sanchez
 
Puppet for Java developers - JavaZone NO 2012
Puppet for Java developers - JavaZone NO 2012Puppet for Java developers - JavaZone NO 2012
Puppet for Java developers - JavaZone NO 2012
Carlos Sanchez
 

Tendances (20)

From Dev to DevOps - ApacheCON NA 2011
From Dev to DevOps - ApacheCON NA 2011From Dev to DevOps - ApacheCON NA 2011
From Dev to DevOps - ApacheCON NA 2011
 
Puppet for Java developers - JavaZone NO 2012
Puppet for Java developers - JavaZone NO 2012Puppet for Java developers - JavaZone NO 2012
Puppet for Java developers - JavaZone NO 2012
 
Puppet at GitHub / ChatOps
Puppet at GitHub / ChatOpsPuppet at GitHub / ChatOps
Puppet at GitHub / ChatOps
 
Puppet at Pinterest
Puppet at PinterestPuppet at Pinterest
Puppet at Pinterest
 
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & HadoopPuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
PuppetCamp SEA 1 - Using Vagrant, Puppet, Testing & Hadoop
 
Building kubectl plugins with Quarkus | DevNation Tech Talk
Building kubectl plugins with Quarkus | DevNation Tech TalkBuilding kubectl plugins with Quarkus | DevNation Tech Talk
Building kubectl plugins with Quarkus | DevNation Tech Talk
 
Antons Kranga Building Agile Infrastructures
Antons Kranga   Building Agile InfrastructuresAntons Kranga   Building Agile Infrastructures
Antons Kranga Building Agile Infrastructures
 
Test Driven Development with Puppet - PuppetConf 2014
Test Driven Development with Puppet - PuppetConf 2014Test Driven Development with Puppet - PuppetConf 2014
Test Driven Development with Puppet - PuppetConf 2014
 
Kubernetes Java Operator
Kubernetes Java OperatorKubernetes Java Operator
Kubernetes Java Operator
 
Take control of your Jenkins jobs via job DSL.
Take control of your Jenkins jobs via job DSL.Take control of your Jenkins jobs via job DSL.
Take control of your Jenkins jobs via job DSL.
 
DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)DevOps(4) : Ansible(2) - (MOSG)
DevOps(4) : Ansible(2) - (MOSG)
 
Docker Starter Pack
Docker Starter PackDocker Starter Pack
Docker Starter Pack
 
Test Driven Development with Puppet
Test Driven Development with Puppet Test Driven Development with Puppet
Test Driven Development with Puppet
 
Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點Ansible 實戰:top down 觀點
Ansible 實戰:top down 觀點
 
The Modern Developer Toolbox
The Modern Developer ToolboxThe Modern Developer Toolbox
The Modern Developer Toolbox
 
Testing Your Automation Code (Docker Version)
Testing Your Automation Code (Docker Version)Testing Your Automation Code (Docker Version)
Testing Your Automation Code (Docker Version)
 
PuppetCamp SEA 1 - Puppet Deployment at OnApp
PuppetCamp SEA 1 - Puppet Deployment  at OnAppPuppetCamp SEA 1 - Puppet Deployment  at OnApp
PuppetCamp SEA 1 - Puppet Deployment at OnApp
 
Configuring Highly Scalable Compile Masters, Vasco Cardoso, AWS
Configuring Highly Scalable Compile Masters, Vasco Cardoso, AWSConfiguring Highly Scalable Compile Masters, Vasco Cardoso, AWS
Configuring Highly Scalable Compile Masters, Vasco Cardoso, AWS
 
Chef for beginners module 5
Chef for beginners   module 5Chef for beginners   module 5
Chef for beginners module 5
 
A Tale of a Server Architecture (Frozen Rails 2012)
A Tale of a Server Architecture (Frozen Rails 2012)A Tale of a Server Architecture (Frozen Rails 2012)
A Tale of a Server Architecture (Frozen Rails 2012)
 

Similaire à Cooking Perl with Chef

Similaire à Cooking Perl with Chef (20)

Kubernetes Introduction
Kubernetes IntroductionKubernetes Introduction
Kubernetes Introduction
 
TDC2018FLN | Trilha Containers - Kubernetes para usuarios Docker.
TDC2018FLN | Trilha Containers - Kubernetes para usuarios Docker.TDC2018FLN | Trilha Containers - Kubernetes para usuarios Docker.
TDC2018FLN | Trilha Containers - Kubernetes para usuarios Docker.
 
Kubernetes_Webinar_Slide_Deck.pdf
Kubernetes_Webinar_Slide_Deck.pdfKubernetes_Webinar_Slide_Deck.pdf
Kubernetes_Webinar_Slide_Deck.pdf
 
Python+gradle
Python+gradlePython+gradle
Python+gradle
 
Kubernetes deep dive - - Huawei 2015-10
Kubernetes deep dive - - Huawei 2015-10Kubernetes deep dive - - Huawei 2015-10
Kubernetes deep dive - - Huawei 2015-10
 
Kubernetes workshop -_the_basics
Kubernetes workshop -_the_basicsKubernetes workshop -_the_basics
Kubernetes workshop -_the_basics
 
Packaging perl (LPW2010)
Packaging perl (LPW2010)Packaging perl (LPW2010)
Packaging perl (LPW2010)
 
Cluster management with Kubernetes
Cluster management with KubernetesCluster management with Kubernetes
Cluster management with Kubernetes
 
Docker module 1
Docker module 1Docker module 1
Docker module 1
 
Kubernetes best practices
Kubernetes best practicesKubernetes best practices
Kubernetes best practices
 
JavaOne 2016: Kubernetes introduction for Java Developers
JavaOne 2016: Kubernetes introduction for Java Developers JavaOne 2016: Kubernetes introduction for Java Developers
JavaOne 2016: Kubernetes introduction for Java Developers
 
Kubernetes for Java Developers
 Kubernetes for Java Developers Kubernetes for Java Developers
Kubernetes for Java Developers
 
Can I Contain This?
Can I Contain This?Can I Contain This?
Can I Contain This?
 
Kubernetes intro public - kubernetes meetup 4-21-2015
Kubernetes intro   public - kubernetes meetup 4-21-2015Kubernetes intro   public - kubernetes meetup 4-21-2015
Kubernetes intro public - kubernetes meetup 4-21-2015
 
Kubernetes intro public - kubernetes user group 4-21-2015
Kubernetes intro   public - kubernetes user group 4-21-2015Kubernetes intro   public - kubernetes user group 4-21-2015
Kubernetes intro public - kubernetes user group 4-21-2015
 
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
Adopt DevOps philosophy on your Symfony projects (Symfony Live 2011)
 
Docker for Devs - John Zaccone, IBM
Docker for Devs - John Zaccone, IBMDocker for Devs - John Zaccone, IBM
Docker for Devs - John Zaccone, IBM
 
DockerDay2015: Getting started with Google Container Engine
DockerDay2015: Getting started with Google Container EngineDockerDay2015: Getting started with Google Container Engine
DockerDay2015: Getting started with Google Container Engine
 
DockerCon EU 2015: Stop Being Lazy and Test Your Software!
DockerCon EU 2015: Stop Being Lazy and Test Your Software!DockerCon EU 2015: Stop Being Lazy and Test Your Software!
DockerCon EU 2015: Stop Being Lazy and Test Your Software!
 
Kubernetes - training micro-dragons without getting burnt
Kubernetes -  training micro-dragons without getting burntKubernetes -  training micro-dragons without getting burnt
Kubernetes - training micro-dragons without getting burnt
 

Plus de David Golden

Plus de David Golden (16)

Slice Recycling Performance and Pitfalls
Slice Recycling Performance and PitfallsSlice Recycling Performance and Pitfalls
Slice Recycling Performance and Pitfalls
 
Free QA!
Free QA!Free QA!
Free QA!
 
Eversion 101: An Introduction to Inside-Out Objects
Eversion 101: An Introduction to Inside-Out ObjectsEversion 101: An Introduction to Inside-Out Objects
Eversion 101: An Introduction to Inside-Out Objects
 
Perl 5 Version 13
Perl 5 Version 13Perl 5 Version 13
Perl 5 Version 13
 
IsTrue(true)?
IsTrue(true)?IsTrue(true)?
IsTrue(true)?
 
One BSON to Rule Them
One BSON to Rule ThemOne BSON to Rule Them
One BSON to Rule Them
 
Adventures in Optimization
Adventures in OptimizationAdventures in Optimization
Adventures in Optimization
 
Make Comments Stand Out
Make Comments Stand OutMake Comments Stand Out
Make Comments Stand Out
 
State of the Velociraptor Mini-Keynote: Perl Toolchain
State of the Velociraptor Mini-Keynote: Perl ToolchainState of the Velociraptor Mini-Keynote: Perl Toolchain
State of the Velociraptor Mini-Keynote: Perl Toolchain
 
Practical Consistency
Practical ConsistencyPractical Consistency
Practical Consistency
 
How I get to the ☞
How I get to the ☞How I get to the ☞
How I get to the ☞
 
Real World Optimization
Real World OptimizationReal World Optimization
Real World Optimization
 
Safer Chainsaw Juggling (Lightning Talk)
Safer Chainsaw Juggling (Lightning Talk)Safer Chainsaw Juggling (Lightning Talk)
Safer Chainsaw Juggling (Lightning Talk)
 
Taking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order FunctionsTaking Perl to Eleven with Higher-Order Functions
Taking Perl to Eleven with Higher-Order Functions
 
Juggling Chainsaws: Perl and MongoDB
Juggling Chainsaws: Perl and MongoDBJuggling Chainsaws: Perl and MongoDB
Juggling Chainsaws: Perl and MongoDB
 
Cooking Perl with Chef: Hello World Tutorial
Cooking Perl with Chef: Hello World TutorialCooking Perl with Chef: Hello World Tutorial
Cooking Perl with Chef: Hello World Tutorial
 

Dernier

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 

Dernier (20)

Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 

Cooking Perl with Chef

  • 1. Cooking Perl with Chef David Golden @xdg http://perlchef.com/ July 2012
  • 2. Configuration Management (e.g. chef, puppet, cfengine, ...)
  • 3. Unknown state ↓ Target state
  • 4. New machine ↓ Deployed app
  • 5. Infrastructure as code automated! repeatable! testable! (no manual steps, checklist, etc.)
  • 6. One tool to deploy the whole stack (DB, caching, messaging, ...)
  • 7. But wait! Isn't that hard to do for Perl apps?
  • 10. App = perl + CPAN + your code
  • 11. CHI DateTime DBI JSON App = perl + CPAN + your code Moose Plack POE Try::Tiny ...
  • 12. CHI DateTime DBI JSON App = perl + CPAN + your code Moose Plack POE Try::Tiny ... your application is the versioned set of all its compontents
  • 13. CHI DateTime DBI JSON App v1.0.0 = perl + CPAN + your code Moose Plack POE Try::Tiny ... your application is the versioned set of all its compontents
  • 14. CHI DateTime DBI JSON App v1.0.0 = Perl + CPAN + your code v5.14.2 Moose Plack POE Try::Tiny ... your application is the versioned set of all its compontents
  • 15. 0.55 0.76 1.622 2.53 App v1.0.0 = Perl + CPAN + your code v5.14.2 2.0603 0.9989 1.354 0.11 ... your application is the versioned set of all its compontents
  • 16. 0.55 0.76 1.622 2.53 App v1.0.0 = Perl + CPAN + your code v5.14.2 v1.0 2.0603 0.9989 1.354 0.11 ... your application is the versioned set of all its compontents
  • 17. 0.55 0.76 1.622 2.53 App v1.0.0 = Perl + CPAN + your code v5.14.2 v1.0 2.0603 0.9989 1.354 0.11 ... change one piece...
  • 18. 0.55 0.76 1.622 2.53 App v1.0.0 = Perl + CPAN + your code v5.16.0 v1.0 2.0603 0.9989 1.354 0.11 ... change one piece...
  • 19. 0.55 0.76 1.622 2.53 App v1.0.1 = Perl + CPAN + your code v5.16.0 v1.02.0603 0.9989 1.354 0.11 ... … and you have a new version of your application
  • 21. Repeatable deployment means... ... the same Perl
  • 22. Repeatable deployment means... ... the same Perl ... the same modules
  • 23. Repeatable deployment means... ... the same Perl ... the same modules ... the same code
  • 24. Repeatable deployment means... ... the same Perl ... the same modules ... the same code ... on demand
  • 26. If we have the right tools
  • 27. Use one-size fits all distribution packagers like apt, yum, etc...? (How much do you like your system perl?!)
  • 28. This problem is not unique to Perl
  • 29. Let's be inspired by Larry
  • 32.
  • 37. Chef ❤ Ruby (written in ruby; various ruby app stacks)
  • 38. Chef ❤ Python (virtualenv; pip; django apps)
  • 40. python → virtualenv + pip ruby → rvm + Bundler
  • 41. We've built tools like these, too
  • 42. Kang-min Liu (gugod) Matt S Trout (mst) Tatsuhiko Miyagawa (and a big community helping them)
  • 43. perlbrew – multiple perl manager Matt S Trout (mst) Tatsuhiko Miyagawa (and a big community helping them)
  • 44. perlbrew – multiple perl manager local::lib – custom @INC manager Tatsuhiko Miyagawa (and a big community helping them)
  • 45. perlbrew – multiple perl manager local::lib – custom @INC manager carton – versioned dependency installer (and a big community helping them)
  • 46. So we have the pieces
  • 48. Repeatable deployment in five parts application-specific Perl application-specific @INC path versioned application code versioned module dependencies automate the previous four
  • 49. Repeatable deployment in five parts perlbrew application-specific @INC path versioned application code versioned module dependencies automate the previous four
  • 50. Repeatable deployment in five parts perlbrew local::lib versioned application code versioned module dependencies automate the previous four
  • 51. Repeatable deployment in five parts perlbrew local::lib git versioned module dependencies automate the previous four
  • 52. Repeatable deployment in five parts perlbrew local::lib git carton automate the previous four
  • 53. Repeatable deployment in five parts perlbrew local::lib git carton @&$%!
  • 55. No support in Chef...
  • 58. (After I learned some Ruby)
  • 59. Now... Chef ❤ Perl (perlbrew; local::lib; carton)
  • 60. Time for a quick Chef glossary... (see http://wiki.opscode.com/)
  • 61. “Cookbook” A collection of components to configure a particular application Typically includes recipes, providers, templates, etc. (CPAN analogy → “distribution”)
  • 62. “Recipe” Component applied that deploys an application or service Typically declarative, specifying desired resources and associated configuration
  • 63. “Resource” An abstraction of something to be deployed
  • 65. “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
  • 66. “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
  • 67. “Role” A collection of recipes and attributes used to apply common configuration across multiple nodes
  • 68. 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
  • 69. I wrote two Perl Chef cookbooks for the Chef community repository (which is like CPAN circa 1996 or so) http://community.opscode.com/
  • 70. 1. perlbrew – for managing perls 2. carton – for deploying apps Also available here: https://github.com/dagolden/perl-chef
  • 71. 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 a particular perlbrew and/or lib
  • 72. 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
  • 73. Time for an example: Deploying a “Hello World” Plack app https://github.com/dagolden/zzz-hello-world
  • 74. Steps for creating Hello World 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
  • 75. $ 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
  • 76. $ 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
  • 77. use strict; use warnings; use ZZZ::Hello::World; my $app = sub { ZZZ::Hello::World->run_psgi(@_) }; (this Plack app just invokes a simple module)
  • 78. $ 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
  • 79. 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)
  • 80. $ 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
  • 81. 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)
  • 82. 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
  • 83. 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
  • 84. $ 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
  • 85. # 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)
  • 86. $ 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
  • 87. # perlbrew to execute with default['hello-world']['perl_version'] = 'perl-5.16.0' # Install directory, repo and tag default['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/port default['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)
  • 88. $ 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
  • 89. 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 :start end (recipe ensures carton and git are available...)
  • 90. 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 :start end (git resource specifies where application code goes...)
  • 91. 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 :start end (attributes parameterize the resource statement...)
  • 92. 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 :start end (carton_app resources installs deps and sets up runit service...)
  • 93. 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 :start end (again, attributes parameterize the resource...)
  • 94. 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 :start end (finally, the resource is idempotently started...)
  • 95. These files – and the Perl Chef cookbooks – are all you need
  • 96. Enough code... let's see how to deploy it
  • 97. Steps for deployment of Hello World 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
  • 98. Steps for deployment of Hello World 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
  • 99.
  • 100. Vagrant is a tool for managing virtual machines “Can I have a VirtualBox now, please?”
  • 101. Vagrant is a tool for managing virtual machines $ vagrant box add base http://files.vagrantup.com/lucid32.box $ vagrant init $ vagrant up
  • 102. Vagrant is great for testing Chef deployment (and other things, besides)
  • 103. Steps for deployment of Hello World 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
  • 104. Chef Solo is Chef without a central configuration server (good for demos and smaller deployments)
  • 105. 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
  • 106.
  • 107. 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)
  • 108. One dis-advantage of Chef Solo... Manual rsync/ssh required (yuck!)
  • 109. Steps for deployment of Hello World 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
  • 110. Pantry is a tool for automating Chef Solo
  • 111. 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
  • 112. Pantry is written in Perl and available on CPAN (Similar to pocketknife [Ruby] and littlechef [Python])
  • 113. Finally, a demonstration... Screencast available at http://youtu.be/H93rt-KtwBE
  • 114. Steps for deployment of Hello World 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
  • 116. Steps for deployment of Hello World 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
  • 118. Steps for deployment of Hello World 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
  • 119. Four cookbooks must be downloaded and copied to the 'cookbooks' directory – hello-world – carton – perlbrew – runit
  • 120. Steps for deployment of Hello World 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
  • 122. Steps for deployment of Hello World 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
  • 125. You can do this, too
  • 126. Don't be afraid. Try it out. Get involved. tutorial and screencast → http://perlchef.com mailing list → perl-devops-subscribe@perl.org