Cooking Perl with Chef: Hello World Tutorial Page 2Step 1: Provision a virtual machineCreate a directory to hold your configuration management files. Its a good idea to keep files in such adirectory under version control using git or a similar program, so youll see that in the examplecommands. Here, we create it under $HOME. If you create it somewhere else, remember to adjust forthat later in the tutorial. $ cd $HOME $ mkdir hw-tutorial $ cd hw-tutorial $ git initIf you have not already downloaded a Vagrant virtual machine when you installed and tested Vagrant,do so now1: $ vagrant box add lucid32 http://files.vagrantup.com/lucid32.boxCreate a Vagrant configuration file and commit it to the repo: $ vagrant init lucid32 $ git add Vagrantfile $ git commit -m "added Vagrantfile"Open the Vagrant config file with your preferred editor, and edit the config.vm.forward_port settingthat forwards local port 8080 to port 80 of the virtual machine. Uncomment it and change it to forward8080 to 8080 so that later well be able to connect to the Hello World application on localhost port8080.2 The resulting diff is shown below: $ vim Vagrantfile ... edit the file ... $ git diff diff --git a/Vagrantfile b/Vagrantfile index 840f77c..98b5e9a 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -29,7 +29,7 @@ Vagrant::Config.run do |config| # Forward a port from the guest to the host, which allows for outside # computers to access the VM, whereas host only networking does not. - # config.vm.forward_port 80, 8080 + config.vm.forward_port 8080, 8080 # Share an additional folder to the guest VM. The first argument is # an identifier, the second is the path on the guest to mount the1 This tutorial was written before Ubuntu Precise LTS was available as a Vagrant box. That box may work, but has not been tested.2 If port 8080 is already in use on your machine, use a different, available port number instead
Cooking Perl with Chef: Hello World Tutorial Page 3Then commit that change, launch the Vagrant virtual machine, and check that you can log into it withVagrants SSH command. After successfully connecting to the virtual machine, exit from ssh. $ git commit -am "Enabled port forwarding" $ vagrant up ... wait for it to boot ... $ vagrant ssh vagrant@lucid32:~$ exitWhen Vagrant launches the machine, it will also create a .vagrant file that youll probably want git toignore: $ echo .vagrant > .gitignore $ git add .gitignore && git commit -m "ignore .vagrant"Congratulations! You have a virtual machine ready to configure.Step 2: Prepare Pantry to manage Chef SoloThis tutorial uses Pantry and Chef Solo to configure the virtual machine and deploy the Hello Worldapplication. Pantry manages your Chef configuration and deploys it to the virtual machine.3Pantry will use SSH to communicate with your server, so you need to ensure that you can SSH to itdirectly, without using the Vagrant command line. Youll do that by adding the Vagrant SSH privatekey to your SSH agent and connecting to port 2222 (which Vagrant forwards to port 22 of the virtualmachine). Github users should read an important footnote.4Once the connection succeeds, look around if youd like and then exit out of ssh. $ ssh-add ~/.vagrant.d/insecure_private_key $ ssh vagrant@localhost -p 2222 vagrant@lucid32:~$ exitNow youre ready to initialize Pantry: $ pantry initThis will create several directories to hold your Chef configuration files and cookbooks.3 If you know Vagrant well, you may wonder why we use Pantry instead of Chef Solo support built into Vagrant. Pantry is a more general solution, and the techniques shown here apply exactly the same whether deploying to a local Vagrant machine or to a remote physical or virtual server.4 Youll want to use ssh-add to remove the Vagrant insecure key from the SSH agent when youre done with the tutorial or Github will reject you as unauthorized, even if you also have a valid Github key. This is a bizarre failing in either ssh- agent or Githubs SSH server.
Cooking Perl with Chef: Hello World Tutorial Page 4Next, use Pantry to create a JSON node file to hold the configuration for your virtual machine, andcommit that to your repository. $ pantry create node vagrant --host localhost --port 2222 --user vagrant $ git add environments $ git commit -m "create node file for vagrant server"These commands create the configuration for a node named "vagrant". Since Vagrant runs onlocalhost, forwards SSH via port 2222, and the SSH key it provides is for the vagrant user, we need tobe explicit with those parameters. For a "real" server, the node name would be the fully-qualifieddomain name and you can omit those extra parameters. The default user name is root, and Pantry willuse sudo instead if you override that with a non-root user.Good job! Now that Pantry is set up, youre ready to configure your node for Hello World.Step 3. Get Hello World cookbook and dependenciesChef implements configuration scripts and related data in the form of "cookbook" directories. For thistutorial, youll need four cookbooks: • Hello World • Perlbrew • Carton • RunitThese are available from various git repositories. Youll need to check them out into separatedirectories and then copy the relevant files into the cookbooks directory that Pantry created. $ cd $HOME $ mkdir cookbook-repos $ cd cookbook-repos $ git clone git://github.com/dagolden/zzz-hello-world.git $ git clone git://github.com/dagolden/perl-chef.gitNote that the Perl Chef repository contains both the Perlbrew and Carton cookbooks.The Runit cookbook is a little different — you need the CHEF-154 branch of my own Runit repository,which addresses some particular bugs and hasnt yet been merged to the master Opscode branch. Plus,the cookbook files are in the top level directory, so you have to omit the .git directory later when youcopy it. $ git clone git://github.com/dagolden/runit.git -b CHEF-154Lets take some time to examine the Hello World application and some of the files inside. $ cd zzz-hello-world $ ls
Cooking Perl with Chef: Hello World Tutorial Page 5Notice the carton.lock file — this contains a frozen set of Perl module dependencies for use with theCarton tool (c.f. https://metacpan.org/module/Carton). Notice also the app.psgi file — this is the webapplication itself.The cookbook directory contains the Chef cookbook for deploying this application with Chef. Look atthe metadata.rb file; it shows that this cookbook depends on the carton cookbook, which is why wevechecked that out as well. (Carton, in turn, depends on Perlbrew and Runit.) Look at the README.mdfile for some bare-bones description; note the list of default configuration attributes available. Thosecan be modified for a given node using Pantry, as well see later in this tutorial. $ cd cookbook/hello-world $ more metadata.rb $ more README.mdYoull probably want to examine the other files later to see how they work and how to adapt them foryour own needs, but for now, youll want to copy the relevant cookbooks to your Pantry cookbookdirectory. (Remember that we have to strip the .git directory from runit.) $ cd $HOME/cookbook-repos $ cp -a zzz-hello-world/cookbook/hello-world $HOME/hw-tutorial/cookbooks $ cp -a perl-chef/cookbooks/carton $HOME/hw-tutorial/cookbooks $ cp -a perl-chef/cookbooks/perlbrew $HOME/hw-tutorial/cookbooks $ rsync -a --exclude=.git runit $HOME/hw-tutorial/cookbooksNow that youve copied all the cookbooks to your Pantry, you should check them in to version control. $ cd $HOME/hw-tutorial $ git add cookbooks $ git commit -m "added hello-world, carton, perlbrew, runit cookbooks"Excellent! Now youre ready to configure the Vagrant node you created to use those cookbooks.Step 4. Configure virtual machine for Hello WorldThere are two parts to configuring the Vagrant node with Pantry. First, you need to add the HelloWorld recipe (from the Hello World cookbook) to the run-list for the node. Second, you need tomodify any configuration settings. In this case, rather than running the default Perl v5.16, lets rununder the previous stable version instead: $ pantry apply node vagrant --recipe hello-world $ pantry apply node vagrant --default hello-world.perl_version=perl-5.14.2 $ git commit -a -m "configured hello world on vagrant node"You can see the resulting configuration with the show command: $ pantry show node vagrantThats it! Your configuration is done.
Cooking Perl with Chef: Hello World Tutorial Page 6Step 5. Deploy and testTo deploy the configuration to the node, run the sync command: $ pantry sync node vagrantThis first run will take a very long time because Chef Solo must compile a fresh copy of Perl in anisolated directory under /opt, then install all the Hello World dependencies in an isolated local library aswell. Because Vagrant gives you a virtual machine with a single processor allocated and very littleRAM, this is slow!So be patient, get a favorite beverage, have mock swordfights or whatever suits you, and wait until itsdone. If youre worried about progress, "vagrant ssh" into the server and tail the perlbrew build file(youll see instructions on screen about it).Assuming there are no errors during the run, you should now be able to browse to localhost:8080 andsee a short web page from the Hello World application.If it didnt work, check Appendix II for some troubleshooting tips.)Congratulations! You did it!If youd like, log into the Vagrant box and look in /opt/perlbrew, /opt/hello-world and /etc/sv/hello-world to see the files that were deployed.Dont forget to shut down the vagrant box when youre done. Destroy it if youd like to reclaim thespace it used. $ vagrant halt $ vagrant destroy
Cooking Perl with Chef: Hello World Tutorial Page 7APPENDIX I: Preparing your own virtual machineIf you would like to use your own virtual machine or other server, you must ensure that Chef 10.4 orhigher is installed. You will either need a root user with SSH access or a non-root user with SSHaccess that is authorized to run sudo. You will need to ensure that the firewall allows access to the SSHport and to port 8080.With the exception of creating a directory and initializing git, you can skip Step 1. In Step 2, modifythe "pantry create" command as appropriate for your server. For a root user and using the standardSSH port, the "pantry create" command only needs the fully qualified hostname. $ pantry create node server.example.netAs a nice convenience, Pantry lets you later refer to that node using any unique subset of the name (e.g."server"). Youll want to use that to refer to the node wherever a pantry command in the tutorial refersto "vagrant".APPENDIX II: TroubleshootingIm sorry that things arent working for you. Your system might be too different than the one I used towrite this tutorial, in which case it might never work ☹. Or maybe you just missed step or a detailalong the way. Here are some things to check, based on problems I had when writing the tutorial: • Check that youre running only one Vagrant box with vboxmanage list runningvms • Check that VirtualBox is forwarding the ports you expect (2222 and 8080) with sudo lsof -i • Check that your Vagrantfile is configured to forward port 8080 (local) to port 8080 (remote) • Check that your Runit cookbook is from the CHEF-154 branch from the dagolden repository on githubWhen I found problems, I found it easiest to start the tutorial over with a fresh Vagrant machine.If those tips dont help you debug it, feel free to email me at firstname.lastname@example.org and tell me whatshappening. I cant promise a fix, but I do promise to read it and get back to you one way or another.Check out http://perlchef.com/ for updates or additional resources.