Install Xcode on your workstation
If you haven't already, install Xcode using your OS X install disc or by downloading it from here.
First, check to see if your operating system already has RubyGems 1.3.5+ installed by running the following:
$ gem -v
1.3.5
Skip to "Installing Chef"
If you are on Debian or Ubuntu Linux, we recommend you install RubyGems from source as described "If you do not have RubyGems at all" in the next section.
Otherwise, run the following:
$ sudo gem update --system
To upgrade to the latest version of RubyGems.
If your OS doesn’t ship with RubyGems, we recommend installing RubyGems from source.
$ cd /tmp
$ wget http://rubyforge.org/frs/download.php/70696/rubygems-1.3.7.tgz
$ tar zxf rubygems-1.3.7.tgz
$ cd rubygems-1.3.7
$ sudo ruby setup.rb
You can then verify that your installation was successful with:
$ gem -v
1.3.7
Use RubyGems to install Chef:
$ sudo gem install chef
You can verify the installation was successful with:
$ chef-client -v
Chef: 0.9.0
Building infrastructure with Chef is like managing source code. As such, working with Chef is much like any other new software project - your first steps are to build a repository to hold your source code. The best practice in the Chef community is to utilize Git for source code control of this repository, and this tutorial will have you interacting with it.
Check to see that Git is installed on your workstation:
$ git --version
git version 1.7.1
If the above command does not work, the fine folks at GitHub have excellent instructions for installing Git on a huge number of operating systems. Head over there now, and we'll be here when you get back.
Building infrastructure with Chef is like managing source code, so one of the first things we need to do is build the repository you'll use. If you have git
installed, do the following:
$ cd ~
$ git clone http://github.com/opscode/chef-repo.git
Otherwise, download the tarball. The file retrieved from the github URL will be named opscode-chef-repo-SHA.tar.gz, where SHA is the latest commit's SHA hash, and this will be in the resulting directory when untarred, too.
$ cd ~
$ wget http://github.com/opscode/chef-repo/tarball/master
$ tar zxvf opscode-chef-repo-*.tar.gz
$ mv opscode-chef-repo-SHA chef-repo
Chef's command line tool, Knife, reads its configuration from .chef
directories. We recommend you configure knife to always connect you to the Opscode Platform when you are in your chef-repo
directory.
$ mkdir -p ~/chef-repo/.chef
Copy the keys and knife configuration you downloaded earlier into this directory:
$ cp USERNAME.pem ~/chef-repo/.chef
$ cp ORGANIZATION-validator.pem ~/chef-repo/.chef
$ cp knife.rb ~/chef-repo/.chef
Replace USERNAME above with your Opscode Platform Username, and ORGANIZATION with the short-name you provided when you signed up.
From now on, whenever you are in the chef-repo
directory, Knife will connect to the Opscode Platform.
You're ready to go! Let's try running a command against the Opscode Platform:
$ cd ~/chef-repo
$ knife client list
[
"ORGANIZATION-validator"
]
Congratulations - you're ready to start building infrastructure with Chef!
In order to get you moving quickly, we're going to start by downloading a published cookbook and using it to write a file on a managed server.
Lets go check out the getting-started cookbook on the cookbooks site. The first thing we're going to do is import this cookbook into our local chef-repo. The best practice in working with the Opscode Platform is to always keep local copies of the cookbooks you are using in your chef-repo.
To import this cookbook:
$ cd ~/chef-repo
$ knife cookbook site vendor getting-started
INFO: Downloading getting-started from the cookbooks site at version 0.1.0
INFO: Cookbook saved: /Users/adam/chef-repo/cookbooks/getting-started.tar.gz
INFO: Checking out the master branch.
INFO: Checking the status of the vendor branch.
INFO: Creating vendor branch.
INFO: Removing pre-existing version.
INFO: Uncompressing getting-started version 0.1.0.
INFO: Adding changes.
INFO: Committing changes.
INFO: Creating tag chef-vendor-getting-started-0.1.0.
INFO: Checking out the master branch.
INFO: Merging changes from getting-started version 0.1.0.
Updating a975703..031081d
Fast-forward
cookbooks/getting-started/README.rdoc | 4 +++
cookbooks/getting-started/metadata.json | 29 ++++++++++++++++++++
cookbooks/getting-started/metadata.rb | 6 ++++
cookbooks/getting-started/recipes/default.rb | 22 +++++++++++++++
.../templates/default/chef-getting-started.txt.erb | 5 +++
5 files changed, 66 insertions(+), 0 deletions(-)
create mode 100644 cookbooks/getting-started/README.rdoc
create mode 100644 cookbooks/getting-started/metadata.json
create mode 100644 cookbooks/getting-started/metadata.rb
create mode 100644 cookbooks/getting-started/recipes/default.rb
create mode 100644 cookbooks/getting-started/templates/default/chef-getting-started.txt.erb
INFO: Cookbook getting-started version 0.1.0 successfully vendored!
This command downloads the getting-started cookbook, and creates a 'vendor branch' for you. For now, all you need to know about this process is that it will enable you to make your own custom changes to the cookbook, keep track of the differences between yours and the upstream.
Cookbooks in Chef contain recipes, which contain lists of resources you want to manage. If you look in ~/chef-repo/cookbooks/getting-started/recipes/default.rb
, you'll see the following:
#
# Cookbook Name:: getting-started
# Recipe:: default
#
# Copyright 2010, Opscode, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
template "/tmp/chef-getting-started.txt" do
source "chef-getting-started.txt.erb"
end
Once you get past the license, you'll see one template resource. It will place a file in /tmp/chef-getting-started.txt
, using the template named chef-getting-started.txt.erb
.
In addition to recipes, cookbooks contain assets that are needed by your recipes - such as files, templates, libraries, and more. In our case, the source template is contained in the cookbook as well. Look at ~/chef-repo/cookbooks/getting-started/templates/default/chef-getting-started.txt.erb
:
Welcome to Chef!
This is Chef version <%= node[:chef_packages][:chef][:version] %>.
Running on <%= node[:platform] %>.
Version <%= node[:platform_version] %>.
Remember all those attributes on your node from the last section? We use several in this template - starting with the version of Chef we have installed, then the OS platform and version we're on. Any of the values you see in a node can be referenced this way, anywhere in Chef.
The first thing you need to do is upload your version of the cookbook to the Opscode Platform - the one we downloaded to your ~/chef-repo. You always have your own copies of every cookbook, since they are used to configure critical parts of your infrastructure.
$ cd ~/chef-repo
$ knife cookbook upload getting-started
INFO: Saving getting-started
INFO: Validating ruby files
INFO: Validating templates
INFO: Syntax OK
INFO: Generating Metadata
INFO: Uploading files
INFO: Uploading /var/folders/+m/+m8eScrGE44c8GqQUMCb-U+++TI/-Tmp-/chef-getting-started-build20100618-85624-1j0yydj-0/getting-started/templates/default/chef-getting-started.txt.erb (checksum hex = b427bb58c76be230865ccfa5217a1f4a) to https://s3.amazonaws.com/opscode-platform-production-data/organization-5a8516776e3647e9986402969be50a18/sandbox-3b16b31de710444da012fcd20c79ad58/checksum-b427bb58c76be230865ccfa5217a1f4a?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1276913564&Signature=67X34B9USfHYtc3lgV3DUVm%2BKdU%3D
INFO: Uploading /var/folders/+m/+m8eScrGE44c8GqQUMCb-U+++TI/-Tmp-/chef-getting-started-build20100618-85624-1j0yydj-0/getting-started/README.rdoc (checksum hex = b5dceb54a25cc705f939d157bdf8d56c) to https://s3.amazonaws.com/opscode-platform-production-data/organization-5a8516776e3647e9986402969be50a18/sandbox-3b16b31de710444da012fcd20c79ad58/checksum-b5dceb54a25cc705f939d157bdf8d56c?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1276913564&Signature=g7rYHJe0siPwg9FZlgk3CvJLWm0%3D
INFO: Uploading /var/folders/+m/+m8eScrGE44c8GqQUMCb-U+++TI/-Tmp-/chef-getting-started-build20100618-85624-1j0yydj-0/getting-started/metadata.json (checksum hex = d36b894e33143c12b640444025098e3a) to https://s3.amazonaws.com/opscode-platform-production-data/organization-5a8516776e3647e9986402969be50a18/sandbox-3b16b31de710444da012fcd20c79ad58/checksum-d36b894e33143c12b640444025098e3a?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1276913564&Signature=nIvNI2UXuXAhVwwhr5Rzf144KcE%3D
INFO: Uploading /var/folders/+m/+m8eScrGE44c8GqQUMCb-U+++TI/-Tmp-/chef-getting-started-build20100618-85624-1j0yydj-0/getting-started/metadata.rb (checksum hex = 0ee39041f2748555089e125beeeb9268) to https://s3.amazonaws.com/opscode-platform-production-data/organization-5a8516776e3647e9986402969be50a18/sandbox-3b16b31de710444da012fcd20c79ad58/checksum-0ee39041f2748555089e125beeeb9268?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1276913564&Signature=oAUV8SCJ9MD%2FsFYjE%2Bw0NmhEAnc%3D
INFO: Uploading /var/folders/+m/+m8eScrGE44c8GqQUMCb-U+++TI/-Tmp-/chef-getting-started-build20100618-85624-1j0yydj-0/getting-started/recipes/default.rb (checksum hex = 1756940127a1dff6904c1b5f2db34519) to https://s3.amazonaws.com/opscode-platform-production-data/organization-5a8516776e3647e9986402969be50a18/sandbox-3b16b31de710444da012fcd20c79ad58/checksum-1756940127a1dff6904c1b5f2db34519?AWSAccessKeyId=AKIAJOZTD2N26S7W6APA&Expires=1276913564&Signature=kV%2BqiN1tntBbvqdO4YgsU20%2BFe4%3D
INFO: Upload complete!
You can verify that the cookbook is ready for use:
$ cd ~/chef-repo
$ knife cookbook list
[
"getting-started"
]
Congratulations! You've just successfully downloaded your first community cookbook and deployed it to your production environment.
Typically, Chef clients will be servers in your infrastructure. If your workstation runs a supported operating system, you may want to use it for this tutorial as this may be easier or more convenient than obtaining a server resource. We'll show both ways.
Please keep in mind, if you choose to run it as a Chef client, your workstation will be wearing two hats: first as a place to work with cookbooks and the Opscode Platform, second as a managed node.
The first step is to generate a configuration file for your Chef Clients with Knife:
$ cd ~/chef-repo
$ knife configure client ./client-config
INFO: Creating client configuration
INFO: Writing client.rb
INFO: Writing validation.pem
You'll now have a client-config directory in your local repository:
$ ls -l client-config
-rw-r--r-- 1 adam staff 155 Jun 18 16:03 client.rb
-rw-r--r--@ 1 adam staff 1679 Jun 18 16:03 validation.pem
To configure your workstation as a chef client, you just need to copy this directory to /etc/chef
:
$ sudo cp -r ~/chef-repo/client-config /etc/chef
Since this is your first time adding a new node to Chef, the node list is empty. Let's verify that:
$ knife node list
[
]
Yep, we have no nodes.
Lets run Chef for the first time on your workstation, and it will create one for us:
$ sudo chef-client
[Fri, 18 Jun 2010 16:05:51 -0700] INFO: Client key /etc/chef/client.pem is not present - registering
[Fri, 18 Jun 2010 16:05:58 -0700] WARN: HTTP Request Returned 404 Not Found: Cannot load node latte
[Fri, 18 Jun 2010 16:05:58 -0700] INFO: Starting Chef Run
[Fri, 18 Jun 2010 16:06:08 -0700] WARN: Node latte has an empty run list.
[Fri, 18 Jun 2010 16:06:12 -0700] INFO: Chef Run complete in 13.309816 seconds
[Fri, 18 Jun 2010 16:06:12 -0700] INFO: Running report handlers
[Fri, 18 Jun 2010 16:06:12 -0700] INFO: Report handlers complete
If we look now, we'll see your workstation is in the node list:
$ knife node list
[
"latte"
]
You have finished configuring your workstation as a chef client and can skip ahead to "Exploring the information" below or set up another server as node.
For this tutorial, we'll show brief instructions on how to use knife bootstrap
to automatically install chef on a server, VM, or cloud instance with the following OS options:
- centos5
- fedora13
- ubuntu10.04
Full install documentation for all supported operating systems is available on the wiki.
You will need to prepare the server by installing the base OS and configuring ssh. As we will need superuser privileges, you can choose to provide either remote ssh as root or remote ssh to a non-root user with passwordless sudo. We recommend using ssh keys and ssh-agent to help you manage all the auth components, rather than entering passwords on the commandline. Fully automated provisioning from several public cloud providers is possible but a bit more involved.
Now you can use the knife boostrap command to get Chef client installed on the target system. Replace NODE with the reachable hostname of the server you want to manage, and DISTRO with centos5-gems
, fedora13-gems
, or ubuntu10.04-gems
, depending on the distro you've chosen.
$ cd ~/chef-repo
$ knife bootstrap NODE --distro DISTRO
Or, if you've chosen to use a non-root user and sudo (as does ubuntu by default), add -x USERNAME --sudo
as in this example:
$ cd ~/chef-repo
$ knife bootstrap NODE --distro DISTRO -x ubuntu --sudo
Problems usually arise with authentication or network connectivity, so be sure to test ssh in context with the specific user and settings first.
You will see copious output from this command. When the bootstrap is complete, the bootstrapped node will:
- have the latest Chef version installed
- be validated with your organization of the Opscode Platform
- have run
chef-client
with an empty run list.
You have finished configuring a server as a chef client!
To see all the data we collected about your node:
$ knife node show YOURNODE
In the output above, "latte" is my workstation. You should replace YOURNODE with whatever the name is you see when you run knife node list
The output of this command is a JSON representation of your node, and while it's very nifty, it's a bit hard to take in all at once.