概要

  • AWS のEC2 Auto Scaling を利用する際に、起動テンプレートを使用してインスタンスの追加や置き換えを行うことが多いかと思います。今回は、起動テンプレートに設定されているUserdata を効率的に更新する方法を紹介します。
  • 想定するシチュエーションは、Userdata に指定するスクリプトに変更を行う場合です。
  • 起動テンプレートの数が少なければ管理コンソールからの作業が容易です。しかし、多くの起動テンプレートを管理する環境においてUserdata を更新する際に、各起動テンプレートからUserdata に指定されているスクリプトを取得し、その後新しいスクリプトに更新する作業は非常に手間がかかります。以下に、AWS CLI を使用して、Userdata のスクリプトを取り出す/更新する方法を記載します。状況に応じて、シェルスクリプトに組み込んでください。

 

AWS CLIでUserdata を取り出す方法

  • 先ず、aws ec2 describe-launch-templatesコマンドを使用し、起動テンプレートの最新バージョンを取得します。
$ lt_id=lt-01234567890123456
$ lt_previos_ver=`aws ec2 describe-launch-templates --launch-template-ids ${lt_id} --region ap-northeast-1 | jq '.LaunchTemplates[].LatestVersionNumber'`

 

  • 次に、aws ec2 describe-launch-template-versionsコマンドを使用し、起動テンプレートに設定されているUserdata スクリプトを取得します。
  • tr -dコマンドは、出力結果からダブルクォーテーションを削除しています。
$ aws ec2 describe-launch-template-versions --launch-template-id ${lt_id} --versions ${lt_previos_ver} --region ap-northeast-1 | jq '.LaunchTemplateVersions[].LaunchTemplateData.UserData' | tr -d '"'
IyEgL2Jpbi9iYXNoCiMgYXdzY2xpIGluc3RhbGwKeXVtIC15IGluc3RhbGwgdW56aXAgPi9kZXYvbnVsbCAyPiYxCmN1cmwgImh0dHBzOi8vYXdzY2xpLmFtYXpvbmF3cy5jb20vYXdzY2xpLWV4ZS1saW51eC14ODZfNjQuemlwIiAtbyAiYXdzY2xpdjIuemlwIiA+L2Rldi9udWxsIDI+JjEKdW56aXAgYXdzY2xpdjIuemlwID4vZGV2L251bGwgMj4mMQouL2F3cy9pbnN0YWxsID4vZGV2L251bGwgMj4mMQoKIyByZXN0YXJ0CnJlYm9vdA==

 

  • しかし、上記コマンドの出力結果はBase64でエンコードされており、スクリプトの変更が難しいです。以下に示すコマンドは出力結果をbase64 -dコマンドでデコードし、ファイルにリダイレクトします。これで、Userdata スクリプトが取得できました。
$ aws ec2 describe-launch-template-versions --launch-template-id ${lt_id} --versions ${lt_previos_ver} --region ap-northeast-1 | jq '.LaunchTemplateVersions[].LaunchTemplateData.UserData' | tr -d '"' | base64 -d > /tmp/userdata.txt

$ cat /tmp/userdata.txt
#! /bin/bash
# awscli install
yum -y install unzip >/dev/null 2>&1
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" >/dev/null 2>&1
unzip awscliv2.zip >/dev/null 2>&1
./aws/install >/dev/null 2>&1

# restart
reboot

 

AWS CLIでUserdata を更新する方法

  • Userdata スクリプトを一部変更したとします。今回は、rebootコマンドをshutdown -rコマンドに置き換えました。スクリプトの変更は、viではなくsedを使用すればさらに効率化できます。
$ vi /tmp/userdata.txt

$ cat /tmp/userdata.txt
#! /bin/bash
# awscli install
yum -y install unzip >/dev/null 2>&1
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" >/dev/null 2>&1
unzip awscliv2.zip >/dev/null 2>&1
./aws/install >/dev/null 2>&1

# restart
shutdown -r now

 

  • importUserdata変数にUserdataスクリプトを格納しています。変数に格納する際に、base64コマンドでエンコードし、tr -dコマンドで改行を削除しています。Base64でエンコードしただけでは改行が含まれるため、エラーとなります。
  • 次に、aws ec2 create-launch-template-versionコマンドを使用し、新しいUserdataスクリプトをセットして、起動テンプレートのバージョンを更新します。
$ importUserdata=$(cat /tmp/userdata.txt | base64 | tr -d '\n')

$ aws ec2 create-launch-template-version --launch-template-id ${lt_id} --source-version ${lt_previos_ver} --launch-template-data '{"UserData": "'${importUserdata}'"}'  --region ap-northeast-1
{
    "LaunchTemplateVersion": {
        "LaunchTemplateId": "lt-01234567890123456",
        "LaunchTemplateName": "niikawa-test-ec2-lt",
        "VersionNumber": 59,
        "CreateTime": "2025-01-07T15:41:23+00:00",
        "CreatedBy": "arn:aws:iam::111111111111:user/niikawa",
        "DefaultVersion": false,
        "LaunchTemplateData": {
            "IamInstanceProfile": {
                "Arn": "arn:aws:iam::111111111111:instance-profile/niikawa-ec2-ssm"
            },
            "ImageId": "ami-0xxxxxxxxxxxxxxxx",
            "InstanceType": "t2.micro",
            "KeyName": "niikawa-testkey",
            "UserData": "IyEgL2Jpbi9iYXNoCiMgYXdzY2xpIGluc3RhbGwKeXVtIC15IGluc3RhbGwgdW56aXAgPi9kZXYvbnVsbCAyPiYxCmN1cmwgImh0dHBzOi8vYXdzY2xpLmFtYXpvbmF3cy5jb20vYXdzY2xpLWV4ZS1saW51eC14ODZfNjQuemlwIiAtbyAiYXdzY2xpdjIuemlwIiA+L2Rldi9udWxsIDI+JjEKdW56aXAgYXdzY2xpdjIuemlwID4vZGV2L251bGwgMj4mMQouL2F3cy9pbnN0YWxsID4vZGV2L251bGwgMj4mMQoKIyByZXN0YXJ0CnNodXRkb3duIC1oIG5vdwo=",
            "SecurityGroupIds": [
                "sg-0yyyyyyyyyyyyyyyy"
            ],
            "MetadataOptions": {
                "HttpTokens": "required",
                "HttpEndpoint": "enabled"
            }
        }
    }
}

 

  • これで、AWS CLIで起動テンプレートのUserdata を取り出し、更新することができました。
  • AWS CLI で起動テンプレートのUserdata を扱う場合、Base64でエンコードが必要であり難易度が上がりますが、上記の方法を活用すれば、効率的にUserdata を更新することができます。また、シェルスクリプトを組めば、自動化も可能です。

 

参考資料

https://docs.aws.amazon.com/cli/latest/reference/ec2/#cli-aws-ec2

既存EC2をベースに起動テンプレートを作る

aws ec2 create-launch-template-version のlaunch-template-data 指定方法