Open3

AWS パッチマネージャー|カスタムAMIの挙動

t13801206t13801206
AWSTemplateFormatVersion: "2010-09-09"
Description: "Create PatchBaseline for Windows staging and production"

Resources:
  # ------------------------------------------------------------#
  # PatchBaseline
  # ------------------------------------------------------------#
  PatchBaselineSTG:
    Type: AWS::SSM::PatchBaseline
    Properties:
      Name: WindowsPatchBaseline
      Description: "PatchBaseline for Windows (STG) created by CloudFormation"
      OperatingSystem: WINDOWS
      PatchGroups:
        - "PG_WINDOWS_STG"
      ApprovalRules:
        PatchRules:
          - PatchFilterGroup:
              PatchFilters:
                - Values:
                    - SecurityUpdates
                    - CriticalUpdates
                  Key: CLASSIFICATION
                - Values:
                    - Critical
                    - Important
                  Key: MSRC_SEVERITY
            ApproveAfterDays: 1
  PatchBaselinePRD:
    Type: AWS::SSM::PatchBaseline
    Properties:
      Name: WindowsPatchBaseline
      Description: "PatchBaseline for Windows(PRD) created by CloudFormation"
      OperatingSystem: WINDOWS
      PatchGroups:
        - "PG_WINDOWS_PRD"
      ApprovalRules:
        PatchRules:
          - PatchFilterGroup:
              PatchFilters:
                - Values:
                    - SecurityUpdates
                    - CriticalUpdates
                  Key: CLASSIFICATION
                - Values:
                    - Critical
                    - Important
                  Key: MSRC_SEVERITY
            ApproveAfterDays: 31
  # ------------------------------------------------------------#
  # MaintenanceWindow
  # ------------------------------------------------------------#
  MaintenanceWindowSTG:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      Name: "MaintenanceWindows-PG_WINDOWS_STG"
      Description: Maintenance Window to update Windows(STG)
      AllowUnassociatedTargets: false
      Cutoff: 1
      Duration: 2
      Schedule: "cron(00 03 * * ? *)"
      ScheduleTimezone: Asia/Tokyo
  MaintenanceWindowPRD:
    Type: AWS::SSM::MaintenanceWindow
    Properties:
      Name: "MaintenanceWindows-PG_WINDOWS_PRD"
      Description: Maintenance Window to update Windows(PRD)
      AllowUnassociatedTargets: false
      Cutoff: 1
      Duration: 2
      Schedule: "cron(00 03 ? * MON *)"
      ScheduleTimezone: Asia/Tokyo
  # ------------------------------------------------------------#
  # MaintenanceWindowTarget
  # ------------------------------------------------------------#
  MaintenanceWindowTargetSTG:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      Name: WindowsPatchTarget
      Description:  Target is PG_WINDOWS_STG
      ResourceType: INSTANCE
      Targets:
        - Key: "tag:Patch Group"
          Values:
            - "PG_WINDOWS_STG"
      WindowId: !Ref MaintenanceWindowSTG
    DependsOn: MaintenanceWindowSTG
  MaintenanceWindowTargetPRD:
    Type: AWS::SSM::MaintenanceWindowTarget
    Properties:
      Name: WindowsPatchTarget
      Description: Target is PG_WINDOWS_PRD
      ResourceType: INSTANCE
      Targets:
        - Key: "tag:Patch Group"
          Values:
            - "PG_WINDOWS_PRD"
      WindowId: !Ref MaintenanceWindowPRD
    DependsOn: MaintenanceWindowPRD
  # ------------------------------------------------------------#
  # MaintenanceWindowTask
  # ------------------------------------------------------------#
  MaintenanceWindowTaskSTG:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      Name: WinOS-PatchTask-STG
      MaxConcurrency: 50
      MaxErrors: 0
      Priority: 1
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref MaintenanceWindowTargetSTG
      TaskArn: AWS-RunPatchBaseline
      TaskType: RUN_COMMAND
      WindowId: !Ref MaintenanceWindowSTG
      TaskInvocationParameters:
        MaintenanceWindowRunCommandParameters:
          TimeoutSeconds: 600
          Parameters: 
            "Operation": ["Install"]
            "RebootOption": ["RebootIfNeeded"]
    DependsOn: MaintenanceWindowTargetSTG

  MaintenanceWindowTaskPRD:
    Type: AWS::SSM::MaintenanceWindowTask
    Properties:
      Name: WinOS-PatchTask-PRD
      MaxConcurrency: 50
      MaxErrors: 0
      Priority: 1
      Targets:
        - Key: WindowTargetIds
          Values:
            - !Ref MaintenanceWindowTargetPRD
      TaskArn: AWS-RunPatchBaseline
      TaskType: RUN_COMMAND
      WindowId: !Ref MaintenanceWindowPRD
      TaskInvocationParameters:
        MaintenanceWindowRunCommandParameters:
          TimeoutSeconds: 600
          Parameters: 
            "Operation": ["Install"]
            "RebootOption": ["RebootIfNeeded"]
    DependsOn: MaintenanceWindowTargetPRD

t13801206t13801206

これはうまく動く

AWSTemplateFormatVersion: '2010-09-09'
Description: 'Windows Server 2019と2022インスタンスを作成するテンプレート'

Resources:
  WindowsServer2022Instance:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: ami-0ca6e4ffd34c17d86  # Windows_Server-2022-English-Full-Base-2025.05.15
      InstanceType: t2.micro
      IamInstanceProfile: EC2SSMManagementRole
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: 15
            VolumeType: gp2
      UserData:
        Fn::Base64: !Sub |
          <powershell>
          $proxy = "${WindowsServer2019Instance.PrivateIp}:8080"
          $bypassList = "*.amazonaws.com;169.254.169.254;ssm.*.amazonaws.com;*.ec2.internal"
          netsh winhttp set proxy $proxy bypass-list="$bypassList"
          </powershell>
      Tags:
        - Key: Name
          Value: Windows_Server-2022-English-Full-Base-2025.05.15

  WindowsServer2019Instance:
    Type: AWS::EC2::Instance
    DeletionPolicy: Delete
    Properties:
      ImageId: ami-0cb6a4b2bfede2ea0  # Windows_Server-2019-English-Full-Base-2025.05.15
      InstanceType: t2.micro
      IamInstanceProfile: EC2SSMManagementRole
      BlockDeviceMappings:
        - DeviceName: /dev/xvda
          Ebs:
            VolumeSize: 15
            VolumeType: gp2
      UserData:
        Fn::Base64: |
          <powershell>
          $proxy = "proxy.com:8080"
          $bypassList = "*.amazonaws.com;169.254.169.254;ssm.*.amazonaws.com;*.ec2.internal"
          netsh winhttp set proxy $proxy bypass-list="$bypassList"
          </powershell>
      Tags:
        - Key: Name
          Value: Windows_Server-2019-English-Full-Base-2025.05.15

Outputs:
  WindowsServer2022InstanceId:
    Description: ID of the Windows Server 2022 instance
    Value: !Ref WindowsServer2022Instance
  
  WindowsServer2019InstanceId:
    Description: ID of the Windows Server 2019 instance
    Value: !Ref WindowsServer2019Instance

  WindowsServer2022PrivateIP:
    Description: Private IP of Windows Server 2022 instance
    Value: !GetAtt WindowsServer2022Instance.PrivateIp
    
  WindowsServer2019PrivateIP:
    Description: Private IP of Windows Server 2019 instance
    Value: !GetAtt WindowsServer2019Instance.PrivateIp
t13801206t13801206

AWS AMI、ユーザーデータ、Sysprepに関する公式情報

公式ドキュメントの出典

ユーザーデータの実行について

Sysprepと AMIについて

パブリックAMIとカスタムAMIの違い

パブリックAMI

  • 提供元: AWSまたはAWSパートナーによって提供
  • 状態: 新鮮な状態(Sysprepされた状態)で提供
  • 特徴:
    • 初回起動時にはセットアッププロセスが実行される
    • ユーザーデータが確実に実行される
    • 基本設定のみで特別なカスタマイズはない

カスタムAMI

  • 提供元: ユーザー自身が作成
  • 状態: ユーザーが設定した状態で保存(設定済み・インストール済み)
  • 特徴:
    • 特定の設定やソフトウェアがプリインストールされている
    • Sysprepが適切に実行されていないとユーザーデータが実行されない可能性がある
    • AMI作成時の「システム状態」が保持される

Sysprepについての詳細説明

Sysprepは「System Preparation tool(システム準備ツール)」の略で、Windowsインスタンスから一意の情報を削除し、新しいインスタンスを作成するための準備を行うツールです。

Sysprepの主な役割

  1. 一意のシステム情報の削除:

    • コンピューター名、SID(セキュリティ識別子)
    • イベントログ
    • 特定のドライバー情報
  2. Windows Welcome画面の準備:

    • 次回起動時に初期セットアップ画面が表示される
  3. EC2固有の設定との関係:

    • EC2LaunchまたはEC2Launch v2と連携して動作
    • AMI作成時にはSysprepモードで実行する必要がある

EC2Launchv2とSysprepのプロセス

Windows Server 2022(および新しいWindows Server 2019)では、EC2Launch v2が使用されており、以下の流れで動作します:

  1. Sysprep実行方法:

    # 標準的なSysprep実行コマンド
    C:\ProgramData\Amazon\EC2Launch\sysprep\ec2launch.exe sysprep
    
    # AMIの再利用のためのリセットコマンド
    C:\ProgramData\Amazon\EC2Launch\sysprep\ec2launch.exe reset -c
    
  2. 設定ファイル: C:\ProgramData\Amazon\EC2Launch\config\agent-config.yml

    • ユーザーデータ実行ポリシーを設定可能
    • userDataExecutionPolicy: once (デフォルト) または always に設定可能
  3. EC2Launch v2の重要な動作:

    • インスタンスが初めて起動するとき、またはEc2LaunchInitializeタスクが実行されるときにユーザーデータを実行
    • AMIから起動したインスタンスでは「初回起動済み」と判断されることがある
    • 公式ドキュメントによると、インスタンスタイプ変更だけではなく、「新しいインスタンス」として認識されない場合がある

ユーザーデータを確実に実行する方法

公式ドキュメントから解決策:

  1. agent-config.yml修正:

    # C:\ProgramData\Amazon\EC2Launch\config\agent-config.yml 内での設定
    userDataExecutionPolicy: always
    
  2. SSMドキュメントを使用:

カスタムAMIでユーザーデータを確実に実行するには、適切なSysprep処理と設定ファイルの修正が重要です。これらの設定はOSバージョンやEC2Launchのバージョンによって異なるため、最新のドキュメントを参照することが推奨されます。