特定タグが設定されたAMIが作成された時に自動で起動テンプレートを更新する

2021.09.03

いわさです。

前回、特定タグが設定されたAMIの作成イベントを検出しました。

この検出からASGの起動テンプレートのAMIを自動更新したいと思います。
実はこれがやりたかった。

動機としては、opswitchやDLMで日次バックアップを自動取得したタイミングに合わせて、ASGのゴールデンイメージも自動更新してみたらどうかなと思ったからです。
なので、今回やってみようかと思いました。

EventBridgeでAMIの作成を検知し、それをトリガーに起動テンプレートを更新してみたいと思います。
更新はLambdaにてPython3.9でBoto3で実行します。

今回はASGの自動適用までは行わず、起動テンプレートの最新バージョンを参照している前提としたいと思いますが、必要に応じてカスタマイズも可能と思います。

なお、他の方法として以下のような記事も既に存在しています。

今回は、どのタイミングで作成されたAMIでも特定タグが付与されていればゴールデンイメージとして更新する、ということをやりたかったので、EventBridge + Lambdaで実装してみました。

実現方法

イベントターゲットにLambda関数を指定します。

Lambda関数

Python3.9で関数を作成し、Boto3を使って起動テンプレートを操作します。
対象の起動テンプレートについてはLambda環境変数より取得します。

import json, boto3, os

launch_template_id = os.environ["launch_template_id"]
ec2 = boto3.client("ec2")

def lambda_handler(event, context):
    new_ami = event
    # create new version launch template
    response = ec2.create_launch_template_version(
        LaunchTemplateId=launch_template_id,
        SourceVersion="$Latest",
        VersionDescription="Latest-AMI",
        LaunchTemplateData={
            "ImageId": new_ami
        }
    )
    # update default version 
    response = ec2.modify_launch_template(
        LaunchTemplateId=launch_template_id,
        DefaultVersion="$Latest"
    )
    # delete old version
    previous_version = str(int(response["LaunchTemplate"]["LatestVersionNumber"]) - 2)
    response = ec2.delete_launch_template_versions(
        LaunchTemplateId=launch_template_id,
        Versions=[
            previous_version,
        ]
    )
    
    return

環境変数を設定します。

また、Lambda実行ロールは起動テンプレートを操作出来るように以下の権限を与えておきます。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:GetLaunchTemplateData",
                "ec2:DescribeLaunchTemplates",
                "ec2:DescribeLaunchTemplateVersions",
                "ec2:ModifyLaunchTemplate",
                "ec2:DeleteLaunchTemplateVersions",
                "ec2:CreateLaunchTemplateVersion"
            ],
            "Resource": "*"
        }
    ]
}

ためしてみる

マスターとなるEC2でコンテンツを更新します。 ※ ASGの希望するインスタンス数は"1"が指定されているとします。

iwasa -> iwasa2 に変更します。

そして、特定タグを付与したAMIを作成します。
起動テンプレートのAMI IDが作成したばかりの最新のAMIに変更されています。

ASG配下のインスタンスを停止してみると、新規で1台のインスタンスが作成されます。

ASG側のインスタンスにアクセスしてみます。

コンテンツが更新された最新のAMIに復元されました。

さいごに

AMI取得時点の状態にゴールデンイメージを保つことが出来ることが確認出来ました。
ASGの起動テンプレート更新方法はどういった方法を行うかのべき論はあるかもしれませんが、まずはAMI取得から起動テンプレート更新までの部分を自動化するひとつの方法として、今回は試してみました。

参考