📝

EC2 Windows Serverでユーザーデータを毎回実行する方法

2021/05/27に公開

カスタムAMIから起動したWindows Serverでユーザーデータが実行されなかったので調査した結果です。
デフォルトでは初回起動時のみしか実行されないユーザーデータを、Windows Serverにおいて起動時に毎回実行する方法を紹介します。

結論

EC2Launch v2を使用しましょう!

EC2Launch v2 は、ブートごとに次のタスクを実行できます。
~ 一部略 ~
・ユーザーデータを実行します。
・メタデータサービスと AWS KMS サーバーに到達するように永続的な静的ルートを設定します。
EC2Launch v2 の概要 - Amazon Elastic Compute Cloud

ユーザーデータって?

Amazon EC2 でインスタンスを起動するとき、起動後にそのインスタンスにユーザーデータを渡し、一般的な自動設定タスクを実行したり、スクリプトを実行したりできます。
起動時に Linux インスタンスでコマンドを実行する - Amazon Elastic Compute Cloud

インスタンスが起動するときに初期処理として必要なソフトウェアのインストールなどを行うことができる機能です。
わかりやすい例だと、Linuxのインスタンスを起動するときにyum updateしてApacheをインストールするというユーザーデータを以下のように記述したとします。

#!/bin/bash
sudo su
yum update -y
yum -y install httpd
chkconfig httpd on
service httpd start

こちらをEC2インスタンス起動時にコンソール上に記述したり、テキストファイルで記述したものをアップロードすることで、起動時にインスタンスにこのユーザーデータが渡されます。

1度しか実行されない

デフォルトではユーザーデータは初回起動時の1回しか実行されません。

デフォルトでは、ユーザーデータスクリプトはインスタンスを起動すると一度だけ実行されます。
Windows インスタンスでの起動時のコマンドの実行 - Amazon Elastic Compute Cloud

しかし、カスタムAMIから起動したインスタンスで毎回スクリプトを実行したり、同一インスタンスで再起動した場合にも処理を実施したい場合もあると思います。今回はカスタムAMIを使用するパターンについて紹介します。

毎回実行の設定

AMIから起動するEC2インスタンスのユーザーデータを編集します。

EC2Launch v2 でユーザデータの実行を有効にするには (プレビュー AMI)
・初回起動時にユーザーデータのタスクを実行するには、frequency を once に設定します。
・起動するたびにユーザーデータのタスクを実行するには、frequency を always に設定します。
Windows インスタンスでの起動時のコマンドの実行 - Amazon Elastic Compute Cloud

yml形式で記述する場合、以下のようになります。
EC2Launch v2 の設定 - Amazon Elastic Compute Cloudより

version: 1.0
tasks:
- task: executeScript
  inputs:
  - frequency: always
    type: powershell
    runAs: localSystem
    content: |-
      New-Item -Path 'C:\PowerShellTest.txt' -ItemType File      

上記は旧バージョンであるEC2Launchにおける下記の記述と互換があります。

次のフォーマットは、このサービスの旧バージョンと互換性があります。

<powershell>
  $file = $env:SystemRoot + "\Temp" + (Get-Date).ToString("MM-dd-yy-hh-mm")
  New-Item $file -ItemType file
</powershell>
<persist>true</persist>

EC2Launchの<persist>true</persist>frequency: alwaysと同じ意味です。
旧バージョンとの互換性があるので、EC2Launch v2に移行した場合でも、旧バージョンの記述でユーザデータを実行することが可能です。

AMIから起動してみる

EC2Launch v2をインストールしたEC2インスタンスからAMIを取得し、そのAMIにユーザーデータを渡しつつEC2インスタンスを起動してみます。
ユーザーデータは以下を記述します。
Cドライブ直下にfuga_(システム日付).txtを出力するというスクリプトです。
ポイントは<persist>true</persist>で、起動するたびにユーザーデータを実行する点です。

<powershell>
$date = Get-Date -Format "yyyyMMddhhmm";
New-Item C:\fuga_$date.txt -itemType File -Value "fuga"
</powershell>
<persist>true</persist>

起動時の設定でユーザーデータに上記を記述します。

あとは通常通り起動します。
起動したらRDP接続でログを確認してもよいですが、面倒なのでSystems Managerのフリートマネージャーでコンソールから確認します。
Cドライブ直下に、テキストファイルが出力されていることが確認できました。

C:\ProgramData\Amazon\EC2Launch\log\agent.logを確認すると、以下のようにユーザーデータが実行されたログが残っています。

これでカスタムAMIから起動してもユーザーデータが実行されていることが確認できました!

まとめ

今回はWindows Serverでユーザーデータを毎回実行する方法をカスタムAMIを用いて紹介しました。
旧バージョンのEC2Launchでは色々な設定が必要だったのですが、v2ではインストールするだけでよく、今までのスクリプトをそのまま使えるのですごく便利になりました!
ただし、旧バージョンからの移行にあたってはいきなり本番環境で実施せず、検証環境で動作確認してから移行するようにしましょう。

参考資料

EC2インスタンス(WindowsServer)への起動時処理設定(ユーザーデータ) - Qiita
EC2Launch v2 の概要 - Amazon Elastic Compute Cloud
起動時に Linux インスタンスでコマンドを実行する - Amazon Elastic Compute Cloud
Windows インスタンスでの起動時のコマンドの実行 - Amazon Elastic Compute Cloud

Discussion