AutoScalingを使ってEC2インスタンスを指定時刻に起動・停止させる

  • このエントリーをはてなブックマークに追加

AutoScalingは、アクセス数の増減の傾向がわかっている時間に応じてWebサーバを自動的に増やしたり減らしたりするのに使われる場合がほとんどだと思いますが、単純に任意の時刻に自動的にサーバを起動させたり停止させたりするということもできます。

これを使うと夜中に1時間だけ起動してバッチを動かすというような使い方ができるので、そのサンプルスクリプトを作ってみました。

なお、userdata.txtは「AmazonLinuxでcloud-initを使う」のものを使っています。

#!/bin/bash

#Create launch configuration params
REGION='--region=ap-northeast-1'
LAUNCH_CONFIGURATION_NAME='--launch-configuration-name=[[Launch Configuration Name]]'
IMAGE_ID='--image-id=ami-35072834'
KEY_NAME='--key-name=[[Key Pair Name]]'
SECURITY_GROUPS='--security-groups=[[Security Group ID(sg-xxxxxxxx)]]'
USER_DATA='--user-data=file://userdata.txt'
INSTANCE_ID=''
INSTANCE_TYPE='--instance-type=t2.micro'
INSTANCE_MONITORING='--instance-monitoring Enabled=[[true/false]]'
IAM_INSTANCE_PROFILE='--iam-instance-profile=xxxxxxxxxx'
ASSOCIATE_PUBLIC_IP_ADDRESS='--associate-public-ip-address'

#Describe launch configuration params
LAUNCH_CONFIGURAGIOIN_NAMES="${LAUNCH_CONFIGURATION_NAME}"

#Create AutoScailng Group params
AUTO_SCALING_GROUP_NAME='--auto-scaling-group-name=[[AutoScaling Group Name]]'
MIN_SIZE='--min-size=0'
MAX_SIZE='--max-size=0'
VPC_ZONE_IDENTIFIER='--vpc-zone-identifier=[[Subnet ID(subnet-xxxxxxxx)]]'
TAGS='--tags=Key=[[Name]],Value=[[Value]]'

#Setting instance start time params
SCHEDULED_ACTION_NAME_START='--scheduled-action-name=start-instance'
SCHEDULED_ACTION_NAME_END='--scheduled-action-name=stop-instance'
#GMT
RECURRENCE_START="--recurrence=0 12 * * *"
RECURRENCE_END="--recurrence=0 13 * * *"
MIN_SIZE_START='--min-size=1'
MAX_SIZE_START='--max-size=1'
MIN_SIZE_END='--min-size=0'
MAX_SIZE_END='--max-size=0'
DESIRED_CAPACITY_START='--desired-capacity=1'
DESIRED_CAPACITY_END='--desired-capacity=0'



#Create launch configuration
RET=$(aws autoscaling create-launch-configuration "${REGION}" "${LAUNCH_CONFIGURATION_NAME}" "${IMAGE_ID}" "${KEY_NAME}" "${SECURITY_GROUPS}" "${USER_DATA}" "${INSTANCE_ID}" "${INSTANCE_TYPE}" "${INSTANCE_MONITORING}" "${IAM_INSTANCE_PROFILE}" "${ASSOCIATE_PUBLIC_IP_ADDRESS}" 2>&1)

if [ $? -ne 0 ]; then
 echo "Creating launch configuration is failed."
# echo ${RET}
 exit 1
fi

#Describe launch configuration
RET=$(aws autoscaling describe-launch-configurations "${REGION}" "${LAUNCH_CONFIGURATION_NAMES}")
LAUNCHCONFIGURATIONARN=$(echo "${RET}" | jq ".LaunchConfigurations[].LaunchConfigurationARN" | sed -e "s/\"//g")

echo "launch configuration created."
echo "LaunchConfigurationARN=${LAUNCHCONFIGURATIONARN}"
#echo ${RET}

#Create AutoScailng Group
RET=$(aws autoscaling create-auto-scaling-group "${REGION}" "${AUTO_SCALING_GROUP_NAME}" "${LAUNCH_CONFIGURATION_NAME}" "${MIN_SIZE}" "${MAX_SIZE}" "${VPC_ZONE_IDENTIFIER}" "${TAGS}" 2>&1)

if [ $? -ne 0 ]; then
 echo "Creating AutoScaling Group is failed."
# echo ${RET}
 exit 1
fi

#Describe AutoScaling Group
RET=$(aws autoscaling describe-auto-scaling-groups "${REGION}" "${AUTO_SCALING_GROUP_NAME}" 2>&1)
AUTOSCALINGGROUPARN=$(echo "${RET}" | jq ".AutoScalingGroups[].AutoScalingGroupARN" | sed -e "s/\"//g")

echo "AutoScaling Group created."
echo "AutoScalingGroupARN=${LAUNCHCONFIGURATIONARN}"
#echo ${RET}


#Setting instance start time
RET=$(aws autoscaling put-scheduled-update-group-action "${REGION}" "${AUTO_SCALING_GROUP_NAME}" "${SCHEDULED_ACTION_NAME_START}" "${RECURRENCE_START}" "${MIN_SIZE_START}" "${MAX_SIZE_START}" "${DESIRED_CAPACITY_START}" 2>&1)

if [ $? -ne 0 ]; then
 echo "Setting instance start time is failed."
 echo ${RET}
 exit 1
fi
#echo ${RET}

#Setting instance end time
RET=$(aws autoscaling put-scheduled-update-group-action "${REGION}" "${AUTO_SCALING_GROUP_NAME}" "${SCHEDULED_ACTION_NAME_END}" "${RECURRENCE_END}" "${MIN_SIZE_END}" "${MAX_SIZE_END}" "${DESIRED_CAPACITY_END}" 2>&1)

if [ $? -ne 0 ]; then
 echo "Setting instance end time is failed."
 echo ${RET}
 exit 1
fi
#echo ${RET}

echo 'end.'

注意点として「put-scheduled-update-group-action」で渡す時刻はGMTである必要があります。

あと気になったこととして、なぜかaws-cliでautoscalingを操作するコマンドを実行した際、成功しても失敗しても何も出力されません。ほかだとjsonが出力されるのですが。。

 

また、このサンプルスクリプトでは素のAmazonLinux AMIが起動するだけなので、起動しても中身が空っぽです。本来はバッチなどを仕込んだセットアップ済みの既存のEC2インスタンスを任意の時間にstartしたりstopしたりできるだけでもいいのですが、少なくともAutoScalingを使った場合はそういうことはできないようでした。

そのため、あらかじめバッチや必要なミドルウェアをインストールしておいたカスタムAMIを起動させるか、起動後にchef-soloなどで自分で自分をセットアップしてあげないと、バッチサーバとしては動作しません。