起動テンプレートと初期化スクリプト
起動パラメーターの形式、版の選択、初期化の結果をそれぞれ確認し、同じ配備を繰り返すために固定すべき条件を説明します。
説明
VMの配備では、イメージ、機種、初期化処理などを起動定義にまとめます。同じ名前の定義を使っても、最新の版を選ぶ指定では内容が変わる場合があります。また、入力形式が正しくても、イメージと機種の組合せや初期化の結果まで正しいとは限りません。
二つの版を持つ固定の起動定義を使います。版1のイメージとUserDataを取り出し、AWS CLIの入力形式検査、シェルによる初期化ファイルの生成、再実行時の重複を確認します。最後に最新の版と版番号の固定、CPUアーキテクチャの組合せを調べます。
起動パラメーターの形式、版の選択、初期化の結果をそれぞれ確認し、同じ配備を繰り返すために固定すべき条件を説明します。
1イメージと機種の対応表
images.jsonは固定イメージのアーキテクチャ、types.jsonは選択する機種のアーキテクチャです。x86_64とarm64は異なる命令セットの系統です。
cat images.jsonイメージの版とアーキテクチャを読む
cat types.json機種側のアーキテクチャを読む版1で使うイメージはx86_64、版2のイメージはarm64です。イメージの識別子だけでなく、実行する機種が対応するアーキテクチャかを確認します。
2版1の初期化処理を取り出す
起動定義の版番号1を選び、Base64のUserDataを復号してbootstrap.shへ保存します。表示するSHA-256はスクリプト内容の照合に使います。
python3 resolve.py --version 1版1の定義と復号したUserDataを取り出すイメージ1とt3.microが選ばれ、PORT=8080をapp.envへ追記するシェルが表示されます。UserDataはバイト列として渡す起動時の設定で、今回の例ではシェルスクリプトです。
3AWS CLIで起動要求の型を検査
MinCountとMaxCountは起動台数の範囲を表す整数です。MaxCountに文字列oneを入れたJSONを、--generate-cli-skeleton outputによる入力検査へ渡します。
aws ec2 run-instances --no-sign-request --cli-input-json file://request-bad.json文字列のMaxCountを含む入力を指定する --generate-cli-skeleton output入力形式を検査して応答の雛形を生成するMaxCountの型がstrで、必要なintに一致しないというParamValidationになります。JSONとして構文が正しくても、APIパラメーターとして必要な型を満たさない場合があります。
4形式検査の成功が示す範囲
MaxCount=1の整数へ直した入力を検査し、生成された応答雛形の項目を確認します。
aws ec2 run-instances --no-sign-request --cli-input-json file://request-valid.json整数へ修正した入力を指定する --generate-cli-skeleton output入力形式の検査と応答雛形の生成を行う > response-shape.json
python3 shape.py雛形が持つ項目を確認する入力形式は受け付けられ、雛形にInstancesとImageIdがあります。この検査はイメージの実在や利用権限、容量の空きを確認するものではありません。形式の検査と配備先の条件を分けて確認します。
5初期化スクリプトの結果
取り出したシェルを実行し、作られたapp.envを読みます。ここでは初期化処理のうち設定ファイルを書く部分を確認します。
sh bootstrap.shUserDataから取り出した設定処理を実行する
cat app.env実際に作られた設定を読むPORT=8080が1行書かれました。コマンドの終了だけでなく、作成された設定値を確認します。
6同じ処理を再実行した場合
同じシェルをもう一度実行します。初期化処理を手動で再適用する場合や、再実行する設定へ変える場合を考えるための確認です。
sh bootstrap.sh同じ初期化処理を再適用する
cat app.env追記による重複を確認するPORT=8080が2行になります。>>は追記なので、同じ処理でも状態が積み上がります。LinuxのUserDataは通常は初回起動時に実行されるため、再起動のたびにこの結果になるという意味ではありません。
7専用ファイルを同じ内容へ戻す処理
app.env全体をこの処理が管理する条件で、追記ではなく同じ内容へ書き直す案を二度実行します。
cat bootstrap-fixed.sh追記を上書きへ変えた案を読む
sh bootstrap-fixed.sh専用設定ファイルを同じ内容へ書き直す
sh bootstrap-fixed.sh
cat app.env二度適用した後の行数と値を読む2回実行してもPORT=8080は1行です。全体を所有するファイルなら同じ内容へ置き換えられます。他の処理も編集する共有ファイルでは、その内容を保つ方法を別に設計する必要があります。
8最新の版を選ぶと内容が変わる
latestを選んで、初期化処理を取り出します。この資料では最新の版は2です。
python3 resolve.py --version latest現在の最新番号に対応する定義を選ぶイメージ2、t4g.micro、PORT=9090になり、スクリプトのSHA-256も変わります。同じ起動定義の名前でも、latestが指す版が変われば配備内容は変わります。
9版番号を固定して同じ定義を選ぶ
もう一度版1を指定します。
python3 resolve.py --version 1番号を固定した定義と内容を再確認する最初と同じイメージ1、t3.micro、PORT=8080、同じSHA-256です。版指定で選択内容は固定できますが、スクリプトが外部の最新版を取得するなら、その依存先も固定する必要があります。
10機種だけを変更した不整合
arm64の版2へ、x86_64のt3.microを上書き指定した条件を検査します。
python3 resolve.py --version 2 --type t3.micro版2と異なるアーキテクチャの機種を組み合わせるimage_arch=arm64とtype_arch=x86_64が一致せず拒否されます。各パラメーターが正しい形式でも、組合せの条件は別に確認が必要です。
まとめ
形式検査、資源や権限の確認、起動後の結果確認は別の工程です。
同じ配備を選ぶには版と依存先を固定し、初期化を再適用した結果も確認します。
イメージと機種など、複数パラメーターの組合せも検査します。
操作履歴と解説を振り返れます。
シェル / AWS CLI 2.38.4 / Python 3
cat images.json
cat types.json{
"ami-00000000000000001": {
"architecture": "x86_64",
"release": "2026-10"
},
"ami-00000000000000002": {
"architecture": "arm64",
"release": "2026-11"
}
}
{
"t3.micro": {
"architecture": "x86_64"
},
"t4g.micro": {
"architecture": "arm64"
}
}python3 resolve.py --version 1version=1 image=ami-00000000000000001 type=t3.micro image_arch=x86_64 type_arch=x86_64 user_data_sha256=debad94b2fc68edd204dc10631d54dc1fb48a8dceab3053a35d8e67ed733edf0 #!/bin/sh set -eu printf "PORT=8080\n" >> app.env printf "initialized\n"
aws ec2 run-instances --no-sign-request --cli-input-json file://request-bad.json --generate-cli-skeleton outputaws: [ERROR]: An error occurred (ParamValidation): Parameter validation failed: Invalid type for parameter MaxCount, value: one, type: <class 'str'>, valid types: <class 'int'>
aws ec2 run-instances --no-sign-request --cli-input-json file://request-valid.json --generate-cli-skeleton output > response-shape.json
python3 shape.pyinput schema accepted response shape contains Instances=True instance sample has ImageId=True
sh bootstrap.sh
cat app.envinitialized PORT=8080
sh bootstrap.sh
cat app.envinitialized PORT=8080 PORT=8080
cat bootstrap-fixed.sh
sh bootstrap-fixed.sh
sh bootstrap-fixed.sh
cat app.env#!/bin/sh set -eu printf "PORT=8080\n" > app.env printf "initialized\n" initialized initialized PORT=8080
python3 resolve.py --version latestversion=2 image=ami-00000000000000002 type=t4g.micro image_arch=arm64 type_arch=arm64 user_data_sha256=d2bb650ffa3abdc6f831bf6f60c764dc49a26914788c9177cd5e639c20702dfa #!/bin/sh set -eu printf "PORT=9090\n" > app.env printf "initialized\n"
python3 resolve.py --version 1version=1 image=ami-00000000000000001 type=t3.micro image_arch=x86_64 type_arch=x86_64 user_data_sha256=debad94b2fc68edd204dc10631d54dc1fb48a8dceab3053a35d8e67ed733edf0 #!/bin/sh set -eu printf "PORT=8080\n" >> app.env printf "initialized\n"
python3 resolve.py --version 2 --type t3.microversion=2 image=ami-00000000000000002 type=t3.micro image_arch=arm64 type_arch=x86_64 rejected: architecture mismatch
演習完了