

• AWS Systems Manager CloudWatch 控制面板在 2026 年 4 月 30 日之后将不再可用。客户可以像现在一样继续使用 Amazon CloudWatch 控制台来查看、创建和管理其 Amazon CloudWatch 控制面板。有关更多信息，请参阅 [Amazon CloudWatch 控制面板文档](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html)。

# 更新自动扩缩组的 AMIs
<a name="automation-tutorial-update-patch-windows-ami-autoscaling"></a>

以下示例使用新修补的 AMI 更新自动扩缩组。此方法确保新映像自动可供使用 Auto Scaling 组的不同计算环境使用。

此示例中自动化的最后一步使用 Python 函数创建将使用新修补的 AMI 的新启动模板。然后更新自动扩缩组以使用新的启动模板。在此类型的 Auto Scaling 方案中，用户可以终止 Auto Scaling 组中的现有实例以强制启动使用新映像的实例。或者，用户可以等待以允许缩减或扩展事件正常启动较新的实例。

**开始前的准备工作**  
在开始本示例之前，请完成以下任务。
+ 为 Automation（AWS Systems Manager 中的一项工具）配置 IAM 角色。Systems Manager 需要实例配置文件角色和服务角色 ARN 来处理自动化。有关更多信息，请参阅 [设置自动化](automation-setup.md)。

## 创建 **PatchAMIAndUpdateASG** 运行手册
<a name="create-autoscaling-update-runbook"></a>

使用以下过程创建 **PatchAMIAndUpdateASG** 运行手册，它将修补您为 **SourceAMI** 参数指定的 AMI。运行手册还会更新自动扩缩组以使用最新修补后的 AMI。

**创建运行手册并运行**

1. 访问 [https://console.aws.amazon.com/systems-manager/](https://console.aws.amazon.com/systems-manager/)，打开 AWS Systems Manager 控制台。

1. 在导航窗格中，选择**文档**。

1. 在**创建文档**下拉菜单中，选择**自动化**。

1. 在**名称**字段中，输入 **PatchAMIAndUpdateASG**。

1. 选择 **Editor**（编辑器）选项卡，然后选择 **Edit**（编辑）。

1. 出现提示时选择 **OK**（确定），然后删除 **Document editor**（文档编辑器）字段中的内容。

1. 在 **Document editor**（文档编辑器）字段中，粘贴以下 YAML 示例运行手册内容。

   ```
   ---
   description: Systems Manager Automation Demo - Patch AMI and Update ASG
   schemaVersion: '0.3'
   assumeRole: '{{ AutomationAssumeRole }}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Required) The ARN of the role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to execute this document.'
       default: ''
     SourceAMI:
       type: String
       description: '(Required) The ID of the AMI you want to patch.'
     SubnetId:
       type: String
       description: '(Required) The ID of the subnet where the instance from the SourceAMI parameter is launched.'
     SecurityGroupIds:
       type: StringList
       description: '(Required) The IDs of the security groups to associate with the instance launched from the SourceAMI parameter.'
     NewAMI:
       type: String
       description: '(Optional) The name of of newly patched AMI.'
       default: 'patchedAMI-{{global:DATE_TIME}}'
     TargetASG:
       type: String
       description: '(Required) The name of the Auto Scaling group you want to update.'
     InstanceProfile:
       type: String
       description: '(Required) The name of the IAM instance profile you want the source instance to use.'
     SnapshotId:
       type: String
       description: (Optional) The snapshot ID to use to retrieve a patch baseline snapshot.
       default: ''
     RebootOption:
       type: String
       description: '(Optional) Reboot behavior after a patch Install operation. If you choose NoReboot and patches are installed, the instance is marked as non-compliant until a subsequent reboot and scan.'
       allowedValues:
         - NoReboot
         - RebootIfNeeded
       default: RebootIfNeeded
     Operation:
       type: String
       description: (Optional) The update or configuration to perform on the instance. The system checks if patches specified in the patch baseline are installed on the instance. The install operation installs patches missing from the baseline.
       allowedValues:
         - Install
         - Scan
       default: Install
   mainSteps:
     - name: startInstances
       action: 'aws:runInstances'
       timeoutSeconds: 1200
       maxAttempts: 1
       onFailure: Abort
       inputs:
         ImageId: '{{ SourceAMI }}'
         InstanceType: m5.large
         MinInstanceCount: 1
         MaxInstanceCount: 1
         IamInstanceProfileName: '{{ InstanceProfile }}'
         SubnetId: '{{ SubnetId }}'
         SecurityGroupIds: '{{ SecurityGroupIds }}'
     - name: verifyInstanceManaged
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 600
       inputs:
         Service: ssm
         Api: DescribeInstanceInformation
         InstanceInformationFilterList:
           - key: InstanceIds
             valueSet:
               - '{{ startInstances.InstanceIds }}'
         PropertySelector: '$.InstanceInformationList[0].PingStatus'
         DesiredValues:
           - Online
       onFailure: 'step:terminateInstance'
     - name: installPatches
       action: 'aws:runCommand'
       timeoutSeconds: 7200
       onFailure: Abort
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
     - name: stopInstance
       action: 'aws:changeInstanceState'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
         DesiredState: stopped
     - name: createImage
       action: 'aws:createImage'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceId: '{{ startInstances.InstanceIds }}'
         ImageName: '{{ NewAMI }}'
         NoReboot: false
         ImageDescription: Patched AMI created by Automation
     - name: terminateInstance
       action: 'aws:changeInstanceState'
       maxAttempts: 1
       onFailure: Continue
       inputs:
         InstanceIds:
           - '{{ startInstances.InstanceIds }}'
         DesiredState: terminated
     - name: updateASG
       action: 'aws:executeScript'
       timeoutSeconds: 300
       maxAttempts: 1
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: update_asg
         InputPayload:
           TargetASG: '{{TargetASG}}'
           NewAMI: '{{createImage.ImageId}}'
         Script: |-
           from __future__ import print_function
           import datetime
           import json
           import time
           import boto3
   
           # create auto scaling and ec2 client
           asg = boto3.client('autoscaling')
           ec2 = boto3.client('ec2')
   
           def update_asg(event, context):
               print("Received event: " + json.dumps(event, indent=2))
   
               target_asg = event['TargetASG']
               new_ami = event['NewAMI']
   
               # get object for the ASG we're going to update, filter by name of target ASG
               asg_query = asg.describe_auto_scaling_groups(AutoScalingGroupNames=[target_asg])
               if 'AutoScalingGroups' not in asg_query or not asg_query['AutoScalingGroups']:
                   return 'No ASG found matching the value you specified.'
   
               # gets details of an instance from the ASG that we'll use to model the new launch template after
               source_instance_id = asg_query.get('AutoScalingGroups')[0]['Instances'][0]['InstanceId']
               instance_properties = ec2.describe_instances(
                   InstanceIds=[source_instance_id]
               )
               source_instance = instance_properties['Reservations'][0]['Instances'][0]
   
               # create list of security group IDs
               security_groups = []
               for group in source_instance['SecurityGroups']:
                   security_groups.append(group['GroupId'])
   
               # create a list of dictionary objects for block device mappings
               mappings = []
               for block in source_instance['BlockDeviceMappings']:
                   volume_query = ec2.describe_volumes(
                       VolumeIds=[block['Ebs']['VolumeId']]
                   )
                   volume_details = volume_query['Volumes']
                   device_name = block['DeviceName']
                   volume_size = volume_details[0]['Size']
                   volume_type = volume_details[0]['VolumeType']
                   device = {'DeviceName': device_name, 'Ebs': {'VolumeSize': volume_size, 'VolumeType': volume_type}}
                   mappings.append(device)
   
               # create new launch template using details returned from instance in the ASG and specify the newly patched AMI
               time_stamp = time.time()
               time_stamp_string = datetime.datetime.fromtimestamp(time_stamp).strftime('%m-%d-%Y_%H-%M-%S')
               new_template_name = f'{new_ami}_{time_stamp_string}'
               try:
                   ec2.create_launch_template(
                       LaunchTemplateName=new_template_name,
                       LaunchTemplateData={
                           'BlockDeviceMappings': mappings,
                           'ImageId': new_ami,
                           'InstanceType': source_instance['InstanceType'],
                           'IamInstanceProfile': {
                               'Arn': source_instance['IamInstanceProfile']['Arn']
                           },
                           'KeyName': source_instance['KeyName'],
                           'SecurityGroupIds': security_groups
                       }
                   )
               except Exception as e:
                   return f'Exception caught: {str(e)}'
               else:
                   # update ASG to use new launch template
                   asg.update_auto_scaling_group(
                       AutoScalingGroupName=target_asg,
                       LaunchTemplate={
                           'LaunchTemplateName': new_template_name
                       }
                   )
                   return f'Updated ASG {target_asg} with new launch template {new_template_name} which uses AMI {new_ami}.'
   outputs:
   - createImage.ImageId
   ```

1. 选择**创建自动化**。

1. 在导航窗格中，选择**自动化**，然后选择**执行自动化**。

1. 在 **Choose document**（选择文档）页面上，选择 **Owned by me**（我拥有的）选项卡。

1. 搜索 **PatchAMIAndUpdateASG** 运行手册，然后选择 **PatchAMIAndUpdateASG** 卡中的按钮。

1. 选择**下一步**。

1. 选择**简单执行**。

1. 指定输入参数的值。确保您指定的 `SubnetId` 和 `SecurityGroupIds` 允许访问公有 Systems Manager 端点或 Systems Manager 的接口端点。

1. 选择**执行**。

1. 自动化完成后，在 Amazon EC2 控制台中，选择 **Auto Scaling**（自动扩缩），然后选择 **Launch Templates**（启动配置）。验证您是否看到了新的启动模板，并且它使用了新的 AMI。

1. 选择 **Auto Scaling**，然后选择 **Auto Scaling 组**。验证自动扩缩组使用了新的启动模板。

1. 终止 Auto Scaling 组中的一个或多个实例。替换实例使用新的 AMI 启动。