【AWS CDK】Batchで起動テンプレートを利用する場合のユーザーデータの実装


Batchのコンピューティング環境で利用する起動テンプレートのユーザーデータは MIME マルチパートアーカイブの形式 で定義しなければならないらしい。
CDKで実装するときに少しハマったので調べた内容を残しておく。

実装

何はともあれ実装。こんな感じで実装するとうまくいく。

from aws_cdk import aws_ec2

# UserDataインスタンスの作成
user_data = aws_ec2.MultipartUserData()

# UserDataの中身を定義。
user_data.add_part(
    # MIME マルチパートアーカイブの形式のUserDataを定義する
    aws_ec2.MultipartBody.from_raw_body(
        # データの種類を指定。今回はシェルスクリプト
        content_type='text/x-shellscript; charset="utf-8"',
        # シェルスクリプトを定義
        body="echo 'hello world'",
    )
)

# 起動テンプレートを定義
launch_template = aws_ec2.LaunchTemplate(
    self, "HogehogeLaunchTemplate",
    ebs_optimized=False,
    key_name=definition.key_name,
    launch_template_name="HogehogeLaunchTemplate",
    user_data=user_data # 先ほど定義した UserDataを指定
)

こんな感じのUserDataが生成される。

Content-Type: multipart/mixed; boundary="+AWS+CDK+User+Data+Separator=="
MIME-Version: 1.0

--+AWS+CDK+User+Data+Separator==
Content-Type: text/x-shellscript; charset="utf-8"

echo 'hello world'

--+AWS+CDK+User+Data+Separator==--

説明

MultipartUserData

MIME マルチパートアーカイブの形式のUserDataオブジェクトは MultipartUserData クラスで作成する。

UserData クラス は抽象クラスでnewできないので注意。

user_data = aws_ec2.MultipartUserData()

MultipartBody

UserDataの中身は MultipartBody クラス で定義する。

  • content_type
    UserDataのデータ形式を指定する。
    シェルスクリプトを書く場合は text/x-shellscript; charset="utf-8" を指定
  • body
    データ本体を記述する。 transfer_encoding を指定しなければ自動でbase64エンコードされる。
  • transfer_encoding
    body のエンコード方法を指定する。指定した場合は body にエンコード済みの文字列を渡さないといけない
user_data.add_part(
    aws_ec2.MultipartBody.from_raw_body(
        content_type='text/x-shellscript; charset="utf-8"',
        body="echo 'hello world'",
    )
)

MultipartBody は下記のような定型的な記述をラッピングしてくれるオブジェクトだと思っていい。

Content-Type: multipart/mixed; boundary="+AWS+CDK+User+Data+Separator=="
MIME-Version: 1.0

--+AWS+CDK+User+Data+Separator==

--+AWS+CDK+User+Data+Separator==--