Slide 1

Slide 1 text

Stabilize your environment, stabilize your code Jacob Mather Software Engineer, Mashery

Slide 2

Slide 2 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Who am I? What I do: • Software Engineer at Mashery • Co-organizer of the
 San Francisco PHP User Group • Community Evangelist Where I can be found: • Blog: http://jmather.com • Twitter: @thejmather

Slide 3

Slide 3 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Why I am giving this talk

Slide 4

Slide 4 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Failure to specifically build an environment for development will directly impact developer productivity and product quality.

Slide 5

Slide 5 text

Let’s talk about
 Vagrant

Slide 6

Slide 6 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 What is Vagrant? A tool that allows you to create and configure lightweight, reproducible, and portable development environments.

Slide 7

Slide 7 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Why was Vagrant created? To solve the problem of how to have easy an to build development environment that is identical across the entire team.

Slide 8

Slide 8 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Vagrant terms • Box, or base box, is the ‘initial image’ of a virtual machine. • Host, or your computer, the machine running the VMs • Guest, or vm, referring to an individual VM instance • Provider, an adapter to a VMS (like VirtualBox or VMWare) • Provisioner, provides post-boot configuration of guests

Slide 9

Slide 9 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrant Commands • vagrant up - Turn guest on • vagrant halt - Turn guest off • vagrant status - Show guest status • vagrant destroy - Delete guest • vagrant suspend - Suspend guest • vagrant resume - Resume guest • vagrant ssh - SSH into guest

Slide 10

Slide 10 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 How to use Vagrant • Install Vagrant - http://vagrantup.com • Check out your repository • Run: vagrant up

Slide 11

Slide 11 text

Let’s talk about
 code

Slide 12

Slide 12 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile Vagrant.configure("2")  do  |config|
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  "http://some/url.box"
 end


Slide 13

Slide 13 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (add file system) Vagrant.configure("2")  do  |config|
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  "http://some/url.box"
    config.vm.synced_folder  "/data",  "/vagrant_data"
 end


Slide 14

Slide 14 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (add port forwarding) Vagrant.configure("2")  do  |config|
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  "http://some/url.box"
    config.vm.synced_folder  "/data",  "/vagrant_data"
    config.vm.network  :forwarded_port,  guest:  80,  host:  8080
 end


Slide 15

Slide 15 text

Let’s talk about
 clouds

Slide 16

Slide 16 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Replicating production matters If you are writing code that will be deployed to a multiple-host environment, why aren’t you writing your code in a multiple- host environment?

Slide 17

Slide 17 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile Vagrant.configure("2")  do  |config|
    config.vm.hostname  =  "web-­‐server"
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  "http://some/url.box"
 end


Slide 18

Slide 18 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile Vagrant.configure("2")  do  |config|   
    config.vm.hostname  =  "web-­‐server"
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  "http://some/url.box"
 end


Slide 19

Slide 19 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest ready) Vagrant.configure("2")  do  |config|
    config.vm.define  "web-­‐server"  do  |node|
        node.vm.hostname  =  "web-­‐server"
        node.vm.box  =  "base-­‐box-­‐name"
        node.vm.box_url  =  "http://some/url.box"
    end
 end


Slide 20

Slide 20 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest ready) Vagrant.configure("2")  do  |config|
    config.vm.define  "web-­‐server"  do  |node|
        node.vm.hostname  =  "web-­‐server"
        node.vm.box  =  "base-­‐box-­‐name"
        node.vm.box_url  =  "http://some/url.box"
    end
 end


Slide 21

Slide 21 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest ready) Vagrant.configure("2")  do  |config|
    config.vm.define  "web-­‐server"  do  |node|
        node.vm.hostname  =  "web-­‐server"
        node.vm.box  =  "base-­‐box-­‐name"
        node.vm.box_url  =  "http://some/url.box"
    end
 end


Slide 22

Slide 22 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest) Vagrant.configure("2")  do  |config|
    config.vm.define  "web-­‐server"  do  |node|
        node.vm.hostname  =  "web-­‐server"
        node.vm.box  =  "base-­‐box-­‐name"
        node.vm.box_url  =  "http://some/url.box"
    end
    config.vm.define  "db-­‐server"  do  |node|
        node.vm.hostname  =  "db-­‐server"
        node.vm.box  =  "base-­‐box-­‐name"  
        node.vm.box_url  =  "http://some/url.box"
    end
 end

Slide 23

Slide 23 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest, useful, part 1) nodes  =  {
        'web-­‐server'  =>  {
                :hostname  =>  'server.example.com',
                :ipAddress  =>  '192.168.56.60',
        },
        'db-­‐server'  =>  {
                :hostname  =>  'db.example.com',
                :ipAddress  =>  '192.168.56.61',
        }
 }

Slide 24

Slide 24 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest, useful, part 2) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        machineName  =  options[:hostname]
        ipAddy  =  options[:ipAddress]          config.vm.define  name  do  |node|
            node.vm.box  =  "base-­‐box-­‐name"
            node.vm.box_url  =  "http://some/url.box"
            node.vm.hostname  =  machineName
            node.vm.network  :private_network,  ip:  ipAddy
        end
    end
 end

Slide 25

Slide 25 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest, useful, part 2) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        machineName  =  options[:hostname]
        ipAddy  =  options[:ipAddress]          config.vm.define  name  do  |node|
            node.vm.box  =  "base-­‐box-­‐name"
            node.vm.box_url  =  "http://some/url.box"
            node.vm.hostname  =  machineName
            node.vm.network  :private_network,  ip:  ipAddy
        end
    end
 end

Slide 26

Slide 26 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest, useful, part 2) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        machineName  =  options[:hostname]
        ipAddy  =  options[:ipAddress]          config.vm.define  name  do  |node|
            node.vm.box  =  "base-­‐box-­‐name"
            node.vm.box_url  =  "http://some/url.box"
            node.vm.hostname  =  machineName
            node.vm.network  :private_network,  ip:  ipAddy
        end
    end
 end

Slide 27

Slide 27 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest, useful, part 2) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        machineName  =  options[:hostname]
        ipAddy  =  options[:ipAddress]          config.vm.define  name  do  |node|
            node.vm.box  =  "base-­‐box-­‐name"
            node.vm.box_url  =  "http://some/url.box"
            node.vm.hostname  =  machineName
            node.vm.network  :private_network,  ip:  ipAddy
        end
    end
 end

Slide 28

Slide 28 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest, useful, part 2) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        machineName  =  options[:hostname]
        ipAddy  =  options[:ipAddress]          config.vm.define  name  do  |node|
            node.vm.box  =  "base-­‐box-­‐name"
            node.vm.box_url  =  "http://some/url.box"
            node.vm.hostname  =  machineName
            node.vm.network  :private_network,  ip:  ipAddy
        end
    end
 end

Slide 29

Slide 29 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (Multi-Guest, useful, part 2) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        machineName  =  options[:hostname]
        ipAddy  =  options[:ipAddress]          config.vm.define  name  do  |node|
            node.vm.box  =  "base-­‐box-­‐name"
            node.vm.box_url  =  "http://some/url.box"
            node.vm.hostname  =  machineName
            node.vm.network  :private_network,  ip:  ipAddy
        end
    end
 end

Slide 30

Slide 30 text

Let’s talk about
 Providers

Slide 31

Slide 31 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Vagrant Providers ! Providers ! Vagrant

Slide 32

Slide 32 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Vagrant Providers VirtualBox VMWare (WS or Fusion) Parallels Desktop ! Providers ! Vagrant

Slide 33

Slide 33 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Vagrant Providers VirtualBox VMWare (WS or Fusion) Parallels Desktop Amazon AWS Digital Ocean ! Providers ! Vagrant

Slide 34

Slide 34 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Vagrant Providers (desktop) • VirtualBox is FREE! (sort of) • Built in FS bridging is historically bad but getting better • Newer versions are less stable (use 4.2.16!!) • VMWare (Workstation or Fusion!) is PAID! • You have to buy both VMWare and provider • Supposed to be more stable and snappy • Parallels Desktop adapter is FREE! • Open source project • You do still have to buy Parallels Desktop

Slide 35

Slide 35 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Vagrant Providers (cloud) • Amazon AWS • Digital Ocean • RackSpace Cloud

Slide 36

Slide 36 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Vagrant Provider Limits Spinning up guests is cool, but what do I do with a box once it’s up? How do I control it? How do I make it useful? ! Computing hardware without software is nearly useless.

Slide 37

Slide 37 text

Let’s talk about
 Provisioners

Slide 38

Slide 38 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Vagrant Provisioners ! Provisioners ! Vagrant

Slide 39

Slide 39 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Shell Scripts Puppet Chef Ansible Vagrant Provisioners ! Provisioners ! Vagrant

Slide 40

Slide 40 text

Let’s talk about
 Puppet

Slide 41

Slide 41 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 What is Puppet? Puppet, an automated administrative engine for your Linux, Unix, and Windows systems, performs administrative tasks (such as adding users, installing packages, and updating server configurations) based on a centralized specification.

Slide 42

Slide 42 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Why was Puppet created? Puppet was created to provide a declarative way to define system and software configuration.

Slide 43

Slide 43 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet terms • Manifests - This is “application” code • Modules - This is “library” code • Templates - Exactly as it sounds • Facter - Environment data • Hiera - Configuration data

Slide 44

Slide 44 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 How to use Puppet? Select a base box for Vagrant from Puppet Labs ! http://puppet-vagrant-boxes.puppetlabs.com/ ! I use CentOS 6.4 for VirtualBox

Slide 45

Slide 45 text

Let’s talk about
 code

Slide 46

Slide 46 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile Vagrant.configure("2")  do  |config|
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  "http://some/url.box"
 end


Slide 47

Slide 47 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile Vagrant.configure("2")  do  |config|
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  “http://some/url.box"   ! ! ! ! 
 end


Slide 48

Slide 48 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile Vagrant.configure("2")  do  |config|
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  “http://some/url.box"   ! ! ! ! 
 end

Slide 49

Slide 49 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (add Puppet) Vagrant.configure("2")  do  |config|
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  "http://some/url.box"
    config.vm.provision  :puppet  do  |puppet|
        puppet.manifests_path  =  "manifests/"
        puppet.manifest_file    =  “init.pp"
        puppet.module_path  =  "modules/"
    end
 end


Slide 50

Slide 50 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Vagrantfile (add Puppet) Vagrant.configure("2")  do  |config|
    config.vm.box  =  "base-­‐box-­‐name"
    config.vm.box_url  =  "http://some/url.box"
    config.vm.provision  :puppet  do  |puppet|
        puppet.manifests_path  =  "manifests/"
        puppet.manifest_file    =  “init.pp"
        puppet.module_path  =  "modules/"
    end
 end


Slide 51

Slide 51 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Puppet Manifest (init.pp) notify  {  "Look!  My  puppet  code  is  working!":  }


Slide 52

Slide 52 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Puppet Manifest (init.pp, add Apache) notify  {  "Look!  My  puppet  code  is  working!":  }
    
 package  {  "httpd":
    ensure  =>  present,
 }
    
 service  {  "httpd":
    require  =>  Package["httpd"],
    ensure  =>  running,
    enabled  =>  true,
 }

Slide 53

Slide 53 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Basic Puppet Manifest (refactored Apache) #  manifests/init.pp
 notify  {  "Code  works!":  }
 require  server::httpd
 #  modules/server/manifests/httpd.pp
 class  server::httpd  {
    package  {  "httpd":
        ensure  =>  present,
    }
    service  {  "httpd":
        require  =>  Package["httpd"],
        ensure  =>  running,
        enabled  =>  true,
    }
 }

Slide 54

Slide 54 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (controlling flow) #  manifests/init.pp   notify  {  "Say  me  third":
    require  =>  Notify["Say  me  second"],
 }
    
 notify  {  "Say  me  second":
    require  =>  Notify["Say  me  first"],
 }
    
 notify  {  "Say  me  first":  }

Slide 55

Slide 55 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (controlling flow) #  manifests/init.pp   notify  {  "Say  me  third":
    require  =>  Notify["Say  me  second"],
 }
    
 notify  {  "Say  me  second":
    require  =>  Notify["Say  me  first"],
 }
    
 notify  {  "Say  me  first":  } Output Say me first Say me second Say me third

Slide 56

Slide 56 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (adding parameters) #  modules/server/manifests/writefile.pp
 class  server::writefile  ($content)  {
    file  {  "/tmp/test":
        content  =>  $content,
    }
 }
 
 #  or,  to  provide  a  default…   class  server::writefile  ($content  =  "")  {
    file  {  "/tmp/test":
        content  =>  $content
    }
 }

Slide 57

Slide 57 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (passing parameters) #  manifests/init.pp  -­‐-­‐  using  defaults
 include  server::writetestfile
 
 #  manifests/init.pp  -­‐-­‐  passing  custom  value
 class  {  "server::writetestfile":
    content  =>  "test  content",
 }

Slide 58

Slide 58 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (including classes) #  manifests/init.pp   #  the  class  below  must  be  loaded  BEFORE  guest
 require  server::writetestfile
    
 #  the  class  below  must  be  loaded  WITH  guest
 include  server::writetestfile      
 #  the  class  below  must  be  loaded  AFTER  guest
 class  {  "server::writetestfile":
    content  =>  "test  content",
 }

Slide 59

Slide 59 text

Let’s talk about
 how to do things conditionally

Slide 60

Slide 60 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 External Input in Puppet There are three primary sources of where data that branches your logic will come from: ! • User Space Variables • $things = “you set yourself” • Facts • Specific details about your current environment, such as the name of the host, ip address, operating system, etc... • Hiera • Configuration you pass in to enable building for multiple configurations from the same shared codebase !

Slide 61

Slide 61 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (variables) #  local  variable
 $host  =  "mybox"
 
 if  ($host  ==  "mybox")  {
    notify  {  "Box!":  }
 }
 
 if  ($host  ==  "mybox")  {
    notify  {  "${host}!":  }
 }

Slide 62

Slide 62 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (scope) #  fact  -­‐  environment  configuration
 if  ($hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!


Slide 63

Slide 63 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (variables, facts, scope) #  fact  -­‐  environment  configuration
 if  ($hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!
 if  ($::hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!


Slide 64

Slide 64 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (variables, facts, scope) #  fact  -­‐  environment  configuration
 if  ($hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!
 if  ($::hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!
 #  assign  $hostname  locally...
 $hostname  =  "some  string"


Slide 65

Slide 65 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (variables, facts, scope) #  fact  -­‐  environment  configuration
 if  ($hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!
 if  ($::hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!
 #  assign  $hostname  locally...
 $hostname  =  "some  string"
 if  ($hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  no  output


Slide 66

Slide 66 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (variables, facts, scope) #  fact  -­‐  environment  configuration
 if  ($hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!
 if  ($::hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!
 #  assign  $hostname  locally...
 $hostname  =  "some  string"
 if  ($hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  no  output
 if  ($::hostname  ==  "box")  {  notify  {  "Box!":  }  }                                                                        #  outputs:  Box!


Slide 67

Slide 67 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (facts, debugging) #  what  facts  are  there?  Let’s  find  out!
    
 #  this  should  be  one  line,  but  it  is  too  long  to  fit
 $tmpl  =  "<%=  scope.to_hash.reject  {  |k,v|  !(  k.is_a?
                  (String)  &&  v.is_a?(String)  )  }.to_yaml  %>"
    
 #  create  a  file...
 file  {  "/tmp/facts.yaml":
    content  =>  inline_template($tmlp),
 }

Slide 68

Slide 68 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (facts, debugging, cont…) What values are available? ! architecture, kernelversion, netmask_eth1, rubyversion, operatingsystem, memorysize_mb, processor0, interfaces, uptime, physicalprocessorcount, osfamily, selinux, operatingsystemrelease, ipaddress, and much more…

Slide 69

Slide 69 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (hiera) #  hieradata/common.yml
 thing:  "Something  Special"
 #  modules/server/manifests/writefile.pp
 class  server::writefile  ()  {
    $content  =  hiera('thing')
    file  {  "/tmp/test":
        content  =>  $content
    }
 }

Slide 70

Slide 70 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (hiera, really neat) #  hieradata/common.yml
 server::writefile::content:  "Something  Special"
 #  modules/server/manifests/writefile.pp
 class  server::writefile  ($content  =  "")  {
    file  {  "/tmp/test":
        content  =>  $content
    }
 }

Slide 71

Slide 71 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (if conditionals) if  ("a"  ==  "b")  {
    notify  {  "Inconceivable!":  }
 }  elsif  ("hello"  =~  "help")  {
    notify  {  "Regex!":  }
 }  else  {
    notify  {  "Echo  something...":  }
 }

Slide 72

Slide 72 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (case conditionals) #  $::operatingsystem  is  a  fact,  provided  by  Facter
 case  $::operatingsystem  {
    centos,  redhat:  {  $apache  =  "httpd"  }
    debian,  ubuntu:  {  $apache  =  "apache2"  }
    default:  {  fail("Unrecognized  operating  system")  }
 }
 
 case  $::operatingsystem  {
    /linux/:  {  fail("We  don’t  support  Linux!”)  }
 }

Slide 73

Slide 73 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Puppet Manifest (selector conditionals) #  $::operatingsystem  is  a  fact,  provided  by  Facter
 $package  =  $::operatingsystem  ?  {
    centos  =>  "httpd",
    redhat  =>  "httpd",
    /(i?)(ubuntu|debian)/  =>  "apache2",
    default  =>  undef
 }

Slide 74

Slide 74 text

Let’s talk about
 real multiple guest configuration

Slide 75

Slide 75 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Define our guest nodes (Vagrantfile) nodes  =  {
        'web'  =>  {
                :hostname  =>  'web-­‐server.example.com',
                :ipAddress  =>  '192.168.56.60',
        },
        'db'  =>  {
                :hostname  =>  'db-­‐server.example.com',
                :ipAddress  =>  '192.168.56.61',
        }
 }

Slide 76

Slide 76 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Define our guest nodes (Vagrantfile) nodes  =  {  /*  ...  node  definition  ...  */  };


Slide 77

Slide 77 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Tell Vagrant about them (Vagrantfile) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        hostname  =  options[:hostname]
        ipAddy  =  options[:ipAddress]
        config.vm.define  name  do  |node|
            node.vm.box  =  "base-­‐box-­‐name"
            node.vm.box_url  =  "http://some/url.box"
            node.vm.hostname  =  hostname
            node.vm.network  :private_network,  ip:  ipAddy
        end
    end
 end

Slide 78

Slide 78 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Tell Vagrant about them (Vagrantfile) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        config.vm.define  name  do  |node|
            /*  ...  basic  node  configuration  ...  */   ! ! ! ! !        end
    end
 end

Slide 79

Slide 79 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Tell Vagrant about them (Vagrantfile) nodes  =  {  /*  ...  node  definition  ...  */  };
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,  options|
        config.vm.define  name  do  |node|
            /*  ...  basic  node  configuration  ...  */   ! ! ! ! !        end
    end
 end

Slide 80

Slide 80 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 nodes  =  {  /*  ...  node  definition  ...  */  }
 Vagrant.configure("2")  do  |config|
    nodes.each_pair  do  |name,options|
        config.vm.define  name  do  |node|
            /*  ...  basic  node  configuration  ...  */              node.vm.provision  :puppet  do  |puppet|
                puppet.manifests_path  =  "manifests/"
                puppet.manifest_file    =  "init.pp"
                puppet.module_path  =  "modules/"
            end          end
    end
 end Tell Vagrant about Puppet (Vagrantfile)

Slide 81

Slide 81 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Tell Puppet about the guest nodes #  file:  manifests/init.pp
 if  ($::hostname  ==  "web-­‐1.example.com")  {
    #  only  run  for  web  server
 }
 
 if  ($::hostname  ==  "db-­‐1.example.com")  {
    #  only  run  for  db  server
 }

Slide 82

Slide 82 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Tell Puppet about the guest nodes (redux) #  file:  manifests/init.pp
 if  ($::hostname  =~  /^web-­‐/)  {
    #  only  run  for  web  servers
 }
 
 if  ($::hostname  =~  /^db-­‐/)  {
    #  only  run  for  db  servers
 }

Slide 83

Slide 83 text

Let’s talk about
 how everything ties together

Slide 84

Slide 84 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Shell Scripts Puppet Chef Ansible VirtualBox VMWare (WS or Fusion) Parallels Desktop Amazon AWS Digital Ocean Vagrant Architecture ! Providers ! Provisioners ! Vagrant

Slide 85

Slide 85 text

Let’s talk about
 how to convince your boss

Slide 86

Slide 86 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Where do you develop your code?

Slide 87

Slide 87 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Production?

Slide 88

Slide 88 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Not Production?

Slide 89

Slide 89 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 “My Computer?”

Slide 90

Slide 90 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 “Development”

Slide 91

Slide 91 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 A Development Environment

Slide 92

Slide 92 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Why developing in production is really bad Assuming, of course, that you are testing your code before you make it live. Production should always move from one stable version of code to another stable version of code. When you edit code in production, you inherently introduce instability, and can no longer be assured that your code is running as tested.

Slide 93

Slide 93 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Why developing on a non production setup is also bad Debugging environmental issues is slow and painful. Developers should be solving problems that are in your software, not debugging configuration issues in your environment. When you build your code in an environment that isn’t related to production in any tangible way, you will often have constant reminders just how different your development environment is from production.

Slide 94

Slide 94 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Where your development environment lives Remote • Easy for operations to set up • Easy to enforce a rigid structure • Limits developer’s choice of tool chain selection • Can get expensive and complicated to maintain • Developers must be online to do any development Local • Can require beefier hardware • Can take extra work to set up • Developers have the freedom to work how they work best • Developers can assist with infrastructural initiatives

Slide 95

Slide 95 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Bad development environments will sap the resources out of your team. In addition to the time spent developing and testing new code and fixing bugs, you will spend time: When development environments attack Debugging broken environments or settings Debugging broken behavior between dev and prod Debugging broken behavior between two dev systems Working in broken ways because “it works”

Slide 96

Slide 96 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 If your development environments do not properly mirror production, you won’t know if your code really works until you make it live.

Slide 97

Slide 97 text

Let’s talk about
 what you should remember

Slide 98

Slide 98 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Takeaways • Bad (or unstable) environments (be it dev, qa, staging, or prod) hurt developers.

Slide 99

Slide 99 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Takeaways • Bad (or unstable) environments (be it dev, qa, staging, or prod) hurt developers. • Puppet lets you automate all of the configuration of your systems (dev, qa, staging, and prod), ensuring consistency between them.

Slide 100

Slide 100 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Takeaways • Bad (or unstable) environments (be it dev, qa, staging, or prod) hurt developers. • Puppet lets you automate all of the configuration of your systems (dev, qa, staging, and prod), ensuring consistency between them. • Vagrant is easy to use, and will let you use your production puppet configs to build development environments.

Slide 101

Slide 101 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Takeaways • Bad (or unstable) environments (be it dev, qa, staging, or prod) hurt developers. • Puppet lets you automate all of the configuration of your systems (dev, qa, staging, and prod), ensuring consistency between them. • Vagrant is easy to use, and will let you use your production puppet configs to build development environments. • You will manage server configuration, whether you decide to or not. If you choose not to do it formally it will come back to bite you when you forget something later.

Slide 102

Slide 102 text

Let’s talk about
 where to go from here

Slide 103

Slide 103 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 If you’re still not sold... h"p://PuPHPet.com/ / PuPHPet/provides/a/ simple/config/tool/for/ those/who/don’t/want/ to/=nker/with/puppet/ and/need/a/LAMP/stack/ up/and/running/NOW./

Slide 104

Slide 104 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 And also look at... • Packer • http://packer.io • Take your Vagrant and Puppet usage to the next level by using Packer to pre-provision images for easy first spins • Build prebuilt systems for multiple VMS and cloud platforms • Docker • http://docker.io • A different idea of how to build multiple machine VM environments

Slide 105

Slide 105 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 And don’t forget... • Vagrant and Puppet Git Repository • https://github.com/jmather/vagrant-and-puppet

Slide 106

Slide 106 text

Stabilize your environment, stabilize your code - MidwestPHP - March 16th, 2014 Thank you! More information about this talk can be found at: ! http://bit.ly/midwestphp-stabilize ! RATE MY TALK AT: https://joind.in/10567 ! PLEASE LEAVE FEEDBACK It’s the only way I can improve