インフラの構築において、TerraformやCloudFormationの User Data を使ってインスタンスの初期セットアップ(ミドルウェアのインストールなど)を自動化することはよくあると思います。
しかし、こんなお悩みはありませんか?
「本当にUser Dataがエラーなく最後まで走り切ったのか?」
「Nginxなどのサービスがちゃんと起動して、HTTPの応答を返しているか?」
1台ずつSSHでログインして確認するのは面倒だし、複数台あるとやってられない!
今回は、TerraformのUser Data(.tpl)による構築から、AWS SSM Run Command を使ってその実行結果やサービス稼働状況を安全かつ一括でチェックし、さらに S3経由でログをローカルへ一括ダウンロードする 一連の流れをご紹介します。
1. User Data(.tplファイル)の準備
まずは、インスタンス初回起動時に実行されるスクリプトの例です。今回はシンプルに Ubuntu 環境へ Nginx をインストールして起動する構成を想定します。
user_data.sh.tpl
#!/bin/bash
set -e
# Ubuntu 向け nginx のインストール
apt-get update
apt-get install -y nginx
systemctl enable nginx
systemctl start nginx
echo "Nginx installed successfully."
このスクリプトが適用されたEC2インスタンスが起動すると、内部で cloud-init を通じてセットアップが実行されます。
2. SSM Run Command で実行するチェック用スクリプト
インスタンスが立ち上がった後、AWS Systems Manager (SSM) Run Command を使って、SSH接続なしでリモートから状態を確認します。
SSMコンソールの AWS-RunShellScript の「コマンドのパラメータ」に、以下のシェルスクリプトを記述して実行します
h=$(hostname)
echo "$h,cloud_init,$(cloud-init status 2>&1 | head -1)"
echo "$h,nginx_pkg,$(dpkg -s nginx 2>&1 | grep -E '^(Status|Version)' | tr '\n' ' ')"
echo "$h,nginx_active,$(systemctl is-active nginx 2>&1)"
echo "$h,nginx_enabled,$(systemctl is-enabled nginx 2>&1)"
echo "$h,http_local,$(curl -s -o /dev/null -w '%{http_code}' http://localhost/ 2>&1)"
echo "$h,userdata_error,$(grep -ciE 'error|fail' /var/log/cloud-init-output.log 2>&1)"
🛠️ スクリプトのポイント解説
h=$(hostname): 出力の先頭にホスト名を付与し、複数台実行時にもCSV風に識別しやすくしています。
cloud-init status: ユーザーデータの処理が正常に完了したか(
status: done)を確認します。dpkg -s nginx: パッケージが正しくインストールされているかをチェックします。
systemctl is-active / is-enabled: サービスが稼働中かつ自動起動設定が有効かを確認します。
curl -w '%{http_code}': ローカルから HTTP リクエストを投げ、
200 OKが返るかを検証します。grep -ciE 'error|fail':
/var/log/cloud-init-output.log内のエラー件数をカウントします(0ならエラーなし)。
3. SSMの出力オプションで Amazon S3 への書き込みを有効化
Run Command 実行時、「出力オプション」 でログを Amazon S3 へ保存するように設定します
「S3 バケットへの書き込みを有効化する」 にチェック
。 保存先の S3 URI(例:
s3://my-app-bucket-ap-se2)を指定。
これで、コマンドの実行結果(stdout)が自動的にS3バケットへアップロードされます
⚠️ S3にログが出力されない(オブジェクトが0件)場合の注意点
S3バケットが空のままになる場合、EC2インスタンスにアタッチされている IAM ロール(インスタンスプロファイル)に対象S3バケットへの
s3:PutObject権限が不足しているケースがほとんどです。あらかじめIAMポリシーを確認しておきましょう。
4. 実行結果の確認
実行後、コンソールで確認できる出力結果は以下の通りです:
ip-10-0-1-29,cloud_init,status: done
ip-10-0-1-29,nginx_pkg,Status: install ok installed Version: 1.24.0-2ubuntu7.18
ip-10-0-1-29,nginx_active,active
ip-10-0-1-29,nginx_enabled,enabled
ip-10-0-1-29,http_local,200
ip-10-0-1-29,userdata_error,0
一目で cloud_init の完了、Nginxのバージョンとアクティブ状態、HTTP 200応答、エラー0件が確認できます。
5. 複数台のログを AWS CLI で一括ダウンロードする
SSM Run Command から S3 へ出力すると、S3上には以下のような階層構造(ディレクトリ)でログが自動生成されます
s3://my-app-bucket-ap-se2/(コマンドID)/(インスタンスID)/awsrunShellScript/0.awsrunShellScript/stdout
複数台のEC2に対して一括実行した場合、インスタンスIDごとにフォルダが生成されるため、コンソールから1つずつ手動ダウンロードするのは手間がかかります。
そこで、手元のターミナルから aws s3 sync を使うことで、一括でローカルに取得できます。
aws s3 sync s3://my-app-bucket-ap-se2/ ./ssm-results/
【実行例】
$ aws s3 sync s3://my-app-bucket-ap-se2/ ./ssm-results/
download: s3://my-app-bucket-ap-se2/8d2e3b24-b0ce-4075-b876-3b2968117da1/i-031f8ce1ca1c2c95c/awsrunShellScript/0.awsrunShellScript/stdout to ssm-results/8d2e3b24-b0ce-4075-b876-3b2968117da1/i-031f8ce1ca1c2c95c/awsrunShellScript/0.awsrunShellScript/stdout
これでローカルの ./ssm-results/ ディレクトリ配下に全台分の実行ログが一瞬で保存されるため、ローカルでの集計やログ調査が非常に楽になります
まとめ
User Data (
.tpl) での環境構築後、SSH不要の SSM Run Command で状態を安全・確実にチェック。 パースしやすいフォーマットで出力することで、稼働状況やエラー件数をひと目で把握。
S3出力 と
aws s3 syncを組み合わせることで、複数台のサーバーログを一括で回収・管理可能。
インフラの自動構築後の検証フローとして非常に有用ですので、ぜひ試してみてください!