7

Click here to load reader

Cooking Perl with Chef: Hello World Tutorial

Embed Size (px)

DESCRIPTION

This tutorial provides a command-by-command walk-through for deploying a simple Perl web application using the Chef configuration management tool.

Citation preview

Page 1: Cooking Perl with Chef: Hello World Tutorial

Cooking Perl with ChefHello World Tutorial

Copyright © 2012 by David A. GoldenThis work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License

Tutorial Version 1.2http://perlchef.com/

Abstract

This tutorial provides a command-by-command walk-through for deploying a simple Perl web application using the Chef configuration management tool. Prerequisites for this tutorial

This tutorial was written with Unix operating systems in mind and was tested using Ubuntu Linux 11.10. You will need to be familiar with Perl, CPAN, git and common Unix tools like ssh and rsync. You will need an Internet connection to download files during this tutorial.

The tutorial uses Vagrant to provide a virtual machine for deployment. Vagrant in turn requires Virtualbox. You should install Virtualbox for your operating system, then install Vagrant. To do so, go to http://vagrantup.com/. Download and install the software. Add "/opt/vagrant/bin" to PATH. See the "getting started docs" on the site. (If you are violently opposed to Vagrant, see Appendix I for tips on configuring your own server to work with the tutorial.) You'll need plenty of disk space and memory to run the virtual machine.

You will also need to install the Pantry tool, which is available on CPAN. Install it using your preferred CPAN client.

Note that you won't need Chef installed on your own machine. You only need it on the virtual machine you are deploying to and the Vagrant box you will use for this tutorial has it pre-installed.

Introduction and overview

This tutorial is broken up into five distinct steps:

• Set up a Vagrant virtual machine• Prepare Pantry to manage Chef Solo• Get Hello World cookbook and dependencies• Configure virtual machine for Hello World• Deploy and test

Appendix II contains some troubleshooting tips if you have problems.

You can contact the author with praise, critique or questions at [email protected] or as @xdg on various social networks. A screencast demonstration based on this tutorial is available athttp://youtu.be/H93rt-KtwBE

Page 2: Cooking Perl with Chef: Hello World Tutorial

Cooking Perl with Chef: Hello World Tutorial Page 2

Step 1: Provision a virtual machine

Create a directory to hold your configuration management files. It's a good idea to keep files in such a directory under version control using git or a similar program, so you'll see that in the example commands. Here, we create it under $HOME. If you create it somewhere else, remember to adjust for that later in the tutorial.

$ cd $HOME$ mkdir hw-tutorial$ cd hw-tutorial$ git init

If 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.box

Create 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' setting that forwards local port 8080 to port 80 of the virtual machine. Uncomment it and change it to forward 8080 to 8080 so that later we'll be able to connect to the Hello World application on localhost port 8080.2 The resulting diff is shown below:

$ vim Vagrantfile ... edit the file ...$ git diffdiff --git a/Vagrantfile b/Vagrantfileindex 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 the

1 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

Page 3: Cooking Perl with Chef: Hello World Tutorial

Cooking Perl with Chef: Hello World Tutorial Page 3

Then commit that change, launch the Vagrant virtual machine, and check that you can log into it with Vagrant's 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 sshvagrant@lucid32:~$ exit

When Vagrant launches the machine, it will also create a .vagrant file that you'll probably want git to ignore:

$ 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 Solo

This tutorial uses Pantry and Chef Solo to configure the virtual machine and deploy the Hello World application. Pantry manages your Chef configuration and deploys it to the virtual machine.3

Pantry will use SSH to communicate with your server, so you need to ensure that you can SSH to it directly, without using the Vagrant command line. You'll do that by adding the Vagrant SSH private key to your SSH agent and connecting to port 2222 (which Vagrant forwards to port 22 of the virtual machine). Github users should read an important footnote.4

Once the connection succeeds, look around if you'd like and then exit out of ssh.

$ ssh-add ~/.vagrant.d/insecure_private_key$ ssh vagrant@localhost -p 2222vagrant@lucid32:~$ exit

Now you're ready to initialize Pantry:

$ pantry init

This 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 You'll want to use ssh-add to remove the Vagrant insecure key from the SSH agent when you're 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 Github's SSH server.

Page 4: Cooking Perl with Chef: Hello World Tutorial

Cooking Perl with Chef: Hello World Tutorial Page 4

Next, use Pantry to create a JSON node file to hold the configuration for your virtual machine, and commit 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 on localhost, forwards SSH via port 2222, and the SSH key it provides is for the 'vagrant' user, we need to be explicit with those parameters. For a "real" server, the node name would be the fully-qualified domain name and you can omit those extra parameters. The default user name is 'root', and Pantry will use sudo instead if you override that with a non-root user.

Good job! Now that Pantry is set up, you're ready to configure your node for Hello World. Step 3. Get Hello World cookbook and dependencies

Chef implements configuration scripts and related data in the form of "cookbook" directories. For this tutorial, you'll need four cookbooks:

• Hello World• Perlbrew• Carton• Runit

These are available from various git repositories. You'll need to check them out into separate directories 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.git

Note 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 hasn't 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 you copy it.

$ git clone git://github.com/dagolden/runit.git -b CHEF-154

Let's take some time to examine the Hello World application and some of the files inside.

$ cd zzz-hello-world$ ls

Page 5: Cooking Perl with Chef: Hello World Tutorial

Cooking Perl with Chef: Hello World Tutorial Page 5

Notice the carton.lock file — this contains a frozen set of Perl module dependencies for use with the Carton tool (c.f. https://metacpan.org/module/Carton). Notice also the app.psgi file — this is the web application itself.

The cookbook directory contains the Chef cookbook for deploying this application with Chef. Look at the metadata.rb file; it shows that this cookbook depends on the 'carton' cookbook, which is why we've checked that out as well. (Carton, in turn, depends on Perlbrew and Runit.) Look at the README.md file for some bare-bones description; note the list of default configuration attributes available. Those can be modified for a given node using Pantry, as we'll see later in this tutorial.

$ cd cookbook/hello-world$ more metadata.rb$ more README.md

You'll probably want to examine the other files later to see how they work and how to adapt them for your own needs, but for now, you'll want to copy the relevant cookbooks to your Pantry cookbook directory. (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/cookbooks

Now that you've 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 you're ready to configure the Vagrant node you created to use those cookbooks.

Step 4. Configure virtual machine for Hello World

There are two parts to configuring the Vagrant node with Pantry. First, you need to add the Hello World recipe (from the Hello World cookbook) to the run-list for the node. Second, you need to modify any configuration settings. In this case, rather than running the default Perl v5.16, let's run under 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 vagrant

That's it! Your configuration is done.

Page 6: Cooking Perl with Chef: Hello World Tutorial

Cooking Perl with Chef: Hello World Tutorial Page 6

Step 5. Deploy and test

To deploy the configuration to the node, run the 'sync' command:

$ pantry sync node vagrant

This first run will take a very long time because Chef Solo must compile a fresh copy of Perl in an isolated directory under /opt, then install all the Hello World dependencies in an isolated local library as well. Because Vagrant gives you a virtual machine with a single processor allocated and very little RAM, this is slow!

So be patient, get a favorite beverage, have mock swordfights or whatever suits you, and wait until it's done. If you're worried about progress, "vagrant ssh" into the server and tail the perlbrew build file (you'll see instructions on screen about it).

Assuming there are no errors during the run, you should now be able to browse to localhost:8080 and see a short web page from the Hello World application.

If it didn't work, check Appendix II for some troubleshooting tips.)

Congratulations! You did it!

If you'd 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.

Don't forget to shut down the vagrant box when you're done. Destroy it if you'd like to reclaim the space it used.

$ vagrant halt$ vagrant destroy

Page 7: Cooking Perl with Chef: Hello World Tutorial

Cooking Perl with Chef: Hello World Tutorial Page 7

APPENDIX I: Preparing your own virtual machine

If you would like to use your own virtual machine or other server, you must ensure that Chef 10.4 or higher is installed. You will either need a root user with SSH access or a non-root user with SSH access that is authorized to run sudo. You will need to ensure that the firewall allows access to the SSH port and to port 8080.

With the exception of creating a directory and initializing git, you can skip Step 1. In Step 2, modify the "pantry create" command as appropriate for your server. For a root user and using the standard SSH port, the "pantry create" command only needs the fully qualified hostname.

$ pantry create node server.example.net

As a nice convenience, Pantry lets you later refer to that node using any unique subset of the name (e.g. "server"). You'll want to use that to refer to the node wherever a pantry command in the tutorial refers to "vagrant".

APPENDIX II: Troubleshooting

I'm sorry that things aren't working for you. Your system might be too different than the one I used to write this tutorial, in which case it might never work . Or maybe you just missed step or a detail☹ along the way. Here are some things to check, based on problems I had when writing the tutorial:

• Check that you're 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

github

When I found problems, I found it easiest to start the tutorial over with a fresh Vagrant machine.

If those tips don't help you debug it, feel free to email me at [email protected] and tell me what's happening. I can't 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.