LoginSignup
3
1

More than 5 years have passed since last update.

【AWS】CliでSpotInstanceを作成&Route53とELB登録

Last updated at Posted at 2015-11-10

前置き

現在性能試験で利用しているEC2の料金が高いことから、スポットインスタンスを検討することになりました。
条件として

  • PrivateIpを固定
  • 異なるAMIからそれぞれのEC2をローンチ
  • 同じELBを利用

があるため、ちょっとめんどくさかったのでメモします。

インスタンス作成リクエスト

spot-instanse-request

参考:http://docs.aws.amazon.com/cli/latest/reference/ec2/request-spot-instances.html

スポットインスタンス作成のリクエストを発行します。
リクエスト発行前にインスタンスのattibuteを設定したjsonを用意しておいて下さい。
リクエスト時に返却されるJsonからリクエストIDを取得して、リクエストの状況を監視します。

instance.json
{
  "ImageId": "ami-12345679",
  "InstanceType": "m3.large",
  "KeyName": "key-name",
  "NetworkInterfaces": [
    {
      "SubnetId": "subnet-12345678",
      "DeviceIndex": 0,
      "PrivateIpAddress": "123.45.67.890",
      "Groups": [
        "sg-12345678"
      ]
    }
  ],
  "IamInstanceProfile": {
      "Name": "iam-name"
  }
}
request-sopt.sh
REQUESTID=$(aws ec2 request-spot-instances --spot-price "0.01" --instance-count 1 --type "one-time" --launch-specification file://instance.json --query SpotInstanceRequests[*].SpotInstanceRequestId --output text)

状況監視

describe-spot-instance

参考:http://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/spot-requests.html

リクエストの状況を監視します(ステータスの移行ルールに関しては上記参考URL参照)。

check-status.sh
while :
do
  STATE=$(aws ec2 describe-spot-instance-requests --filters Name=spot-instance-request-id,Values=${REQUESTID} --query SpotInstanceRequests[*].State --output text)
  echo ${STATE}
  if [ -z ${STATE} ]; then
    sleep 5s
  elif [ ${STATE} = "active" ]; then
    break
  elif [ ${STATE} = "failed" ]; then
    exit 1
  else
    sleep 5s
  fi
done

ステータスがactiveになった時点でELBへの登録を行います。

Route53登録

参考:http://qiita.com/3utama/items/5a0211e6bad7380b8a27

# Get Public Dns
PUBLICDNS=$(aws ec2 describe-instances --region ap-northeast-1 --instance-ids ${INSTANCEID} --query Reservations[*].Instances[*].PublicDnsName --output text)

if [ -z ${PUBLICDNS} ]; then                                                                                                                                          # Get Private IP
  PRIVATEIP=$(aws ec2 describe-instances --region ap-northeast-1 --instance-ids ${INSTANCEID} --query Reservations[*].Instances[*].PrivateIpAddress --output text)
  # Create Route53 A Reocrd
  sudo cli53 rrcreate hosted_zone $3 A ${PRIVATEIP} --replace --ttl 60
else
  # Create Route53 CNAME Reocrd
  sudo cli53 rrcreate hosted_zone $3 CNAME ${PUBLICDNS} --replace --ttl 60
fi

ELB設定

参考:http://docs.aws.amazon.com/ja_jp/ElasticLoadBalancing/latest/DeveloperGuide/elb-deregister-register-instances.html#deregister-instances-cli

まずはアクティブになったリクエストのインスタンスIDを取得します。

get-instance-id.sh
INSTANCEID=$(aws ec2 describe-spot-instance-requests --filters Name=spot-instance-request-id,Values=${REQUESTID} --query SpotInstanceRequests[*].InstanceId --output text)

そのインスタンスをELBに登録します。

regist-lb.sh
aws elb register-instances-with-load-balancer --load-balancer-name lbname --instances ${INSTANCEID}

まとめ

まとめるとこんな感じです。

引数は、落札価格 ドメイン名 ELB名です。
※ドメイン名.jsonでインスタンスプロパティーを設定しておいて下さい。
 作成したいインスタンスタイプ毎に分けておくと便利かも。

request-spot-elb.sh
# Spot Instance Request
REQUESTID=$(aws ec2 request-spot-instances --spot-price "$1" --instance-count 1 --type "one-time" --launch-specification file://$2.json --query SpotInstanceRequests[*].SpotInstanceRequestId --output text)

# Check Status
while :
do
  STATE=$(aws ec2 describe-spot-instance-requests --filters Name=spot-instance-request-id,Values=${REQUESTID} --query SpotInstanceRequests[*].State --output text)
  echo ${STATE}
  if [ -z ${STATE} ]; then
    sleep 10s
  elif [ ${STATE} = "active" ]; then
    break
  elif [ ${STATE} = "failed" ]; then
    exit 1
  else
    sleep 5s
  fi
done
if [ $? -eq 1 ];then
  exit 1
fi

# Get Instance Id 
INSTANCEID=$(aws ec2 describe-spot-instance-requests --filters Name=spot-instance-request-id,Values=${REQUESTID} --query SpotInstanceRequests[*].InstanceId --output text)

# Get Public Dns
PUBLICDNS=$(aws ec2 describe-instances --region ap-northeast-1 --instance-ids ${INSTANCEID} --query Reservations[*].Instances[*].PublicDnsName --output text)
if [ -z ${PUBLICDNS} ]; then                                                                                                                                          # Get Private IP
  PRIVATEIP=$(aws ec2 describe-instances --region ap-northeast-1 --instance-ids ${INSTANCEID} --query Reservations[*].Instances[*].PrivateIpAddress --output text)
  # Create Route53 A Reocrd
  sudo cli53 rrcreate hosted_zone $3 A ${PRIVATEIP} --replace --ttl 60
else
  # Create Route53 CNAME Reocrd
  sudo cli53 rrcreate hosted_zone $3 CNAME ${PUBLICDNS} --replace --ttl 60
fi

# Regist ELB
if [ -n "$4" ]; then
  aws elb register-instances-with-load-balancer --load-balancer-name $3 --instances ${INSTANCEID}
fi

監視サイクルは5秒、activeになるまでのタイムアウトは5分でやってます。
一時的なインスタンスを手ごろにコストダウンするのにいいですね。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1