<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Cognizant Transmutation &#187; Scalable Deployment</title>
	<atom:link href="http://blog.ibd.com/category/scalable-deployment/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ibd.com</link>
	<description>Internet Bandwidth Development: Composting the Internet for over Two Decades</description>
	<lastBuildDate>Fri, 03 Feb 2012 06:44:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Avoiding a series of tests with Ruby Hashes of Hashes that might have nil before the leaf hash</title>
		<link>http://blog.ibd.com/ruby-rails/avoiding-a-series-of-tests-with-hashes-of-hashes-that-might-have-nil-before-the-leaf-hash/</link>
		<comments>http://blog.ibd.com/ruby-rails/avoiding-a-series-of-tests-with-hashes-of-hashes-that-might-have-nil-before-the-leaf-hash/#comments</comments>
		<pubDate>Thu, 04 Aug 2011 05:41:11 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[Opscode Chef]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Chef]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=805</guid>
		<description><![CDATA[<p>I&#8217;m mostly using Ruby to write Opscode Chef Cookbooks. There are a lot of hashes of hashes that contain attributes or Data Bags. Things that look like:</p> app['rds_database'][environment]['rds_name'] <p>If I wanted to test if this value is set I couldn&#8217;t safely just say:</p> if app['rds_database'][environment]['rds_name'] <p>because in some cases</p> if app['rds_database'] <p>or</p> if app['rds_database'][environment] [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m mostly using Ruby to write <a href="http://www.opscode.com/" target="_blank">Opscode </a>Chef <a href="http://wiki.opscode.com/display/chef/Cookbooks" target="_blank">Cookbooks</a>. There are a lot of hashes of hashes that contain <a href="http://wiki.opscode.com/display/chef/Attributes" target="_blank">attributes</a> or <a href="http://wiki.opscode.com/display/chef/Data+Bags" target="_blank">Data Bags</a>. Things that look like:</p>
<pre class="brush: ruby; title: ; notranslate">app['rds_database'][environment]['rds_name']</pre>
<p>If I wanted to test if this value is set I couldn&#8217;t safely just say:</p>
<pre class="brush: ruby; title: ; notranslate">if app['rds_database'][environment]['rds_name']</pre>
<p>because in some cases</p>
<pre class="brush: ruby; title: ; notranslate">if app['rds_database']</pre>
<p>or</p>
<pre class="brush: ruby; title: ; notranslate">if app['rds_database'][environment]</pre>
<p>may be nil .</p>
<p>If ether of those were nil and I execute</p>
<pre class="brush: ruby; title: ; notranslate">if app['rds_database'][environment]['rds_name']</pre>
<p>I would get an exception like:</p>
<pre class="brush: plain; title: ; notranslate">NoMethodError: undefined method `[]' for nil:NilClass</pre>
<p>I have been doing something like:</p>
<pre class="brush: ruby; title: ; notranslate">if app['rds_database'] &amp;&amp; app['rds_database'][environment] &amp;&amp; app['rds_database'][environment]['rds_name']</pre>
<p>But that was starting to make me sick to my stomach. I like my Ruby fine and DRY</p>
<p>So I scoured the Internet (well googled a bit) and found a couple of good Stack Overflow posts like <a href="http://stackoverflow.com/questions/6334639/how-to-access-an-element-deep-in-an-array-of-arrays-without-getting-undefined-me" target="_blank">How to access an element deep in an array of arrays without getting &#8216;undefined method&#8217; error</a> and <a href="http://stackoverflow.com/questions/4371716/looking-for-a-good-way-to-avoid-hash-conditionals-in-ruby" target="_blank">Looking for a Good Way to Avoid Hash Conditionals in Ruby</a>.</p>
<p>But most of them were ways to Monkey Patch the Hash Object or use new operators that are loaded by Gems.</p>
<p>One of them was pretty simple and was pretty DRY. Though some commentors called it <em>an indiscriminate use of </em> <code>rescue</code> <em>and EEEEVVVVIIILLLLL.</em></p>
<p>But it seems to me to be a very discriminate use of rescue, as any case where the rescue happens, I want it to return nil:</p>
<pre class="brush: ruby; title: ; notranslate">if (app['rds_database'][environment]['rds_name'] rescue nil)</pre>
<p>The parenthesis aren&#8217;t needed, but I think it makes it clearer whats going on. Especially if you say something like:</p>
<pre class="brush: ruby; title: ; notranslate">return unless (app['rds_database'][environment]['rds_name'] rescue nil)</pre>
<p>So I&#8217;m going to give that a try for a while.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/ruby-rails/avoiding-a-series-of-tests-with-hashes-of-hashes-that-might-have-nil-before-the-leaf-hash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Deploy WordPress to Amazon EC2 Micro Instance with Opscode Chef</title>
		<link>http://blog.ibd.com/howto/deploy-wordpress-to-amazon-ec2-micro-instance-with-opscode-chef/</link>
		<comments>http://blog.ibd.com/howto/deploy-wordpress-to-amazon-ec2-micro-instance-with-opscode-chef/#comments</comments>
		<pubDate>Mon, 03 Jan 2011 07:08:16 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Opscode Chef]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[blogging]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[Wordpress]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=599</guid>
		<description><![CDATA[Updates September 9, 2011 <p>Included the latest Chef Knife ec2 server create argument that sets the EBS Volume to not be deleted on the termination of the EC2 Instance</p> Intro <p>Up until recently a friend lent me a Virtual Machine in he Cloud for my Blog. I didn&#8217;t have to do anything to manage [...]]]></description>
			<content:encoded><![CDATA[<h2>Updates</h2>
<h3>September 9, 2011</h3>
<p>Included the latest Chef Knife ec2 server create argument that sets the EBS Volume to not be deleted on the termination of the EC2 Instance</p>
<h2>Intro</h2>
<p>Up until recently a friend lent me a Virtual Machine in he Cloud for my Blog. I didn&#8217;t have to do anything to manage it. But his company is no longer supporting those machines so I had to move my blog.<br />
Right around that time Amazon announced their Micro Instances at a very low price. I also wanted to try out the new Opscode Chef knife commands that bootstrap an EC2 instance from scratch as well as their Chef Server SaaS. So this was a good reason to combine all these to create my new Blog Instance. And now Amazon even offers the ability to have a single micro instance free for a year! (You still have to pay for I/O charges but they are really cheap compared to the instance charges, unless you have a blog that is too popular, but then you&#8217;ll need a bigger server anyway)<br />
<strong>Spoiler Alert:</strong> It was way too easy and no problem at all! (Though I did end up having to write a few support cookbooks like <em>vsftpd</em>, but now you don&#8217;t have to)</p>
<h3>Some Assumptions for this post</h3>
<ul>
<li>You are using a *nix platform for your local development (ie your laptop is a Mac, Linux, *BSD or equivalent) and that your target server you want to deploy to is a relatively recent Ubuntu Linux.</li>
<li>You have or will install git client on your local development box</li>
<li>You followed the directions or have done the equivalent of the instructions in the Opscode <a href="http://help.opscode.com/faqs/start/how-to-get-started" target="_blank">How to Get Started</a> pages as noted below</li>
</ul>
<h2>Set up an Account on Amazon Web Services</h2>
<p>If you don&#8217;t already have an Amazon EC2 Account, go to the <a href="http://aws.amazon.com/" target="_blank">Amazon Web Services</a> page and click on the <a href="http://www.amazon.com/gp/aws/registration/registration-form.html" target="_blank">Sign Up Now button</a>. Create all your user info and then Sign Up for Amazon EC2. You&#8217;ll need to put in  credit card info at this point since you&#8217;ll need to pay for the EC2 instance you&#8217;ll be using shortly. After you complete your signup, you&#8217;ll need to get your credentials at the <a href="http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key" target="_blank">AWS Security Credentials page</a>.  Copy down your Access Key ID and click on Show under the Secret Access Key and get that as well. You will need these values to put into your knife.rb file that you will get to in the following steps.</p>
<h2>Get an Opscode Platform Account</h2>
<p>Its free and easy. Just go to the <a href="https://cookbooks.opscode.com/users/new" target="_blank">Opscode Platform Signup page</a>. Fill in your information and submit. There is no cost for up to 5 client nodes. Once you set up and confirm your account you can go thru the <a href="http://help.opscode.com/faqs/start/how-to-get-started" target="_blank">How to Get Started</a> pages which includes how to set up your client development machine (installing Chef Client, Knife and various dependencies) as well as downloading your private key, organization key and your Knife Configuration File. You should go thru all 5 steps of the Getting Started section. And please do follow their examples of using git. The rest of this post assumes you have git installed and will use it for your own repository even if you don&#8217;t push it to an upstream git repository.</p>
<p>Once you have completed that you will be ready to use the remaining steps of this blog post. The remaining steps will assume you put your chef-repo in the same location as the Opscode instructions suggested (~/chef-repo). If you put it somewhere else, just adjust your path to your chef-repo as appropriate.</p>
<p>It also assumes you got your private user key (<em>your_user_name.pem</em>) and organization validator key (<em>your_organization-validator.pem</em>) and knife.rb in Section 3 of How to Get Started: <a href="http://help.opscode.com/faqs/start/chef-client" target="_blank">Setting Up a Chef Client</a>. In that section you ran the command <code>knife configure client ./client-config</code> inside your ~/chef-repo/ directory. That will have created ~/chef-repo/.chef and put the keys and knife.rb in that directory.</p>
<p>For the use of this blog post, we will use the username: <em>rberger_test</em> and organization name: <em>install_wordpress</em>. So the private user key name for this example will be: <em>rberger_test.pem</em> and the organization validator key will be called <em>install_wordpress-validator.pem.</em> You should copy your keys someplace that you will not loose outside of ~/chef-repo. There are ways to <a title="Create a new private user key" href="http://help.opscode.com/faqs/account/getting-a-new-private-key-for-your-opscode-user" target="_blank">create new ones</a>, but its always easier not to have to. Bottom line, is its expected that your keys and the knife.rb will be in your <em>~/chef-repo/.chef </em>directory at this point.</p>
<h2>Set up your Development Environment</h2>
<p>Your development environment is your home or work computer/laptop. Its the machine that is local to you. It is on this machine that you put together your Cookbooks. From here you push your cookbooks to the Opscode Chef Server, issue the commands to configure AWS and launch your AWS instances.</p>
<h3>Tweak up your chef-repo</h3>
<p>I like to keep the &#8220;standard&#8221; chef recipes that get downloaded from git or from cookbook.opscode.com in their own directory (called <em>cookbooks</em>) and all the cookbooks I create or highly modify in another directory (<em>site-cookbooks</em>). In Step 2 of the How to Get Started: <a href="http://help.opscode.com/faqs/start/user-environment" target="_blank">Setting Up Your User Environment</a>, they had you create a <em>~/chef-repo</em> directory and populate it from git or from a tar ball. You should add the <em>site-cookbooks</em> directory to your <em>~/chef-repo</em>. We&#8217;re also going to add an empty <em>README.md</em> to the <em>site-cookbooks </em>directory so when we create our own git repository that directory will be there (an empty directory will not be added to a git repository)</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/chef-repo
mkdir site-cookbooks
echo &quot;Directory for customized cookbooks&quot; &gt; site-cookbooks/README.md
</pre>
<p>You will probably also not want to include your <em>.chef </em>directory with all your keys in what gets uploaded to any outside chef repository. If you are just keeping things local, you can skip this step. Edit <em>~/chef-repo/.gitignore</em> and add .<em>chef </em>to the file on its own line. You might also want to add <em>client-config</em> to <em>.gitignore</em> as well as any temporary or backup file suffixes you might have. For instance if you use Emacs, you would add <em>~*</em> (emacs backup files suffix), the .DS_Store which is something left by the Mac filesystem,  .rake_test_cache which is left around by Rake and metadata.json which is a file generated by chef. My <em>.gitignore</em> looks like:</p>
<pre class="brush: bash; title: ; notranslate">
.chef
client-config
*~
.DS_Store
.rake_test_cache
metadata.json
</pre>
<p>If you created the <em>~chef-repo</em> from the git clone of the Opscode repository, you&#8217;ll want to get rid of the git configuration and history from the cloning of the Opscode chef-repo and create your own git repository:</p>
<pre class="brush: bash; title: ; notranslate">
rm -rf .git
git init
git add -A
git commit -a -m &quot;Created my own basic chef-repo&quot;
</pre>
<p>The above commands will have removed the old git config that came when you did the git clone <em>http://github.com/opscode/chef-repo.git</em> command as part of the Opscode <a href="http://help.opscode.com/faqs/start/how-to-get-started" target="_blank">How to Get Started</a> pages. The git init, add and commit will create a new local git repository for your own use not connected to the opscode repository. You can then add a remote repository if you want to be able to push your repository and future changes to another git repository such as github.com.</p>
<h3>Updating your knife.rb file with Amazon Credentials</h3>
<p>Add the following lines to the end of your ~/chef-repo/.chef/knife.rb file. You should have gotten your AWS Access Key and Secret Access key when you signed up to Amazon Web Services, but you can always go back and get it at <a href="http://aws-portal.amazon.com/gp/aws/developer/account/index.html?action=access-key" target="_blank">AWS Security Credentials page</a>. Your final knife.rb should look something like this, except the various items that are customized to your setup. In the example below <em>rberger_test</em> would be replaced by your Opscode User name and <em>install_wordpress</em> would be replaced by your Opscode Organization name that was used when you went thru the Section 3 of the Opscode How to Get Started: <a href="http://help.opscode.com/faqs/start/chef-client" target="_blank">Setting Up a Chef Client</a>.</p>
<pre class="brush: ruby; highlight: [12,13]; title: ; notranslate">
current_dir = File.dirname(__FILE__)
log_level                :info
log_location             STDOUT
node_name                &quot;rberger_test&quot;
client_key               &quot;#{current_dir}/rberger_test.pem&quot;
validation_client_name   &quot;install_wordpress-validator&quot;
validation_key           &quot;#{current_dir}/install_wordpress-validator.pem&quot;
chef_server_url          &quot;https://api.opscode.com/organizations/install_wordpress&quot;
cache_type               'BasicFile'
cache_options( :path =&gt; &quot;#{ENV['HOME']}/.chef/checksums&quot; )
cookbook_path            [&quot;#{current_dir}/../cookbooks&quot;, &quot;#{current_dir}/../site-cookbooks&quot;]
knife[:aws_access_key_id]     = &quot;Your Access Key&quot;
knife[:aws_secret_access_key] = &quot;Your Secret Access Key&quot;
</pre>
<p>You can test that your knife.rb is setup enough to access AWS by issuing the command</p>
<pre class="brush: bash; title: ; notranslate">knife ec2 server list</pre>
<p>And you should see something like this (just the heading and no instances unless you&#8217;ve launched some EC2 instances earlier:</p>
<pre class="brush: bash; title: ; notranslate">
Instance ID      Public IP        Private IP       Flavor        Image        Security Groups  State
</pre>
<h3>Get the Appropriate Cookbooks</h3>
<p>We&#8217;ll get cookbooks using the <a href="http://wiki.opscode.com/display/chef/Knife" target="_blank">knife command</a> and the <a href="http://cookbooks.opscode.com/" target="_blank">cookbooks.opscode.com</a> web service. We&#8217;ll be using the following cookbooks:</p>
<ul>
<li>chef</li>
<li>apache2</li>
<li>mysql</li>
<li>openssl</li>
<li>php</li>
<li>postfix</li>
<li>sudo</li>
<li>users</li>
<li>vsftpd</li>
<li>wordpress</li>
</ul>
<p>Use the knife command on your local development machine to pull down the cookbooks you need. The command we&#8217;re using (knife cookbook site vendor COOKBOOK) will automatically download the cookbooks and install them in the ~/chef-repo/cookbooks directory. It will also check them into your git repository as a vendor branch (Stay on the master branch at least until you have installed all the cookbooks).</p>
<pre class="brush: bash; title: ; notranslate">
cd ~/chef-repo
knife cookbook site vendor chef -d
knife cookbook site vendor apache2 -d
knife cookbook site vendor mysql -d
knife cookbook site vendor openssl -d
knife cookbook site vendor php -d
knife cookbook site vendor postfix -d
knife cookbook site vendor sudo -d
knife cookbook site vendor users -d
knife cookbook site vendor vsftpd -d
knife cookbook site vendor wordpress -d
</pre>
<p>Those commands will download all the cookbooks and any other cookbook dependencies they may have into your ~/chef-repo/cookbooks directory and check each one in as a git branch in your repo. If you do an ls on your ~/chef-repo/cookbooks directory you should see:</p>
<pre class="brush: plain; title: ; notranslate">
README.md       bluepill        couchdb         java            php             runit           users           xml
apache2         build-essential daemontools     mysql           postfix         sudo            vsftpd          zlib
apt             chef            erlang          openssl         rabbitmq_chef   ucspi-tcp       wordpress
</pre>
<p>And if you do a git branch you should see your master branch as the current and a chef-vendor- for each of the cookbooks you installed:</p>
<pre class="brush: plain; title: ; notranslate">
  chef-vendor-apache2
  chef-vendor-apt
  chef-vendor-bluepill
  chef-vendor-build-essential
  chef-vendor-chef
  chef-vendor-couchdb
  chef-vendor-daemontools
  chef-vendor-erlang
  chef-vendor-java
  chef-vendor-mysql
  chef-vendor-openssl
  chef-vendor-php
  chef-vendor-postfix
  chef-vendor-rabbitmq_chef
  chef-vendor-runit
  chef-vendor-sudo
  chef-vendor-ucspi-tcp
  chef-vendor-users
  chef-vendor-vsftpd
  chef-vendor-wordpress
  chef-vendor-xml
  chef-vendor-zlib
* master
</pre>
<p>If you ever want to update these standard cookbooks,  you can just redo the <code>knife cookbook site vendor Cookbook</code> command.</p>
<h2>Create site-cookbooks to extend standard cookbooks</h2>
<p>It is standard practice to put the official cookbooks in the <em>~chef-repo/cookbooks</em> directory, as we just did in the previous step. Any cookbook overrides, extensions or custom cookbooks go into the <em>~chef-repo/site-cookbooks</em> directory. If you create a cookbook directory in ~chef-repo/site-cookbooks with the same name as a cookbook in the <em>~chef-repo/cookbooks</em> directory, the files, templates and/or recipes in the <em>~chef-repo/site-cookbook</em> directory will override the matching files, templates and/or recipes in the cookbook of the same name in the <em>~chef-repo/cookbooks</em> directory. We will now extend two of the cookbooks; users and wordpress.</p>
<h3>Extend the Sudo cookbook so its suitable for EC2</h3>
<p>The standard sudo cookbook creates a sudoers file that requires passwords to activate sudo. Most EC2 environments do not allow passwords for logins and require that you login only with ssh keys. So we need to modify the Sudo cookbook to create the sudoers file with the NOPASSWORD flag set for all the users we want to have sudo powers. We just need to override the template file used in the standard sudo cookbook.</p>
<p>First have to make a directory for the new template in your site-cookbooks directory:</p>
<pre class="brush: plain; title: ; notranslate">
mkdir -p site-cookbooks/sudo/templates/default
</pre>
<p>Copy the following into site-cookbooks/sudo/templates/default/sudoers.erb:</p>
<pre class="brush: plain; title: ; notranslate">
#
# /etc/sudoers
#
# Generated by Chef for
#

Defaults !lecture,tty_tickets,!fqdn

# User privilege specification
root  ALL=(ALL) ALL

 ALL=(ALL) NOPASSWD:ALL

# Members of the sysadmin group may gain root privileges
%sysadmin ALL=(ALL) NOPASSWD:ALL

# Members of the group '' may gain root privileges
% ALL=(ALL) NOPASSWD:ALL
</pre>
<h3>Fix a bug in the latest version of the Standard Mysql Cookbook</h3>
<p>As I was writing this post, Opscode came out with a new version of the Mysql Cookbook that seems to have a bug with the Chef Client version 0.9.12. It may be fixed by the time you read this. If you are running Chef 0.9.12, check for line 59 of cookbooks/mysql/recipes/client.rb. Change</p>
<pre class="brush: plain; title: ; notranslate">
if platform_version.to_f &gt;= 5.0
</pre>
<p>to:</p>
<pre class="brush: plain; title: ; notranslate">
if node.platform_version.to_f &gt;= 5.0
</pre>
<h3>Extend the WordPress cookbook to do some custom actions</h3>
<p>We need to do a few custom actions after we install wordpress. The main one being to change the onwnership of the wordpress directory and most of the files to the user blog.</p>
<p>We need to add a user named <em>blog</em> that has its home directory the same as the wordpress directory. We will use this <em>blog</em> user to do automatic updates to wordpress. It will use vsftpd for secure ftp and will have only access to the wordpress directory.</p>
<p>We also need to add a swap file to the server. We could create a new cookbook to hold this as its not really wordpress related, but because this is such a simple system, we will just add a new recipe to wordpress to handle these miscellaneous actions.</p>
<h4>Create a recipe to add the blog user and change ownership of the wordpress directory</h4>
<p>First make the directories in site-cookbooks for extending the wordpress cookbook:</p>
<pre class="brush: plain; title: ; notranslate">
mkdir -p site-cookbooks/wordpress/recipes
mkdir -p site-cookbooks/wordpress/attributes
mkdir -p site-cookbooks/wordpress/templates/default
</pre>
<p>Create and edit the file site-cookbooks/wordpress/attributes/wordpress.rb and put the following in it (note, this must have a different name than the one used in the standard wordpress cookbook templates directory):</p>
<pre class="brush: plain; title: ; notranslate">
default[:wordpress][:blog_updater][:username] = &quot;blog&quot;

::Chef::Node.send(:include, Opscode::OpenSSL::Password)

default[:wordpress][:blog_updater][:password] = secure_password
# hash set by recipe or manually using makepasswd
default[:wordpress][:blog_updater][:hash] = nil

# For creating the swap partition. Swap_size is in GB
default[:wordpress][:gb_swap_size] = 2
default[:wordpress][:swap_file] = &quot;/swap_file&quot;
</pre>
<p>This will set the <em>[:wordpress][:blog_updater]</em> to be the name &#8220;blog&#8221;. This is the default for the username that will have the ability to use vsftpd to update wordpress and its plugins. We actually override this in the wordpress.rb role file. But we put a default here as well for good practice (ie. the cookbook will work even if someone doesn&#8217;t override the value in a role).</p>
<p>The <em>::Chef::Node.send(:include, Opscode::OpenSSL::Password)</em> line is there so we can use the Chef mechanism to create an auto-generated password (<em>secure_password</em>). We then use that mechanism to set the default password for the <em>blog_updater</em>.</p>
<p>Create and edit site-cookbooks/wordpress/recipes/blog_user.rb. put the following as the contents:</p>
<pre class="brush: plain; title: ; notranslate">
# Get the password cryptographic hash for node[:wordpress][:blog_updater][:password
package &quot;makepasswd&quot;
package &quot;libshadow-ruby1.8&quot;
if node[:wordpress][:blog_updater][:hash].nil? || node[:wordpress][:blog_updater][:hash].empty?
  cmd = &quot;echo #{node[:wordpress][:blog_updater][:password]} | /usr/bin/makepasswd --clearfrom=- --crypt-md5 |awk '{ print $2 }'&quot;
  ruby_block &quot;create_blog_updater_pw&quot; do
    block do
      node.set[:wordpress][:blog_updater][:hash] = `#{cmd}`.chomp
    end
    action :create
  end
end

# Create the blog_updater user with their home directory being the wordpress directory and the group as the same group as the Apache runtime group
user &quot;#{node[:wordpress][:blog_updater][:username]}&quot; do
  home &quot;#{node[:wordpress][:dir]}&quot;
  gid &quot;#{node[:apache][:user]}&quot;
  shell &quot;/bin/bash&quot;
  supports :manage_home =&gt; true
  unless node[:wordpress][:blog_updater][:hash].nil? || node[:wordpress][:blog_updater][:hash].empty?
    password &quot;#{node[:wordpress][:blog_updater][:hash]}&quot;
  end
end

# Change the ownership of the wordpress directory so that the blog user can update
execute &quot;chown wordpress home for blog user&quot; do
  cwd &quot;#{node[:wordpress][:dir]}&quot;
  user &quot;root&quot;
  command &quot;chown -R #{node[:wordpress][:blog_updater][:username]}:#{node[:apache][:user]} #{node[:wordpress][:dir]}&quot;
  not_if { node[:wordpress][:dir].nil? || node[:wordpress][:dir].empty? || (not File.exists?(node[:wordpress][:dir])) }
end
</pre>
<p>The above code will create the blog_user as a Linux user on the target system and set its home directory to be the wordpress directory. This is to make it work with vsftpd.</p>
<h4>Create a template to override the default wordpress apache config</h4>
<p>The standard WordPress cookbook sets the Apache Server Name the FQDN of the EC2 Public DNS and sets the Server Aliases to the EC2 FQDN Private DNS name. This is pretty useless. We would like to have the cookbook set the Server Alias to the FQDN&#8217;s based on our own DNS names. To do this without overriding the whole standard WordPress cookbook, we can override one template and name it: <em>site-cookbooks/wordpress/templates/default/wordpress.conf.erb</em>.</p>
<pre class="brush: plain; title: ; notranslate">

  ServerName
  ServerAlias
  DocumentRoot

  &gt;
    Options FollowSymLinks
    AllowOverride FileInfo
    Order allow,deny
    Allow from all

    Options FollowSymLinks
    AllowOverride None

  LogLevel info
  ErrorLog /-error.log
  CustomLog /-access.log combined

  RewriteEngine On
  RewriteLog /-rewrite.log
  RewriteLogLevel 0
</pre>
<p>The key changes are the ServerAlias line where we now add the <code>@node[:wordpress][:server_aliases]</code> will add any aliases specified by this attribute which we set in the wordpress.rb role file. We also change the AllowOverride to FileInfo for the docroot</p>
<h4>Create a recipe to add a swap file to the server</h4>
<p>The t1.micro instance only has 612MB of RAM. You can easily run out of that with a WordPress blog. So we have a recipe to add a swap file system utilizing some space the EBS  disk Volume. This recipe creates a 2GB file called /swap_file  using dd and then uses the mkswap and swapon commands to make that file into a swap partition. The recipe also updates the /etc/fstab file so that the swap file will be mounted again if the instance reboots.</p>
<p>Create and edit the file site-cookbooks/wordpress/recipes/add_swap.rb with the following content:</p>
<pre class="brush: plain; title: ; notranslate">
mb_block_size = 100
count = (node[:wordpress][:gb_swap_size] * 1024) / mb_block_size
bash &quot;add_swap&quot; do
  user &quot;root&quot;
  code &lt; &quot;#{node[:wordpress][:swap_file]}&quot;
  )
end
</pre>
<p>Create and edit the file site-cookbooks/wordpress/templates/default/fstab.erb and put the following content:</p>
<pre class="brush: plain; title: ; notranslate">
# /etc/fstab: static file system information.
#
proc                   /proc           proc   nodev,noexec,nosuid     0       0
      none            swap   sw                      0       0
/dev/sda1              /               ext3   defaults                0       0
/dev/sda2              /mnt            auto   defaults,nobootwait,comment=cloudconfig 0       0
</pre>
<h3>Create WordPress Role</h3>
<p>This example will use a single role named <em>wordpress</em>. Use your favorite editor to create a file in your repo with the path roles/wordpress.rb with the following contents (Substitute your domain for ibd.com and change the hostnames such as test and wordpress-test to names appropriate for your blog. Replace <em>rberger_test </em>with the userid you want to use to log into your server via ssh):</p>
<pre class="brush: ruby; title: ; notranslate">
name &quot;wordpress&quot;
description &quot;Blog using wordpress&quot;
recipes &quot;apt&quot;, &quot;build-essential&quot;, &quot;chef::client_service&quot;, &quot;users::sysadmins&quot;,
        &quot;sudo&quot;, &quot;postfix&quot;, &quot;mysql::server&quot;, &quot;wordpress&quot;, &quot;wordpress::blog_user&quot;,
        &quot;wordpress::add_swap&quot;, &quot;vsftpd&quot;

override_attributes(
  &quot;postfix&quot; =&gt; {&quot;myhostname&quot; =&gt; &quot;test.ibd.com&quot;, &quot;mydomain&quot; =&gt; &quot;ibd.com&quot;},
  &quot;authorization&quot; =&gt; {
    &quot;sudo&quot; =&gt; {
      &quot;groups&quot; =&gt; [],
      &quot;users&quot; =&gt; [&quot;rberger_test&quot;, &quot;ubuntu&quot;]
    }
  },
  &quot;wordpress&quot; =&gt; {
     &quot;server_aliases&quot; =&gt; %w(test.ibd.com wordpress-test.ibd.com),
     &quot;version&quot; =&gt; &quot;3.0.4&quot;,
     &quot;checksum&quot; =&gt; &quot;c68588ca831b76ac8342d783b7e3128c9f4f75aad39c43a7f2b33351634b74de&quot;,
     &quot;blog_updater&quot; =&gt; {
       &quot;username&quot; =&gt; &quot;blog&quot;,
       &quot;password&quot; =&gt; &quot;big-secret&quot;
     }
   },
   &quot;vsftpd&quot; =&gt; {&quot;chroot_users&quot; =&gt; %w(blog)}
)
</pre>
<p>The recipes line will be used to determine which cookbook/recipes (order is important) should be loaded by Chef when the chef-client is run on your new server.</p>
<ul>
<li><strong>apt: </strong>Configures various APT components on Debian-like systems.</li>
<li><strong>build-essential: </strong>Installs C compiler / build tools</li>
<li><strong>chef::client_service:</strong> Sets up a Chef client daemon to run periodically</li>
<li><strong>users::sysadmins:</strong> Creates users with ssh authorized keys. Requires a databag to be configured with users info</li>
<li><strong>sudo:</strong> Installs sudo and configures the /etc/sudoers file</li>
<li><strong>postfix: </strong>Installs and configures postfix for outgoing email</li>
<li><strong>mysql::server: </strong>Installs &amp; configures packages required for mysql servers</li>
<li><strong>wordpress:</strong> Installs and configures WordPress according to the instructions at http://codex.wordpress.org/Installing_WordPress</li>
<li><strong>wordpress::blog_user:</strong> Custom add-on recipe to add a user named &#8220;blog&#8221; to use with vsftpd for automatic wordpress and plugin updates</li>
<li><strong>wordpress::add_swap:</strong> Custom add-on recipe to add a swap partition to the instance</li>
<li><strong>vsftpd:</strong> Very Basic installation and configuration of vsftpd to support Secure (SSL) SFTP</li>
</ul>
<p>The <em>override_attributes</em> are used to configure various cookbooks.</p>
<ul>
<li><strong>postfix</strong> &#8211; Parameters for the postfix cookbook. Mainly sets the host and domain name to be meaningful</li>
<li><strong>authorization</strong> &#8211; Configures the sudo cookbook. Tells which users and groups should have sudo capability</li>
<li><strong>wordpress </strong>Some of these override values in the base cookbook and others for the site-cookbook version
<ul>
<li><strong>server-aliases</strong> &#8211; Sets aliases for the blog name. Will be used as serveralias names in the apache config.</li>
<li><strong>version</strong> &#8211; The version of wordpress to download.</li>
<li><strong>checksum</strong> &#8211; The checksum of the tar image of the wordpress download.</li>
<li><strong>blog_updater</strong>- Info needed to create a user that will do auto updates to wordpress via vsftps
<ul>
<li><strong>username</strong> &#8211; The username of the user</li>
<li><strong>password</strong> &#8211; The password to create for the user</li>
</ul>
</li>
</ul>
</li>
<li><strong>vsftpd</strong> &#8211; Sets what user should be allowed to access via ftp and have their home directory chroot&#8217;d (should be the same as wordpress-blog_updater).</li>
</ul>
<h3>Upload the cookbooks and roles to Opscode Chef Platform</h3>
<p>Run the following commands while you are in ~/chef-repo. This will upload the wordpress role and all the cookbooks in your chef-repo to your account on the Opscode Chef Platform:</p>
<pre class="brush: plain; title: ; notranslate">
knife role from file roles/wordpress.rb
knife cookbook upload -a
</pre>
<h3>Create the Users databag</h3>
<p>The <em>users</em> <em>cookbook</em> will take info from Opscode Chef Server Data Bag names <em>users</em>. There can be an item for each user that you want to create a login for. The standard Opscode <em>users cookbook </em>expects the users set up in the data bags to be in the group sysadmin and have the ability to sudo and gain root powers.</p>
<p>We&#8217;ll need to create an item for each user you would like to have on your system. I suggest you make at least one for yourself. Here is the data bag I used for my setup. I don&#8217;t show the ssh key. You&#8217;ll have to substitute your own public ssh key for &lt;<em>your public ssh key&gt;</em> that you will use to ssh to the server. Its a requirement that you have an ssh key as described in the next section on the <em>sudo</em> <em>cookbook</em>.</p>
<p>Here is the JSON representation of my user data bag item. Create a directory users in ~/chef-repo/data_bags/users and put the following JSON in the file ~/chef-repo/users/.json (where is the username you want to have on the target system. The id will be the name of the item in the data bag and what will become your username  (in this case <em>rberger_test</em>) You will also need to include the public ssh key you want associated with this user. You will need to have created a ssh keypair (private and public) locally using something like ssh-keygen. You don&#8217;t really need the openid. You should be able to set that to an empty string (&#8220;&#8221;):</p>
<pre class="brush: plain; title: rberger_test.json; notranslate">
{
  &quot;id&quot;: &quot;rberger_test&quot;,
  &quot;comment&quot;: &quot;Robert J. Berger&quot;,
  &quot;uid&quot;: 2001,
  &quot;groups&quot;: &quot;sysadmin&quot;,
  &quot;shell&quot;: &quot;/bin/bash&quot;,
  &quot;openid&quot;: &quot;rberger_test.myopenid.com&quot;,
  &quot;ssh_keys&quot;: &quot;&quot;
}
</pre>
<p>You will need to create the users databag and then upload your version of the user JSON (rberger_test.json in the example) to the Chef server with the following commands:</p>
<pre class="brush: plain; title: ; notranslate">
knife data bag create users
knife data bag from file users data_bags/users/rberger_test.json
</pre>
<p>With Amazon EC2 instances its best to only allow access without passwords using ssh keys. Since the login is protected by ssh keys, and you don&#8217;t have passwords associated with the users, you need to make sure sudo is set up to allow invoking sudo for specific users (sysadmins) without a password. The users cookbook creates such a user based on the users data bag. But the sudo cookbook does not set up sudoers to support not having password. We will modify the sudoers.erb template later. Make sure you don&#8217;t deploy without this modification as the default sudo cookbook will make it impossible to sudo on an EC2 instance after its run.</p>
<h2>Configure AWS</h2>
<p>You can do most of the following by using the a GUI web app such as <a href="https://console.aws.amazon.com/ec2/home" target="_blank">Amazon&#8217;s AWS console</a>, the Firefox plugin <a href="http://aws.amazon.com/developertools/609?_encoding=UTF8&amp;jiveRedirect=1" target="_blank">ElasticFox</a> other such GUI  tools or the command line <a href="http://aws.amazon.com/developertools/351?_encoding=UTF8&amp;queryArg=searchQuery&amp;x=0&amp;fromSearch=1&amp;y=0&amp;searchPath=developertools&amp;searchQuery=ec2-api-tools" target="_blank">ec2-api-tools</a>. For now, we&#8217;ll show how to do this with the Amazon AWS Console.</p>
<h3>Set up Security Group</h3>
<p>Add a WordPress group, that enables  ssh, http and https. You should open at least http and https to all IP addresses (represented by Source IP: 0.0.0.0/0) You can decide to open up ssh to every IP or just to your own development network or host. In this example we&#8217;ll open it up to the world. Note: by default ping (ICMP) is not enabled so you can not ping your instance. You can enable ping by adding a line where it doesn&#8217;t matter what is in Connection Method, Protocol is ICMP, From Port and To Port is set to -1 and Source IP is 0.0.0.0/0.</p>
<div id="attachment_686" class="wp-caption aligncenter" style="width: 826px"><img class="size-full wp-image-686" title="AWS Management Console Security Group" src="http://blog.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console-Security-Group.jpg" alt="" width="816" height="609" /><p class="wp-caption-text">Navigate to Security Groups and Click on Create Security Group</p></div>
<div id="attachment_687" class="wp-caption aligncenter" style="width: 551px"><img class="size-full wp-image-687" title="Enter Security Group Name" src="http://blog.ibd.com/wp-content/uploads/2010/10/Enter-Security-Group-Name.jpg" alt="" width="541" height="309" /><p class="wp-caption-text">Enter the name and description of the Security Group</p></div>
<div id="attachment_688" class="wp-caption aligncenter" style="width: 799px"><img class="size-full wp-image-688 " title="Setting ports" src="http://blog.ibd.com/wp-content/uploads/2010/10/Setting-ports.jpg" alt="" width="789" height="485" /><p class="wp-caption-text">Set the Ports that are to be enabled (Select the Connection Method, enter the Source IP, and click Save)</p></div>
<h3>Generate an SSH Key Pair for accessing your instance[s]</h3>
<p>You need to use the Amazon Key Pair generator to generate a key that will be used to make initial ssh connections to your new instances after they are created. You can also do this on the AWS <span style="font-size: 15.6px;">Management Console&#8217;s EC2 Key Pairs page:</span></p>
<div id="attachment_694" class="wp-caption aligncenter" style="width: 904px"><img class="size-full wp-image-694" title="AWS Management Console Key Pairs" src="http://blog.ibd.com/wp-content/uploads/2010/10/AWS-Management-Console.jpg" alt="" width="894" height="524" /><p class="wp-caption-text">Navigate to the Key Pairs page and click on Create Key Pair</p></div>
<p>You can name the key pair anything, but you may want to use this key pair to access this and future instances, so you might want to name it something general like aws-east. Here we&#8217;re going to name it something more specific: aws-wordpress just for this example.</p>
<div id="attachment_695" class="wp-caption aligncenter" style="width: 364px"><img class="size-full wp-image-695 " title="Create Key Pair naming" src="http://blog.ibd.com/wp-content/uploads/2010/10/Create-Key-Pair-naming.jpg" alt="" width="354" height="217" /><p class="wp-caption-text">Enter the name for the key</p></div>
<div id="attachment_697" class="wp-caption aligncenter" style="width: 363px"><img class="size-full wp-image-697" title="keypair created message" src="http://blog.ibd.com/wp-content/uploads/2010/10/keypair-created-message.jpg" alt="" width="353" height="234" /><p class="wp-caption-text">After the key pair is created, make sure to save the private key that is downloaded automatically</p></div>
<p>At this point a file named asw-wordpress.pem will have been downloaded by your browser. Make sure not to loose it! Put it into your ~/.ssh directory and chmod it to 0600:</p>
<pre class="brush: plain; title: ; notranslate">
chmod 0600 ~/.ssh/aws-wordpress.pem
</pre>
<p>The final Key Pairs page on the AWS Management Console should look something like:</p>
<div id="attachment_696" class="wp-caption aligncenter" style="width: 897px"><img class="size-full wp-image-696" title="Final Keypair display" src="http://blog.ibd.com/wp-content/uploads/2010/10/Final-Keypair-display.jpg" alt="" width="887" height="524" /><p class="wp-caption-text">Final Key Pair Page</p></div>
<h2>Create the Instance and Bootstrap Chef on the Instance</h2>
<p>The Chef Knife command has the ability to launch EC2 (and other cloud) instances. This process automatically installs chef and all its dependencies after the instance is created. If all goes well, it then loads and executes your roles and cookbooks on the instance creating your server.</p>
<p>You can see what options are available to this command:</p>
<pre class="brush: plain; title: ; notranslate">
# knife ec2 server create --help
knife ec2 server create (options)
    -Z, --availability-zone ZONE     The Availability Zone
    -A, --aws-access-key-id KEY      Your AWS Access Key ID
    -K SECRET,                       Your AWS API Secret Access Key
        --aws-secret-access-key
        --user-data USER_DATA_FILE   The EC2 User Data file to provision the instance with
        --bootstrap-version VERSION  The version of Chef to install
    -N, --node-name NAME             The Chef node name for your new node
        --server-url URL             Chef Server URL
    -k, --key KEY                    API Client Key
        --color                      Use colored output
    -c, --config CONFIG              The configuration file to use
        --defaults                   Accept default values for all questions
    -d, --distro DISTRO              Bootstrap a distro using a template
        --ebs-no-delete-on-term      Do not delete EBS volumn on instance termination
        --ebs-size SIZE              The size of the EBS volume in GB, for EBS-backed instances
    -e, --editor EDITOR              Set the editor to use for interactive commands
    -E, --environment ENVIRONMENT    Set the Chef environment
    -f, --flavor FLAVOR              The flavor of server (m1.small, m1.medium, etc)
    -F, --format FORMAT              Which format to use for output
    -i IDENTITY_FILE,                The SSH identity file used for authentication
        --identity-file
    -I, --image IMAGE                The AMI for the server
        --no-color                   Don't use colors in the output
    -n, --no-editor                  Do not open EDITOR, just accept the data as is
        --no-host-key-verify         Disable host key verification
    -u, --user USER                  API Client Username
        --prerelease                 Install the pre-release chef gems
        --print-after                Show the data after a destructive operation
        --region REGION              Your AWS region
    -r, --run-list RUN_LIST          Comma separated list of roles/recipes to apply
    -G, --groups X,Y,Z               The security groups for this server
    -S, --ssh-key KEY                The AWS SSH key id
    -P, --ssh-password PASSWORD      The ssh password
    -x, --ssh-user USERNAME          The ssh username
    -s, --subnet SUBNET-ID           create node in this Virtual Private Cloud Subnet ID (implies VPC mode)
        --template-file TEMPLATE     Full path to location of template to use
    -V, --verbose                    More verbose output. Use twice for max verbosity
    -v, --version                    Show chef version
    -y, --yes                        Say yes to all prompts for confirmation
    -h, --help                       Show this message
</pre>
<p>The actual command we&#8217;ll use is:</p>
<pre class="brush: plain; title: ; notranslate">
knife ec2 server create --run-list 'role[wordpress]' --node-name test-wordpress --flavor t1.micro \
--identity-file ~/.ssh/aws-wordpress.pem --image ami-a2f405cb --groups wordpress \
--ssh-key aws-wordpress --ssh-user ubuntu --ebs-no-delete-on-term
</pre>
<h3>Details of knife command to launch instance</h3>
<p><strong>role[wordpress]: </strong>The role[s] given to this instance. More than one can be specified by an orderd space separated list of strings: &#8216;role[role0]&#8216; &#8216;role[role1]&#8216; &#8230;</p>
<p><strong>&#8211;node-name test-wordpress:</strong> The name of the instance. Used by Chef to name the Node and Client</p>
<p><strong>&#8211;flavor t1.micro:</strong> The <a href="http://aws.amazon.com/ec2/instance-types/" target="_blank">EC2 Instance Type</a>. Here we are using the smallest type. This is the only one that is <a href="http://aws.amazon.com/free/" target="_blank">&#8220;free&#8221;</a></p>
<p><strong>&#8211;identity-file ~/.ssh/aws-wordpress.pem:</strong> The path to the ssh private key that was downloaded earlier from the AWS Management Console. You could potentially not include this if you added the key to your ssh-agent.</p>
<p><strong>&#8211;image ami-a2f405cb: </strong>The Amazon Machine Image assigned to this instance. It is the image of the root file system for the instance and thus determines what OS and software is booted when the instance is started. In this case it is the Canonical Ubuntu 10.4 32 bit AMI. You can find the latest Ubuntu AMIs for each region at the top of the home page of <a href="http://alestic.com/" target="_blank">Eric Hammond&#8217;s super helpful site</a>.</p>
<p><strong>&#8211;groups wordpress:</strong> The Security Group[s] to be assigned to this instance. In this case its &#8220;wordpress&#8221; Multiple Groups can be assigned as a comma separated list</p>
<p><strong>&#8211;ssh-key aws-wordpress: </strong>The name of the SSH Key Pair that was downloaded from the AWS Management Console</p>
<p><strong>&#8211;ssh-user ubuntu: </strong>The user name for ssh access. This AMI uses &#8220;ubuntu&#8221;. The AMI&#8217;s usually are configured to allow only a single user to ssh by default. Different AMI&#8217;s use different names such as root or ec2-user.</p>
<p><strong>&#8211;ebs-no-delete-on-term: </strong>By default, the EBS Volume is deleted when the EC2 instance is terminated. By adding this flag it will instead make it so the EBS volume will continue to exist after the EC2 instance has been terminated. You want this for your final deployed site so that if something goes wrong with the EC2 instance you will still have your EBS volume and can use it to create a new EC2 instance without loosing your data. (That is the topic of another tutorial though!)</p>
<h3>Successful launch results</h3>
<p>After you fire off the knife ec2 server create command, you&#8217;ll see something like:</p>
<pre class="brush: plain; title: ; notranslate">
[WARN] Fog::AWS::EC2#new is deprecated, use Fog::AWS::Compute#new instead (/Library/Ruby/Gems/1.8/gems/chef-0.9.12/lib/chef/knife/ec2_server_create.rb:145:in `run')
Instance ID: i-d10ae5bd
Flavor: t1.micro
Image: ami-a2f405cb
Availability Zone: us-east-1b
Security Groups: wordpress
SSH Key: aws-wordpress

Waiting for server..............
Public DNS Name: ec2-184-73-44-17.compute-1.amazonaws.com
Public IP Address: 184.73.44.17
Private DNS Name: domU-12-31-39-10-60-17.compute-1.internal
Private IP Address: 10.198.99.229

Waiting for sshd...done
INFO: Bootstrapping Chef on ec2-184-73-44-17.compute-1.amazonaws.com
</pre>
<p>That will be followed by loads of debugging info as the knife command bootstraps chef and its related packages and gems. This can go on for 10 to 20 minutes. Eventually you&#8217;ll see something along the lines of:</p>
<pre class="brush: plain; title: ; notranslate">
Instance ID: i-d10ae5bd
Flavor: t1.micro
Image: ami-a2f405cb
Availability Zone: us-east-1b
Security Groups: wordpress
SSH Key: aws-wordpress
Public DNS Name: ec2-184-73-44-17.compute-1.amazonaws.com
Public IP Address: 184.73.44.17
Private DNS Name: domU-12-31-39-10-60-17.compute-1.internal
Private IP Address: 10.198.99.229
Run List: role[wordpress]
</pre>
<p>You can look just before this block and see if chef finished the running of the wordpress related cookbooks ok. If within a page above the last block you don&#8217;t see any errors then all is ok. The last few lines should be something like:</p>
<pre class="brush: plain; title: ; notranslate">
[Mon, 03 Jan 2011 07:23:34 +0000] INFO: Chef Run complete in 10.945359 seconds
[Mon, 03 Jan 2011 07:23:34 +0000] INFO: cleaning the checksum cache
[Mon, 03 Jan 2011 07:23:34 +0000] INFO: Running report handlers
[Mon, 03 Jan 2011 07:23:34 +0000] INFO: Report handlers complete
</pre>
<p>If there are errors, you&#8217;ll have to debug your cookbooks which is beyond the scope of this post.</p>
<p>Now you should be able to log into your instance ether as the ubuntu default user or the user you created in the wordpress role and the Users Databag (rberger_test in this example):</p>
<pre class="brush: plain; title: ; notranslate">
# Using the ubuntu user and an explicit ssh key
ssh -i ~/.ssh/aws-wordpress.pem ubuntu@ec2-184-73-44-17.compute-1.amazonaws.com

# Using the user created by the cookbook and a key that is already on you ssh-agent
ssh rberger_test@ec2-184-73-44-17.compute-1.amazonaws.com
</pre>
<h2>Configure DNS to have preferred FQDNs point to your instance</h2>
<p>You can access your site using the Amazon Public DNS name, but that would not be good in general. You probably want to access it via a URL like <em>http://www.myydomain.com</em>. To do this you must configure your DNS to add a CNAME to map your FQDN to the Amazon Public DNS name. How this is done is very specific to your DNS service provider. Bottom line is that you want to do a CNAME not an A record.  (I.E. an alias of your FQDN for the Amazon Public DNS name, not an A record that uses the Amazon IP address). There are some issues of using an A record with Amazon. You probably won&#8217;t see them for a simple situation such as hosting a single instance. But once you have many instances that need to talk to each other, using the CNAME will make life easier.</p>
<h2>Installing your WordPress Blog</h2>
<p>At this point you should be able to access your new instance via http. The initial screen will be the WordPress setup dialog. You should be able to access it via http using the Amazon Public DNS name or any CNAME aliases  you created and also added in the wordpress.rb role file override attribute for (wordpress =&gt;server_aliases. You should see something like:</p>
<div id="attachment_717" class="wp-caption aligncenter" style="width: 785px"><img class="size-full wp-image-717" title="WordPress › Installation" src="http://blog.ibd.com/wp-content/uploads/2010/10/WordPress-›-Installation.jpg" alt="" width="775" height="871" /><p class="wp-caption-text">Wordpress startup installation page</p></div>
<p>It is possible to move an existing WordPress Blog to this new instance but that is beyond the scope of this post.</p>
<h2>Happily Ever After</h2>
<p>By default, the chef client runs every 1/2 hour on the instance. If you change any of the cookbooks and push them up to the Opscode Chef Server, those changes will be propogated to the instance the next time the chef-client runs again on the instance.</p>
<p>This is the way to maintain the server. By updating or adding cookbooks, you define the state of the server and the server will converge to that state when the chef-client runs. The inverse is true. If you change something on the server directly and the service you changed is managed by Chef, your direct changes could be reverted by the chef-client the next time it runs.</p>
<p>You shouldn&#8217;t need to but you can disable the chef-client from running automatically by running the following command while ssh&#8217;d to the instance:</p>
<pre class="brush: plain; title: ; notranslate">
sudo /etc/init.d/chef-client stop
</pre>
<p>That will be reset (ie automatic chef-client runs will be re-enabled) if you reboot. You can permanently disable the automatic running of chef-client by running the following commands while ssh&#8217;d into the instance:</p>
<pre class="brush: plain; title: ; notranslate">
cd /etc/init.d
sudo update-rc.d -f chef-client remove
</pre>
<h3>Using the WordPress Automatic Upgrade Mechanism</h3>
<p>At this point you should be able to use your wordpress blog as normal. You should be able to use the automatic update feature of WordPress to update WordPress itself and the plugins. When you are asked to supply the Connection Information, put in:</p>
<ul>
<li><span style="font-size: 10px;"><strong>Hostname</strong>: The Public FQDN of the host (ether the EC2 Public DNS Name or one of the DNS CNAMEs you set up)</span></li>
<li><span style="font-size: 10px;"><strong>FTP Username</strong>: &#8220;blog&#8221; (or whatever you set node[:wordpress][:blog_updater][:username] in the wordpress.rb role file)</span></li>
<li><span style="font-size: 10px;"><strong>FTP Password</strong>: &#8220;big-secret&#8221; (or whatever you <strong>SHOULD</strong> have set node[:wordpress][:blog_updater][:password] in the wordpress.rb role</span></li>
<li><span style="font-size: 10px;"><strong>Connection Type</strong>: FTPS (SSL)</span></li>
</ul>
<p>For instance for the Plugin Update Page:</p>
<div id="attachment_746" class="wp-caption aligncenter" style="width: 781px"><img class="size-full wp-image-746" title="Upgrade Plugins ‹ WordPress Test — WordPress" src="http://blog.ibd.com/wp-content/uploads/2010/10/Upgrade-Plugins-‹-Wordpress-Test-—-WordPress.jpg" alt="" width="771" height="511" /><p class="wp-caption-text">Upgrade Plugins Connection Information</p></div>
<p>That should work and be secure using the vsftpd server that we installed automatically.</p>
<p>Hopefully all will work well for you. I will try to answer questions but can&#8217;t guarantee quick response here. A great resource is the Opscode Chef IRC channel <a href="irc://irc.freenode.net/chef" target="_blank">irc.freenode.net #chef</a>. And of course the <a href="http://wiki.opscode.com/" target="_blank">Opscode Chef Wiki</a> and the <a href="http://help.opscode.com/home" target="_blank">Opscode Support Site</a>.</p>
<h3>Source Code at Github</h3>
<p>You can get all the source for this at <a href="https://github.com/rberger/ibd-wordpress-repo" target="_blank">https://github.com/rberger/ibd-wordpress-repo</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/howto/deploy-wordpress-to-amazon-ec2-micro-instance-with-opscode-chef/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Modyfying Jets3t S3 GUI tool to work with Walrus (Eucalyptus S3)</title>
		<link>http://blog.ibd.com/howto/getting-the-jet3t-s3-gui-tool-to-work-with-walrus-eucalyptus-s3/</link>
		<comments>http://blog.ibd.com/howto/getting-the-jet3t-s3-gui-tool-to-work-with-walrus-eucalyptus-s3/#comments</comments>
		<pubDate>Fri, 18 Jun 2010 01:37:18 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Scalable Deployment]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[Eucalyptus]]></category>
		<category><![CDATA[S3]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[Walrus]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=582</guid>
		<description><![CDATA[<p>Jets3t (pronounced &#8220;jet-set&#8221;) is a free, open-source Java toolkit and application suite for the Amazon Simple Storage Service (Amazon S3) and Amazon CloudFront content delivery network. For some reason almost all the standard tools for accessing S3 will not easily work with the Eucalyptus equivalent to S3 called Walrus. I am use to using [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://jets3t.s3.amazonaws.com/index.html" target="_blank">Jets3t</a> (pronounced &#8220;jet-set&#8221;) is a free, open-source Java toolkit and application suite for the <a href="http://www.amazon.com/s3" target="_blank">Amazon Simple Storage Service (Amazon S3)</a> and <a href="http://www.amazon.com/cloudfront" target="_blank">Amazon CloudFront</a> content delivery network. For some reason almost all the standard tools for accessing S3 will not easily work with the <a href="http://open.eucalyptus.com/" target="_blank">Eucalyptus</a> equivalent to S3 called <a href="http://open.eucalyptus.com/wiki/EucalyptusWalrusInteracting_v1.6" target="_blank">Walrus</a>. I am use to using the excellent S3Fox add-on for Firefox and wanted some GUI tool that had similar capabilities. I was able to piece together how to get Jets3t to work with Eucalyptus Walrus. This article puts it all together in one place.</p>
<p>The basic build procedure is based on the <a href="http://bitbucket.org/jmurty/jets3t/wiki/Build_Instructions" target="_blank">instructions</a> for downloading and building Jet3t from Source. I got the hints for what to change to make things work with Walrus from the <a href="http://groups.google.com/group/jets3t-users/browse_thread/thread/49e1296ed110f0ab/6872154bfd96e8b8" target="_blank">Jets3t Users Forum article <em>eucalyptus walrus</em></a>. And an almost unrelated <a href="http://getsatisfaction.com/cloudera/topics/hadoop_in_eucalyptus_private_cloud" target="_blank">article <em>hadoop in eucalyptus private cloud</em></a> in the Cloudera Support Forum. Search on the page for the section that says <em>my jets3t file has these values</em>.</p>
<h2>Prerequisites</h2>
<p>These instructions assume you are on Ubuntu (I had 10.4 Lucid) though it should be easily modifiable to work on any platform that supports Java.</p>
<p>You&#8217;ll need to install</p>
<ul>
<li>Mercurial (hg)</li>
<li>Sun Java 6 (I couldn&#8217;t get it to work with openjdk-6)</li>
<li>Ant</li>
</ul>
<p>You can use the command:</p>
<pre><code>sudo apt-get install mercurial sun-java6-jdk ant1.8</code></pre>
<h2>Get the Source of Jets3t with Mercurial</h2>
<p>cd to where you want to create the directory that will contain the source. Then use the following command to create a local mercurial repository of the source. Then cd into the repository directory jets3t</p>
<pre><code>hg clone http://bitbucket.org/jmurty/jets3t/
cd jets3t
</code></pre>
<h2>Edit files to make jets3t work with Walrus</h2>
<p>Use your favorite editor (emacs of course <img src='http://blog.ibd.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  to make the following edits.</p>
<h3>Edit <code>LoginCredentialsPanel.java</code> to not check the length of login credentials</h3>
<p>Jets3t enforces the length of the Access Key and Access Secret Key. But some newer versions of Walrus do not fit the assumptions. This edit eliminates the checks.</p>
<p>This should be around line 230 of <code>src/org/jets3t/apps/cockpit/gui/LoginCredentialsPanel.java</code>. Comment out the lines that have <code>errors.add</code>. It should look something like the following after you comment out the two lines with <code>errors.add</code>.</p>
<pre><code>    if (getAWSAccessKey().length() == 20) {
        // Correct length for AWS Access Key
    } else if (getAWSAccessKey().length() == 22) {
        // Correct length for Eucalyptus ID
    } else {
        // errors.add("Access Key must have 20 or 22 characters");
	}

    if (getAWSSecretKey().length() == 40) {
        // Correct length for AWS Access Key
	} else if (getAWSSecretKey().length() == 38) {
        // Correct length for Eucalyptus Secret Key
	} else {
        //  errors.add("Secret Key must have 40 or 38 characters");
    }
</code></pre>
<h3>Edit <code>jets3t.properties</code> to use parameters for accessing Walrus instead of AWS S3</h3>
<p>You&#8217;ll want to set the following for Walrus access in <code>jets3t/configs/jets3t.properties</code>. The following are the values you need to change. s3service.s3-endpoint should be set to the fully qualified domain name of the host that runs Walrus (you could use an ip address I believe). I had to set s3service.https-only to false since I don&#8217;t know what it would take to set up SSL/TLS between the Java environment and the Walrus environment. If you do, let me know!</p>
<pre><code>
s3service.https-only=false
s3service.s3-endpoint=your_walrus_host_name
s3service.s3-endpoint-http-port=8773
s3service.s3-endpoint-https-port=8443
s3service.disable-dns-buckets=true
s3service.s3-endpoint-virtual-path=/services/Walrus
</code></pre>
<h3>Optionally edit <code>build.properties</code></h3>
<p>If you want to mark the build version in a way that distinguishes from the standard version and or change the debug level.<br />
I changed the version to <code>version=0.7.4-runa</code>.</p>
<h2>Build Jets3t with your changes to work with Walrus</h2>
<p>The following use the default target of <em>dist</em> which will create a target tree in the top level directory <em>dist</em>.</p>
<pre><code>ant
</code></pre>
<p>If that works (it will say <em>BUILD SUCCESSFUL</em> at the end if it was) then there will be a director <em>dist/jets3t-0.7.4-runa</em> (or whatever you set the version value to in build.properties). You should be able to:</p>
<pre><code>cd dist/jets3t-0.7.4-runa/bin
bash cockpit.sh &amp;
</code></pre>
<p>This should start up an application window and a window for you to enter your Eucalyptus credentials. Select the <em>Direct Login</em> tab and enter you Eucalyptus Access Key and Access Secret Key.</p>
<p><a href="http://blog.ibd.com/wp-content/uploads/2010/06/Cockpit-Login-1.jpg"></a><a href="http://blog.ibd.com/wp-content/uploads/2010/06/Cockpit-Login-2.jpg"><img class="aligncenter size-full wp-image-586" title="Jets3t Cockpit Login" src="http://blog.ibd.com/wp-content/uploads/2010/06/Cockpit-Login-2.jpg" alt="Jets3t Cockpit Login" width="499" height="399" /></a></p>
<p>After you click ok, you should see your Walrus buckets!</p>
<p><a href="http://blog.ibd.com/wp-content/uploads/2010/06/JetS3t-Cockpit-_-admin.jpg"><img class="aligncenter size-full wp-image-585" title="JetS3t Cockpit" src="http://blog.ibd.com/wp-content/uploads/2010/06/JetS3t-Cockpit-_-admin.jpg" alt="JetS3t Cockpit" width="799" height="555" /></a></p>
<p>Once it all works you can use the &lt;i&gt;Store Credentials&lt;/i&gt; option on the login window to store your credentials on Walrus and use a login/password to access Walrus. But that is optional.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/howto/getting-the-jet3t-s3-gui-tool-to-work-with-walrus-eucalyptus-s3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>HBase/Hadoop on Mac OS X (Pseudo-Distributed)</title>
		<link>http://blog.ibd.com/howto/hbase-hadoop-on-mac-ox-x/</link>
		<comments>http://blog.ibd.com/howto/hbase-hadoop-on-mac-ox-x/#comments</comments>
		<pubDate>Mon, 03 May 2010 03:50:13 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Macintosh]]></category>
		<category><![CDATA[Scalable Deployment]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[HBase]]></category>
		<category><![CDATA[Mac OS X]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=565</guid>
		<description><![CDATA[<p>I wanted to do some experimenting with various tools for doing Hadoop and HBase activities and didn&#8217;t want to have to bother making it work with our Cluster in the Cloud. I just wanted a simple experimental environment on my Macbook Pro running Snow Leopard Mac OS X.</p> <p>So I thought it was time [...]]]></description>
			<content:encoded><![CDATA[<p>I wanted to do some experimenting with various tools for doing Hadoop and HBase activities and didn&#8217;t want to have to bother making it work with our Cluster in the Cloud. I just wanted a simple experimental environment on my Macbook Pro running Snow Leopard Mac OS X.</p>
<p>So I thought it was time to revisit installing Hadoop and HBase on the Mac using the latest versions of everything. This will be deployed as Psuedo-Distributed mode native to Mac OS X. Some folks actually create a set of Linux VMs with a full Hadoop/HBase stack and run that on the Mac, but that is a bit of overkill for now.</p>
<p>These instructions mainly follow the standard instructions for <a href="http://hadoop.apache.org/common/docs/current/quickstart.html" target="_blank">Apache Hadoop</a> and <a href="http://hadoop.apache.org/hbase/docs/current/api/overview-summary.html#pseudo-distrib" target="_blank">Apache HBase</a></p>
<h2>Prerequisits</h2>
<p>Mac OS X Xcode developer tools which includes Java 1.6.x. You can get this for free from the <a href="https://developer.apple.com/mac/" target="_blank">Apple Mac Dev Center</a>. You have to become a member but there is a free membership available.</p>
<h2>Download and Unpack Latest Distros</h2>
<p>You can get a link to a mirror for Hadoop via the <a href="http://www.apache.org/dyn/closer.cgi/hadoop/core/" target="_blank">Hadoop Apache Mirror link</a> and for Hbase at the <a href="http://www.apache.org/dyn/closer.cgi/hadoop/hbase/" target="_blank">HBase Apache Mirror link</a>. Each of those links will bring you to a suggested link to a mirror for Hadoop or HBase. Once you click on the suggest link, it will bring you to a mirror with the recent releases. You can click on the <em>stable</em> link which will then bring you to a directory that has the latest stable Hadoop (as of this writing: hadoop-0.20.2.tar.gz) or HBase (as of this writing: hbase-0.20.3.tar.gz ). Click on those tar.gz files to download them.</p>
<p>I am going to keep the distros in ~/work/pkgs. I usually create a directory ~/work/pkgs and unpack the tar files there as numbered versions and then create symbolic links to them in ~/work. But you can do this all in any directory that you can control.:</p>
<pre><code>cd ~/work
mkdir -p pkgs
cd pkgs
tar xvzf hadoop-0.20.2.tar.gz
tar xvzf hbase-0.20.3.tar.gz
cd ..
ln -s pkgs/hadoop-0.20.2 hadoop
ln -s pkgs/hbase-020.3 hbase
mkdir -p hadoop/logs
mkdir -p hbase/logs</code></pre>
<p>Now you can have your tools all access ~/work/hadoop or ~/work/hbase and not care what version it is. You can update to later version just by downloading, untarring the distro and then just change the symbolic links.</p>
<h2>Configure Hadoop</h2>
<p>All the configuration files mentioned here will be in <em>~/work/hadoop/conf.</em> In this example we are assuming that the Hadoop servers will only be accessed from this <em>localhost</em>. If you need to make it accessable from other hosts or VMs on your lan that support Bonjour, you could use the bonjour name  (ie. the name of your mac followed by .local such as <em>mymac.local</em>) instead of <em>localhost</em> in the following Hadoop and HBase configuraitons</p>
<h3>hadoop-env.sh</h3>
<p>Mainly need to tell Hadoop where your JAVA_HOME is.</p>
<p>Add the following line below the commented out JAVA_HOME line is in hadoop-env.sh</p>
<pre><code>export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home</code></pre>
<h3>core-site.xml</h3>
<pre><code>&lt;?xml version="1.0"?&gt;
&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;

&lt;configuration&gt;
  &lt;property&gt;
    &lt;name&gt;fs.default.name&lt;/name&gt;
    &lt;value&gt;hdfs://localhost:9000&lt;/value&gt;
  &lt;/property&gt;
&lt;/configuration&gt;</code></pre>
<h3>hdfs-site.xml</h3>
<pre><code>&lt;?xml version="1.0"?&gt;
&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;

&lt;configuration&gt;
  &lt;property&gt;
    &lt;name&gt;dfs.replication&lt;/name&gt;
    &lt;value&gt;1&lt;/value&gt;
  &lt;/property&gt;
&lt;/configuration&gt;</code></pre>
<h3>mapred-site.xml</h3>
<pre><code>&lt;?xml version="1.0"?&gt;
&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;

&lt;configuration&gt;
  &lt;property&gt;
    &lt;name&gt;mapred.job.tracker&lt;/name&gt;
    &lt;value&gt;localhost:9001&lt;/value&gt;
  &lt;/property&gt;
&lt;/configuration&gt;</code></pre>
<h3>Make sure you can ssh without a password to the hostname used in the configs</h3>
<p>The Hadoop and Hbase start/stop scripts use ssh to access the various servers. In this case of doing a Pseudo-Distributed mode, everything is running on the <em>localhost</em>, but we still need to allow the scripts to ssh to the localhost.</p>
<h4>Check that you can ssh to the <em>localhost</em> (or whatever hostname you used in the above configs)</h4>
<p>We&#8217;re assuming that we&#8217;ll be running the Hadoop/HBase servers as the same user as our login. You can set things up to run as the hadoop user, but its kind of complicated on Mac OS X. See the section<em> File System Layout</em> in an earlier post <em><a href="http://blog.ibd.com/scalable-deployment/hadoop-hdfs-and-hbase-on-ubuntu/" target="_blank">Hadoop, HDFS and Hbase on Ubuntu &amp; Macintosh Leopard</a>.</em> That section and a few other points thru that post describe how to create and use a hadoop user to run the Hadoop and HBase servers.</p>
<p>Back to just doing this as our own user. Test that you can ssh to the <em>localhost</em> without a password:</p>
<pre>ssh localhost</pre>
<p>If you see something like the following paragraph  that ends up with a password prompt, then you need to add a key to your ssh setup that does not need a password (you may need to say yes if you are asked if you want to continue connecting).</p>
<pre>The authenticity of host 'localhost (::1)' can't be established.
RSA key fingerprint is 3c:5d:6a:39:64:78:02:9d:a3:c9:69:68:50:23:71:eb.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'localhost' (RSA) to the list of known hosts.
Password:</pre>
<p>To create a passwordless key and add it to your set of authorized keys that can access your host, do the following (as yourself, not as root. The id_dsa file name can be arbitrary):</p>
<pre>ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa_for_hadoop
cat ~/.ssh/id_dsa_for_hadoop.pub &gt;&gt; ~/.ssh/authorized_keys</pre>
<p>If you have strong alternative opinions on how to set up your own keys to accomplish the same thing please do it your own way. This is just the basic way of doing a passwordless ssh. You may want to use a key you already have lying around or some other mechanism.</p>
<h3>Start Hadoop</h3>
<h4>One time format of  Hadoop File System</h4>
<p>Only once, before the first time you use Hadoop, you have to create a formated Hadoop File System. Don&#8217;t do this again once you have data in your Hadoop file system as it will erase anything you might have saved there. You may have to do this command again if somehow you screw up your file system. But its not something to do lightly the second time.</p>
<pre>~/work/hadoop/bin/hadoop namenode -format</pre>
<p>If all goes well, you should see something like:</p>
<pre>10/05/02 18:45:04 INFO namenode.NameNode: STARTUP_MSG:
/************************************************************
STARTUP_MSG: Starting NameNode
STARTUP_MSG:   host = Psion.local/192.168.50.16
STARTUP_MSG:   args = [-format]
STARTUP_MSG:   version = 0.20.2
STARTUP_MSG:   build = https://svn.apache.org/repos/asf/hadoop/common/branches/branch-0.20 -r 911707; compiled by 'chrisdo' on Fri Feb 19 08:07:34 UTC 2010
************************************************************/
10/05/02 18:45:04 INFO namenode.FSNamesystem: fsOwner=rberger,rberger,admin,com.apple.access_screensharing,_developer,_lpoperator,_lpadmin,_appserveradm,_appserverusr,localaccounts,everyone,com.apple.sharepoint.group.2,com.apple.sharepoint.group.3,dev,com.apple.sharepoint.group.1,workgroup
10/05/02 18:45:04 INFO namenode.FSNamesystem: supergroup=supergroup
10/05/02 18:45:04 INFO namenode.FSNamesystem: isPermissionEnabled=true
10/05/02 18:45:04 INFO common.Storage: Image file of size 97 saved in 0 seconds.
10/05/02 18:45:04 INFO common.Storage: Storage directory /tmp/hadoop-rberger/dfs/name has been successfully formatted.
10/05/02 18:45:04 INFO namenode.NameNode: SHUTDOWN_MSG:
/************************************************************
SHUTDOWN_MSG: Shutting down NameNode at Psion.local/192.168.50.16
************************************************************/</pre>
<h4>Starting and stopping Hadoop</h4>
<p>Now you can start Hadoop. You will use this command to start Hadoop in general:</p>
<pre>~/work/hadoop/bin/start-all.sh</pre>
<p>You can stop Hadoop with the command</p>
<pre>~/work/hadoop/bin/stop-all.sh</pre>
<p>But remember if you are running HBase, stop that first, then stop Hadoop.</p>
<h3>Making sure Hadoop is working</h3>
<p>You can see the Hadoop logs in ~/work/hadoop/logs</p>
<p>You should be able to see the Hadoop Namenode web interface at <a href="http://localhost:50070/" target="_blank">http://localhost:50070/</a> and the JobTracker Web Interface at <a href="http://localhost:50030/" target="_blank">http://localhost:50030/</a>. If not, check that you have 5 java processes running where each of those java processes have one of the following as their last command line (as seen from a <code>ps ax | grep hadoop</code> command) :</p>
<pre>org.apache.hadoop.mapred.JobTracker
org.apache.hadoop.hdfs.server.namenode.NameNode
org.apache.hadoop.mapred.TaskTracker
org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode
org.apache.hadoop.hdfs.server.datanode.DataNode</pre>
<p>If you do not see these 5 processes, check the logs in ~work/hadoop/logs/*.{out,log} for messages that might give you a hint as to what went wrong.</p>
<h4>Run some example map/reduce jobs</h4>
<p>The Hadoop distro comes with some example / test map / reduce jobs. Here we&#8217;ll run them and make sure things are working end to end.</p>
<pre><code>cd ~/work/hadoop
# Copy the input files into the distributed filesystem
# (there will be no output visible from the command):
bin/hadoop fs -put conf input
# Run some of the examples provided:
# (there will be a large amount of INFO statements as output)
bin/hadoop jar hadoop-*-examples.jar grep input output 'dfs[a-z.]+'
# Examine the output files:
bin/hadoop fs -cat output/part-00000
</code></pre>
<p>The resulting output should be something like:</p>
<pre>3	dfs.class
2	dfs.period
1	dfs.file
1	dfs.replication
1	dfs.servers
1	dfsadmin
1	dfsmetrics.log</pre>
<h2>Configuring HBase</h2>
<p>The following config files all reside in <em>~/work/hbase/conf</em>. As mentioned earlier, use a FQDN or a Bonjour name instead of localhost if you need remote clients to access HBase. But if you don&#8217;t use localhost here, make sure you do the same in the Hadoop config.</p>
<h3>hbase-env.sh</h3>
<p>Add the following line below the commented out JAVA_HOME line is in hbase-env.sh</p>
<pre><code>export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home</code></pre>
<p>Add the following line below the commented out HBASE_CLASSPATH= line</p>
<pre><code>export HBASE_CLASSPATH=${HOME}/work/hadoop/conf</code></pre>
<h3>hbase-site.xml</h3>
<pre><code>&lt;?xml version="1.0"?&gt;
&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;
&lt;?xml version="1.0"?&gt;&lt;?xml-stylesheet type="text/xsl" href="configuration.xsl"?&gt;
&lt;configuration&gt;
  &lt;property&gt;
    &lt;name&gt;hbase.rootdir&lt;/name&gt;
    &lt;value&gt;hdfs://localhost:9000/hbase&lt;/value&gt;
    &lt;description&gt;The directory shared by region servers.
    &lt;/description&gt;
  &lt;/property&gt;
&lt;/configuration&gt;
</code></pre>
<h3>Making Sure HBase is Working</h3>
<p>If you do a ps ax | grep hbase you should see two java processes. One should end with:<br />
<code>org.apache.hadoop.hbase.zookeeper.HQuorumPeer start</code><br />
And the other should end with:<br />
<code>org.apache.hadoop.hbase.master.HMaster start</code><br />
Since we are running in the Pseudo-Distributed mode, there will not be any explicit regionservers running. If you have problems, check the logs in ~/work/hbase/logs/*.{out,log}</p>
<h3>Testing HBase using the HBase Shell</h3>
<p>From the unix prompt give the following command:</p>
<pre>~/work/hbase/bin/hbase shell</pre>
<p>Here is some example commands from the Apache HBase Installation Instructions:</p>
<pre>base&gt; # Type "help" to see shell help screen
hbase&gt; help
hbase&gt; # To create a table named "mylittletable" with a column family of "mylittlecolumnfamily", type
hbase&gt; create "mylittletable", "mylittlecolumnfamily"
hbase&gt; # To see the schema for you just created "mylittletable" table and its single "mylittlecolumnfamily", type
hbase&gt; describe "mylittletable"
hbase&gt; # To add a row whose id is "myrow", to the column "mylittlecolumnfamily:x" with a value of 'v', do
hbase&gt; put "mylittletable", "myrow", "mylittlecolumnfamily:x", "v"
hbase&gt; # To get the cell just added, do
hbase&gt; get "mylittletable", "myrow"
hbase&gt; # To scan you new table, do
hbase&gt; scan "mylittletable"</pre>
<p>You can stop hbase with the command:</p>
<pre>~/work/hbase/bin/stop-hbase.sh</pre>
<p>Once that has stopped you can stop hadoop:</p>
<pre>~/work/hadoop/bin/stop-all.sh</pre>
<h2>Conclusion</h2>
<p>You should now have a fully working Pseudo-Distributed Hadoop / HBase setup on your Mac. This is not suitable for any kind of large data or production project. In fact it will probably fail if you try to do anything with lots of data or high volumes of I/O. HBase seems to not like to work well until you get 4 &#8211; 5 regionservers.</p>
<p>But this Pseudo-Distributed version should be fine for doing experiments with tools and small data sets.</p>
<p>Now I can get on with playing with <a href="http://github.com/clj-sys/cascading-clojure" target="_blank">Cascading-Clojure</a> and <a href="http://nathanmarz.com/blog/introducing-cascalog/" target="_blank">Cascalog</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/howto/hbase-hadoop-on-mac-ox-x/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>Copy an EBS AMI image to another Amazon EC2 Region</title>
		<link>http://blog.ibd.com/scalable-deployment/copy-an-ebs-ami-image-to-another-amazon-ec2-region/</link>
		<comments>http://blog.ibd.com/scalable-deployment/copy-an-ebs-ami-image-to-another-amazon-ec2-region/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 08:45:24 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[Scalable Deployment]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=551</guid>
		<description><![CDATA[<p>Since I&#8217;ve already created an image I liked in the us-west-1 region, I would like to reuse it in other regions. Turns out there is no mechanism within Amazon EC2 to do that. (See How do I launch an Amazon EBS volume from a snapshot across Regions?). I did find one post that talked [...]]]></description>
			<content:encoded><![CDATA[<p>Since I&#8217;ve already created an image I liked in the us-west-1 region, I would like to reuse it in other regions. Turns out there is no mechanism within Amazon EC2 to do that. (See <a href="http://docs.amazonwebservices.com/AWSEC2/latest/DeveloperGuide/index.html?FAQ_Regions_Availability_Zones.html" target="_self">How do I launch an Amazon EBS volume from a snapshot across Regions?</a>). I did find <a href="http://citizen428.net/archives/420-Move-EC2-AMIs-between-regions.html" target="_self">one post</a> that talked a bit about how it can be done &#8220;out of band&#8221;. So I figured I would give that a try instead of doing a full recreation in the new region.</p>
<h2>Prepare the Source Instance and Volume</h2>
<h3>Start an instance in the source region</h3>
<p>Here I&#8217;ll start an instance in us-west-1a where I have the EBS image I want to copy. In this case I&#8217;ll use the image I want to copy, but it could be any image as long as its in the same region as the EBS AMI image that is to be copied. Though we are going to use the instance info to figure out some parameters for creating the new AMI. So if you don&#8217;t make the source instance the same AMI as the one you are copying you will need to supply some of the parameters yourself.</p>
<p>You can use a tool like ElasticFox to do the following creating of instances. Here we&#8217;ll do it with command line tools.</p>
<h3>Set some Shell source variables on host machine</h3>
<p>Just to make using these instructions as a cookbook, we&#8217;ll have some shell variables that you can set once and then all the instructions will use the variables so you can just cut and paste the instructions into your shell.</p>
<pre>src_keypair=id_runa-staging-us-west
src_fullpath_keypair=~/.ssh/runa/id_runa-staging-us-west
src_availability_zone=us-west-1a
src_instance_type=m1.large
src_region=us-west-1
src_origin_ami=ami-1f4e1f5a
src_device=/dev/sdh
src_dir=/src
src_user=ubuntu</pre>
<h3>Start up the source instance and capture the instanceid</h3>
<pre>src_instanceid=$(ec2-run-instances \
  --key $src_keypair \
  --availability-zone $src_availability_zone \
  --instance-type $src_instance_type \
  $src_origin_ami \
  --region $src_region  | \
  egrep ^INSTANCE | cut -f2)
echo "src_instanceid=$src_instanceid"

# Wait for the instance to move to the “running” state
while src_public_fqdn=$(ec2-describe-instances --region $src_region "$src_instanceid" | \
  egrep ^INSTANCE | cut -f4) &amp;&amp; test -z $src_public_fqdn; do echo -n .; sleep 1; done
echo src_public_fqdn=$src_public_fqdn</pre>
<p>This should loop till you see something like:</p>
<pre>$ echo src_public_fqdn=$src_public_fqdn
src_public_fqdn=ec2-184-72-2-93.us-west-1.compute.amazonaws.com</pre>
<h3>Create a volume from the EBS AMI snapshot</h3>
<p>Normally when starting an EBS AMI instance, it automatically created a volume from the snapshot associated with the AMI. Here we create the volume from the snapshot ourselves</p>
<pre># Get the volume id
ec2-describe-instances --region $src_region "$src_instanceid" &gt; /tmp/src_instance_info
src_volumeid=$(egrep ^BLOCKDEVICE /tmp/src_instance_info | cut -f3); echo $src_volumeid
# Now get the snapshot id from the volume id
ec2-describe-volumes --region $src_region $src_volumeid | egrep ^VOLUME &gt; /tmp/volume_info
src_snapshotid=$(cut /tmp/volume_info | cut -f2)
echo $src_snapshotid
src_size=$(cut /tmp/volume_info | cut -f2)
echo $src_size
# Create a new volume from the snapshot
src_volumeid=$(ec2-create-volume --region $src_region --snapshot $src_snapshotid -z $src_availability_zone | egrep ^VOLUME | cut -f2)
echo $src_volumeid</pre>
<h3>Mount the EBS Image of the AMI you want to copy</h3>
<p>Now we&#8217;ll mount the EBS AMI image as a plain mount on the running source instance. In this case we&#8217;re going to use the same image as we launched, but it doesn&#8217;t have to be the same image or even the same architecture.</p>
<pre>ec2-attach-volume --region $src_region $src_volumeid -i $src_instanceid -d $src_device</pre>
<p>You should see something like:</p>
<pre>ATTACHMENT	vol-6e7fee06	i-fb0804be	/dev/sdh	attaching	2010-03-14T09:02:58+0000</pre>
<h2>Prepare the Destination Instance and Volume</h2>
<h3>Set some Shell destination variables on host machine</h3>
<p>You&#8217;ll want to tune these to your needs. This example makes the destination size the same as the source. You could make the destination an arbitrary size as long as it fits the source data.</p>
<pre>dst_keypair=runa-production-us-east
dst_fullpath_keypair=~/.ssh/runa/id_runa-production-us-east
dst_availability_zone=us-east-1b
dst_instance_type=m1.large
dst_region=us-east-1
dst_origin_ami=ami-7d43ae14
dst_size=$src_size
dst_device=/dev/sdh
dst_dir=/dst
dst_user=ubuntu</pre>
<h3>Start up the destination instance and capture the dst_instanceid</h3>
<pre>dst_instanceid=$(ec2-run-instances \
  --key $dst_keypair \
  --availability-zone $dst_availability_zone \
  --instance-type $dst_instance_type \
  $dst_origin_ami \
  --region $dst_region  | \
  egrep ^INSTANCE | cut -f2)
echo "dst_instanceid=$dst_instanceid"

# Wait for the instance to move to the “running” state
while dst_public_fqdn=$(ec2-describe-instances --region $dst_region "$dst_instanceid" | \
  egrep ^INSTANCE | cut -f4) &amp;&amp; test -z $dst_public_fqdn; do echo -n .; sleep 1; done
echo dst_public_fqdn=$dst_public_fqdn</pre>
<p>This should loop till you see something like:</p>
<pre>$ echo dst_public_fqdn=$dst_public_fqdn
dst_public_fqdn=ec2-184-73-71-160.compute-1.amazonaws.com</pre>
<h3>Create an empty destination volume</h3>
<pre>dst_volumeid=$(ec2-create-volume --region $dst_region --size $dst_size -z $dst_availability_zone | egrep ^VOLUME | cut -f2)
echo $dst_volumeid</pre>
<h3>Mount the EBS Image of the AMI you want to copy</h3>
<p>Now we&#8217;ll mount the EBS AMI image as a plain mount on the running source instance. In this case we&#8217;re going to use the same image as we launched, but it doesn&#8217;t have to be the same image or even the same architecture.</p>
<pre>ec2-attach-volume --region $dst_region $dst_volumeid -i $dst_instanceid -d $dst_device</pre>
<p>You should see something like:</p>
<pre>ATTACHMENT	vol-450ed02c	i-65be1f0e	/dev/sdh	attaching	2010-03-14T09:39:20+0000</pre>
<h2>Copy the data from the Source Volume to the Destination Volume</h2>
<h3>Copy your credentials to the source machine</h3>
<p>We&#8217;re going to use rsync to copy from the source to the destination tunneled thru ssh. This eliminates any issues with EC2 security groups. But it does mean you have to copy an ssh private key to the source machine that will then be able to access the destination machine via ssh.</p>
<pre>scp -i $src_fullpath_keypair $dst_fullpath_keypair ${src_user}@${src_public_fqdn}:.ssh</pre>
<h3>Mount the source and destination volumes on their instances</h3>
<pre>ssh -i $src_fullpath_keypair ${src_user}@${src_public_fqdn} sudo mkdir -p $src_dir
ssh -i $src_fullpath_keypair ${src_user}@${src_public_fqdn} sudo mount $src_device $src_dir
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo mkfs.ext3 -F $dst_device
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo mkdir -p $dst_dir
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo mount $dst_device $dst_dir</pre>
<h3>Get the FQDN of the Amazon internal address of the destination machine</h3>
<p>We&#8217;re assuming that the dst instance is the us-east equivalent base AMI of the us-west source base AMI so we can use these kernel and ramdisk to build the new AMI later.</p>
<pre>ec2-describe-instances --region $dst_region "$dst_instanceid" &gt; /tmp/dst_instance_info
dst_internal_fqdn=$(egrep ^INSTANCE /tmp/dst_instance_info | cut -f5); echo $dst_internal_fqdn
dst_kernel=$(egrep ^INSTANCE /tmp/dst_instance_info | cut -f13); echo $dst_kernel
dst_ramdisk=$(egrep ^INSTANCE /tmp/dst_instance_info | cut -f14) ;echo $dst_ramdisk</pre>
<h2>Commands to run on the source machine</h2>
<p>You could do the rsync by logging into the source machine and do the following. I tried to do this by using ssh commands, but the fact that the first ssh from source to destination has to be authenticated was a blocker for me. You could log into the source machine and then sudo ssh to the destination machine (you have to do sudo ssh since the rsync has to be run with sudo and the keys are stored separately for the sudo user and the regular user).<br />
I&#8217;ll show both ways.<br />
Here&#8217;s how you can ssh to the source machine:</p>
<pre>ssh -i $src_fullpath_keypair ${src_user}@${src_public_fqdn}</pre>
<h3>Set up some shell variables on the source machine shell environment</h3>
<pre># This is the key you just copied over
dst_fullpath_keypair=~/.ssh/id_runa-production-us-east
# You need to use the Public FQDN of the destination since its cross region
dst_keypair=runa-production-us-east
src_public_fqdn=ec2-184-72-2-93.us-west-1.compute.amazonaws.com
dst_public_fqdn=ec2-184-73-71-160.compute-1.amazonaws.com
dst_user=ubuntu
src_user=ubuntu
src_dir=/src
dst_dir=/dst</pre>
<h3>Do the rsync</h3>
<p>We are using the rsync options</p>
<ul>
<li><strong>P</strong> Keep partial transferred files and Show Progress</li>
<li><strong>H</strong> Preserve Hard Links</li>
<li><strong>A</strong> Preserve ACLs</li>
<li><strong>X</strong> Preserve extended attributes</li>
<li><strong>a</strong> Archive mode</li>
<li><strong>z</strong> Compress files for transfer</li>
</ul>
<pre>rsync -PHAXaz --rsh "ssh -i /home/${src_user}/.ssh/id_${dst_keypair}" --rsync-path "sudo rsync" ${src_dir}/ ${dst_user}@${dst_public_fqdn}:${dst_dir}/</pre>
<h2>If you want to do the rsync from your local host</h2>
<p>I found that I still had to log into the source instance</p>
<pre>ssh -i $src_fullpath_keypair ${src_user}@${src_public_fqdn}</pre>
<p>and then on the source instance do:</p>
<pre>sudo ssh -i /home/${src_user}/.ssh/id_${dst_keypair} ${dst_user}@${dst_public_fqdn}</pre>
<p>and accept &#8220;<em>The authenticity of host</em>&#8221; for the first time so the destination host is in the known keys of the sudo user<br />
Then back on your local host you can issue the remote command that will run on the source instance and rsync to the destination host:</p>
<pre>ssh -i $src_fullpath_keypair ${src_user}@${src_public_fqdn} sudo "rsync -PHAXaz --rsh \"ssh -i /home/${src_user}/.ssh/id_${dst_keypair}\" --rsync-path \"sudo rsync\" ${src_dir}/ ${dst_user}@${dst_public_fqdn}:${dst_dir}/"</pre>
<h2>Complete the new AMI from your Local Host</h2>
<p>The remaining steps will be done back on your local host. This assumes that the shell variables we set up earlier are still there.</p>
<h3>Some Cleanup for new Region</h3>
<p>Ubuntu has their apt sources tied to the region you are in. So we have to update the apt sources for the new region.<br />
We&#8217;ll do this by chrooting to the mount /dst directory and running some commands as if they were being run on an ami with the /dst image. We might as well update things at the same time to the latest packages.</p>
<pre># Allow network access from chroot environment
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo cp /etc/resolv.conf $dst_dir/etc/

# Upgrade the system and install packages
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo -E chroot $dst_dir mount -t proc none /proc
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo -E chroot $dst_dir mount -t devpts none /dev/pts

cat &lt;&lt;EOF &gt; /tmp/policy-rc.d
#!/bin/sh
exit 101
EOF
scp -i $dst_fullpath_keypair /tmp/policy-rc.d ${dst_user}@${dst_public_fqdn}:/tmp
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo mv /tmp/policy-rc.d $dst_dir/usr/sbin/policy-rc.d

ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} chmod 755 $dst_dir/usr/sbin/policy-rc.d

# This has to be done to set up the Locale &amp; apt sources
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} DEBIAN_FRONTEND=noninteractive sudo -E chroot $dst_dir /usr/bin/ec2-set-defaults

# Update the apt sources
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} DEBIAN_FRONTEND=noninteractive sudo -E chroot $dst_dir apt-get update

# Optionally update the packages
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} DEBIAN_FRONTEND=noninteractive sudo -E chroot $dst_dir apt-get dist-upgrade -y

# Optionally update your gems
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo -E chroot $dst_dir gem update --system
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo -E chroot $dst_dir gem update</pre>
<h4>Clean up from the building of the image</h4>
<pre>ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo chroot $dst_dir umount /proc
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo -E chroot $dst_dir umount /dev/pts
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo -E rm -f $dst_dir/usr/sbin/policy-rc.d</pre>
<h3>There are a few more shell variables we&#8217;ll need</h3>
<p>I got the kernel and ramdisk from the destination instance since it has the alestic.com us-east-1 equivalent base AMI to the us-west-1 one that we are copying from.</p>
<pre># Some info for creating the name and description
codename=karmic
release=9.10
tag=server

# Make sure you set this as appropriate
# 64bit
arch=x86_64

# You will need to set the aki and ari values base on the actual base AMI you used
# It will be different for different regions.  These are set for x86_64 and us-east-1
ebsopts="--kernel=${dst_kernel} --ramdisk=${dst_ramdisk}"
ebsopts="$ebsopts --block-device-mapping /dev/sdb=ephemeral0"

now=$(date +%Y%m%d-%H%M)
# Make this specific to what you are making
chef_version="0.8.6"
prefix=runa-chef-${chef_version}-ubuntu-${release}-${codename}-${tag}-${arch}-${now}
description="Runa Chef ${chef_version} Ubuntu $release $codename $tag $arch $now"</pre>
<h3>Snapshot the Destination Volume and register the new AMI in the destination region</h3>
<pre># Unmount the destination filesystem
ssh -i $dst_fullpath_keypair ${dst_user}@${dst_public_fqdn} sudo umount $dst_dir

# Detach the Destination Volume (it may speed up the snapshot)
ec2-detach-volume --region $dst_region "$dst_volumeid"

# Make the snapshot
dst_snapshotid=$(ec2-create-snapshot -region $dst_region -d "$description" $dst_volumeid | cut -f2)

# Wait for snapshot to complete. This can take a while
while ec2-describe-snapshots --region $dst_region "$dst_snapshotid" | grep -q pending
  do echo -n .; sleep 1; done

# Register the Destination Snapshot as a new AMI in the Destination Region
new_ami=$(ec2-register \
  --region $dst_region \
  --architecture $arch \
  --name "$prefix" \
  --description "$description" \
  $ebsopts \
  --snapshot "$dst_snapshotid")
echo $new_ami</pre>
<h2>Conclusion</h2>
<p>You should now have a shiny new ami in your destination region. Use the value of $new_ami to start a new instance in your destination region using your favorite tool or technique.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/scalable-deployment/copy-an-ebs-ami-image-to-another-amazon-ec2-region/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Nice jruby installation cookbook (Opscode)</title>
		<link>http://blog.ibd.com/sysadmin/nice-jruby-installation-cookbook-opscode/</link>
		<comments>http://blog.ibd.com/sysadmin/nice-jruby-installation-cookbook-opscode/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 03:04:01 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[Opscode Chef]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=546</guid>
		<description><![CDATA[<p>There are a lot of good example Opscode cookbooks out there. Unfortunately they can be hard to find. People are not submitting them to the Opscode Cookbook repository. Its still hard to untangle your own cookbooks into something that can be put in a sharable format I guess.</p> <p>Right now, the most productive way [...]]]></description>
			<content:encoded><![CDATA[<p>There are a lot of good example Opscode cookbooks out there. Unfortunately they can be hard to find. People are not submitting them to the Opscode Cookbook repository. Its still hard to untangle your own cookbooks into something that can be put in a sharable format I guess.</p>
<p>Right now, the most productive way to find cookbooks seems to be to search github. I always do a search before I write my own. Google searches are tough since &#8220;chef&#8221;, &#8220;cookbooks&#8221; are overloaded from the &#8220;real cooking&#8221; domain. And if you put in some package name, you tend to get announcements about the package and a mention about Opscode, but rarely about an Opscode Cookbook for that package.</p>
<p>Today I discovered that I needed a cookbook to install jruby. So after a useless Google Search. I did a search &#8220;jruby cookbook&#8221; on github and soon found <a href="http://github.com/theoooo" target="_blank">Theo Cushion</a>&#8216;s <a href="http://github.com/theoooo/cookbooks/tree/master/jruby/" target="_blank">cookbook clone with a jruby addition</a>.</p>
<p>Its better to not have to write it yourself! My thanks to Theo and the many others who share their code.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/sysadmin/nice-jruby-installation-cookbook-opscode/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple update and clone an Amazon EC2 EBS Boot image</title>
		<link>http://blog.ibd.com/scalable-deployment/simple-update-and-clone-an-amazon-ec2-ebs-boot-image/</link>
		<comments>http://blog.ibd.com/scalable-deployment/simple-update-and-clone-an-amazon-ec2-ebs-boot-image/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 07:54:41 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[Scalable Deployment]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=533</guid>
		<description><![CDATA[Introduction <p>Well there is already an update to Chef&#8217;s Ohai library. At first I thought, &#8220;Oh no, I have to generate another EC2 image&#8221;. But then I remember reading that you can update and clone a running EBS boot image.</p> <p>One of the cool features of using an Amazon EC2 instance that boots from [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<p>Well there is already an update to Chef&#8217;s Ohai library. At first I thought, &#8220;Oh no, I have to generate another EC2 image&#8221;. But then I remember reading that you can update and clone a running EBS boot image.</p>
<p>One of the cool features of using an Amazon EC2 instance that boots from an EBS Snapshot is that its easy to create new boot images from an existing running EC2 instance, assuming that you are running an EC2 instance that is itself bootable from an EBS Image.</p>
<h2>Prerequisites</h2>
<p>The following expects that you have a recent copy of the Amazon ec2-api-tools on the instance and that you have recent version of the ec2-api-tools on your host development system.</p>
<h2>Start up an instance, make changes</h2>
<p>Start up an instance you can use as a base, for instance the one we created in Using the Official Opscode 0.8.x Gems to build EC2 AMI Chef Client and Server</p>
<h3>Get the name of the instance</h3>
<p>First you will need the instance name of your instance you want to copy. You can use Elasticfox or other tool. Or run the following command on the instance:</p>
<pre>wget -qO- http://instance-data/latest/meta-data/instance-id</pre>
<h2>On another host</h2>
<p>The rest of the instructions will be run on your host development system (not the system you are copying). This makes it so you don&#8217;t have to put your Amazon Certs onto the machine you are cloning (you don&#8217;t want those keys to end up on the cloned image)</p>
<h3>Create some shell defines</h3>
<p>To make the instructions easier make some defines we&#8217;ll use in commands. Tune them for your environment.</p>
<pre># This will be the instance id of the running instance you want to clone
instanceid=i-07202042

# Some info for creating the name and description
codename=karmic
release=9.10
tag=server
region=us-west-1
availability_zone=us-west-1a

# Make sure you set this as appropriate
# 64bit
arch=x86_64
arch2=amd64
#32bit
arch=i386
arch2=i386
now=$(date +%Y%m%d-%H%M)

# Make this specific to what you are making
prefix=runa-chef-0.8.4-ubuntu-$release-$codename-$tag-$arch-$now
description="Runa Chef 0.8.4 Ubuntu $release $codename $tag $arch $now"</pre>
<h3>Get the info  about your running instance</h3>
<p>Use Elasticfox or your favorite tool or the following command to get the volume id of the instance</p>
<pre>ec2-describe-instances --region $region "$instanceid" &gt; /tmp/instance_info
volumeid=$(egrep ^BLOCKDEVICE /tmp/instance_info | cut -f3); echo $volumeid
kernel=$(egrep ^INSTANCE /tmp/instance_info | cut -f13); echo $kernel
ramdisk=$(egrep ^INSTANCE /tmp/instance_info | cut -f14) ;echo $ramdisk</pre>
<h3>Shutdown  the instance</h3>
<p>Its not clear if you really need to do this. But when I first tried doing it without shuting down the instance, the snapshots took forever.</p>
<h3>Create a new snapshot</h3>
<pre>snapshotid=$(ec2-create-snapshot -region $region -d "$description" $volumeid | cut -f2)</pre>
<h3>Register the new image</h3>
<pre>ec2reg --region $region -s $snapshotid -a $arch --kernel $kernel --ramdisk $ramdisk -d "$description" -n "$prefix"</pre>
<p>The result of this command will be the ami image name. After this completes, the image and snapshot can be used to create new instances.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/scalable-deployment/simple-update-and-clone-an-amazon-ec2-ebs-boot-image/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using the Official Opscode 0.8.x Gems to build EC2 AMI Chef Client and Server</title>
		<link>http://blog.ibd.com/howto/using-the-official-opscode-0-8-x-gems-to-build-ec2-ami-chef-client-and-server/</link>
		<comments>http://blog.ibd.com/howto/using-the-official-opscode-0-8-x-gems-to-build-ec2-ami-chef-client-and-server/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 06:50:57 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Opscode Chef]]></category>
		<category><![CDATA[Ruby / Rails]]></category>
		<category><![CDATA[Scalable Deployment]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=513</guid>
		<description><![CDATA[Updates Mar 3, 2010 Added call to script ec2-set-defaults that is normally called on ec2 init that sets the locale and apt sources for EC availability Zone Introduction <p>Opscode has officially released 0.8.x of Chef. It is now even more fabulous. I&#8217;ve been using the pre-release version for the last couple of months and [...]]]></description>
			<content:encoded><![CDATA[<h2>Updates</h2>
<ul>
<li><strong>Mar 3, 2010</strong> Added call to script <em>ec2-set-defaults </em>that is normally called on ec2 init that sets the locale and apt sources for EC availability Zone</li>
</ul>
<h2>Introduction</h2>
<p>Opscode has officially released 0.8.x of Chef. It is now even more fabulous. I&#8217;ve been using the pre-release version for the last couple of months and it is rock steady and very powerful. I&#8217;ll be having a post soon on how I used it to deploy a pretty complicated cloud stack with multiple Rails/Mysql/Nginx/Unicorn/Postfix apps for front-ends, and a back end made up of a mix of a Clojure/Swarmiji distributed processing swarm, HBase/Hadoop, Redis, RabbitMQ.</p>
<p>But first, I needed to upgrade my Amazon EC2 AMIs for the officially released Chef 0.8.x. I also wanted to try the EBS Boot image as a basis for the AMI.</p>
<p>This is an update to my earlier post, <a href="http://blog.ibd.com/scalable-deployment/creating-an-amazon-ami-for-chef-0-8/" target="_blank">Creating an Amazon EC2 AMI for Opscode Chef 0.8</a>, but now using the official Opscode 0.8.x Gems instead of building your own Gems. A lot of the content is the same, but you can consider this mostly superceding the older one except where mentioned otherwise. This version will use the EBS Boot AMIs as per Eric Hammond&#8217;s Tutorial Building <a href="http://alestic.com/2010/01/ec2-ebs-boot-ubuntu" target="_blank">EBS Boot AMIs Using Canonical&#8217;s Downloadable EC2 Images</a>. Much of this is blog post is taken from Eric&#8217;s blog post but in the context of creating a Chef Client base AMI and a Chef Server. Note that <a href="http://thecloudmarket.com/owner/345069653647--opscode" target="_blank">Opscode now has their own AMIs,</a> including ones for Chef 0.8.4, but as of this writing, they do not have AMIs for Amazon us-west.</p>
<h2>Setup</h2>
<h3>Prerequisites</h3>
<p>On your host development machine (ie your laptop or whatever machine you are developing from) you should have already installed:</p>
<ul>
<li>ec2-api-tools and ec2-ami-tools (these assume you have a modern Java run time setup)</li>
<li>chef-0.8.4 or later chef client gem (which implies the entire ruby 1.8.x and rubygems toolchain)</li>
</ul>
<h3>Set some Shell variables on host machine</h3>
<p>Just to make using these instructions as a cookbook, we&#8217;ll have some shell variables that you can set once and then all the instructions will use the variables so you can just cut and paste the instructions into your shell.</p>
<pre>keypair=id_runa-staging-us-west
fullpath_keypair=~/.ssh/runa/id_runa-staging-us-west
availability_zone=us-west-1a
instance_type=m1.large
region=us-west-1

# Pick one of these two AMIs (Note that it will be different for different Amazon Regions)
# 32bit AMI
origin_ami=ami-fd5100b8
#64bit AMI
origin_ami=ami-ff5100ba</pre>
<h3>Start up an instance and capture the instanceid</h3>
<pre>instanceid=$(ec2-run-instances \
  --key $keypair \
  --availability-zone $availability_zone \
  --instance-type $instance_type \
  $origin_ami \
  --region $region  |
  egrep ^INSTANCE | cut -f2)
echo "instanceid=$instanceid"</pre>
<h3>Wait for the instance to move to the “running” state</h3>
<pre>while host=$(ec2-describe-instances --region $region "$instanceid" |
  egrep ^INSTANCE | cut -f4) &amp;&amp; test -z $host; do echo -n .; sleep 1; done
echo host=$host</pre>
<p>This should loop till you see something like:</p>
<pre>$ echo host=$host
host=ec2-184-72-2-93.us-west-1.compute.amazonaws.com</pre>
<h3>Upload your certs</h3>
<p>This assumes that your Amazon certs are in ~/.ec2</p>
<pre>rsync                            \
 --rsh="ssh -i $fullpath_keypair" \
 --rsync-path="sudo rsync"      \
 ~/.ec2/{cert,pk}-*.pem         \
 ubuntu@$host:/mnt/</pre>
<h3>Connect to the instance</h3>
<pre>ssh -i $fullpath_keypair ubuntu@$host</pre>
<h3>Update the Amazon ec2 tools on the instance</h3>
<pre>export DEBIAN_FRONTEND=noninteractive
echo "deb http://ppa.launchpad.net/ubuntu-on-ec2/ec2-tools/ubuntu karmic main" |
  sudo tee /etc/apt/sources.list.d/ubuntu-on-ec2-ec2-tools.list &amp;&amp;
sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9EE6D873 &amp;&amp;
sudo apt-get update &amp;&amp;
sudo -E apt-get dist-upgrade -y &amp;&amp;
sudo -E apt-get install -y ec2-api-tools</pre>
<h3>Set some parameters on instance shell environment</h3>
<p>Again this makes it easier to cut and paste the instructions.</p>
<pre>codename=karmic
release=9.10
tag=server
region=us-west-1
availability_zone=us-west-1a
if [ $(uname -m) = 'x86_64' ]; then
  arch=x86_64
  arch2=amd64
  # You will need to set the aki and ari values base on the actual base AMI you used
  # It will be different for different regions.  These are set for us-west-1
  ebsopts="--kernel=aki-7f3c6d3a --ramdisk=ari-cf2e7f8a"
  ebsopts="$ebsopts --block-device-mapping /dev/sdb=ephemeral0"
else
  arch=i386
  arch2=i386
  # You will need to set the aki and ari values base on the actual base AMI you used
  # It will be different for different regions. These are set for us-west-1
  ebsopts="--kernel=aki-773c6d32 --ramdisk=ari-c12e7f84"
  ebsopts="$ebsopts --block-device-mapping /dev/sda2=ephemeral0"
fi</pre>
<h3>Download and unpack the latest released Ubuntu server image file</h3>
<p>This contains the output of vmbuilder as run by Canonical.</p>
<pre>imagesource=http://uec-images.ubuntu.com/releases/$codename/release/unpacked/ubuntu-$release-$tag-uec-$arch2.img.tar.gz
image=/mnt/$codename-$tag-uec-$arch2.img
imagedir=/mnt/$codename-$tag-uec-$arch2
wget -O- $imagesource |
  sudo tar xzf - -C /mnt
sudo mkdir -p $imagedir
sudo mount -o loop $image $imagedir</pre>
<h3>Bring the packages on the instance up to date</h3>
<pre># Allow network access from chroot environment
sudo cp /etc/resolv.conf $imagedir/etc/

# Fix what I consider to be a bug in vmbuilder
sudo rm -f $imagedir/etc/hostname

# Add multiverse
sudo perl -pi -e 's%(universe)$%$1 multiverse%' \
$imagedir/etc/ec2-init/templates/sources.list.tmpl

# Add Alestic PPA for runurl package (handy in user-data scripts)
echo "deb http://ppa.launchpad.net/alestic/ppa/ubuntu karmic main" |
sudo tee $imagedir/etc/apt/sources.list.d/alestic-ppa.list
sudo chroot $imagedir \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys BE09C571

# Add ubuntu-on-ec2/ec2-tools PPA for updated ec2-ami-tools
echo "deb http://ppa.launchpad.net/ubuntu-on-ec2/ec2-tools/ubuntu karmic main" |
sudo tee $imagedir/etc/apt/sources.list.d/ubuntu-on-ec2-ec2-tools.list
sudo chroot $imagedir \
apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 9EE6D873

# Upgrade the system and install packages
sudo chroot $imagedir mount -t proc none /proc
sudo chroot $imagedir mount -t devpts none /dev/pts

cat &lt;&lt;EOF &gt; /tmp/policy-rc.d
#!/bin/sh
exit 101
EOF
sudo mv /tmp/policy-rc.d $imagedir/usr/sbin/policy-rc.d

chmod 755 $imagedir/usr/sbin/policy-rc.d
DEBIAN_FRONTEND=noninteractive

# It seems this has to be done to set up the Locale &amp; apt sources
sudo -E chroot $imagedir /usr/bin/ec2-set-defaults

# Update the apt sources and packages
sudo chroot $imagedir apt-get update &amp;&amp;
sudo -E chroot $imagedir apt-get dist-upgrade -y &amp;&amp;
sudo -E chroot $imagedir apt-get install -y runurl ec2-ami-tools</pre>
<h2>Install Chef Client and other customizations</h2>
<h3>Install Ruby and needed packages</h3>
<pre><code>sudo -E chroot $imagedir apt-get -y install ruby ruby1.8-dev libopenssl-ruby1.8 rdoc ri irb \
build-essential wget ssl-cert git-core rake librspec-ruby libxml-ruby \
thin couchdb zlib1g-dev libxml2-dev emacs23-nox</code></pre>
<h4>Install Rubygems</h4>
<p>Rubygems will be installed from source since debian/ubuntu try to control rubygems upgrades. If you don&#8217;t care you can install it via apt-get install rubygems</p>
<pre><code>cd $imagedir/tmp
wget http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz
tar zxf rubygems-1.3.6.tgz
cd rubygems-1.3.6
sudo -E chroot $imagedir ruby /tmp/rubygems-1.3.6/setup.rb
cd ..
sudo rm -rf rubygems-1.3.6
sudo -E chroot $imagedir ln -sfv /usr/bin/gem1.8 /usr/bin/gem
sudo -E chroot $imagedir gem sources -a http://gems.opscode.com
sudo -E chroot $imagedir gem sources -a http://gemcutter.org
sudo -E chroot $imagedir gem install chef
</code></pre>
<h3>Use Opscode Chef Solo Bootstrap to configure the Chef Client</h3>
<p>The following will set up all the default paths and directories as well as install and configure runit to start and monitor the chef-client. Originally I shied away from runit, but this time I&#8217;m going as Opscode Vanilla as possible and they like runit.</p>
<h4>Create the solo.rb file</h4>
<p>All of the following files should be done in $imagedir as we are going to have to run this as chroot to $imagedir</p>
<p>Create $imagedir/solo.rb with an editor and put in the following:</p>
<pre>file_cache_path "/tmp/chef-solo"
cookbook_path "/tmp/chef-solo/cookbooks"
recipe_url "http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz"</pre>
<h4>Create the chef.json file</h4>
<p>Create $imagedir/chef.json with the following. (set the server_fqdn to the chef server you are using):</p>
<pre>{
  "bootstrap": {
    "chef": {
      "url_type": "http",
      "init_style": "runit",
      "path": "/srv/chef",
      "serve_path": "/srv/chef",
      "server_fqdn": "chef-server-staging.runa.com"
    }
  },
  "run_list": [ "recipe[bootstrap::client]" ]
}</pre>
<h4>Run the chef-solo command</h4>
<pre>sudo -E chroot $imagedir chef-solo -c solo.rb -j chef.json \
  -r http://s3.amazonaws.com/chef-solo/bootstrap-latest.tar.gz</pre>
<p>I had to run it 3 times before it completed with no errors.<br />
After it does work, clean up the chef-solo stuff:</p>
<pre>sudo rm $imagedir/{solo.rb,chef.json}</pre>
<h3>Update the client config file</h3>
<p>The Chef Solo Client bootstrap process creates an /etc/chef/client.rb that is not ideal for Amazon EC2. The following will replace that:</p>
<pre><code>mkdir -p /etc/chef
chown root:root /etc/chef
chmod 755 /etc/chef
</code></pre>
<p>Put the following in /etc/chef/client.rb:</p>
<pre><code>
# Chef Client Config File
# Automatically grabs configuration from ohai ec2 metadata.

require 'ohai'
require 'json'

o = Ohai::System.new
o.all_plugins
chef_config = JSON.parse(o[:ec2][:userdata])
if chef_config.kind_of?(Array)
  chef_config = chef_config[o[:ec2][:ami_launch_index]]
end

log_level        :info
log_location     STDOUT
node_name        o[:ec2][:instance_id]
chef_server_url  chef_config["chef_server"]

unless File.exists?("/etc/chef/client.pem")
  File.open("/etc/chef/validation.pem", "w", 0600) do |f|
    f.print(chef_config["validation_key"])
  end
end

if chef_config.has_key?("attributes")
  File.open("/etc/chef/client-config.json", "w") do |f|
    f.print(JSON.pretty_generate(chef_config["attributes"]))
  end
  json_attribs "/etc/chef/client-config.json"
end

validation_key "/etc/chef/validation.pem"
validation_client_name chef_config["validation_client_name"]

Mixlib::Log::Formatter.show_time = true
</code></pre>
<h2>Finish creating the new image</h2>
<h3>Clean up from the building of the image</h3>
<pre>sudo chroot $imagedir umount /proc
sudo chroot $imagedir umount /dev/pts
sudo rm -f $imagedir/usr/sbin/policy-rc.d</pre>
<h3>Copy the image files to a new EBS volume, snapshot and register the snapshot</h3>
<pre>size=15 # root disk in GB
now=$(date +%Y%m%d-%H%M)
prefix=runa-chef-0.8.4-ubuntu-$release-$codename-$tag-$arch-$now
description="Runa Chef 0.8.4 Ubuntu $release $codename $tag $arch $now"
export EC2_CERT=$(echo /mnt/cert-*.pem)
export EC2_PRIVATE_KEY=$(echo /mnt/pk-*.pem)

volumeid=$(ec2-create-volume --region $region --size $size \
  --availability-zone $availability_zone | cut -f2)

instanceid=$(wget -qO- http://instance-data/latest/meta-data/instance-id)

ec2-attach-volume --region $region --device /dev/sdi --instance "$instanceid" "$volumeid"

while [ ! -e /dev/sdi ]; do echo -n .; sleep 1; done

sudo mkfs.ext3 -F /dev/sdi
ebsimage=$imagedir-ebs
sudo mkdir $ebsimage
sudo mount /dev/sdi $ebsimage

sudo tar -cSf - -C $imagedir . | sudo tar xvf - -C $ebsimage
sudo umount $ebsimage

ec2-detach-volume --region $region "$volumeid"
snapshotid=$(ec2-create-snapshot --region $region "$volumeid" | cut -f2)

ec2-delete-volume --region $region "$volumeid"

# This takes a while
while ec2-describe-snapshots --region $region "$snapshotid" | grep -q pending
  do echo -n .; sleep 1; done

ec2-register \
  --region $region \
  --architecture $arch \
  --name "$prefix" \
  --description "$description" \
  $ebsopts \
  --snapshot "$snapshotid"</pre>
<h2>Afterward</h2>
<p>That will get you an AMI that you can now use as a chef-client. You can use the directions from the section <em>Creating a Chef Server from your new Image</em> in the previous article: <a href="http://blog.ibd.com/scalable-deployment/creating-an-amazon-ami-for-chef-0-8/" target="_blank">Creating an Amazon EC2 AMI for Opscode Chef 0.8</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/howto/using-the-official-opscode-0-8-x-gems-to-build-ec2-ami-chef-client-and-server/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reseting the Opscode Chef Server Validation key/pem</title>
		<link>http://blog.ibd.com/howto/reseting-the-opscode-chef-server-validation-keypem/</link>
		<comments>http://blog.ibd.com/howto/reseting-the-opscode-chef-server-validation-keypem/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 09:48:31 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Opscode Chef]]></category>
		<category><![CDATA[Scalable Deployment]]></category>
		<category><![CDATA[Sysadmin]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=502</guid>
		<description><![CDATA[<p>In upgrading from my own custom hacked pre-0.8.x Chef server/clients to the official new and shiny 0.8.2 release, I wanted to make everything vanilla. One issue was somewhere along the line I set the validation_client_name to &#8220;validator&#8221;. The vanilla setting is &#8220;chef-validator&#8221;.</p> <p>To do this I had to get rid of the &#8220;validator&#8221; and [...]]]></description>
			<content:encoded><![CDATA[<p>In upgrading from my own custom hacked pre-0.8.x Chef server/clients to the official new and shiny 0.8.2 release, I wanted to make everything vanilla. One issue was somewhere along the line I set the validation_client_name to &#8220;validator&#8221;. The vanilla setting is &#8220;chef-validator&#8221;.</p>
<p>To do this I had to get rid of the &#8220;validator&#8221; and &#8220;chef-validator&#8221; authentication client entries I had on the chef-server. It turns out you can&#8217;t just delete them with knife or the web-ui. You have to edit the couchdb to delete the entries.</p>
<p>The fantastic Chef IRC channel came to the rescue in the usual personage of Josh Timberman (jtimberman) who paused from I&#8217;m sure one of his most hectic days of his life (they were still cleaning up all the loose ends of todays release of 0.8.2) to help me. The steps are:</p>
<ul>
<li>Create an ssh tunnel from your local machine to the chef-server:</li>
</ul>
<pre style="padding-left: 60px;">ssh -L 5984:localhost:5984 fqdn-of-chef-server</pre>
<ul>
<li>Then with a browser on your local machine access:</li>
</ul>
<pre style="padding-left: 60px;">http://localhost:5984/_utils</pre>
<p>That will connect you to futon, a web interface to couchdb running on the chef-server.</p>
<ul>
<li>Click on &#8220;chef&#8221;</li>
</ul>
<p style="padding-left: 30px;"><a href="http://ec2-184-72-136-141.compute-1.amazonaws.com/wp-content/uploads/2010/03/Apache-CouchDB-Futon_-Overview-2.jpg"><img class="size-full wp-image-504 alignnone" title="Futon Access to Chef Server CouchDB" src="http://ec2-184-72-136-141.compute-1.amazonaws.com/wp-content/uploads/2010/03/Apache-CouchDB-Futon_-Overview-2.jpg" alt="Futon Access to Chef Server CouchDB" width="383" height="258" /></a></p>
<ul>
<li>Select the View to be Client-&gt;All</li>
</ul>
<p style="padding-left: 30px;"><a href="http://ec2-184-72-136-141.compute-1.amazonaws.com/wp-content/uploads/2010/03/Select-VIew.jpg"><img class="alignnone size-full wp-image-505" title="Select VIew" src="http://ec2-184-72-136-141.compute-1.amazonaws.com/wp-content/uploads/2010/03/Select-VIew.jpg" alt="" width="407" height="287" /></a></p>
<ul>
<li>Select the &#8220;chef-validator&#8221;</li>
</ul>
<p><a href="http://ec2-184-72-136-141.compute-1.amazonaws.com/wp-content/uploads/2010/03/Select-chef-validator.jpg"><img class="alignnone size-full wp-image-506" title="Select chef-validator" src="http://ec2-184-72-136-141.compute-1.amazonaws.com/wp-content/uploads/2010/03/Select-chef-validator.jpg" alt="" width="507" height="361" /></a></p>
<p>Then delete the &#8220;chef-validator&#8221;</p>
<p style="padding-left: 30px;"><a href="http://ec2-184-72-136-141.compute-1.amazonaws.com/wp-content/uploads/2010/03/Select-Delete.jpg"><img class="alignnone size-full wp-image-507" title="Select Delete" src="http://ec2-184-72-136-141.compute-1.amazonaws.com/wp-content/uploads/2010/03/Select-Delete.jpg" alt="" width="507" height="357" /></a></p>
<p>Once you have removed the client authentication from the couchdb, you need to remove the validation.{pem,key,crt} from /etc/chef on the chef server (there may just be validation.pem). Then restart the chef server (/etc/init.d/chef-server restart).</p>
<p>You should now have a fresh clean valid validation.pem in /etc/chef on the chef-server. You can then copy that to the /etc/chef on your chef client[s]. Remeber to also remove the client.pem in /etc/chef on the client. If client.pem is there, the chef-client will not try to re-validate with the new valdation.pem.</p>
<p>Once I had the proper validation.pem I  used the <a href="http://wiki.opscode.com/display/chef/Upgrading+Chef+0.7.x+to+0.8.x" target="_blank">Chef upgrade bootstrapping process</a> to update all my server and clients and use the new validation.pem to create new client authentication on the server. Everything was clean and fresh after that.</p>
<p>Note that this is an unusual situation that requires clearing out the old validator client.  You should not have this problem in any normal situation. If you do have this problem, make backup copies of any validation.pem or client.pem until you make sure everything is cool.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/howto/reseting-the-opscode-chef-server-validation-keypem/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Upstart Documentation Secret Hiding Place</title>
		<link>http://blog.ibd.com/scalable-deployment/documentation-on-upstart/</link>
		<comments>http://blog.ibd.com/scalable-deployment/documentation-on-upstart/#comments</comments>
		<pubDate>Tue, 23 Feb 2010 00:17:42 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[Scalable Deployment]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[upstart]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=493</guid>
		<description><![CDATA[<p>To quote the Upstart home page:</p> <p>is an event-based replacement for the /sbin/init daemon which handles starting of tasks and services duringboot, stopping them during shutdown and supervising them while the system is running.</p> <p>One would think that the best place to find the current documentation on Upstart would be its home page and/or the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.ibd.com/wp-content/uploads/2010/02/upstart80.png"></a>To quote the <a href="http://upstart.ubuntu.com/" target="_blank">Upstart home page</a>:</p>
<blockquote><p><a href="http://blog.ibd.com/wp-content/uploads/2010/02/upstart80.png"><img class="alignleft" title="Upstart" src="http://blog.ibd.com/wp-content/uploads/2010/02/upstart80.png" alt="" width="88" height="24" /></a>is an event-based replacement for the <code>/sbin/init</code> daemon which handles starting of tasks and services duringboot, stopping them during shutdown and supervising them while the system is running.</p></blockquote>
<p>One would think that the best place to find the current documentation on Upstart would be its home page and/or the <a href="http://upstart.ubuntu.com/wiki/" target="_blank">Upstart Wiki</a>. But you would be wrong. The homepage has almost no documentation and the Wiki has ancient documentation (mostly from version 0.3.9 and one page of useless info from 0.5.1while the current version is 0.6.5) with no mention on how to find current documentation.</p>
<p>If you look in /usr/share/doc/upstart* you will find nothing of use.</p>
<p>The secret is man 5 init on an Ubuntu system that has upstart installed (like Ubuntu 9.10). This has some quite good and complete reference info on Upstart.</p>
<p>I have been using forms of Unix for over 30 years (yikes!) and &#8220;init&#8221; is not what I think of when I think of Upstart. Yes I know its a replacement for init now. But I still don&#8217;t think of it the same. If at least the Upstart pages would say &#8220;See man 5 init&#8221; for details, I might remember&#8230;</p>
<p>Anyway, I updated the wiki page to remind me and others that is where to get the latest info&#8230;</p>
<p>A good article that is a bit dated, but has more info than I found anywhere else is:</p>
<p><a href="http://screwyouenterpriseedition.blogspot.com/2008/07/upstart-050trunk-job-definitions.html" target="_blank">Upstart 0.5.0/trunk job definitions: The missing manual!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/scalable-deployment/documentation-on-upstart/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

