📝

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

2021/08/03に公開

以前、
EC2 Windows Serverでユーザーデータを毎回実行する方法
という記事で、カスタムAMIから起動したWindows Serverでユーザーデータを実行するには、EC2Launch v2を使うという方法を紹介しました。

しかし、その後別の問題が発生したため、続編として紹介します。

発生した問題

AMI取得元インスタンスと、AMIから起動したインスタンスで、インスタンスタイプが異なる場合、ユーザーデータが実行されないという問題が発生しました。

解決法

単純にAMI取得元インスタンスと、AMIから起動するインスタンスで、インスタンスタイプを統一するという方法で解決しました。

詳細

問題が発生した経緯

以前の記事で、EC2Launch v2を使えばカスタムAMIからでもユーザーデータが実行されることは判明したため、本番環境でもEC2Launch v2への移行と、ユーザーデータの実行を導入することにしました。

本番環境では、リリースにCloudFormationを使用しており、以下の更新を行います。
・パラメーターにカスタムAMI IDを指定し、起動テンプレートバージョンを更新
・起動テンプレートの設定にユーザーデータを記述
・ユーザーデータでcfn-init.exeを実行し、スクリプトをコール、処理終了後にcfn-signalを送信
・Auto Scalingグループを置換更新
・Auto Scalingの設定にcfn-initを記述し、ユーザーデータからスクリプトが呼ばれる

「ふ、これで完璧だな」
と思い、涼しい顔で更新を眺めていました。
ところが・・・

失敗!!
な・ぜ・に!?

すぐに環境をロールバックし、原因調査を始めました。

難航する原因調査

調査を始めたはいいものの、原因と考えられる箇所がいくつかあり、どこが根本原因なのかを突き止めるのに時間がかかりました。具体的には以下の点を疑いました。
・ユーザーデータの記述ミス
・CloudFormationテンプレートの記述ミス
・CloudFormation実行時の権限不足
・EC2にアタッチしているIAMロールの権限不足
・EC2Launch v2への移行ミス

しかし、上記のいずれも原因ではありませんでした。
また、検証環境で「ほぼ」本番と同じ更新を行ったところ、ユーザーデータは実行されました。
「は?実行されるじゃん!」
という状況になり、余計に調査が難航しました。
そこで、検証環境で、本番環境と「完全に」同じ手順で同じ更新を再現することにしました。

再現完了

さきほど、「ほぼ」と「完全に」と書きましたが、ここが大きな問題でした。
「ほぼ」:AMI取得元インスタンスと、AMIから起動するインスタンスは同じインスタンスタイプ
「完全に」:AMI取得元インスタンスと、AMIから起動するインスタンスは異なるインスタンスタイプ

そう、初期調査ではインスタンスタイプの差異まで疑っておらず、スルーしていたのです。
ところが、「完全に」同じ手順で再現したところ、見事に事象が再現しました。

しかし、ここでまた1つ問題が発生しました。
なぜかエラーログが出ておらず、ユーザーデータが実行されていないという事実しか分かりませんでした。

助けてサポート

自力での調査が厳しいことは分かっていたので、初期調査開始時点でサポートにも相談していましたが、サポート側も調査が難航しているとのことでした。
色々とログを提供しているうちに、サポートから
「インスタンスタイプが異なることが原因の可能性がある」
「インスタンスタイプが異なる場合、ハードウェアも異なり、ドライバーなどの初期化が必要になる場合がある」
という回答を頂きました。

この回答でひらめきました。
「AMI取得元のインスタンスのインスタンスタイプを変更して、EC2Launch v2に移行すればうまくいくのでは?」

インスタンスタイプの統一

この検証では、いくつかのパターンを試しました。

  1. AMI取得元インスタンスがt2.microのままEC2Launch v2に移行し、AMIからt3.mediumでインスタンスを起動
  2. AMI取得元インスタンスがt2.microのままEC2Launch v2に移行し、インスタンスタイプをt3.mediumに変更
  3. AMI取得元インスタンスをt2.microからt3.mediumに変更してからEC2Launch v2に移行後、インスタンスが稼働状態のままAMIを取得し、AMIからt3.mediumのインスタンスを起動
  4. 2のパターンで、AMI取得元インスタンスを停止してからAMIを取得して、AMIからt3.mediumのインスタンスを起動
  5. 1と3のパターンで新規に起動したインスタンスを再起動する

パターン1

これはもともと失敗していたパターンだったので、結果は予想通り失敗でした。

パターン2

ここでは面白い事象が発生しました。
t2.microでEC2Launch v2に移行したはずなのに、インスタンスタイプをt3.mediumに変更すると、もとのEC2Launchに戻っていたのです。
つまり、インスタンスタイプの変更により、EC2Launch v2への移行がなかったことになっていたということです。

パターン3

インスタンスタイプが統一されているので、一見うまくいきそうですが、これも失敗しました。EC2Launch v2への移行後に、AMI取得元インスタンスが稼働状態のまま取得したAMIでは、AMIから起動したインスタンスでEC2Launch v2がうまく実行されていないようでした。

パターン4

このパターンは成功しました。
インスタンスタイプを統一し、EC2Launch v2への移行後に、AMI取得元インスタンスは停止させ、そこからAMIを取得しました。そのAMIからt3.mediumでインスタンスを起動すれば、見事にユーザーデータが実行されていました。

パターン5

失敗していたパターン1と3において、試しにAMIから起動したインスタンスを停止→開始という流れで再起動させてみました。
すると、再起動時にはユーザーデータが実行されていることがわかりました。
ここから、ユーザーデータが実行されない問題は、初回起動時のみという推測もできました。

パターンの総括

カスタムAMIからの初回起動時にユーザーデータを実行させるには、以下の手順となりました。

  1. AMI取得元インスタンスのインスタンスタイプを変更
  2. AMI取得元インスタンスでEC2Launch v2へ移行
  3. AMI取得元インスタンスを停止
  4. AMIを取得
  5. AMIから同じインスタンスタイプでインスタンスを起動

実際にこの手順を3回以上繰り返しましたが、すべてユーザーデータが実行されていることが確認できました。
ひとまずこの方向で大丈夫そうなので、上記手順を実行することが問題の解決方法ということにしました。

根本原因は不明

サポートにも継続的な調査を行って頂いていたのですが、どうやら同じ事象が再現できないために、原因究明が難しいとのことでした。
代替案として、上記の解決法を採用することをお伝えし、根本原因の調査については引き続き協力するということにしました。
インスタンスタイプが異なることが原因の一部である可能性はあるとは思いますが、すべてのタイプで発生するのか、各タイプとEC2Launch v2の関連などは調べていないので、この記事で原因の断定はしないことにします。

まとめ

今回は、EC2 Windows Serverでユーザーデータを毎回実行する方法の続編を紹介しました。
EC2Launch v2に移行すること自体は間違っていなかったのですが、インスタンスタイプの差異まで影響している可能性があるということは新発見でした。
現状では先述の手順を解決パターンとすることで、いったん調査を終了しましたが、今後別の解決策なども出てくるかもしれません。
その時はまた記事にできるかな?
かなりニッチな問題かと思いますが、どなたかの参考になれば幸いです。

Discussion