Using Chef with Joyent Compute Service and SmartDataCenter

A random collection of thoughts and tools I use for interacting with Joyent Compute Service and SmartDataCenter and Chef.

This is not a tutorial for setting up the SDC CLI (npm smartdc) or Chef or Knife for Joyent within Chef.  I expect that you already have those set up.

I assume you have run the following:

npm install -g smartdc jsontool
gem install knife-joyent --no-ri --no-rdoc

One of the most common things you will want is a lightning-quick report of the machines you are running.  This can be done with either knife-joyent:

knife joyent server list

Or with SDC CLI and jsontool:

sdc-listmachines | json -a id name state ips[0]

The script above for sdc-listmachines can be easily tuned to generate a great variety of reports, but I find id, name, state, and public IP very useful most of the time.

A common thing to do when doing infrastructure research is to bring up a pile of instances and then tear them down again.  Removing the tedium of this so that it can be done reliably and not burn a hole in your pocket is good.  It is also good to not delete your chef server.  Been there, done that, got the dunce cap so I gave my chef server a name containing chef and made sure not to delete it in future. Here is a script that deletes running instances that are not the chef server:

sdc-listmachines | json -a id name state | grep -v chef | \
grep running | xargs -n1 knife joyent server delete -y

I have found it useful to create machines directly with sdc-createmachine.  It has some interesting capabilities, but it will return before the machine is up so you need a strategy for waiting until a machine is up.  knife-joyent has this problem solved so you can get off the crazy train here if you like.

Create a tool ~/bin/check_state:

#!/bin/bash -e
sdc-getmachine $1 | json -a state

Create a tool ~/bin/wait_for_server:

#!/bin/bash -e
until [ "$(check_state $1)" == running ]
do
  sleep 2
done
echo $1

With these tools you can make a pipeline to build a system with entirely vanilla tools from all parties, no Knife Plugins required:

sdc-createmachine --package g3-standard-3.75-smartos \
  --dataset f669428c-a939-11e2-a485-b790efc0f0c1 \
  --name alain-demo-$(uuid) | json -a id | \
  xargs wait_for_server | xargs sdc-getmachine | \
  json -a ips[0] | xargs -n1 knife bootstrap \
  --distro joyent-smartmachine --node-name demo-example \
  --run-list 'role[demo]'

Not the most elegant beast, but it can easily be made to hide inside a script itself.  If a Knife Plugin lacks the capabilities you need you don't need to sit around and wait for a fix, you can easily reach for the SDC CLI which is feature complete.  This is no way a knock on Kevin's work on knife-joyent, which is excellent.  It is just a reality that the Knife Plugin is playing catch-up and you may need to immediately avail of SDC functionality that it doesn't yet have.  The tools are composable so it makes sense to compose them in my mind.