Auto Scalingで起動したインスタンスにEIPを自動で設定する方法
みなさんこんにちは。@ryuzeeです。
ピーク性のあるWebシステムをAWS上で運用している場合、Auto Scalingを使ってサーバの台数を増減させるのがベストプラクティスの1つです。こうすることで最大時にあわせたムダなキャパシティを確保する必要がなくなります。
一方で、Webシステムでは、他の外部システムと連携したり、APIを呼び出したりといったことも多くあり、さらに外部システム側ではアクセス元のIPアドレスを絞り込んでいることがあります。
この場合に、外部システムとの通信を行うために、Proxyを用意するというのも手ですが、Proxy自体の可用性や拡張性の問題もあります。 そこで以下では、Auto Scalingで起動したインスタンスに自動でEIPを割り当てる方法を紹介します。こうすることでProxyを経由させる必要もなくなります。
なお、なんでもかんでもEIPを割り当てるのは良い方法とは言えません。上記のような制約がある場合のみで使うことをお勧めします。
事前準備
- 割り当て対象となるEIPを確保します。その際に、Auto Scalingの最大インスタンス起動数にあわせてEIPを確保することになります。なおデフォルトでは1リージョンあたりで使えるEIPの数は5個なので、それで足りない場合は、上限緩和申請をすることになります。
- 起動したEC2インスタンスの中からAPIコールを行ないますので、IAM Roleを作成してください。
スクリプトの作成
方式としては、インスタンスの中でスクリプトを実行し、事前準備のところで確保しておいたEIPの中からまだ割り当てられていないものを割り当てるようにします。
スクリプト(ここではファイル名をeip_from_pool.sh
とします)は以下のようになります。必要な情報はインスタンスメタデータから取得しますので、特にリージョンによる違いはありません。(なお、EC2-Classicではなく、VPC環境での利用を想定していますので、もしEC2-Classic環境の場合は適宜書き換えが必要です)
#!/bin/sh
## 以下は自分の環境に合わせる。
## 作成済みAMIでサービスの起動設定ができていればこういった記述は不要
sudo yum -y install httpd
sudo \rm /etc/httpd/conf.d/welcome.conf
sudo touch /var/www/html/index.html
sudo chmod 666 /var/www/html/index.html
echo "I LOVE SUSHI!!" > /var/www/html/index.html
sudo /sbin/chkconfig --level 2345 httpd on
sudo /etc/rc.d/init.d/httpd restart
## 以下EIPの自動割り当て処理
INSTANCE_ID=`curl http://169.254.169.254/latest/meta-data/instance-id`
REGION=`curl http://169.254.169.254/latest/dynamic/instance-identity/document | grep region | awk -F\" '{print $4}'`
for ALLOC_ID in `aws ec2 describe-addresses --region=$REGION --filter "Name=domain,Values=vpc" --output text | grep -v eipassoc- | awk '{print $2}'`
do
CMD="aws ec2 associate-address --instance-id $INSTANCE_ID --allocation-id $ALLOC_ID --no-allow-reassociation --region=$REGION"
$CMD
STATUS=$?
if [ 0 = $STATUS ] ; then
exit 0
fi
done
exit 1
Auto ScalingのLaunch Configurationの設定
あとは、Auto Scalingの設定をすればOKです。作成自体はコマンドラインでもマネジメントコンソールからでもどちらからでも作成できます。ここではマネジメントコンソール経由で作成します。
マネジメントコンソールでEC2の項目を開き、左ナビゲーションから、Launch Configuration
を選択します。

ここで、Create launch configuration
をクリックします。すると以下のようにAMIの選択の画面に進みます。

自分が利用したいAMIを選択して次に進んでください。なお、本稿で紹介する方式はcloud-init
とawscli
を利用していますので、予めAMIの中にそれらが含まれている必要があります。ここでは、Amazon Linux AMI 2014.09.1 (HVM)
を選択しました。
以下のようにインスタンスタイプの選択画面が表示されるので、好きなものを選びます。

次に詳細設定です。ここが肝になります。

ここでは
- IAM Roleのプルダウンで事前準備で作成しておいたIAM Roleを選択して、起動したEC2インスタンスからアクセスキーやシークレットキーの埋め込みなしでAPIコールできるようにします。
Advanced Details
の項目をクリックして展開します。- そこで、
User data
の項目があるので、As file
を選択してください。ダイアログが表示されるので、先ほど作成したeip_from_pool.sh
を選択します。 IP Address Type
の箇所でAssign a public IP address to every instance.
を選択してください。
以上が終わったら、次に進みます。以下のようにストレージ容量の設定が出ますので、適当なサイズを指定します。

次に、セキュリティグループの設定です。

さらに進むと確認画面が表示されます。

問題なければページ右下のCreate launch configuration
ボタンをクリックします。さらにキーペアの選択ダイアログが表示されますので、利用するキーペアを指定します。

引き続き、Auto Scaling Groupを作ります。上記の画面右下のCreate an Auto Scaling group using this launch configuration
をクリックします。
以下のような画面が表示されるので、初期の台数や起動するVPC、Subnet、紐付けるELBなどを指定します。

必要に応じて、スケーリングポリシーの設定をしたりしてください(ここでは割愛します)。

次に通知設定が表示されますので、ここでも必要に応じて設定してください。

起動するインスタンスに対するタグ付けの設定をお好みに応じて行ないます。

確認画面が表示されます。

問題なければ先に進みます。以下のような画面が表示されればOKです。

これで暫く待っていればEC2インスタンスが起動してきます。このタイミングで先ほどLaunch configuration
で設定したスクリプトが動き、EIPが割り当てられます。
EIPの一覧画面で見てみると、以下のように表示されることが分かると思います。

それでは。