AutoScallingグループで構成されたEC2インスタンスを
決められたスケジュールでリブート運用してみます。
AutoScallingで構成されたEC2を単純にリブートしてしまうとヘルスチェックに失敗してしまうため
以下のいずれかの対応を行う必要があります。
- インスタンスの状態をスタンバイにする
- AutoScallingグループからインスタンスをデタッチする
- AutoScallingのヘルスチェックプロセスを停止する
今回はインスタンスの状態をスタンバイにする方法でやってみます。
スタンバイ状態にすることでAutoScalingのインスタンスのヘルスチェックが実行されなくなります。
スケジューリングにはCloudWatchEventsを利用し、毎月第3日曜日の02:00時にリブートするよう設定します。
■参考URL
Auto Scalingグループからのインスタンスの一時的な削除
利用するサービス
処理の流れ
- EC2インスタンスをスタンバイ状態に設定し、リブートを行うLambda関数を作成
- 「1」で作成したLambdaをスケジューリング実行するCloudWatchEventsルールを作成
今回はAutoScallingグループ配下に2つのインスタンスを起動した状態でテストします。
スケーリングの設定は以下に設定しておきます。
希望する容量;2
最小キャパシティ:0
最大キャパシティ;2
Lambda関数実行用のIAM作成
Lambda関数実行用のIAMポリシーとロールを作成します。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": [
"ec2:StartInstances",
"ec2:StopInstances",
"ec2:RebootInstances"
],
"Resource": "*"
}
]
}
EC2をスタンバイ状態に変更するLambda関数の作成
指定したAutoScalling配下のインスタンスをスタンバイ状態に変更するLambda関数を作成します。
EnteringStandby ⇒ Standby状態に変更になるまでは結構時間がかかります。
import boto3
def lambda_handler(event, context):
# get autoscaling client
as_client = boto3.client('autoscaling')
as_groups = as_client.describe_auto_scaling_groups(
AutoScalingGroupNames=[
'asg-nginx'
])
# List to hold the instance-ids
instance_ids = []
for i in as_groups['AutoScalingGroups']:
for k in i['Instances']:
instance_ids.append(k['InstanceId'])
# enter standby
response = as_client.enter_standby(
InstanceIds=instance_ids,
AutoScalingGroupName='asg-nginx',
ShouldDecrementDesiredCapacity=True
)
EC2を停止するLambda関数
ここでは指定したオートスケーリンググループ配下のインスタンス一覧を
取得し停止しています。ここはタグから取得するなど色々なやり方もあると思います。
import boto3
def lambda_handler(event, context):
# get autoscaling client
as_client = boto3.client('autoscaling')
as_groups = as_client.describe_auto_scaling_groups(
AutoScalingGroupNames=[
'asg-nginx'
])
# List to hold the instance-ids
instance_ids = []
for i in as_groups['AutoScalingGroups']:
for k in i['Instances']:
instance_ids.append(k['InstanceId'])
# get ec2 client
ec2_client = boto3.client('ec2')
ec2_client.stop_instances(InstanceIds=instance_ids)
EC2を開始するLambda関数
import boto3
def lambda_handler(event, context):
# get autoscaling client
as_client = boto3.client('autoscaling')
as_groups = as_client.describe_auto_scaling_groups(
AutoScalingGroupNames=[
'asg-nginx'
])
# List to hold the instance-ids
instance_ids = []
for i in as_groups['AutoScalingGroups']:
for k in i['Instances']:
instance_ids.append(k['InstanceId'])
# get ec2 client
ec2_client = boto3.client('ec2')
ec2_client.start_instances(InstanceIds=instance_ids)
Lambda関数のスケジューリング
Lambdaをスケジューリング実行するCloudWatchEventsルールを作成します。
例えば毎月第3日曜日の02:00時(UTC)に実行するのでcron式には以下を指定します。
0 2 ? * 1#3 *
参考:ルールのスケジュール式
時間的な制約が無く、厳密な状態チェック等も不要で単純に実施するだけなら
ルールを3つ準備し、スタンバイ状態変更⇒EC2停止⇒EC2開始をそれぞれ
時間を開けてスケジューリングすればOKです。
以上