<?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 Transmutaion &#187; Cloud Computing</title>
	<atom:link href="http://blog.ibd.com/tag/cloud-computing/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, 18 Jun 2010 02:00:26 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Modyfying Jets3t S3 GUI tool to work with Walrus (Eucalyptus S3)</title>
		<link>http://blog.ibd.com/scalable-deployment/getting-the-jet3t-s3-gui-tool-to-work-with-walrus-eucalyptus-s3/</link>
		<comments>http://blog.ibd.com/scalable-deployment/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 the excellent [...]]]></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>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/scalable-deployment/getting-the-jet3t-s3-gui-tool-to-work-with-walrus-eucalyptus-s3/feed/</wfw:commentRss>
		<slash:comments>2</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 a bit [...]]]></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>
<div style='clear:both'></div>]]></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>3</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 an EBS Snapshot is [...]]]></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>
<div style='clear:both'></div>]]></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>Creating an Amazon EC2 AMI for Opscode Chef 0.8 Client and Server</title>
		<link>http://blog.ibd.com/scalable-deployment/creating-an-amazon-ami-for-chef-0-8/</link>
		<comments>http://blog.ibd.com/scalable-deployment/creating-an-amazon-ami-for-chef-0-8/#comments</comments>
		<pubDate>Tue, 12 Jan 2010 09:00:21 +0000</pubDate>
		<dc:creator>Robert J Berger</dc:creator>
				<category><![CDATA[HowTo]]></category>
		<category><![CDATA[Opscode Chef]]></category>
		<category><![CDATA[Runa]]></category>
		<category><![CDATA[Scalable Deployment]]></category>
		<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[AWS]]></category>
		<category><![CDATA[Cloud Computing]]></category>
		<category><![CDATA[EC2]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Infrastructure]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.ibd.com/?p=333</guid>
		<description><![CDATA[Changes Since Original

1/13/10: Fix various minor inaccuracies and improved description on how to set up the chef-server. Also removed nanite as a requirement (its no longer used)
1/17/10: Add the requirement to build and install mixlib-authentication for the chef-client
1/21/10: Added a mkdir for /var/log/chef
1/22/10: Added step to insure that /tmp permissions are set

Introduction
<p>Here&#8217;s my experience setting up [...]]]></description>
			<content:encoded><![CDATA[<h2>Changes Since Original</h2>
<ul>
<li>1/13/10: Fix various minor inaccuracies and improved description on how to set up the chef-server. Also removed nanite as a requirement (its no longer used)</li>
<li>1/17/10: Add the requirement to build and install mixlib-authentication for the chef-client</li>
<li>1/21/10: Added a mkdir for /var/log/chef</li>
<li>1/22/10: Added step to insure that /tmp permissions are set</li>
</ul>
<h2>Introduction</h2>
<p>Here&#8217;s my experience setting up an Amazon EC2 AMI and Instance for a Chef Server and Client. It is based mostly on <a href="http://loftninjas.org/" target="_blank">Bryan Mclellan (btm)</a>&#8216;s post of Nov 24, 2009 <a href="http://blog.loftninjas.org/2009/11/24/installing-chef-08-alpha-on-ubuntu-karmic/" target="_blank">Installing Chef 0.8 alpha on Ubuntu Karmic</a> and  his more up to date <a href="http://gist.github.com/242523" target="_blank">GIST: chef 0.8 alpha installation</a>. It has a slightly different focus and is a bit stale if you are building your own 0.8 gems from the <a href="http://github.com/opscode/chef" target="_blank">source</a>.</p>
<h2>Instantiate an Amazon EC2 Instance</h2>
<p>We&#8217;ll start with the Canonical Ubuntu 9.10 Karmic AMI. I always go to <a href="http://alestic.com/" target="_blank">Eric Hammond&#8217;s site  alestic.com</a> to get the pointers to the right AMIs. In this case we&#8217;re using a 32bit image for the US-West Region: ami-7d3c6d38 US-East 32bit: ami-1515f67c. You can use the US-West 64bit image ami-7b3c6d3e, US-East 64bit: ami-ab15f6c2</p>
<p>Start the instance from your local dev machine using the command line ec2-api-tools (available as a package or directly from <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=351" target="_blank">Amazon</a>) or using something like the Firefox <a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=609" target="_blank">Elasticfox</a> and then ssh into the instance so that you can do the following steps on the instance. For the sake of this example, lets say that the Public DNS name for the instance you started is ec2-204-222-170-10.us-west-1.compute.amazonaws.com and the ssh keypair you associated with this new instance is now on your local dec machine in  ~/.ssh/gsg-keypair</p>
<h2>Prerequisite preparation</h2>
<p>The first set of steps need to be done on the instance you just created so login via ssh:</p>
<pre>ssh -i ~/.ssh/gsg-keypair ec2-204-222-170-10.us-west-1.compute.amazonaws.com</pre>
<h3>If on Amazon us-west</h3>
<p>There is a bug in the current us-west Canonical AMI where it does not use the us-west apt server. So you have to correct the apt soruces.list:</p>
<pre><code>sed -i.bak '1,$s/us.ec2.archive.ubuntu.com/us-west-1.ec2.archive.ubuntu.com/' \
/etc/apt/sources.list</code></pre>
<h3>For all cases</h3>
<pre><code>sudo sed -i.bak2 '1,$s/universe/universe multiverse/' /etc/apt/sources.list
sudo apt-get -y update
sudo apt-get -y upgrade
sudo apt-get -y install emacs23 # Of course this is the first package to install!</code></pre>
<pre><code># Will need these to manipulate ec2 images
sudo apt-get -y install ec2-api-tools ec2-ami-tools </code></pre>
<h3>Set up the ruby environment and install rubygems</h3>
<h4>Install Ruby and needed packages</h4>
<pre><code>sudo apt-get -y install -y 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</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 /tmp
wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz
tar zxf rubygems-1.3.5.tgz
cd rubygems-1.3.5
sudo ruby setup.rb
sudo ln -sfv /usr/bin/gem1.8 /usr/bin/gem
sudo gem sources -a http://gems.opscode.com
sudo gem sources -a http://gemcutter.org</code></pre>
<h4>Install Pre-requisit Gems</h4>
<pre><code>sudo gem install cucumber merb-core jeweler uuidtools \
json libxml-ruby --no-ri --no-rdoc</code></pre>
<h3>Building and Installing Chef Related Gems</h3>
<p>Until there are final 0.8.x Chef gems, you will have had to build them on your local machine and upload them to this instance. On your dev machine (this example builds things in ~/src, but it could be anywhere appropriate) follow these instructions to build all the gems and install gems you might need to use your local machine. You will use your local dev machine to develop and manage cookbooks and to manage a remote chef-server:</p>
<pre><code>mkdir ~/src
cd ~/src
git clone git://github.com/opscode/chef.git
git clone git://github.com/opscode/ohai.git
git clone git://github.com/opscode/mixlib-log
git clone git://github.com/opscode/mixlib-authentication.git
# Need to get mixlib-log for client &amp; server and
# mixlib-authentication for the client from git till the 1.1.0 update hits
# See http://tickets.opscode.com/browse/CHEF-823
cd mixlib-log
sudo rake install
cd mixlib-authentication
sudo rake install
cd ../ohai
sudo rake install
cd ../chef
rake gem
# Now cd into ~/src/chef/chef to install the chef client/dev gem on your local machine
cd chef
rake install </code></pre>
<p>Upload the gems needed for the client to your instance. From ~/src on your local dev machine do:</p>
<pre>scp -i ~/.ssh/gsg-keypair chef/chef/pkg/chef-0.8.0.gem  ohai/pkg/ohai-0.3.7.gem \
mixlib-authentication/pkg/mixlib-authentication-1.1.0.gem \
mixlib-log/pkg/mixlib-log-1.1.0.gem  ec2-204-222-170-10.us-west-1.compute.amazonaws.com:</pre>
<h2>Set up the Chef Client on the new Instance</h2>
<p>Now back in your home directory on the instance ec2-204-222-170-10.us-west-1.compute.amazonaws.com install the gems you just copied over:</p>
<pre><code>sudo gem install mixlib-log-1.1.0.gem ohai-0.3.7.gem
sudo gem install chef-0.8.0.gem </code></pre>
<h3>Create the client config file</h3>
<pre><code>mkdir /var/log/chef
mkdir /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

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     "/var/log/chef/client.log"
chef_server_url  chef_config["chef_server"]
registration_url chef_config["chef_server"]
openid_url       chef_config["chef_server"]
template_url     chef_config["chef_server"]
remotefile_url   chef_config["chef_server"]
search_url       chef_config["chef_server"]
role_url         chef_config["chef_server"]
client_url       chef_config["chef_server"]

node_name        o[:ec2][:instance_id]

unless File.exists?("/etc/chef/client.pem")
  File.open("/etc/chef/validation.pem", "w") 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>
<h4>Set up the /etc/init.d/chef-client</h4>
<p>Copy the example init.d script (You can also use runit instead, but we&#8217;re not going to describe that here)</p>
<pre><code>cp /usr/lib/ruby/gems/1.8/gems/chef-0.8.0/distro/debian/etc/init.d/chef-client /etc/init.d
cd /etc/init.d
update-rc.d chef-client defaults</code></pre>
<h4>Create an Init script to set /tmp to proper permmissions</h4>
<p>It looks like the Canonical Images will not  have /tmp with proper permissions if you exclude /tmp from your bundle process. Eric Hammond <a href="https://developer.amazonwebservices.com/connect/message.jspa?messageID=160098" target="_blank">recommends</a> doing the following.</p>
<p>Create a file /etc/init.d/ec2-mkdir-tmp with the following contents:</p>
<pre>#!/bin/sh
#
# ec2-mkdir-tmp Create /tmp if missing (as it's nice to bundle without it).
#
mkdir -p    /tmp
chmod 01777 /tmp</pre>
<p>Then set up the /etc/rc dirs to launch this on boot:</p>
<pre>
<pre>chmod a+x /etc/init.d/ec2-mkdir-tmp
ln -s /etc/init.d/ec2-mkdir-tmp /etc/rcS.d/S36ec2-mkdir-tmp</pre>
</pre>
<h3><strong>Build the EC2 Image</strong></h3>
<p>The always amazingly helpful <a href="http://www.anvilon.com/" target="_blank">Eric Hammond</a> has a post, <a href="http://alestic.com/2009/06/ec2-ami-bundle" target="_blank">Creating a New Image for EC2 by Rebundling a Running Instance</a>, that describes the basics of how to do this. The following is pretty much a direct synopsis with minimal explanation. See his blog post for more details.</p>
<h3>Clean up potential security holes</h3>
<p>Remove stuff you don&#8217;t want to freeze into your image.</p>
<pre><code>sudo rm -f /root/.*hist* $HOME/.*hist*
sudo rm -f /var/log/*.gz</code></pre>
<h3>Copy AWS Certs to Instance</h3>
<p>Back on your local development system, copy your Amazon certificates to the instance.</p>
<pre><code>
remotehost=&lt;ec2-instance-hostname&gt;
remoteuser=ubuntu
scp -i &lt;private-ssh-key&gt; \
  &lt;path-to-certs&gt;/{cert,pk}-*.pem \
  $remoteuser@$remotehost:/tmp
</code></pre>
<h3>Create the new Image on the Instance</h3>
<p>Back on the ec2 instance, you&#8217;ll do the following to create the image.</p>
<h4>Define where to store the image on S3</h4>
<p>This assumes you have an S3 account setup on AWS. You don&#8217;t have to have already created the bucket. Set some bash variables that will be used by the commands that follow. You should set the prefix to something that is meaningful. Below is what I used as an example. You&#8217;ll want to make it unique to your environment. The Bucket name must be Globally unique across all of Amazon S3.</p>
<pre><code>bucket=runa-west-amis
prefix=runa-ubuntu-9.10-i386-20100101-base</code></pre>
<h4>Define your AWS credentials and target processor</h4>
<pre><code>export AWS_USER_ID=&lt;your-value&gt;
export AWS_ACCESS_KEY_ID=&lt;your-value&gt;
export AWS_SECRET_ACCESS_KEY=&lt;your-value&gt;

if [ $(uname -m) = 'x86_64' ]; then
  arch=x86_64
else
  arch=i386
fi
</code></pre>
<p>Bundle the files<br />
This also runs on the current instance and will bundle the everything on the instance file system except for dirs specified with the -e flag into a copy of the image under /mnt:</p>
<pre><code>sudo -E ec2-bundle-vol           \
  -r $arch                       \
  -d /mnt                        \
  -p $prefix                     \
  -u $AWS_USER_ID                \
  -k /tmp/pk-*.pem               \
  -c /tmp/cert-*.pem             \
  -s 10240                       \
  -e /mnt,/tmp,/root/.ssh,/home/ubuntu/.ssh
</code></pre>
<h5>If you are deploying to US-West-1 AWS Region</h5>
<p>Looks like the Amazon ec2 ami tools are not super aware about us-west yet. So you have to do this extra step right now. You&#8217;ll have to change the &#8211;kernel and &#8211;ramdisk to the ones appropriate for your kernel. You can inspect the values used for the AMI you used to boot the original instance. You can do this with ElasticFox or with the command (specify the AMI and region its in thatyou want to check):</p>
<pre>ec2-describe-images ami-7d3c6d38   -C /tmp/cert-*.pem -K /tmp/pk-*.pem --region us-west-1</pre>
<p>Then execute the following command and specify the right kernel and ramdisk</p>
<pre><code>sudo -E ec2-migrate-manifest        \
  -c /tmp/cert-*.pem             \
  -k /tmp/pk-*.pem               \
  -m /mnt/$prefix.manifest.xml   \
  --access-key $AWS_ACCESS_KEY_ID  \
  --secret-key $AWS_SECRET_ACCESS_KEY \
  --kernel aki-773c6d32          \
  --ramdisk ari-713c6d34         \
  --region us-west-1</code></pre>
<p><code> </code></p>
<h4>Upload the bundle to a bucket on S3:</h4>
<pre><code>sudo -E ec2-upload-bundle        \
    -b $bucket                   \
    -m /mnt/$prefix.manifest.xml \
    -a $AWS_ACCESS_KEY_ID        \
    -s $AWS_SECRET_ACCESS_KEY    \
    --location us-west-1
</code></pre>
<p>You may be prompted with something like:</p>
<pre><code>You are bundling in one region, but uploading to another. If the kernel or ramdisk associated with this AMI are not in the target region, AMI registration will fail.
You can use the ec2-migrate-manifest tool to update your manifest file with a kernel and ramdisk that exist in the target region.
Are you sure you want to continue? [y/N]
</code></pre>
<p>You should enter y return to accept.</p>
<h4>Register the AMI</h4>
<p>Back on your local development machine:</p>
<pre><code>ec2-register $bucket/$prefix.manifest.xml --region us-west-1</code></pre>
<p>The output of this will be the ami-id of your new instance. You can use this to instantiate your new ami.</p>
<p>You now have a private ami image you can start just like any other image. If you want to make it public</p>
<pre><code>ec2-modify-image-attribute -l -a all </code></pre>
<h2>Using the new AMI Image</h2>
<p>You can now use this instance as the basis for chef clients and also the basis to create a Chef Server. Use the Amazon EC2 tool, ElasticFox or whatever you favorite tool for managing EC2 instances to make a new instance first to create a Chef Server. Then after that you can create clients and have them load their roles and recipes from the chef server. Once you have a Chef Server, you can use knife ec2 instance command to create user data that includes a run list, credentials and other json that can be passed to the general ec2 tools to build specific instances.</p>
<h3>Creating a Chef Server from your new Image</h3>
<p>Using an EC2 tool like ec2-tools or elasticfox, create a new instance based on the AMI created earlier. You should use at least a c1.medium as the m1.small is just too painfully wimpy to use. Assume the new instance has the Public DNS name: <code>ec2-204-203-51-20.us-west-1.compute.amazonaws.com</code><br />
Copy the chef server gems to the new instance from the ~/src directory in your local dev environment to the new instance:</p>
<pre><code>scp -i ~/.ssh/gsg-keypair chef/*/pkg/*.gem \
ec2-204-203-51-20.us-west-1.compute.amazonaws.com:</code></pre>
<p>ssh to the new instance and do the following:</p>
<pre><code>sudo gem install chef-server-0.8.0.gem chef-server-api-0.8.0.gem \
chef-server-webui-0.8.0.gem chef-solr-0.8.0.gem</code></pre>
<h4>Set things up to use bootstrap client using chef-solo</h4>
<p>We&#8217;ll be using the last part of BTM&#8217;s GIST, and danielsdeleo (Dan DeLeo)&#8217;s <a href="http://github.com/danielsdeleo/cookbooks/tree/08boot/bootstrap" target="_blank">bootstrap cookbook</a> and chef-solo to set up this initial server.</p>
<pre><code>mkdir -p /tmp/chef-solo
cd /tmp/chef-solo
git clone git://github.com/danielsdeleo/cookbooks.git
cd cookbooks
git checkout 08boot
</code></pre>
<p>Create ~/chef.json:</p>
<pre><code>{
  "bootstrap": {
    "chef": {
      "url_type": "http",
      "init_style": "runit",
      "path": "/srv/chef",
      "serve_path": "/srv/chef",
      "server_fqdn": "localhost"
    }
  },
  "recipes": "bootstrap::server"
}
# End of file
</code></pre>
<p>Create ~/solo.rb with the following content:</p>
<pre><code>file_cache_path "/tmp/chef-solo"
cookbook_path "/tmp/chef-solo/cookbooks"
# End of ~/solo.rb file
</code></pre>
<p>Run chef-solo which will execute the chef bootstrap recipes using the bootstrap params in ~/chef.json to actually setup and configure this chef server</p>
<p>If you had installed rubygems with the ubuntu apt package you may have to specify the path:</p>
<pre><code>/var/lib/gems/1.8/bin/</code></pre>
<p>instead of:</p>
<pre><code>/usr/bin</code></pre>
<p>for the knife and various chef commands in the following code.</p>
<pre><code>/usr/bin/chef-solo -j ~/chef.json -c ~/solo.rb -l debug</code></pre>
<p>You will see a lot of Debug statements go by and it will take several minutes to complete. It should complete with something like:</p>
<pre><code>[Thu, 14 Jan 2010 00:19:38 +0000] INFO: Chef Run complete in 38.59808 seconds
[Thu, 14 Jan 2010 00:19:38 +0000] DEBUG: Exiting</code></pre>
<h5>Setup basic cookbooks</h5>
<p>The following will install the standard cookbooks on the chef server</p>
<pre><code>cd
git clone git://github.com/opscode/chef-repo.git
cd chef-repo
rm cookbooks/README
git clone git://github.com/opscode/cookbooks.git
</code></pre>
<p>Now upload the standard cookbooks using the credentials set up by the bootstrap process (user chef-webui)</p>
<pre><code>knife cookbook upload --all -u chef-webui \
-k /etc/chef/webui.pem -o cookbooks
</code></pre>
<h5>Startup the Chef Server web ui</h5>
<p>Do to a bug (http://tickets.opscode.com/browse/CHEF-839) you have to run this twice, the first time will create the admin user:</p>
<pre><code>sudo /usr/bin/chef-server-webui -p 4002</code></pre>
<p>But the first time will abort with an error message like:</p>
<pre><code>Loading init file from /usr/lib/ruby/gems/1.8/gems/chef-server-0.8.0/config/init-webui.rb
Loading /usr/lib/ruby/gems/1.8/gems/chef-server-0.8.0/config/environments/development.rb
~ Loaded slice 'ChefServerWebui' ...
WARN: HTTP Request Returned 404 Not Found: Cannot load user admin
~ Compiling routes...
~ Could not find resource model Node
~ Could not find resource model Client
~ Could not find resource model Role
~ Could not find resource model Search
~ Could not find resource model Cookbook
~ Could not find resource model Client
~ Could not find resource model Databag
~ Could not find resource model DatabagItem
/usr/lib/ruby/gems/1.8/gems/chef-server-0.8.0/config/init-webui.rb:32: uninitialized constant OpenID (NameError)
from /usr/lib/ruby/gems/1.8/gems/merb-core-1.0.15/lib/merb-core/bootloader.rb:1258:in `call'
from /usr/lib/ruby/gems/1.8/gems/merb-core-1.0.15/lib/merb-core/bootloader.rb:1258:in `run'
from /usr/lib/ruby/gems/1.8/gems/merb-core-1.0.15/lib/merb-core/bootloader.rb:1258:in `each'
from /usr/lib/ruby/gems/1.8/gems/merb-core-1.0.15/lib/merb-core/bootloader.rb:1258:in `run'
from /usr/lib/ruby/gems/1.8/gems/merb-core-1.0.15/lib/merb-core/bootloader.rb:99:in `run'
from /usr/lib/ruby/gems/1.8/gems/merb-core-1.0.15/lib/merb-core/server.rb:172:in `bootup'
from /usr/lib/ruby/gems/1.8/gems/merb-core-1.0.15/lib/merb-core/server.rb:42:in `start'
from /usr/lib/ruby/gems/1.8/gems/merb-core-1.0.15/lib/merb-core.rb:173:in `start'
from /usr/lib/ruby/gems/1.8/gems/chef-server-0.8.0/bin/chef-server-webui:76
from /usr/bin/chef-server-webui:19:in `load'
from /usr/bin/chef-server-webui:19</code></pre>
<p>Then again to actually start the WebUI and have it run in the background. You might want to start it in <a href="http://www.gnu.org/software/screen/" target="_blank">screen</a> for now or possibly redirect its output to a log file The following example shows sending the output of the command to a log file. You&#8217;ll want to check that log file after starting to make sure there were no errors.</p>
<pre><code>sudo sh -c '/usr/bin/chef-server-webui -p 4002 &gt; /var/log/</code><code>chef-server-webui.log' &amp;</code></pre>
<p>If you look at the output of a ps, you&#8217;ll see the shell command above, but the real work is being done by a merb instance with the port you specified (4002):</p>
<pre><code>#ps ax | grep webui
5533 pts/0    S      0:00 sh -c /usr/bin/chef-server-webui -p 4002 &gt; /var/log/chef-server-webui.log
#ps ax | grep merb
3694 ?        Sl     0:55 merb : worker (port 4000)
5534 pts/0    Sl     0:07 merb : worker (port 4002)</code></pre>
<p>The first merb worker is the chef-server itself, the second is the WebUI server.</p>
<p>Accessing the Chef Web UI</p>
<p>You can access the Chef Web UI web server using a web browser at the IP address / Public DNS name of this server that was just set up. Assuming the Public DNS is</p>
<pre><code>ec2-204-203-51-20.us-west-1.compute.amazonaws.com</code></pre>
<p>Assuming that you set up this instance to allow you to access port 4002 from the IP adddress of your local dev machine, you should be able to access the Web UI at</p>
<pre><code>http://ec2-204-203-51-20.us-west-1.compute.amazonaws.com:4002</code></pre>
<p>You can allow access to port 4002 from specific ip address ranges by updating your <a href="http://docs.amazonwebservices.com/AWSEC2/2007-08-29/DeveloperGuide/distributed-firewall-concepts.html" target="_blank">security group</a>. You can do that with ElasticFox (easy) or via the <a href="http://docs.amazonwebservices.com/AWSEC2/2007-08-29/DeveloperGuide/distributed-firewall-examples.html" target="_blank">command line tools</a> (a pain for a one off). Eventually you (or hopefully Opscode) will  set up an apache or nginx reverse proxy, Passenger or equiv to allow normal port 80 / 443 http/https access.</p>
<h2>Conclusion</h2>
<p>You should now be able to use  knife your local dev environment to develop cookbooks and upload roles and cookbooks to your new Chef Server and spin up new chef cookbook driven instances. You should use the knife documentation from the Opscode main wiki <a href="http://wiki.opscode.com/display/chef/Knife" target="_blank">Knife Page</a> <strong>NOT</strong> the docs in the Alpha Forums / Getting Started With Opscode / <a href="http://opscode.zendesk.com/forums/58858/entries/53988" target="_blank">Knife &#8211; Commandline API</a> as the later is actually more obsolete in terms of the version that you built from the opscode git repository. There is also a man page and knife &#8211;help gives you pretty much the same correct info as the wiki.</p>
<p>I hope to have a follow up post on how to do this in more details.</p>
<p>Feel free to leave comments if you find problems or have questions.</p>
<div style='clear:both'></div>]]></content:encoded>
			<wfw:commentRss>http://blog.ibd.com/scalable-deployment/creating-an-amazon-ami-for-chef-0-8/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
