はじめての cloud-init:hostname を Name タグのものにそろえる

EC2 インスタンスの起動時に、せっかく Name タグがあるのに hostname と同じものになっていないのはもったいないな、と思って
それを自動的にやる方法について調べてみました。

Amazon LinuxUbuntu には、EC2 インスタンスの起動時にインスタンスの user-data 属性にセットされたスクリプトを実行する
cloud-init という機能を持っているというところにたどり着いたので、
この記事ではこの cloud-init を使って設定することにしました。

はじめての cloud-init

cloud-init は前述通り、インスタンスの user-data にスクリプトを突っ込んでおくだけで動作します。
登録しておくスクリプトにはいくつか形式があり、YAML 形式で書いて設定する方法もある(#cloud-config 方式?)ようですが、
ここではシンプルにシェルスクリプトを使って設定を行うことにします。

というわけで、書いたスクリプトをぺたっと貼っておきます。

#!/bin/sh
export DOMAIN=my_app.com
export EC2_HOME=/opt/aws/apitools/ec2
export JAVA_HOME=/usr/lib/jvm/jre
export REGION=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone/ | sed 's/.$//'`
export INSTANCE_ID=`/usr/bin/curl -s http://169.254.169.254/latest/meta-data/instance-id`
export TAG_NAME=`/opt/aws/bin/ec2-describe-instances -O $AWS_ACCESS_KEY_ID -W $AWS_SECRET_ACCESS_KEY --region $REGION $INSTANCE_ID | grep "^TAG.*\sName" | cut -f5`

hostname $TAG_NAME.$DOMAIN

やっていることはシンプルで、

  • AWS の Web API を使ってそのインスタンスが属するリージョンを調べて
  • 自分のインスタンス ID を取得して
  • ec2-describe-instances コマンドで Name タグの情報を取り出して
  • hostname コマンドで設定する

というものです。
ec2-describe-instances を実行するには $EC2_HOME や $JAVA_HOME の設定が必要だったり、
フルパス指定しないとコマンドが見つからなかったりするのにしばらくハマってました orz

あと、貼り付ける際に AWS_ACCESS_KEY_ID と AWS_SECRET_ACCESS_KEY の設定行を消してあるので、ここは適切なものを設定置いてください。

このスクリプトをあたらしいインスタンスの user-data に貼り付けて起動してみてください。
ログインすれば Name タグと同じホスト名になっているはずです。

※ /etc/sysconfig だの /etc/hosts だのは書き換えていないので、必要に応じてスクリプトを加筆しておいてください。

なんのために hostname を自動設定するの?

chef-client は起動時の hostname を使って chef-server に登録を行うので、
最初に付けられているホスト名ではなく、よりわかりやすい名前を付けるために Name タグを使ってみることにしました。

でも、よく考えたら自分の場合は capistrano + chef-solo という組み合わせでほとんど用が足りているので、
この処理も capistrano でやってしまえばよかったですね。ざんねん。