ニュース&ブログ
AWS LambdaでAuto ScalingのAMI更新を自動化
AWS LambdaでAuto ScalingのAMI更新を自動化する方法
こんにちは。クラウドコンサルティング事業部の関口です。
今回は、 AWS LambdaでAuto ScalingのAMI更新を自動化する方法です。
運用しているシステム内のEC2インスタンスのバックアップとして日時でAMIを自動作成していますが、ついでにAutoScalingのAMIを最新のものに自動更新できたらいいな~と思っていたら、「Amazon EC2 Systems Manager」のユーザガイドにそれっぽい事ができるとの情報が!
参考リンク:「Amazon EC2 Systems Manager」ユーザーガイド
AMI にパッチを適用し、Auto Scaling グループを更新する
しかし、やりたい事と少し違う(AWS Lambdaを実行するイベントを手動で実行する?)内容でした。。。
そこで、公開されているコードを改修し、CloudWatchイベントスケジュールで自動実行できるようにしてみました。
やりたい事
日時AMI作成が完了している時間帯にAWS Lambdaを実行し、AutoScalingのAMIを最新のものに自動更新する。
前提条件
日時でAMIを自動作成する方法については割愛します。
設定方法
設定方法は、先ほどの上記参考リンクの「タスク 1: AWS Lambda の IAM ロールを作成する」「タスク 2: AWS Lambda 関数を作成する」ですので、そちらを参照して下さい。
参考リンクの設定方法から変更・追加している箇所のみ記載します。
・AWS LambdaのIAM ロールにアタッチするポリシー
[AWSLambdaExecute]
[AutoScalingFullAccess]
[AmazonEC2ReadOnlyAccess] <— 追加 ※AMI名を取得するため
・「Lambda function code」には以下の改修したコードを設定
from __future__ import print_function
import json
import datetime
import time
import boto3
print('Loading function')
def lambda_handler(event, context):
print("Received event: " + json.dumps(event, indent=2))
# get autoscaling client
client = boto3.client('autoscaling')
# get object for the ASG we're going to update, filter by name of target ASG
targetASG = "autoscaling-group01" # AutoScalingグループ名を記入する
response = client.describe_auto_scaling_groups(AutoScalingGroupNames=[targetASG])
if not response['AutoScalingGroups']:
return 'No such ASG'
# get name of InstanceID in current ASG that we'll use to model new Launch Configuration after
sourceInstanceId = response.get('AutoScalingGroups')[0]['Instances'][0]['InstanceId']
AmiNameKeyword="web01_DailyBackup" # AMI名のキーワードを記入
images = boto3.client('ec2', region_name='ap-northeast-1').describe_images(Filters=[{'Name':'name','Values':[AmiNameKeyword + "*"]}])["Images"]
n = 1
for image in sorted(images, key=lambda x: x["CreationDate"],reverse=True):
if ( n == 1 ):
Image=image
n += 1
else:
break
newAmiID=Image['ImageId']
# create LC using instance from target ASG as a template, only diff is the name of the new LC and new AMI
timeStamp = time.time()
timeStampString = datetime.datetime.fromtimestamp(timeStamp).strftime('%Y-%m-%d %H-%M-%S')
newLaunchConfigName = 'LC '+ newAmiID + ' ' + timeStampString
client.create_launch_configuration(
InstanceId = sourceInstanceId,
InstanceType='t2.micro', # インスタンプタイプを記入
SecurityGroups=[
'sg-xxxxxxxx', # SecurityGroupIDを記入
],
LaunchConfigurationName=newLaunchConfigName,
ImageId= newAmiID )
# update ASG to use new LC
response = client.update_auto_scaling_group(AutoScalingGroupName = targetASG,LaunchConfigurationName = newLaunchConfigName)
return 'Updated ASG `%s` with new launch configuration `%s` which includes AMI `%s`.' % (targetASG, newLaunchConfigName, newAmiID)
[改修内容]
・LambdaのイベントでAMI名とAutoScalingグループ名を取得している箇所を全て解除。・指定したキーワードにマッチする最新のAMI名を取得する箇所を追加。
・インスタンスタイプ、SecurityGroupを指定する箇所を追加。
LambdaのトリガーにCloudWatchスケジュール イベントを設定
「Schedule expression」には、AMI作成が完了している時間帯を設定して下さい。
これでトリガーに指定した時間帯にAuto ScalingのAMI更新が自動実行されます。
以上です。それではまた次回。

関口 直行
株式会社システムサポート 東京支社 クラウドコンサルティング事業部所属
クラウドソリューションアーキテクト
AWS Summit Tokyoで事例公開された案件などのプロジェクトリーダーを担当
AWS認定ソリューションアーキテクト-プロフェッショナルレベル