[小ネタ]ImageBuilerで作成されたWindowsインスタンスイメージのタイムゾーンを常に「Tokyo Standard Time」にする方法

タイムゾーン設定に気をつけましょう。
2023.04.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!AWSエンジニアのおつまみです!

先日ImageBuilderを構築していた時に困った内容をシェアします!

困っていた内容

windows-server-2022-english-full-base-x86(最新版)を使用したベースイメージで、タイムゾーンをUTC →Tokyo Standard Time に設定予定でした。
そのため、下記のカスタムコンポーネントでタイムゾーン設定を実施することにしました。

- name: SetTimeZone
        action: ExecutePowerShell
        onFailure: Continue
        inputs:
          commands:
            - |
              # 現在のタイムゾーンを取得
              Write-Host 'Get current timezone...'
              Get-TimeZone | Select-Object Id, BaseUtcOffset | Out-String

              # タイムゾーンの変更
              $timeZoneId = 'Tokyo Standard Time' # JSTに設定する場合(必要に応じて変更する)
              Write-Host 'Configure timezone...'
              Set-TimeZone -Id $timeZoneId | Out-String

              # 変更した結果を確認
              Write-Host 'Get new timezone...'
              Get-TimeZone | Select-Object Id, BaseUtcOffset | Out-String

しかし、作成されたイメージからEC2インスタンスを起動すると、タイムゾーンがUTCに戻っている現象に陥りました。。

ログにも以下が出力されており、ビルド時点では問題なさそうでした。

2023-04-03T08:00:25.592147400Z Stdout: Id  BaseUtcOffset
2023-04-03T08:00:25.592147400Z Stdout: --  -------------
2023-04-03T08:00:25.592147400Z Stdout: UTC 00:00:00     
2023-04-03T08:00:25.592147400Z Stdout: 
2023-04-03T08:00:25.592147400Z Stdout: 
2023-04-03T08:00:25.597644300Z Stdout: 
2023-04-03T08:00:25.598287100Z Stdout: Configure timezone...
2023-04-03T08:00:25.599471200Z Stdout: 
2023-04-03T08:00:25.604510700Z Stdout: Get new timezone...
2023-04-03T08:00:25.605692900Z Stdout: 
2023-04-03T08:00:25.605692900Z Stdout: Id  BaseUtcOffset
2023-04-03T08:00:25.605692900Z Stdout: --  -------------
2023-04-03T08:00:25.605692900Z Stdout: Tokyo Standard Time 09:00:00

結論:なぜ戻ってしまったか?

  • カスタムコンポーネントで定義した設定はbuildフェーズで実施される。
  • build, testフェーズが終わると sysprep が実行される。
  • sysprepが実行されると、sysprep 構成ファイルUnattend.xml で定義されているデフォルトのUTC に戻されてしまう。
  • そのため、カスタムコンポーネントではsysprep 構成ファイルUnattend.xml の変更が必要。

Sysprepとは?

Sysprep とは、Microsoft 社が提供する Windows OS を展開するためのシステム準備ツールです。

Windows インスタンスを複製する際に、そのまま AMI を取得すると、マシンSIDというユニークに付与されるIDが重複し、ライセンス認証に関する問題が発生する可能性があるなど、問題のひとつの要因になりえます。

そのためWindows ServerのAMIを作成する時は、Sysprepを実行することによって、Windowsのインストールイメージを準備し、他のコンピューターに展開することができます。

そして、このSysprepがImageBuilderでイメージを作成する時のフローに含まれています。

ImageBuilderのフローについて

ImageBuilderでWindowsインスタンスのイメージを作成した場合、このようなフローとなります。

順番 ステップ名 実施内容
1 LaunchBuildInstance Image Builderでカスタムイメージを作成するために使用されるインスタンスを起動します。
2 ApplyBuildComponents インストールする必要のあるソフトウェアコンポーネントをインストールします。
3 InventoryCollection パッケージやファイル、構成などの情報を収集します。
4 RunSanitizeScript 収集された情報を処理し、AMIを構成するための準備を行います。
5 RunSysPrepScript システムを準備し、オペレーティングシステムの汎用化を実行します。
6 CreateOutputAMI 新しいAMIを作成し、そのAMIのIDを出力します。
7 TerminateBuildInstance インスタンスを終了します。

結論でお伝えしたとおり、No.2のbuild, testフェーズ終了後に No.5のsysprep が実行されています。そのため、sysprepが実行されると、sysprep 構成ファイルUnattend.xml で定義されているデフォルトのUTC に戻されてしまうということでした。

対処方法

カスタムコンポーネント内でsysprep 構成ファイルUnattend.xml の設定をUTC →Tokyo Standard Time に変更するよう設定します。

- name: build
    steps:
      - name: SetTimeZone-Region-DisplayLanguage
        action: ExecutePowerShell
        onFailure: Continue
        inputs:
          commands:
            - |
              # 構成ファイルの設定
              Write-Host 'Configure timezone...'
              (Get-Content "C:\ProgramData\Amazon\EC2Launch\sysprep\Unattend.xml").replace('<TimeZone>UTC</TimeZone>', '<TimeZone>Tokyo Standard Time</TimeZone>') | Set-Content "C:\ProgramData\Amazon\EC2Launch\sysprep\Unattend.xml"

参考:AWS Image Builder - Setting the Timezone in a Windows Image | Tom’s blog

sysprep 構成ファイル`Unattend.xml` のファイルパスは使用するベースイメージ(Windows2019か2022か)で異なります。 正式なパスは参考資料にある公式ドキュメントをご確認ください。

このコンポーネントを設定するようにImageBuilderを実行します。 作成されたイメージからEC2インスタンスを起動してみます。無事タイムゾーンがTokyo Standard Time になっていました!

さいごに

今回はImageBuilerで作成されたWindowsインスタンスイメージのタイムゾーンを常に「Tokyo Standard Time」にする対処方法についてお伝えしました。

単純なタイムゾーンの設定だけでは、設定が元に戻ってしまうことにご注意ください。 Sysprepで設定している項目はタイムゾーン以外にもあるので、詳しくはこちらのブログをご参照ください。

最後までお読みいただきありがとうございました!
どなたかのお役に立てれば幸いです。

以上、おつまみ(@AWS11077)でした!

参考資料

Sysprep のトラブルシューティング - Amazon Elastic Compute Cloud