

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

# AWS Systems Manager 自动化
自动化

Automation 是 AWS Systems Manager 中的一项工具，其简化了 Amazon Elastic Compute Cloud（Amazon EC2）、Amazon Relational Database Service（Amazon RDS）、Amazon Redshift、Amazon Redshift、Amazon Simple Storage Service（Amazon S3）等 AWS 服务的常见维护、部署和修复任务。要开始使用自动化，请打开 [Systems Manager 控制台](https://console.aws.amazon.com/systems-manager/automation)。在导航窗格中，选择**自动化**。

Automation 可帮助您构建用于大规模部署、配置和管理 AWS 资源的自动化解决方案。借助 Automation，您可以精确控制自动化的并发性。这意味着您可以指定同时定位多少资源，以及在停止自动化之前可能发生的错误数。

为了帮助您开始使用 Automation，AWS 开发和维护了几个预先定义的运行手册。根据您的应用场景，您可以使用这些预定义的运行手册来执行各种任务，或者创建更适合您的需求的自定义运行手册。要监控自动化的进度和状态，您可以使用 Systems Manager Automation 控制台或您的首选命令行工具。Automation 还与 Amazon EventBridge 集成，可帮助您大规模构建事件驱动型架构。

**注意**  
对于截至 2025 年 8 月 14 日的 Systems Manager Automation 新客户，自动化免费套餐不可用。对于已经使用自动化的客户，免费套餐服务将于 2025 年 12 月 31 日结束。有关当前服务成本的信息，请参阅 [AWS Systems Manager 定价](https://aws.amazon.com/systems-manager/pricing/)。

## 我的组织如何从 Automation 获益？


Automation 具备下列优势：
+ **运行手册内容中的脚本支持**

  使用 `aws:executeScript` 操作，您可以直接从运行手册中运行自定义 Python 和 PowerShell 函数。这使您可以更灵活地创建自定义运行手册，因为您可以完成其他 Automation 操作不支持的各种任务。您还可以更好地控制运行手册的逻辑。有关如何使用此操作以及如何帮助改进现有自动化解决方案的示例，请参阅 [创作自动化运行手册](automation-authoring-runbooks.md)。
+  **从一个集中位置跨多个 AWS 账户 和 AWS 区域 运行自动化** 

  管理员可以从 Systems Manager 控制台跨多个账户和区域对资源运行自动化。
+  **增强操作安全** 

  管理员可以集中地授予和撤销对运行手册的访问。仅使用 AWS Identity and Access Management (IAM) 策略，您就可以控制贵企业中的哪些个人用户或组能够使用 Automation 以及他们能够访问的运行手册。
+  **自动执行常见 IT 任务** 

  自动执行常见任务可以帮助提高运营效率、强制执行组织标准并减少操作员错误。例如，您可以使用 `AWS-UpdateCloudFormationStackWithApproval` 运行手册来更新通过使用 AWS CloudFormation 模板部署的资源。更新会应用新模板。在更新开始之前，您可以配置 Automation 以请求由一个或多个用户批准。
+  **安全地批量执行中断性任务** 

  Automation 包含诸如速率控制之类的功能，使您可以通过指定并发值和错误阈值来控制自动化在整个机群上的部署。有关使用速率控制的更多信息，请参阅 [大规模运行自动化操作](running-automations-scale.md)。
+ **简化复杂任务**

  Automation 提供了预定义的运行手册，可简化复杂而耗时的任务，例如创建黄金 Amazon Machine Images (AMIs)。例如，您可以使用 `AWS-UpdateLinuxAmi` 和 `AWS-UpdateWindowsAmi` 运行手册从源 AMI 创建黄金 AMIs。使用这些运行手册，您可以在应用更新前后运行自定义脚本。您还可以包含特定软件包或从安装中排除这些软件包。有关如何使用这些运行手册的示例，请参阅 [教程](automation-tutorials.md)。
+ **为输入定义约束条件**

  您可以在自定义运行手册中定义约束条件，以限制 Automation 将为特定输入参数接受的值。例如，`allowedPattern` 将只接受与您定义的正则表达式匹配的输入参数的值。如果您为输入参数指定 `allowedValues`，只接受您在运行手册中指定的值。
+  **将自动化操作输出记录到 Amazon CloudWatch Logs 中** 

  为了满足组织的操作或安全要求，您可能需要提供在运行手册期间运行的脚本记录。使用 CloudWatch Logs，您可以监控、存储和访问各种 AWS 服务 的日志文件。您可以将 `aws:executeScript` 操作的输出发送到 CloudWatch Logs 日志组中用于调试和故障排除目的。在将日志数据发送到日志组时，可以使用您的 KMS 密钥进行 AWS KMS 加密，也可以不加密。有关更多信息，请参阅 [使用 CloudWatch Logs 记录自动化操作输出](automation-action-logging.md)。
+  **Amazon EventBridge 集成** 

  支持将 Automation 作为 Amazon EventBridge 规则中的*目标*类型。这意味着您可以通过使用事件触发运行手册。有关更多信息，请参阅 [使用 Amazon EventBridge 监控 Systems Manager 事件](monitoring-eventbridge-events.md) 和 [引用：Amazon EventBridge 事件模式和 Systems Manager 类型](reference-eventbridge-events.md)。
+ **分享组织最佳实践**

  您可以在跨账户和区域共享的运行手册中定义资源管理、运营任务等的最佳实践。

## 谁应该使用 Automation？

+ 任何希望大规模提高其运营效率、减少与手动干预相关的错误以及缩短解决常见问题的时间的 AWS 客户。
+ 希望自动执行部署和配置任务的基础设施专家。
+ 想要可靠地解决常见问题、提高故障排除效率和减少重复性操作的管理员。
+ 想要自动执行通常需要手动执行的任务的用户。

## 什么是自动化？


*自动化*由运行手册中定义的所有任务组成，并由 Automation 服务执行。Automation 使用以下组件运行自动化。


****  

| 概念 | Details | 
| --- | --- | 
|  自动化运行手册  |  Systems Manager 自动化运行手册定义 Systems Manager 对托管式节点和 AWS 资源执行的自动化操作。自动化包含几个预定义的自动化运行手册，您可以用它们来执行常见任务，例如重启一个或多个 Amazon EC2 实例，或创建 Amazon Machine Image (AMI)。您也可以创建自己的运行手册。运行手册使用 YAML 或 JSON,，并包括您指定的步骤和参数。步骤按先后顺序运行。有关更多信息，请参阅 [创建您自己的运行手册](automation-documents.md)。 运行手册是 `Automation` 类型的 Systems Manager 文档，而不是`Command`、`Policy`、`Session` 文档。运行手册支持 0.3 版架构。命令文档使用 1.2、2.0 或 2.2 版本的架构。策略文档使用 2.0 或更高版本的架构。  | 
|  自动化操作  |  运行手册中定义的自动化包括一个或多个步骤。每个步骤都与特定操作关联。此操作确定本步的输入、行为和输出。在运行手册的 `mainSteps` 部分定义步骤。自动化支持 20 种不同的操作类型。有关更多信息，请参阅[Systems Manager 自动化操作参考](automation-actions.md)。  | 
|  自动化配额  |  每个 AWS 账户 账户可以同时运行 100 项自动化。这包括子自动化（由其他自动化启动的自动化）和速率控制自动化。如果您尝试运行的自动化多于此数量，Systems Manager 会将额外的自动化添加到一个队列中，状态显示为“待处理”。此限额可使用自适应并发来调整。有关更多信息，请参阅 [允许 Automation 适应您的并发需求](adaptive-concurrency.md)。有关运行自动化的更多信息，请参阅 [运行由 Systems Manager Automation 支持的自动化操作](running-simple-automations.md)。  | 
|  自动化队列配额  |  如果尝试运行的自动化数量超过并发自动化限制，后续自动化将添加到队列中。每个 AWS 账户可以排列 5000 个自动化。自动化完成（或达到最终状态）后，队列中的第一个自动化将启动。  | 
|  速率控制自动化配额  |  每个 AWS 账户 可以同时运行 25 项速率控制自动化。如果您尝试运行的速率控制自动化多于并发费率控制自动化限制，Systems Manager 会将后续速率控制自动化添加到一个队列中，状态显示为“待处理”。有关运行速率控制自动化的更多信息，请参阅 [大规模运行自动化操作](running-automations-scale.md)。  | 
|  速率控制自动化队列配额  |  如果尝试运行的自动化数量超过并发速率控制自动化限制，后续自动化将添加到队列中。每个 AWS 账户 可以排列 1000 个速率控制自动化。自动化完成（或达到最终状态）后，队列中的第一个自动化将启动。  | 

**Topics**
+ [

## 我的组织如何从 Automation 获益？
](#automation-benefits)
+ [

## 谁应该使用 Automation？
](#automation-who)
+ [

## 什么是自动化？
](#what-is-an-automation)
+ [

# 设置自动化
](automation-setup.md)
+ [

# 运行由 Systems Manager Automation 支持的自动化操作
](running-simple-automations.md)
+ [

# 重新运行自动化执行
](automation-rerun-executions.md)
+ [

# 运行需要审批的自动化
](running-automations-require-approvals.md)
+ [

# 大规模运行自动化操作
](running-automations-scale.md)
+ [

# 在多个 AWS 区域 和账户中运行自动化
](running-automations-multiple-accounts-regions.md)
+ [

# 基于 EventBridge 事件运行自动化
](running-automations-event-bridge.md)
+ [

# 要按步骤运行自动化
](automation-working-executing-manually.md)
+ [

# 使用 State Manager 关联调度自动化
](scheduling-automations-state-manager-associations.md)
+ [

# 使用维护窗口计划自动化
](scheduling-automations-maintenance-windows.md)
+ [

# Systems Manager 自动化操作参考
](automation-actions.md)
+ [

# 创建您自己的运行手册
](automation-documents.md)
+ [

# Systems Manager 自动化运行手册参考
](automation-documents-reference.md)
+ [

# 教程
](automation-tutorials.md)
+ [

# 了解 Systems Manager Automation 返回的状态
](automation-statuses.md)
+ [

# Systems Manager 自动化故障排除
](automation-troubleshooting.md)

# 设置自动化


要设置 Automation（AWS Systems Manager 中的一项工具），您必须确保用户对 Automation 服务具有访问权限并按情景配置角色，以便服务可在您的资源上执行操作。我们还建议您在 Automation 首选项中选择使用自适应并发模式。自适应并发会自动扩展您的自动化配额以满足您的需求。有关更多信息，请参阅 [允许 Automation 适应您的并发需求](adaptive-concurrency.md)。

为确保正确访问 AWS Systems Manager 自动化，请查看以下用户和服务角色要求。

## 验证用户的运行手册访问权限


确认您有权使用运行手册。如果已为您的用户、组或角色分配了管理员权限，则您有权访问 Systems Manager 自动化。如果您没有管理员权限，则管理员必须通过向您的用户、组或角色分配 `AmazonSSMFullAccess` 托管策略或提供类似权限的策略，来向您授予权限。

**重要**  
IAM policy `AmazonSSMFullAccess` 授予对 Systems Manager 进行操作的权限。但是，某些运行手册需要其他服务的权限，例如运行手册 `AWS-ReleaseElasticIP`，它需要 `ec2:ReleaseAddress` 的 IAM 权限。因此，您必须查看运行手册中采取的操作，以确保为您的用户、组或角色分配了执行运行手册包括的操作所需的权限。

## 为自动化配置服务角色（担任角色）访问权限


自动化可以在服务角色（或*代入角色*）的上下文下启动。这样服务就能够代表您执行操作。如果未指定担任角色，则自动化将使用调用了自动化的用户的上下文。

不过，以下情况需要您为自动化指定服务角色：
+ 当您想限制用户对资源的权限，但希望用户运行需要提升权限的自动化时。在这种情况下，您可以创建具有提升权限的服务角色并允许用户运行自动化。
+ 创建 Systems Manager State Manager 关联，运行一个运行手册。
+ 您有运行时长预计将超过 12 小时的操作时。
+ 在运行不归 Amazon 所有并使用 `aws:executeScript` 操作调用 AWS API 操作或对 AWS 资源执行操作的运行手册时。有关信息，请参阅[使用运行手册的权限](automation-document-script-considerations.md#script-permissions)。

如果您需要为自动化创建一个服务角色，可以使用以下方法之一。

**Topics**
+ [

## 验证用户的运行手册访问权限
](#automation-setup-user-access)
+ [

## 为自动化配置服务角色（担任角色）访问权限
](#automation-setup-configure-role)
+ [

# 通过使用 CloudFormation 为 Automation 创建服务角色
](automation-setup-cloudformation.md)
+ [

# 使用控制台为 Automation 创建服务角色
](automation-setup-iam.md)
+ [

# 设置基于身份的策略示例
](automation-setup-identity-based-policies.md)
+ [

# 允许 Automation 适应您的并发需求
](adaptive-concurrency.md)
+ [

# 为节流的操作配置自动重试
](automation-throttling-retry.md)
+ [

# 为自动化实施更改控制
](automation-change-calendar-integration.md)

# 通过使用 CloudFormation 为 Automation 创建服务角色


您可以通过 AWS CloudFormation 模板为 Automation（AWS Systems Manager 中的一项工具）创建一个服务角色。创建服务角色后，可以使用参数 `AutomationAssumeRole` 在运行手册中指定服务角色。

## 使用 CloudFormation 创建服务角色


使用 CloudFormation，通过以下过程为 Systems Manager 自动化创建所需的 AWS Identity and Access Management (IAM) 角色。

**创建所需的 IAM 角色**

1. 下载并解压缩 [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationServiceRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationServiceRole.zip) 文件。此文件夹包含 `AWS-SystemsManager-AutomationServiceRole.yaml` CloudFormation 模板文件。

1. 通过以下网址打开 CloudFormation 控制台：[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 选择**创建堆栈**。

1. 在**指定模板**部分，选择**上传模板文件**。

1. 选择**浏览**，然后选择 `AWS-SystemsManager-AutomationServiceRole.yaml` CloudFormation 模板文件。

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

1. 在**指定堆栈详细信息**页面的**堆栈名称**字段中，输入名称。

1. 在**配置堆栈选项**页面上，您无需进行任何选择。选择**下一步**。

1. 在**审核**页面上，向下滚动并选择**我确认 CloudFormation 可能创建 IAM 资源**选项。

1. 选择**创建**。

大约三分钟左右，CloudFormation 会显示 **CREATE\$1IN\$1PROGRESS** 状态。创建堆栈并且您的角色准备好使用之后，状态会变为 **CREATE\$1COMPLETE**。

**重要**  
如果您运行使用 AWS Identity and Access Management (IAM) 服务角色调用其他服务的自动化工作流程，请注意必须使用权限将该服务角色配置为调用这些服务。该要求适用于所有 AWS 自动化运行手册（`AWS-*` 运行手册），例如 `AWS-ConfigureS3BucketLogging`、`AWS-CreateDynamoDBBackup` 和 `AWS-RestartEC2Instance` 运行手册等。对于您创建的任何自定义自动化运行手册，如果这些文档使用调用其他服务的操作来调用其他 AWS 服务，则此要求同样适用。例如，如果使用 `aws:executeAwsApi`、`aws:createStack` 或 `aws:copyImage` 操作，则您必须配置具有权限的服务角色来调用这些服务。您可以将 IAM 内联策略添加到该角色，从而向其他 AWS 服务授予权限。有关更多信息，请参阅 [（可选）添加自动化内联策略或客户管理型策略来调用其他 AWS 服务](automation-setup-iam.md#add-inline-policy)。

## 复制自动化的角色信息


使用以下过程从 CloudFormation 控制台复制关于自动化服务角色的信息。当您使用运行手册时，必须指定这些角色。

**注意**  
如果您运行 `AWS-UpdateLinuxAmi` 或 `AWS-UpdateWindowsAmi` 运行手册，则无需使用此过程来复制角色信息。这些运行手册已将必需角色指定为默认值。这些运行手册中指定的角色使用 IAM 托管式策略。

**复制角色名称**

1. 通过以下网址打开 CloudFormation 控制台：[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 选择您在前一个过程中创建的自动化 **Stack name (堆栈名称)**。

1. 选择**资源**选项卡。

1. 选择 **AutomationServiceRole** 的**物理 ID** 链接 IAM 控制台将打开并显示自动化服务角色的摘要。

1. 复制**角色 ARN** 旁边的 Amazon Resource Name (ARN)。该 ARN 类似于以下这样：`arn:aws:iam::12345678:role/AutomationServiceRole`。

1. 将 ARN 粘贴到文本文件供以后使用。

您已完成了为自动化配置服务角色。现在，您可在运行手册中使用自动化服务角色 ARN。

# 使用控制台为 Automation 创建服务角色


如果需要为 Automation（AWS Systems Manager 中的一项工具）创建一个服务角色，请完成以下任务。有关自动化何时需要服务角色的更多信息，请参阅 [设置自动化](automation-setup.md)。

**Topics**
+ [

## 任务 1：为自动化创建服务角色
](#create-service-role)
+ [

## 任务 2：将 iam:PassRole 策略附加到您的自动化角色
](#attach-passrole-policy)

## 任务 1：为自动化创建服务角色


使用以下过程为 Systems Manager 自动化创建服务角色（或*承担角色*）。

**注意**  
您也可以在运行手册中使用此角色，例如 `AWS-CreateManagedLinuxInstance` 运行手册。使用此角色或 AWS Identity and Access Management (IAM) 角色的 Amazon Resource Name (ARN)，在运行手册中允许自动化在您的环境中执行操作，例如启动新实例和代表您执行操作。

**创建 IAM 角色并允许自动化担任该角色**

1. 通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在导航窗格中，选择 **Roles (角色)**，然后选择 **Create role (创建角色)**。

1. 在 **Select type of trusted entity (选择受信任实体的类型)** 下，选择 **AWS service (Amazon Web Services 服务)**。

1. 在 **Choose a use case (选择使用场景)** 部分，选择 **Systems Manager**，然后选择 **Next: Permissions (下一步：权限)**。

1. 在**附加的权限策略**页面中，搜索 **AmazonSSMAutomationRole** 策略，选择它，然后选择**下一步：审核**。

1. 在**审核**页面上，在**角色名称**框中输入名称，然后输入描述。

1. 选择**创建角色**。系统将让您返回到 **角色** 页面。

1. 在**角色**页面中，选择刚刚创建的角色以打开**摘要**页面。记下**角色名称**和**角色 ARN**。在下一步骤中，当您将 **iam:PassRole** 策略附加到您的 IAM 账户时，将指定该角色 ARN。您还可以在运行手册中指定角色名称和 ARN。

**注意**  
`AmazonSSMAutomationRole` 策略会将自动化角色权限分配给您账户内 AWS Lambda 函数的子集。这些函数以“自动化”开头。如果计划通过 Lambda 函数使用 自动化，则 Lambda ARN 必须使用以下格式：  
`"arn:aws:lambda:*:*:function:Automation*"`  
如果现有 Lambda 函数的 ARN 未使用此格式，您还必须为自动化角色附加额外的 Lambda 策略，例如 **AWSLambdaRole** 策略。其他策略或角色必须提供对 AWS 账户 账户内 Lambda 函数更宽泛的访问权限。

创建服务角色后，我们建议编辑信任策略，以帮助防止跨服务的混淆代理问题。*混淆代理问题*是一个安全问题，即没有执行操作权限的实体可能会迫使更具权限的实体执行该操作。在 AWS 中，跨服务模拟可能会导致混淆代理问题。一个服务（*呼叫服务*）调用另一项服务（*所谓的服务*）时，可能会发生跨服务模拟。可以操纵调用服务，使用其权限以在其他情况下该服务不应有访问权限的方式对另一个客户的资源进行操作。为防止这种情况，AWS 提供可帮助您保护所有服务的数据的工具，而这些服务中的服务主体有权限访问账户中的资源。

我们建议使用资源策略中的 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourcearn) 和 [https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-sourceaccount) 全局条件上下文键，限制 Automation 为另一项服务提供的资源访问权限。如果 `aws:SourceArn` 值不包含账户 ID，例如 Amazon S3 存储桶 ARN，您必须使用两个全局条件上下文密钥来限制权限。如果同时使用全局条件上下文密钥和包含账户 ID 的 `aws:SourceArn` 值，则 `aws:SourceAccount` 值和 `aws:SourceArn` 值中的账户在同一策略语句中使用时，必须使用相同的账户 ID。如果您只希望将一个资源与跨服务访问相关联，请使用 `aws:SourceArn`。如果您想允许该账户中的任何资源与跨服务使用操作相关联，请使用。`aws:SourceAccount``aws:SourceArn` 的值必须是自动化执行的 ARN。如果您不知道资源的完整 ARN，或正在指定多个资源，请针对 ARN 未知部分使用带有通配符 (`*`) 的 `aws:SourceArn` 全局上下文条件键。例如 `arn:aws:ssm:*:123456789012:automation-execution/*`。

以下示例演示如何使用适用于自动化的 `aws:SourceArn` 和 `aws:SourceAccount` 全局条件上下文键，防止发生混淆代理问题。

------
#### [ JSON ]

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "ssm.amazonaws.com"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "aws:SourceAccount": "123456789012"
        },
        "ArnLike": {
          "aws:SourceArn": "arn:aws:ssm:*:123456789012:automation-execution/*"
        }
      }
    }
  ]
}
```

------

**要修改角色的信任策略**

1. 通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在导航窗格中，选择**角色**。

1. 在账户的角色列表中，请选择 Automation 服务角色的名称。

1. 选择 **信任关系** 选项卡，然后选择 **编辑信任关系**。

1. 使用适用于 Automation 的 `aws:SourceArn` 和 `aws:SourceAccount` 全局条件上下文键编辑信任策略，以防止发生混淆代理问题。

1. 要保存更改，请选择 **Update Trust Policy**（更新信任策略）。

### （可选）添加自动化内联策略或客户管理型策略来调用其他 AWS 服务


如果您运行使用 IAM 服务角色来调用其他 AWS 服务的自动化，则必须为该服务角色配置调用这些服务的权限。该要求适用于所有 AWS 自动化运行手册（`AWS-*` 运行手册），例如 `AWS-ConfigureS3BucketLogging`、`AWS-CreateDynamoDBBackup` 和 `AWS-RestartEC2Instance` 运行手册等。对于您创建的任何自定义运行手册，如果这些文档使用调用其他服务的操作来调用其他 AWS 服务，则此要求同样适用。例如，如果使用 `aws:executeAwsApi`、`aws:CreateStack` 或 `aws:copyImage` 操作等，则您必须配置具有权限的服务角色来调用这些服务。您可以将 IAM 内联策略或客户管理型策略添加到该角色，从而向其他 AWS 服务 授予权限。

**为服务角色嵌入内联策略（IAM 控制台）**

1. 登录 AWS 管理控制台，然后通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在导航窗格中，选择**角色**。

1. 在列表中，选择您要编辑的角色的名称。

1. 选择**权限**项卡。

1. 在**添加权限**下拉列表中，选择**附加策略**或**创建内联策略**。

1. 如果选择**附加策略**，请选中要添加的策略旁边的复选框，然后选择**添加权限**。

1. 如果选择**创建策略**，请选择 **JSON** 选项卡。

1. 输入您希望调用的 AWS 服务的 JSON 策略文档。以下是两个示例 JSON 策略文档。

   **Amazon S3 PutObject 和 GetObject 示例**

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "s3:PutObject",
                   "s3:GetObject"
               ],
               "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*"
           }
       ]
   }
   ```

------

   **Amazon EC2 CreateSnapshot 和 DescribeSnapShots 示例**

------
#### [ JSON ]

****  

   ```
   {
      "Version":"2012-10-17",		 	 	 
      "Statement":[
         {
            "Effect":"Allow",
            "Action":"ec2:CreateSnapshot",
            "Resource":"*"
         },
         {
            "Effect":"Allow",
            "Action":"ec2:DescribeSnapshots",
            "Resource":"*"
         }
      ]
   }
   ```

------

   有关 IAM policy 语言的详细信息，请参阅《IAM 用户指南》中的 [IAM JSON 策略参考](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html)。

1. 完成后，选择**查看策略**。[策略验证程序](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_policy-validator.html)将报告任何语法错误。

1. 在**查看策略**页面上，为创建的策略输入**名称**。查看策略**摘要**以查看您的策略授予的权限。然后，选择**创建策略**以保存您的工作。

1. 创建内联策略后，它会自动嵌入您的角色。

## 任务 2：将 iam:PassRole 策略附加到您的自动化角色


使用以下过程将 `iam:PassRole` 策略附加到您的自动化服务角色。这让 Automation 服务能够在运行自动化时将角色传递给其他服务或 Systems Manager 工具。

**将 iam:PassRole 策略附加到您的自动化角色**

1. 在刚刚创建的角色的**摘要**页面中，选择**权限**选项卡。

1. 选择 **Add inline policy (添加内联策略)**。

1. 在 **Create policy (创建策略)** 页面上，选择 **Visual editor (可视化编辑器)** 选项卡。

1. 选择**服务**，然后选择 **IAM**。

1. 选择**选择操作**。

1. 在**筛选操作**文本框中，键入 **PassRole**，然后选择 **PassRole** 选项。

1. 选择**资源**。确保已选择**特定**，然后选择**添加 ARN**。

1. 在**为角色指定 ARN** 字段中，粘贴您在任务 1 结束时复制的自动化角色 ARN。系统会自动填充**账户**和**具有路径的角色名称**字段。
**注意**  
如果希望自动化服务角色将 IAM 实例配置文件角色附加到 EC2 实例，则必须添加 IAM 实例配置文件角色的 ARN。这使自动化服务角色可以将 IAM 实例配置文件角色传递给目标 EC2 实例。

1. 选择**添加**。

1. 选择**查看策略**。

1. 在 **Review Policy (审核策略)** 页面上输入一个名称，然后选择 **Create Policy (创建策略)**。

# 设置基于身份的策略示例


以下部分提供了 AWS Systems Manager Automation 服务的基于 IAM 身份的策略示例。要详细了解如何使用这些示例 JSON 策略文档创建基于 IAM 身份的策略，请参阅《IAM 用户指南》**中的[创建 IAM 策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create.html#access_policies_create-json-editor)。

**注意**  
所有示例都包含虚构的账户 ID。不应在 AWS 自有公共文档的 Amazon 资源名称（ARN）中指定账户 ID。

 **示例** 
+  [示例 1：允许用户运行自动化文档并查看自动化执行情况](#automation-setup-identity-based-policies-example-1) 
+  [示例 2：允许用户运行自动化文档的特定版本](#automation-setup-identity-based-policies-example-2) 
+  [示例 3：允许用户执行具有特定标签的自动化文档](#automation-setup-identity-based-policies-example-3) 
+  [示例 4：当为自动化执行提供了特定的标签参数时，允许用户运行自动化文档](#automation-setup-identity-based-policies-example-4) 

## 示例 1：允许用户运行自动化文档并查看自动化执行情况


以下示例 IAM 策略允许用户执行以下操作：
+ 运行策略中指定的自动化文档。文档名称由以下条目确定。

  ```
  arn:aws:ssm:*:111122223333:document/{{DocumentName}}
  ```
+ 停止并向自动化执行发送信号。
+ 在自动化执行启动后查看其详细信息。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:document/{{DocumentName}}",
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ]
        },
        {
            "Action": [
                "ssm:StopAutomationExecution",
                "ssm:GetAutomationExecution",
                "ssm:DescribeAutomationExecutions",
                "ssm:DescribeAutomationStepExecutions",
                "ssm:SendAutomationSignal"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        }
    ]
}
```

------

## 示例 2：允许用户运行自动化文档的特定版本


以下示例 IAM 策略允许用户运行自动化文档的特定版本：
+ 自动化文档名称由以下条目确定。

  ```
  arn:aws:ssm:*:111122223333:document/{{DocumentName}}
  ```
+ 自动化文档版本由以下条目确定。

  ```
  "ssm:DocumentVersion": "5"
  ```

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:document/{{DocumentName}}"
            ],
            "Condition": {
                "ForAnyValue:StringEquals": {
                   "ssm:DocumentVersion": ["5"]
                }
            }
        },
        {
            "Action": [
                "ssm:StartAutomationExecution"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "ssm:StopAutomationExecution",
                "ssm:GetAutomationExecution",
                "ssm:DescribeAutomationExecutions",
                "ssm:DescribeAutomationStepExecutions",
                "ssm:SendAutomationSignal"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        }
    ]
}
```

------

## 示例 3：允许用户执行具有特定标签的自动化文档


以下示例 IAM 策略允许用户执行具有特定标签的任何自动化文档：
+ 自动化文档名称由以下条目确定。

  ```
  arn:aws:ssm:*:111122223333:document/{{DocumentName}}
  ```
+ 自动化文档标签由以下条目确定。

  ```
  "ssm:DocumentVersion": "5"
  ```

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:document/*"
            ],
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/stage": "production"
                }
            }
        },
        {
            "Action": [
                "ssm:StartAutomationExecution"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "ssm:StopAutomationExecution",
                "ssm:GetAutomationExecution",
                "ssm:DescribeAutomationExecutions",
                "ssm:DescribeAutomationStepExecutions",
                "ssm:SendAutomationSignal"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow"
        }
    ]
}
```

------

## 示例 4：当为自动化执行提供了特定的标签参数时，允许用户运行自动化文档


当为自动化执行提供了特定的标签参数时，以下示例 IAM 策略向用户授予运行自动化文档的权限：
+ 运行策略中指定的自动化文档。文档名称由以下条目确定。

  ```
  arn:aws:ssm:*:111122223333:document/{{DocumentName}}
  ```
+ 必须为自动化执行提供特定的标签参数。自动化执行资源的标签参数由以下条目确定。

  ```
  "aws:ResourceTag/stage": "production"
  ```
+ 停止并向具有指定标签的自动化执行发送信号。
+ 查看有关具有指定标签的自动化执行的详细信息。
+ 为 SSM 资源添加指定标签

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": "ssm:StartAutomationExecution",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:document/{{DocumentName}}"
            ]
        },
        {
            "Action": [
                "ssm:StartAutomationExecution",
                "ssm:StopAutomationExecution",
                "ssm:GetAutomationExecution",
                "ssm:DescribeAutomationExecutions",
                "ssm:DescribeAutomationStepExecutions",
                "ssm:SendAutomationSignal"
            ],
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ],
            "Effect": "Allow",
            "Condition": {
                "StringEquals": {
                    "aws:ResourceTag/environment": "beta"
                }
            }
        },
        {
            "Action": "ssm:AddTagsToResource",
            "Effect": "Allow",
            "Resource": [
                "arn:aws:ssm:*:111122223333:automation-execution/*"
            ]
        }
    ]
}
```

------

# 允许 Automation 适应您的并发需求


默认情况下，Automation 允许您一次最多运行 100 次并发自动化。Automation 还提供了一个可选设置，您可以使用该设置自动调整并发自动化配额。使用此设置，您的并发自动化配额最多可容纳 500 个并发自动化，具体取决于可用资源。

**注意**  
如果您的自动化调用 API 操作，自适应地扩展到目标可能会导致限制异常。如果在启用自适应并发的情况下运行自动化时反复出现限制异常，则可能必须请求提高 API 操作的配额（如果可用）。

**要使用 AWS 管理控制台 开启自适应并发**

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

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

1. 选择**首选项**选项卡，然后选择**编辑**。

1. 选中 **Enable adaptive concurrency**（启用自适应并发）旁边的复选框。

1. 选择**保存**。

**要使用命令行开启自适应并发**
+ 打开 AWS CLI 或 Tools for Windows PowerShell，运行以下命令，在请求区域中为您的账户开启自适应并发。

------
#### [ Linux & macOS ]

  ```
  aws ssm update-service-setting \
      --setting-id /ssm/automation/enable-adaptive-concurrency \
      --setting-value True
  ```

------
#### [ Windows ]

  ```
  aws ssm update-service-setting ^
      --setting-id /ssm/automation/enable-adaptive-concurrency ^
      --setting-value True
  ```

------
#### [ PowerShell ]

  ```
  Update-SSMServiceSetting `
      -SettingId "/ssm/automation/enable-adaptive-concurrency" `
      -SettingValue "True"
  ```

------

# 为节流的操作配置自动重试


每个账户中可以运行的并发自动化执行数量存在限制。尝试在一个账户中同时运行多个自动化可能会导致节流问题。您可以使用自动节流重试功能为节流的自动化步骤配置重试行为。

自动化操作的自动节流重试为大规模操作提供了更具弹性的执行环境。节流重试功能支持除 `aws:executeScript` 之外的所有[自动化操作](automation-actions.md)。

节流重试设置与现有 `maxAttempts` 的步骤属性配合使用。两者都配置好后，系统首先尝试在指定的时间限制内节流重试次数，如果步骤仍然失败，再应用 `maxAttempts` 设置。

**使用AWS 管理控制台配置节流重试**

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

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

1. 选择**首选项**选项卡，然后选择**编辑**。

1. 在**节流重试时间限制**字段中，输入介于 0 到 3600 秒之间的值。这指定了系统重试节流的步骤的最长时间。

1. 选择**保存**。

**使用命令行配置节流重试**
+ 打开 AWS CLI 或 Tools for Windows PowerShell，运行以下命令，在请求区域中为您的账户配置节流。

------
#### [ Linux & macOS ]

  ```
  aws ssm update-service-setting \
      --setting-id /ssm/automation/throttling-retry-time-limit \
      --setting-value 3600
  ```

------
#### [ Windows ]

  ```
  aws ssm update-service-setting ^
      --setting-id /ssm/automation/throttling-retry-time-limit ^
      --setting-value 3600
  ```

------
#### [ PowerShell ]

  ```
  Update-SSMServiceSetting `
      -SettingId "/ssm/automation/throttling-retry-time-limit" `
      -SettingValue "3600"
  ```

------

# 为自动化实施更改控制


默认情况下，自动化允许您不受日期和时间限制地使用运行手册。通过将自动化与 Change Calendar 集成，您可以对您的 AWS 账户 中的所有自动化实施更改控制。借助此设置，您账户中的 AWS Identity and Access Management（IAM）主体只能在更改日历允许的时间段内运行自动化。要了解有关使用 Change Calendar 的更多信息，请参阅 [使用 Change Calendar](systems-manager-change-calendar-working.md)。

**打开更改控制（控制台）**

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

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

1. 选择**首选项**选项卡，然后选择**编辑**。

1. 选择**打开 Change Calendar 集成**旁边的复选框。

1. 在**选择更改日历**下拉列表中，选择您希望自动化遵循的更改日历。

1. 选择**保存**。

# 运行由 Systems Manager Automation 支持的自动化操作


在您运行自动化时，默认情况下，自动化将在启动该自动化的用户的上下文中运行。也就是说，例如，如果您的用户拥有管理员权限，则该自动化运行时也拥有管理员权限，并且对该自动化配置的资源拥有完全访问权限。作为最佳安全实践，建议使用配置有 AmazonSSMAutomationRole 托管式策略的 IAM 服务角色（在本例中也称为*担任*角色）运行自动化。您可能需要将其他 IAM policy 添加到您的担任角色，以使用各种运行手册。使用 IAM 服务角色运行自动化称为*委托管理*。

如果使用服务角色，则允许对 AWS 资源运行自动化，但运行自动化的用户对这些资源的访问受限（或无法访问）。例如，您可以配置一个服务角色，并将其与自动化配合使用以自动重启一个或多个 Amazon Elastic Compute Cloud (Amazon EC2) 实例。Automation 是 AWS Systems Manager 中的一项工具。自动化会重启实例，但服务角色不会授予用户访问这些实例的权限。

可以在您运行自动化的运行时中指定服务角色，也可以创建自定义自动化运行手册，并直接在运行手册中指定服务角色。无论您是在运行时还是在运行手册中指定了服务角色，服务都会在所指定服务角色的上下文中运行。如果您未指定服务角色，则系统会在用户上下文中创建临时会话并运行自动化。

**注意**  
对于预计运行时长超过 12 小时的自动化，必须指定服务角色。如果您在用户环境中启动了长时间运行的自动化，用户的临时会话会在 12 小时后过期。

委托管理可确保更高的安全性，还能更好地控制您的 AWS 资源。它还能够增强审核体验，因为针对您的资源进行的操作是由集中服务角色执行的，而不是由多个 IAM 账户执行。

**开始前的准备工作**  
在您完成以下过程之前，必须创建 IAM 服务角色并为 Automation（AWS Systems Manager 中的一项工具）配置信任关系。有关更多信息，请参阅 [任务 1：为自动化创建服务角色](automation-setup-iam.md#create-service-role)。

以下过程介绍了如何使用 Systems Manager 控制台或您首选的命令行工具运行简单的自动化。

## 运行简单的自动化（控制台）


以下过程介绍了如何使用 Systems Manager 控制台运行简单的自动化。

**运行简单的自动化**

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

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

1. 在**自动化文档**列表中，请选择运行手册。在**文档类别**窗格中选择一个或多个选项，以便根据 SSM 文档的用途对其进行筛选。要查看您拥有的运行手册，请选择**我拥有的**选项卡。要查看与您的账户共享的运行手册，请选择**与我共享**选项卡。要查看所有运行手册，请选择**所有文档**选项卡。
**注意**  
您可以通过选择运行手册名称来查看有关该手册的信息。

1. 在**文档详细信息**部分中，验证**文档版本**已设置为要运行的版本。系统包括以下版本选项：
   + **运行时的默认版本** – 如果定期更新自动化运行手册并分配新的默认版本，请选择此选项。
   + **运行时的最新版本** – 如果定期更新自动化运行手册并且想要运行最新更新的版本，请选择此选项。
   + **1（默认）** – 选择此选项可执行文档的第一个版本，即默认版本。

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

1. 在**执行模式**部分中，选择**简单执行**。

1. 在 **输入参数** 部分中，指定所需的输入。或者，您也可以从 **AutomationAssumeRole** 列表选择一个 IAM 服务角色。

1. （可选）选择一个 CloudWatch 警报以应用于您的自动化进行监控。要将 CloudWatch 警报附加到自动化，启动自动化的 IAM 主体必须具有 `iam:createServiceLinkedRole` 操作的权限。有关 CloudWatch 警报的更多信息，请参阅[使用 Amazon CloudWatch 警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)。请注意，如果您的警报激活，自动化将停止。如果使用 AWS CloudTrail，您将在跟踪中看到 API 调用。

1. 选择**执行**。

控制台将显示自动化的状态。如果自动化无法运行，请参阅 [Systems Manager 自动化故障排除](automation-troubleshooting.md)。

自动化执行完成后，您可以使用相同或修改后的参数重新运行该执行。有关更多信息，请参阅 [重新运行自动化执行](automation-rerun-executions.md)。

## 运行简单的自动化（命令行）


以下过程介绍了如何使用 AWS CLI（在 Linux 或 Windows 上）或 AWS Tools for PowerShell 运行简单的自动化。

**运行简单的自动化**

1. 安装并配置 AWS CLI 或 AWS Tools for PowerShell（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

1. 运行以下命令以启动一个简单的自动化。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --parameters runbook parameters
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --parameters runbook parameters
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
     -DocumentName runbook name `
     -Parameter runbook parameters
   ```

------

   以下是使用 `AWS-RestartEC2Instance` 运行手册重新启动指定 EC2 实例的示例。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name "AWS-RestartEC2Instance" \
       --parameters "InstanceId=i-02573cafcfEXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name "AWS-RestartEC2Instance" ^
       --parameters "InstanceId=i-02573cafcfEXAMPLE"
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
     -DocumentName AWS-RestartEC2Instance `
     -Parameter @{"InstanceId"="i-02573cafcfEXAMPLE"}
   ```

------

   系统将返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionId": "4105a4fc-f944-11e6-9d32-0123456789ab"
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionId": "4105a4fc-f944-11e6-9d32-0123456789ab"
   }
   ```

------
#### [ PowerShell ]

   ```
   4105a4fc-f944-11e6-9d32-0123456789ab
   ```

------

1. 运行以下命令以检索自动化的状态。

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-automation-executions \
       --filter "Key=ExecutionId,Values=4105a4fc-f944-11e6-9d32-0123456789ab"
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-automation-executions ^
       --filter "Key=ExecutionId,Values=4105a4fc-f944-11e6-9d32-0123456789ab"
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecutionList | `
     Where {$_.AutomationExecutionId -eq "4105a4fc-f944-11e6-9d32-0123456789ab"}
   ```

------

   系统将返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionMetadataList": [
           {
               "AutomationExecutionStatus": "InProgress",
               "CurrentStepName": "stopInstances",
               "Outputs": {},
               "DocumentName": "AWS-RestartEC2Instance",
               "AutomationExecutionId": "4105a4fc-f944-11e6-9d32-0123456789ab",
               "DocumentVersion": "1",
               "ResolvedTargets": {
                   "ParameterValues": [],
                   "Truncated": false
               },
               "AutomationType": "Local",
               "Mode": "Auto",
               "ExecutionStartTime": 1564600648.159,
               "CurrentAction": "aws:changeInstanceState",
               "ExecutedBy": "arn:aws:sts::123456789012:assumed-role/Administrator/Admin",
               "LogFile": "",
               "Targets": []
           }
       ]
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionMetadataList": [
           {
               "AutomationExecutionStatus": "InProgress",
               "CurrentStepName": "stopInstances",
               "Outputs": {},
               "DocumentName": "AWS-RestartEC2Instance",
               "AutomationExecutionId": "4105a4fc-f944-11e6-9d32-0123456789ab",
               "DocumentVersion": "1",
               "ResolvedTargets": {
                   "ParameterValues": [],
                   "Truncated": false
               },
               "AutomationType": "Local",
               "Mode": "Auto",
               "ExecutionStartTime": 1564600648.159,
               "CurrentAction": "aws:changeInstanceState",
               "ExecutedBy": "arn:aws:sts::123456789012:assumed-role/Administrator/Admin",
               "LogFile": "",
               "Targets": []
           }
       ]
   }
   ```

------
#### [ PowerShell ]

   ```
   AutomationExecutionId       : 4105a4fc-f944-11e6-9d32-0123456789ab
   AutomationExecutionStatus   : InProgress
   AutomationType              : Local
   CurrentAction               : aws:changeInstanceState
   CurrentStepName             : startInstances
   DocumentName                : AWS-RestartEC2Instance
   DocumentVersion             : 1
   ExecutedBy                  : arn:aws:sts::123456789012:assumed-role/Administrator/Admin
   ExecutionEndTime            : 1/1/0001 12:00:00 AM
   ExecutionStartTime          : 7/31/2019 7:17:28 PM
   FailureMessage              : 
   LogFile                     : 
   MaxConcurrency              : 
   MaxErrors                   : 
   Mode                        : Auto
   Outputs                     : {}
   ParentAutomationExecutionId : 
   ResolvedTargets             : Amazon.SimpleSystemsManagement.Model.ResolvedTargets
   Target                      : 
   TargetMaps                  : {}
   TargetParameterName         : 
   Targets                     : {}
   ```

------

# 重新运行自动化执行


您可以重新运行 AWS Systems Manager 自动化执行，使用相同或修改后的参数重复执行任务。重新运行功能使您无需手动重新创建自动化配置即可高效地复制自动化执行，从而减少运营开销和潜在的配置错误。

当您重新运行自动化执行时，Systems Manager 会保留上次执行的原始运行手册参数、Amazon CloudWatch 警报和标签。系统使用新的执行 ID 和更新的时间戳来创建新执行。您可以重新运行任何类型的自动化执行，包括简单执行、速率控制执行、跨账户和跨区域执行以及手动执行。

## 重新运行自动化执行（控制台）


以下过程介绍了如何使用 Systems Manager 控制台重新运行自动化执行。

**从自动化主页重新运行自动化执行**

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

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

1. 在执行列表中，选择要重新运行的执行。

1. 选择**重新运行执行**。

1. 在**执行自动化文档**页面上，查看原始执行中预填充的参数、执行模式和目标配置。

1. （可选）根据重新运行的需要修改任何参数、目标或其他设置。

1. 选择**执行**，使用新的执行 ID 开始重新运行。

**从执行详细信息页面重新运行自动化执行**

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

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

1. 选择您想重新运行的自动化的执行 ID。

1. 在执行详细信息页面上，选择**重新运行执行**。

1. 在**执行自动化文档**页面上，查看原始执行中预填充的参数、执行模式和目标配置。

1. （可选）根据重新运行的需要修改任何参数、目标或其他设置。

1. 选择**执行**，使用新的执行 ID 开始重新运行。

**将自动化执行复制到新执行**

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

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

1. 选择您想复制的自动化的执行 ID。

1. 在执行详细信息页面上，选择**操作**，然后选择**复制到新执行**。

1. 在**执行自动化文档**页面上，查看原始执行中预填充的参数、执行模式和目标配置。

1. （可选）根据新执行的需要修改任何参数、目标或其他设置。

1. 选择**执行**以开始新的执行。

# 运行需要审批的自动化


以下过程介绍了如何使用 AWS Systems Manager 控制台和 AWS Command Line Interface (AWS CLI) 通过简单执行来运行包含审批的自动化。该自动化使用自动化操作 `aws:approve`，这会暂停自动化，直到指定的委托人批准或拒绝该操作。自动化在当前用户的上下文中运行。因此，只要您有权使用运行手册和此运行手册调用的任何操作，就无需配置其他 IAM 权限。如果您在 IAM 中拥有管理员权限，则已有权运行此运行手册。

**开始前的准备工作**  
除了运行手册所需的标准输入外，`aws:approve` 操作还需要以下两个参数：
+ 审批者列表。审批者列表必须以用户名或用户 ARN 的形式包含至少一个审批者。如果提供了多个审批者，还必须在运行手册内指定对应的最少审批数。
+ Amazon Simple Notification Service (Amazon SNS) 主题 ARN Amazon SNS 主题名称必须以 `Automation` 开头。

此过程假设您已经创建了 Amazon SNS 主题，这是提交审批请求所必需的。有关信息，请参阅《Amazon Simple Notification Service 开发人员指南》**中的[创建主题](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html#CreateTopic)。

## 运行包含审批者的自动化（控制台）


**运行包含审批者的自动化**

以下过程介绍了如何使用 Systems Manager 控制台运行包含审批者的自动化。

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

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

1. 在**自动化文档**列表中，请选择运行手册。在**文档类别**窗格中选择一个或多个选项，以便根据 SSM 文档的用途对其进行筛选。要查看您拥有的运行手册，请选择**我拥有的**选项卡。要查看与您的账户共享的运行手册，请选择**与我共享**选项卡。要查看所有运行手册，请选择**所有文档**选项卡。
**注意**  
您可以通过选择运行手册名称来查看有关该手册的信息。

1. 在**文档详细信息**部分中，验证**文档版本**已设置为要运行的版本。系统包括以下版本选项：
   + **运行时的默认版本** – 如果定期更新自动化运行手册并分配新的默认版本，请选择此选项。
   + **运行时的最新版本** – 如果定期更新自动化运行手册并且想要运行最新更新的版本，请选择此选项。
   + **1（默认）** – 选择此选项可执行文档的第一个版本，即默认版本。

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

1. 在**执行自动化文档**页面上，选择**简单执行**。

1. 在**输入参数** 部分，指定所需的输入参数。

   例如，如果选择了 `AWS-StartEC2InstanceWithApproval` 运行手册，则必须为 **InstanceId** 参数指定或选择实例 ID。

1. 在**审批者**部分中，指定自动化操作的审批者的用户名或用户 ARN。

1. 在 **SNSTopicARN** 部分，指定要用于发送审批通知的 SNS 主题 ARN。SNS 主题名称必须以**自动化**开头。

1. 或者，您也可以从 **AutomationAssumeRole** 列表选择一个 IAM 服务角色。如果您将超过 100 个的账户和地区设置为目标，则必须指定 `AWS-SystemsManager-AutomationAdministrationRole`。

1. 选择**执行自动化**。

指定的审批者将收到包含详细信息的 Amazon SNS 通知以批准或拒绝自动化。此审批操作从发布之日起 7 天内有效，此操作可以使用 Systems Manager 控制台或 AWS Command Line Interface (AWS CLI) 发布。

如果选择批准自动化，自动化将继续运行指定的运行手册中包含的步骤。控制台将显示自动化的状态。如果自动化无法运行，请参阅 [Systems Manager 自动化故障排除](automation-troubleshooting.md)。

**批准或拒绝自动化**

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

1. 在导航窗格中，选择**自动化**，然后选择上一过程中运行的自动化。

1. 选择**操作**，然后选择**批准/拒绝**。

1. 选择**批准**或**拒绝**，并选择性地提供注释。

1. 选择**提交**。

## 运行包含审批者的自动化（命令行）


以下过程介绍了如何使用 AWS CLI（在 Linux 或 Windows 上）或 AWS Tools for PowerShell 运行包含审批者的自动化。

**运行包含审批者的自动化**

1. 安装并配置 AWS CLI 或 AWS Tools for PowerShell（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

1. 运行以下命令以运行包含审批者的自动化。将每个*示例资源占位符*替换为您自己的信息。在文档名称部分中，指定包括自动化操作 `aws:approve` 的运行手册。

   对于 `Approvers`，指定该操作的审批者的用户名或用户 ARN。对于 `SNSTopic`，指定用于发送审批通知的 SNS 主题 ARN。Amazon SNS 主题名称必须以 `Automation` 开头。
**注意**  
审批者和 SNS 主题的参数值的具体名称取决于您选择的运行手册中指定的值。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name "AWS-StartEC2InstanceWithApproval" \
       --parameters "InstanceId=i-02573cafcfEXAMPLE,Approvers=arn:aws:iam::123456789012:role/Administrator,SNSTopicArn=arn:aws:sns:region:123456789012:AutomationApproval"
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name "AWS-StartEC2InstanceWithApproval" ^
       --parameters "InstanceId=i-02573cafcfEXAMPLE,Approvers=arn:aws:iam::123456789012:role/Administrator,SNSTopicArn=arn:aws:sns:region:123456789012:AutomationApproval"
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
       -DocumentName AWS-StartEC2InstanceWithApproval `
       -Parameters @{
           "InstanceId"="i-02573cafcfEXAMPLE"
           "Approvers"="arn:aws:iam::123456789012:role/Administrator"
           "SNSTopicArn"="arn:aws:sns:region:123456789012:AutomationApproval"
       }
   ```

------

   系统将返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionId": "df325c6d-b1b1-4aa0-8003-6cb7338213c6"
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionId": "df325c6d-b1b1-4aa0-8003-6cb7338213c6"
   }
   ```

------
#### [ PowerShell ]

   ```
   df325c6d-b1b1-4aa0-8003-6cb7338213c6
   ```

------

**批准自动化**
+ 运行以下命令来批准自动化。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ Linux & macOS ]

  ```
  aws ssm send-automation-signal \
      --automation-execution-id "df325c6d-b1b1-4aa0-8003-6cb7338213c6" \
      --signal-type "Approve" \
      --payload "Comment=your comments"
  ```

------
#### [ Windows ]

  ```
  aws ssm send-automation-signal ^
      --automation-execution-id "df325c6d-b1b1-4aa0-8003-6cb7338213c6" ^
      --signal-type "Approve" ^
      --payload "Comment=your comments"
  ```

------
#### [ PowerShell ]

  ```
  Send-SSMAutomationSignal `
      -AutomationExecutionId df325c6d-b1b1-4aa0-8003-6cb7338213c6 `
      -SignalType Approve `
      -Payload @{"Comment"="your comments"}
  ```

------

  如果此命令成功，则无任何输出。

**拒绝自动化**
+ 运行以下命令来拒绝自动化。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ Linux & macOS ]

  ```
  aws ssm send-automation-signal \
      --automation-execution-id "df325c6d-b1b1-4aa0-8003-6cb7338213c6" \
      --signal-type "Deny" \
      --payload "Comment=your comments"
  ```

------
#### [ Windows ]

  ```
  aws ssm send-automation-signal ^
      --automation-execution-id "df325c6d-b1b1-4aa0-8003-6cb7338213c6" ^
      --signal-type "Deny" ^
      --payload "Comment=your comments"
  ```

------
#### [ PowerShell ]

  ```
  Send-SSMAutomationSignal `
      -AutomationExecutionId df325c6d-b1b1-4aa0-8003-6cb7338213c6 `
      -SignalType Deny `
      -Payload @{"Comment"="your comments"}
  ```

------

  如果此命令成功，则无任何输出。

# 大规模运行自动化操作


借助 AWS Systems Manager Automation，您可以使用*目标*在 AWS 资源的实例集上运行自动化。此外，您还可以通过指定并发值和错误阈值来控制自动化在整个队列上的部署。并发和错误阈值功能统称为*速率控制*。并发值决定允许同时运行自动化的资源数量。Automation 还提供了一种可以选择加入的自适应并发模式。自适应并发会自动将自动化配额从 100 个同时运行的自动化配额扩展到 500 个。错误阈值决定在 Systems Manager 停止将自动化发送到其他资源之前允许自动化执行失败的次数。

有关并发性和错误阈值的更多信息，请参阅 [大规模控制自动化](running-automations-scale-controls.md)。有关目标的更多信息，请参阅 [映射自动化目标](running-automations-map-targets.md)。

以下程序介绍了如何开启自适应并发性，以及如何使用 Systems Manager 控制台和 AWS Command Line Interface (AWS CLI) 运行具有目标和速率控制的自动化。

## 运行具有目标和速率控制自动化（控制台）


以下过程介绍了如何使用 Systems Manager 控制台运行具有目标和速率控制的自动化。

**运行具有目标和速率控制的自动化**

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

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

1. 在**自动化文档**列表中，请选择运行手册。在**文档类别**窗格中选择一个或多个选项，以便根据 SSM 文档的用途对其进行筛选。要查看您拥有的运行手册，请选择**我拥有的**选项卡。要查看与您的账户共享的运行手册，请选择**与我共享**选项卡。要查看所有运行手册，请选择**所有文档**选项卡。
**注意**  
您可以通过选择运行手册名称来查看有关该手册的信息。

1. 在**文档详细信息**部分中，验证**文档版本**已设置为要运行的版本。系统包括以下版本选项：
   + **运行时的默认版本** – 如果定期更新自动化运行手册并分配新的默认版本，请选择此选项。
   + **运行时的最新版本** – 如果定期更新自动化运行手册并且想要运行最新更新的版本，请选择此选项。
   + **1（默认）** – 选择此选项可执行文档的第一个版本，即默认版本。

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

1. 在**执行模式**部分中，选择**速率控制**。如果要使用目标和速率控制，则必须使用此模式或**多账户和多区域**。

1. 在**目标**部分中，选择希望如何设置要在其中运行自动化的 AWS 资源。这些选项是必需的。

   1. 使用**参数**列表选择一个参数。**参数**列表中的项目由此过程开始时选择的自动化运行手册中的参数确定。通过选择参数，可以定义在其上运行自动化工作流的资源类型。

   1. 使用**目标**列表选择设置目标资源的方式。

      1. 如果选择使用参数值将资源设置为目标，请输入您在**输入参数**部分为参数选择的参数值。

      1. 如果选择使用 AWS Resource Groups 将资源设置为目标，请从**资源组**列表中选择组的名称。

      1. 如果选择使用标签将资源设置为目标，请在提供的字段中输入标签键和（可选）标签值。选择**添加**。

      1. 如果要在当前 AWS 账户 和 AWS 区域 中的所有实例上运行自动化运行手册，则选择**所有实例**。

1. 在**输入参数** 部分中，指定所需的输入。或者，您也可以从 **AutomationAssumeRole** 列表中选择一个 IAM 服务角色。
**注意**  
您可能不需要选择**输入参数**部分中的某些选项。原因是您使用标签或资源组将多个资源设置为目标。例如，如果选择了 `AWS-RestartEC2Instance` 运行手册，则无需在**输入参数** 部分中指定或选择实例 ID。自动化执行过程使用您指定的标签资源组查找要重新启动的实例。

1. 使用**速率控制**部分中的选项限制可在每个账户-区域对中运行自动化的 AWS 资源的数量。

   在**并发**部分中，选择一个选项：
   + 选择**目标**，以输入可同时运行自动化工作流目标的绝对数量。
   + 选择**百分比**，以输入可同时运行自动化工作流的目标集的百分比。

1. 在**错误阈值**部分中，选择一个选项：
   + 选择**错误**，以输入自动化停止将工作流程发送到其他资源之前允许的错误的绝对数量。
   + 选择**百分比**，以输入自动化停止将工作流程发送到其他资源之前允许的错误的百分比。

1. （可选）选择一个 CloudWatch 警报以应用于您的自动化进行监控。要将 CloudWatch 警报附加到自动化，启动自动化的 IAM 主体必须具有 `iam:createServiceLinkedRole` 操作的权限。有关 CloudWatch 警报的更多信息，请参阅[使用 Amazon CloudWatch 警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)。请注意，如果您的警报激活，自动化将停止。如果使用 AWS CloudTrail，您将在跟踪中看到 API 调用。

1. 选择**执行**。

要查看由速率控制自动化启动的自动化程序，请在导航窗格中，选择自动化，然后选择**显示子自动化程序**。

自动化执行完成后，您可以使用相同或修改后的参数重新运行该执行。有关更多信息，请参阅 [重新运行自动化执行](automation-rerun-executions.md)。

## 运行具有目标和速率控制的自动化（命令行）


以下过程介绍了如何使用 AWS CLI（在 Linux 或 Windows 上）或 AWS Tools for PowerShell 运行具有目标和速率控制的自动化。

**运行具有目标和速率控制的自动化**

1. 安装并配置 AWS CLI 或 AWS Tools for PowerShell（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

1. 运行以下命令以查看文档列表。

------
#### [ Linux & macOS ]

   ```
   aws ssm list-documents
   ```

------
#### [ Windows ]

   ```
   aws ssm list-documents
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentList
   ```

------

   记下要使用的运行手册的名称。

1. 运行以下命令以查看有关运行手册的详细信息。用您想要查看其详细信息的运行手册的名称替换 *runbook name*。同时，记下要用于 `--target-parameter-name` 选项的参数名称（例如 `InstanceId`）。此参数确定在其上运行自动化的资源的类型。

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-document \
       --name runbook name
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-document ^
       --name runbook name
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentDescription `
       -Name runbook name
   ```

------

1. 创建一个要运行的使用目标和速率控制选项的命令。将每个*示例资源占位符*替换为您自己的信息。

   *使用标签设置目标*

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --targets Key=tag:key name,Values=value \
       --target-parameter-name parameter name \
       --parameters "input parameter name=input parameter value,input parameter 2 name=input parameter 2 value" \
       --max-concurrency 10 \
       --max-errors 25%
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --targets Key=tag:key name,Values=value ^
       --target-parameter-name parameter name ^
       --parameters "input parameter name=input parameter value,input parameter 2 name=input parameter 2 value" ^
       --max-concurrency 10 ^
       --max-errors 25%
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "tag:key name"
   $Targets.Values = "value"
   
   Start-SSMAutomationExecution `
       DocumentName "runbook name" `
       -Targets $Targets `
       -TargetParameterName "parameter name" `
       -Parameter @{"input parameter name"="input parameter value";"input parameter 2 name"="input parameter 2 value"} `
       -MaxConcurrency "10" `
       -MaxError "25%"
   ```

------

   *使用参数值设置目标*

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --targets Key=ParameterValues,Values=value,value 2,value 3 \
       --target-parameter-name parameter name \
       --parameters "input parameter name=input parameter value" \
       --max-concurrency 10 \
       --max-errors 25%
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --targets Key=ParameterValues,Values=value,value 2,value 3 ^
       --target-parameter-name parameter name ^
       --parameters "input parameter name=input parameter value" ^
       --max-concurrency 10 ^
       --max-errors 25%
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ParameterValues"
   $Targets.Values = "value","value 2","value 3"
   
   Start-SSMAutomationExecution `
       -DocumentName "runbook name" `
       -Targets $Targets `
       -TargetParameterName "parameter name" `
       -Parameter @{"input parameter name"="input parameter value"} `
       -MaxConcurrency "10" `
       -MaxError "25%"
   ```

------

   *使用 AWS Resource Groups 设置目标*

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --targets Key=ResourceGroup,Values=Resource group nname \
       --target-parameter-name parameter name \
       --parameters "input parameter name=input parameter value" \
       --max-concurrency 10 \
       --max-errors 25%
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --targets Key=ResourceGroup,Values=Resource group name ^
       --target-parameter-name parameter name ^
       --parameters "input parameter name=input parameter value" ^
       --max-concurrency 10 ^
       --max-errors 25%
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ResourceGroup"
   $Targets.Values = "Resource group name"
   
   Start-SSMAutomationExecution `
       -DocumentName "runbook name" `
       -Targets $Targets `
       -TargetParameterName "parameter name" `
       -Parameter @{"input parameter name"="input parameter value"} `
       -MaxConcurrency "10" `
       -MaxError "25%"
   ```

------

   *将当前 AWS 账户 和 AWS 区域 中的所有 Amazon EC2 实例设置为目标*

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --targets "Key=AWS::EC2::Instance,Values=*"  \
       --target-parameter-name instanceId \
       --parameters "input parameter name=input parameter value" \
       --max-concurrency 10 \
       --max-errors 25%
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --targets Key=AWS::EC2::Instance,Values=* ^
       --target-parameter-name instanceId ^
       --parameters "input parameter name=input parameter value" ^
       --max-concurrency 10 ^
       --max-errors 25%
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "AWS::EC2::Instance"
   $Targets.Values = "*"
   
   Start-SSMAutomationExecution `
       -DocumentName "runbook name" `
       -Targets $Targets `
       -TargetParameterName "instanceId" `
       -Parameter @{"input parameter name"="input parameter value"} `
       -MaxConcurrency "10" `
       -MaxError "25%"
   ```

------

   该命令将会返回执行 ID。请将该 ID 复制到剪贴板。您可以使用此 ID 查看自动化的状态。

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionId": "a4a3c0e9-7efd-462a-8594-01234EXAMPLE"
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionId": "a4a3c0e9-7efd-462a-8594-01234EXAMPLE"
   }
   ```

------
#### [ PowerShell ]

   ```
   a4a3c0e9-7efd-462a-8594-01234EXAMPLE
   ```

------

1. 运行以下命令以查看自动化。将每个 *automation execution ID* 替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-automation-executions \
       --filter Key=ExecutionId,Values=automation execution ID
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-automation-executions ^
       --filter Key=ExecutionId,Values=automation execution ID
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecutionList | `
       Where {$_.AutomationExecutionId -eq "automation execution ID"}
   ```

------

1. 运行以下命令以查看有关自动化进展的详细信息。将每个 *automation execution ID* 替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm get-automation-execution \
       --automation-execution-id automation execution ID
   ```

------
#### [ Windows ]

   ```
   aws ssm get-automation-execution ^
       --automation-execution-id automation execution ID
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecution `
       -AutomationExecutionId automation execution ID
   ```

------

   系统将返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecution": {
           "StepExecutionsTruncated": false,
           "AutomationExecutionStatus": "Success",
           "MaxConcurrency": "1",
           "Parameters": {},
           "MaxErrors": "1",
           "Outputs": {},
           "DocumentName": "AWS-StopEC2Instance",
           "AutomationExecutionId": "a4a3c0e9-7efd-462a-8594-01234EXAMPLE",
           "ResolvedTargets": {
               "ParameterValues": [
                   "i-02573cafcfEXAMPLE"
               ],
               "Truncated": false
           },
           "ExecutionEndTime": 1564681619.915,
           "Targets": [
               {
                   "Values": [
                       "DEV"
                   ],
                   "Key": "tag:ENV"
               }
           ],
           "DocumentVersion": "1",
           "ExecutionStartTime": 1564681576.09,
           "ExecutedBy": "arn:aws:sts::123456789012:assumed-role/Administrator/Admin",
           "StepExecutions": [
               {
                   "Inputs": {
                       "InstanceId": "i-02573cafcfEXAMPLE"
                   },
                   "Outputs": {},
                   "StepName": "i-02573cafcfEXAMPLE",
                   "ExecutionEndTime": 1564681619.093,
                   "StepExecutionId": "86c7b811-3896-4b78-b897-01234EXAMPLE",
                   "ExecutionStartTime": 1564681576.836,
                   "Action": "aws:executeAutomation",
                   "StepStatus": "Success"
               }
           ],
           "TargetParameterName": "InstanceId",
           "Mode": "Auto"
       }
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecution": {
           "StepExecutionsTruncated": false,
           "AutomationExecutionStatus": "Success",
           "MaxConcurrency": "1",
           "Parameters": {},
           "MaxErrors": "1",
           "Outputs": {},
           "DocumentName": "AWS-StopEC2Instance",
           "AutomationExecutionId": "a4a3c0e9-7efd-462a-8594-01234EXAMPLE",
           "ResolvedTargets": {
               "ParameterValues": [
                   "i-02573cafcfEXAMPLE"
               ],
               "Truncated": false
           },
           "ExecutionEndTime": 1564681619.915,
           "Targets": [
               {
                   "Values": [
                       "DEV"
                   ],
                   "Key": "tag:ENV"
               }
           ],
           "DocumentVersion": "1",
           "ExecutionStartTime": 1564681576.09,
           "ExecutedBy": "arn:aws:sts::123456789012:assumed-role/Administrator/Admin",
           "StepExecutions": [
               {
                   "Inputs": {
                       "InstanceId": "i-02573cafcfEXAMPLE"
                   },
                   "Outputs": {},
                   "StepName": "i-02573cafcfEXAMPLE",
                   "ExecutionEndTime": 1564681619.093,
                   "StepExecutionId": "86c7b811-3896-4b78-b897-01234EXAMPLE",
                   "ExecutionStartTime": 1564681576.836,
                   "Action": "aws:executeAutomation",
                   "StepStatus": "Success"
               }
           ],
           "TargetParameterName": "InstanceId",
           "Mode": "Auto"
       }
   }
   ```

------
#### [ PowerShell ]

   ```
   AutomationExecutionId       : a4a3c0e9-7efd-462a-8594-01234EXAMPLE
   AutomationExecutionStatus   : Success
   CurrentAction               : 
   CurrentStepName             : 
   DocumentName                : AWS-StopEC2Instance
   DocumentVersion             : 1
   ExecutedBy                  : arn:aws:sts::123456789012:assumed-role/Administrator/Admin
   ExecutionEndTime            : 8/1/2019 5:46:59 PM
   ExecutionStartTime          : 8/1/2019 5:46:16 PM
   FailureMessage              : 
   MaxConcurrency              : 1
   MaxErrors                   : 1
   Mode                        : Auto
   Outputs                     : {}
   Parameters                  : {}
   ParentAutomationExecutionId : 
   ProgressCounters            : 
   ResolvedTargets             : Amazon.SimpleSystemsManagement.Model.ResolvedTargets
   StepExecutions              : {i-02573cafcfEXAMPLE}
   StepExecutionsTruncated     : False
   Target                      : 
   TargetLocations             : {}
   TargetMaps                  : {}
   TargetParameterName         : InstanceId
   Targets                     : {tag:Name}
   ```

------
**注意**  
您也可以在控制台中监控自动化的状态。在**自动化执行**列表中，请选择您刚才运行的自动化，然后选择**执行步骤**选项卡。该选项卡显示自动化操作的状态。

# 映射自动化目标


通过 `Targets` 参数，可以快速定义自动化的目标资源。例如，如果需要运行一个重新启动托管实例的自动化，不必在控制台中手动选择数十个实例 ID 或在命令中键入它们，您可以通过使用 `Targets` 参数指定 Amazon Elastic Compute Cloud (Amazon EC2) 标签将实例设为目标。

运行使用目标的自动化时，AWS Systems Manager 会为每个目标创建一个子自动化。例如，如果您通过指定标签将 Amazon Elastic Block Store (Amazon EBS) 卷指定为目标，并且这些标签解析为 100 个 Amazon EBS 卷，则 Systems Manager 创建 100 个子自动化。当所有子自动化都到达最终状态时，父自动化完成。

**注意**  
在运行时指定的任何 `input parameters`（在控制台的**输入参数**部分或在命令行中使用 `parameters` 选项）都由所有子自动化自动处理。

您可以使用标签、Resource Groups 和参数值为自动化设置目标资源。此外，您还可以使用 `TargetMaps` 选项在命令行或文件中将多个参数值设为目标。下一节更详细地介绍每个设置目标选项。

## 设置目标标签


您可以指定单个标签作为自动化目标。多个 AWS 资源支持标签，包括 Amazon Elastic Compute Cloud (Amazon EC2) 和 Amazon Relational Database Service (Amazon RDS) 实例、Amazon Elastic Block Store (Amazon EBS) 卷和快照、Resource Groups 以及 Amazon Simple Storage Service (Amazon S3) 存储桶（仅举几例）。您可以通过设置目标标签在 AWS 资源上快速运行自动化。标签是一种键值对，例如 Operating\$1System:Linux 或 Department:Finance。如果为资源指定一个特定名称，则还可以使用“Name”作为键，将资源名称用作值。

在将标签指定为自动化目标时，还可以指定目标参数。目标参数使用 `TargetParameterName` 选项。通过选择目标参数，可以定义在其上运行自动化的资源的类型。使用标签指定的目标参数必须是运行手册中定义的有效参数。例如，如果要使用标签将数十个 EC2 实例设为目标，请选择 `InstanceId` 目标参数。通过选择此参数，可以将*实例* 定义为自动化的资源类型。在创建自定义运行手册时，您必须将**目标类型**指定为 `/AWS::EC2::Instance`，以确保仅使用实例。否则，所有具有相同标签的资源都将被设置为目标。使用标签定位实例时，可能会包括已终止的实例。

下面的屏幕截图使用 `AWS-DetachEBSVolume` 运行手册。逻辑目标参数为 `VolumeId`。

![\[使用标签作为 Systems Manager Automation 的目标\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/automation-rate-control-tags-1-new.png)


`AWS-DetachEBSVolume` 运行手册还包含一个名为**目标类型**的特殊属性，设置为 `/AWS::EC2::Volume`。这意味着，如果标签键对 `Finance:TestEnv` 返回不同类型的资源（例如，EC2 实例、Amazon EBS 卷、Amazon EBS 快照），则仅使用 Amazon EBS 卷。

**重要**  
目标参数名称区分大小写。如果使用 AWS Command Line Interface (AWS CLI) 或 AWS Tools for Windows PowerShell 运行自动化，则必须完全按照运行手册中的定义输入目标参数名称。否则，系统将返回 `InvalidAutomationExecutionParametersException` 错误。您可以使用 [DescribeDocument](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribeDocument.html) API 操作来查看有关特定运行手册中可用目标参数的信息。下面是一个示例 AWS CLI 命令，其中提供有关 `AWS-DeleteSnapshot` 文档的信息。  

```
aws ssm describe-document \
    --name AWS-DeleteSnapshot
```

下面是一些使用标签设置资源目标的示例 AWS CLI 命令。

**示例 1：使用键值对将标签指定为目标以重启 Amazon EC2 实例**

此示例重新启动带有键为 *Department*、值为 *HumanResources* 的标签的所有 Amazon EC2 实例。目标参数使用运行手册中的 *InstanceId* 参数。该示例使用了一个附加参数，通过使用自动化服务角色（也称为*担任角色*）来运行自动化。

```
aws ssm start-automation-execution \
    --document-name AWS-RestartEC2Instance \
    --targets Key=tag:Department,Values=HumanResources \
    --target-parameter-name InstanceId \
    --parameters "AutomationAssumeRole=arn:aws:iam::111122223333:role/AutomationServiceRole"
```

**示例 2：使用键值对将标签指定为目标以删除 Amazon EBS 快照**

下面的示例使用 `AWS-DeleteSnapshot` 运行手册删除键为 *Name*、值为 *January2018Backups* 的所有快照。目标参数使用 *VolumeId* 参数。

```
aws ssm start-automation-execution \
    --document-name AWS-DeleteSnapshot \
    --targets Key=tag:Name,Values=January2018Backups \
    --target-parameter-name VolumeId
```

## 设置目标 AWS Resource Groups


您可以指定单个 AWS 资源组作为自动化目标。Systems Manager 为目标资源组中的每个对象创建一个子自动化。

例如，假设您的一个 Resource Groups 名为 PatchedAMIs。此资源组包括一个列表，其中有 25 个定期进行修补的 Windows Amazon Machine Images (AMIs)。如果您运行使用 `AWS-CreateManagedWindowsInstance` 运行手册并以此资源组为目标的自动化，则 Systems Manager 会为 25 个 AMIs 中的每一个创建一个子自动化。也就是说，通过将 PatchedAMIs 资源组设置为目标，自动化会从修补的 AMIs 列表中创建 25 个实例。当所有子自动化都完成处理或到达最终状态时，父自动化完成。

下面的 AWS CLI 命令适用于此 PatchAMIs 资源组示例。该命令中，`--target-parameter-name` 选项采用 *AmiId* 参数。该命令不包含定义从每个 AMI 创建的实例类型的附加参数。`AWS-CreateManagedWindowsInstance` 运行手册默认为 t2.medium 实例类型，因此该命令将创建 25 个适用于 Windows Server 的 t2.medium Amazon EC2 实例。

```
aws ssm start-automation-execution \
    --document-name AWS-CreateManagedWindowsInstance \
    --targets Key=ResourceGroup,Values=PatchedAMIs  \
    --target-parameter-name AmiId
```

下面的控制台示例使用名为 t2-micro-instances 的资源组。

![\[将具有 Systems Manager 自动化功能的 AWS 资源组设为目标\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/automation-rate-control-resource-groups-new.png)


## 设置目标参数值


您也可以将参数值设置为目标：输入 `ParameterValues` 作为键，然后输入要在其上运行自动化的特定资源值。如果指定多个值，Systems Manager 将在指定的每个值上运行子自动化。

例如，假设运行手册包含 **InstanceID** 参数。如果在运行此自动化时将 **InstanceID** 参数值设置为目标，则 Systems Manager 会为指定的每个实例 ID 值运行一个子自动化。当自动化完成每个指定实例的运行或执行失败时，父自动化完成。您最多可以将 50 个参数值设置为目标。

以下示例使用 `AWS-CreateImage` 运行手册。指定的目标参数名称为 *InstanceId*。键使用 *ParameterValues*。值为两个 Amazon EC2 实例 ID。此命令为每个实例创建一个自动化，这将从每个实例生成一个 AMI。

```
aws ssm start-automation-execution 
    --document-name AWS-CreateImage \
    --target-parameter-name InstanceId \
    --targets Key=ParameterValues,Values=i-02573cafcfEXAMPLE,i-0471e04240EXAMPLE
```

**注意**  
`AutomationAssumeRole` 不是有效的参数。运行以参数值为目标的自动化时，不要选择此项。

### 设置目标参数值映射


`TargetMaps` 选项扩展了您设置 `ParameterValues` 目标的能力。您可以在命令行中使用 `TargetMaps` 输入一个参数值数组。在命令行中，最多可以指定 50 个参数值。如果要运行指定 50 个以上参数值的命令，请在 JSON 文件中输入这些值。然后，可以在命令行中调用该文件。

**注意**  
控制台中不支持 `TargetMaps` 选项。

在命令中使用 `TargetMaps` 选项以下面的格式指定多个参数值。将每个*示例资源占位符*替换为您自己的信息。

```
aws ssm start-automation-execution \
    --document-name runbook name \
    --target-maps “parameter=value, parameter 2=value, parameter 3=value”  “parameter 4=value, parameter 5=value, parameter 6=value”
```

如果要为 `TargetMaps` 选项输入 50 个以上的参数值，请使用以下 JSON 格式在文件中指定这些值。在提供多个参数值时，使用 JSON 文件还有助于提高可读性。

```
[

    {“parameter”: "value", “parameter 2”: "value", “parameter 3”: "value"},

    {“parameter 4”: "value", “parameter 5”: "value", "parameter 6": "value"}

]
```

使用 .json 文件扩展名保存该文件。可以使用下面的命令调用此文件。将每个*示例资源占位符*替换为您自己的信息。

```
aws ssm start-automation-execution \
    --document-name runbook name \
    –-parameters input parameters \
    --target-maps path to file/file name.json
```

您还可以从 Amazon Simple Storage Service (Amazon S3) 存储桶下载此文件，前提是您有权从存储桶读取数据。使用下面的命令格式。将每个*示例资源占位符*替换为您自己的信息。

```
aws ssm start-automation-execution \
    --document-name runbook name \
    --target-maps http://amzn-s3-demo-bucket.s3.amazonaws.com/file_name.json
```

下面是一个帮助您了解 `TargetMaps` 选项的示例方案。在此方案中，用户想要从不同的 AMIs 创建不同类型的 Amazon EC2 实例。为了执行此任务，用户创建一个名为 AMI\$1Testing 的运行手册。此运行手册定义两个输入参数：`instanceType` 和 `imageId`。

```
{
  "description": "AMI Testing",
  "schemaVersion": "0.3",
  "assumeRole": "{{assumeRole}}",
  "parameters": {
    "assumeRole": {
      "type": "String",
      "description": "Role under which to run the automation",
      "default": ""
    },
    "instanceType": {
      "type": "String",
      "description": "Type of EC2 Instance to launch for this test"
    },
    "imageId": {
      "type": "String",
      "description": "Source AMI id from which to run instance"
    }
  },
  "mainSteps": [
    {
      "name": "runInstances",
      "action": "aws:runInstances",
      "maxAttempts": 1,
      "onFailure": "Abort",
      "inputs": {
        "ImageId": "{{imageId}}",
        "InstanceType": "{{instanceType}}",
        "MinInstanceCount": 1,
        "MaxInstanceCount": 1
      }
    }
  ],
  "outputs": [
    "runInstances.InstanceIds"
  ]
}
```

然后，用户在名为 `AMI_instance_types.json` 的文件中指定以下目标参数值。

```
[
  {
    "instanceType" : ["t2.micro"],     
    "imageId" : ["ami-b70554c8"]     
  },
  {
    "instanceType" : ["t2.small"],     
    "imageId" : ["ami-b70554c8"]     
  },
  {
    "instanceType" : ["t2.medium"],     
    "imageId" : ["ami-cfe4b2b0"]     
  },
  {
    "instanceType" : ["t2.medium"],     
    "imageId" : ["ami-cfe4b2b0"]     
  },
  {
    "instanceType" : ["t2.medium"],     
    "imageId" : ["ami-cfe4b2b0"]     
  }
]
```

用户可以通过运行以下命令来运行此自动化并创建在 `AMI_instance_types.json` 中定义的五个 EC2 实例：

```
aws ssm start-automation-execution \
    --document-name AMI_Testing \
    --target-parameter-name imageId \
    --target-maps file:///home/TestUser/workspace/runinstances/AMI_instance_types.json
```

## 将所有 Amazon EC2 实例设置为目标


您可以通过选择**目标**列表中的**所有实例**，在当前 AWS 账户 和 AWS 区域 中的所有 Amazon EC2 实例上运行自动化。例如，如果要重新启动 AWS 账户 和当前 AWS 区域 的所有 Amazon EC2 实例，您可以选择 `AWS-RestartEC2Instance` 运行手册，然后选择**目标**列表中的**所有实例**。

![\[将运行手册的所有 Amazon EC2 实例设置为目标\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/automation-rate-control-target-all-instances.png)


在您选择**所有实例**后，Systems Manager 将填充带有星号 (\$1) 的**实例**字段，并使字段不可更改（该字段呈灰色）。Systems Manager 还会使 **InstanceId** 字段中的**输入参数**字段不可更改。如果您选择将所有实例设置为目标，则使这些字段不可更改是预期行为。

# 大规模控制自动化


您可以通过指定并发值和错误阈值来控制自动化在 AWS 资源队列上的部署。并发和错误阈值统称为*速率控制*。

**并发**  
通过并发，您可以指定允许同时运行自动化的资源数量。并发有助于在处理自动化时限制对资源的影响或停机时间。您可以指定绝对数量的资源（如 20），也可以指定目标集百分比（如 10%）。

队列系统将自动化传输到单个资源，等到初始调用完成之后，再将自动化发送到其他两个资源。系统以指数增长方式将自动化发送到更多资源，直到达到并发值。

**错误阈值**  
通过错误阈值，您可以指定在 AWS Systems Manager 停止将自动化发送到其他资源之前允许自动化失败的次数。您可以指定绝对数量的错误（如 10），也可以指定目标集百分比（如 10%）。

例如，如果指定错误的绝对数为 3，则系统将在收到第四个错误时停止发送自动化。如果指定 0，则系统会在返回第一个错误结果后停止向其他资源发送自动化。

例如，如果向 50 个实例发送自动化并将错误阈值设置为 10%，则系统会在收到第五个错误时停止向其他实例发送命令。当达到错误阈值时，允许完成已经运行自动化的调用，但是其中一些自动化也可能失败。如果需要确保错误数不超过为错误阈值指定的数量，请将**并发**值设置为 1，以便一次只处理一个自动化。

# 在多个 AWS 区域 和账户中运行自动化


您可以在中央账户的多个 AWS 区域 区域和 AWS 账户 账户或 AWS Organizations 组织部门 (OU) 中运行 AWS Systems Manager 自动化。Automation 是 AWS Systems Manager 中的一项工具。在多个区域和账户或 OU 中运行自动化可减少管理 AWS 资源所需的时间，同时提高计算环境的安全性。

例如，您可以使用自动化运行手册执行以下操作：
+ 集中实施补丁和安全更新。
+ 修复 VPC 配置或 Amazon S3 桶策略的合规性偏差。
+ 大规模管理资源，例如 Amazon Elastic Compute Cloud (Amazon EC2) EC2 实例。

下图显示了一个用户在中央账户的多个区域和账户中运行 `AWS-RestartEC2Instances` 运行手册的示例。自动化在目标区域和账户中使用指定的标签以查找实例。

![\[显示 Systems Manager 自动化在多个区域和多个账户中运行的示意图。\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/automation-multi-region-and-multi-account.png)


**为自动化选择中央账户**  
如果要在 OU 中运行自动化，中央账户必须具有列出 OU 中所有账户的权限。这只能通过委派管理员账户或组织的管理账户实现。我们建议您遵循 AWS Organizations 最佳实践并使用委派管理员账户。有关 AWS Organizations 最佳实践的更多信息，请参阅 *AWS Organizations 用户指南*中的[管理账户的最佳实践](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_best-practices_mgmt-acct.html)。要为 Systems Manager 创建委派管理员账户，可以将 `register-delegated-administrator` 命令与 AWS CLI 一起使用，如以下示例所示。

```
aws organizations register-delegated-administrator \
    --account-id delegated admin account ID \
    --service-principal ssm.amazonaws.com
```

如果您想跨多个不受 AWS Organizations 托管的账户运行自动化，我们建议您创建一个专用账户用于自动化管理。从专用账户运行所有跨账户自动化可简化 IAM 权限管理、故障排除工作，并在操作和管理之间建立分离层。如果您使用 AWS Organizations，但只希望针对个人账户而不是 OU，也建议使用此方法。

**自动化的工作原理**  
跨多个区域和账户或 OU 运行自动化的工作方式如下：

1. 登录要配置为 Automation 中央账户的账户。

1. 使用本主题中的 [设置进行多区域和多账户自动化的管理账户权限](#setup-management-account-iam-roles) 过程创建以下 IAM 角色：
   + `AWS-SystemsManager-AutomationAdministrationRole` - 此角色为用户提供在多个账户和 OU 中运行自动化的权限。
   + `AWS-SystemsManager-AutomationExecutionRole` - 此角色为用户提供在目标账户中运行自动化的权限。

1. 选择要运行自动化的运行手册、区域、账户或 OU。
**注意**  
确保目标 OU 包含所需的账户。如果选择自定义运行手册，则必须与所有目标账户共享运行手册。有关共享运行手册的信息，请参阅 [共享 SSM 文档](documents-ssm-sharing.md)。有关使用共享运行手册的信息，请参阅 [使用共享 SSM 文档](documents-ssm-sharing.md#using-shared-documents)。

1. 运行自动化。

1. 通过 AWS Systems Manager 控制台或 AWS CLI 使用 [GetAutomationExecution](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_GetAutomationExecution.html)、[DescribeAutomationStepExecutions](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribeAutomationStepExecutions.html) 和 [DescribeAutomationExecutions](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_DescribeAutomationExecutions.html) API 操作监控自动化进度。您的主账户中自动化步骤的输出将是子自动化的 `AutomationExecutionId`。要查看在目标账户中创建的子自动化的输出，请确保在您的请求中指定相应的账户、区域和 `AutomationExecutionId`。

## 设置进行多区域和多账户自动化的管理账户权限


按照以下过程操作，使用 AWS CloudFormation 创建进行 Systems Manager 自动化多区域和多账户自动化所需的 IAM 角色。此过程介绍如何创建 `AWS-SystemsManager-AutomationAdministrationRole` 角色。您只需要在自动化中央账户中创建此角色。此过程还介绍了如何创建 `AWS-SystemsManager-AutomationExecutionRole` 角色。您必须在要设置为多区域和多账户自动化运行目标的*每一个*账户中创建该角色。我们建议使用 CloudFormation StackSets 您想要设置为多区域和多账户自动化运行目标的账户创建 `AWS-SystemsManager-AutomationExecutionRole` 角色。

**使用 CloudFormation 创建进行多区域和多账户自动化所需的 IAM 管理角色**

1. 下载并解压缩 [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationAdministrationRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationAdministrationRole.zip)。

   –或者–

   如果您的账户由 AWS Organizations [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationAdministrationRole (org).zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationAdministrationRole (org).zip) 管理。

   这些文件分别包含 `AWS-SystemsManager-AutomationAdministrationRole.yaml` 和 `AWS-SystemsManager-AutomationAdministrationRole (org).yaml` CloudFormation 模板文件。

1. 通过以下网址打开 CloudFormation 控制台：[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 选择**创建堆栈**。

1. 在 **Specify template**（指定模板）部分中，选择 **Upload a template**（上传模板）。

1. 选择**选择文件**，然后根据您在步骤 1 中所做的选择选择 `AWS-SystemsManager-AutomationAdministrationRole.yaml` 或 `AWS-SystemsManager-AutomationAdministrationRole (org).yaml` CloudFormation 模板文件。

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

1. 在**指定堆栈详细信息**页面的**堆栈名称**字段中，输入名称。

1. 选择 **Next（下一步）**。

1. 在 **Configure stack options**（配置堆栈选项）页面上，为要使用的所有选项输入值。选择 **Next（下一步）**。

1. 在**审核**页面上，向下滚动并选择**我确认 CloudFormation 可能使用自定义名称创建了 IAM 资源**选项。

1. 选择**创建堆栈**。

大约三分钟左右，CloudFormation 会显示 **CREATE\$1IN\$1PROGRESS** 状态。状态变为 **CREATE\$1COMPLETE**。

在要设置为多区域和多账户自动化运行目标的*每一个*账户中，您必须重复以下过程。

**使用 CloudFormation 创建进行多区域和多账户自动化所需的 IAM 自动化角色**

1. 下载 [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationExecutionRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationExecutionRole.zip)。

   - 或

   如果您的账户由 AWS Organizations [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationExecutionRole (org).zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWS-SystemsManager-AutomationExecutionRole (org).zip) 管理。

   这些文件分别包含 `AWS-SystemsManager-AutomationExecutionRole.yaml` 和 `AWS-SystemsManager-AutomationExecutionRole (org).yaml` CloudFormation 模板文件。

1. 通过以下网址打开 CloudFormation 控制台：[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 选择**创建堆栈**。

1. 在 **Specify template**（指定模板）部分中，选择 **Upload a template**（上传模板）。

1. 选择**选择文件**，然后根据您在步骤 1 中所做的选择选择 `AWS-SystemsManager-AutomationExecutionRole.yaml` 或 `AWS-SystemsManager-AutomationExecutionRole (org).yaml` CloudFormation 模板文件。

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

1. 在**指定堆栈详细信息**页面的**堆栈名称**字段中，输入名称。

1. 在 **Parameters**（参数）部分的 **AdminAccountId** 字段中，输入自动化中央账户的 ID。

1. 如果您要为 AWS Organizations 环境设置此角色，则该部分中还有另一个名为 **OrganizationID** 的字段。输入 AWS 组织的 ID。

1. 选择 **Next（下一步）**。

1. 在 **Configure stack options**（配置堆栈选项）页面上，为要使用的所有选项输入值。选择 **Next（下一步）**。

1. 在**审核**页面上，向下滚动并选择**我确认 CloudFormation 可能使用自定义名称创建了 IAM 资源**选项。

1. 选择**创建堆栈**。

大约三分钟左右，CloudFormation 会显示 **CREATE\$1IN\$1PROGRESS** 状态。状态变为 **CREATE\$1COMPLETE**。

## 在多个区域和账户中运行自动化（控制台）


以下过程介绍了如何使用 Systems Manager 控制台在自动化管理账户的多个区域和账户中运行自动化。

**开始前的准备工作**  
在完成以下过程之前，请记下以下信息：
+ 用于运行多区域或多账户自动化的用户或角色必须拥有 `AWS-SystemsManager-AutomationAdministrationRole` 角色的 `iam:PassRole` 权限。
+ 要在其中运行自动化的 AWS 账户 账户 ID 或 OU。
+ 将在其中运行自动化的[受 Systems Manager 支持区域](https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region)。
+ 要在其中运行自动化的标签键和标签值或资源组的名称。

**在多个区域和账户中运行自动化**

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

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

1. 在**自动化文档**列表中，请选择运行手册。在**文档类别**窗格中选择一个或多个选项，以便根据 SSM 文档的用途对其进行筛选。要查看您拥有的运行手册，请选择**我拥有的**选项卡。要查看与您的账户共享的运行手册，请选择**与我共享**选项卡。要查看所有运行手册，请选择**所有文档**选项卡。
**注意**  
您可以通过选择运行手册名称来查看有关该手册的信息。

1. 在**文档详细信息**部分中，验证**文档版本**已设置为要运行的版本。系统包括以下版本选项：
   + **运行时的默认版本** – 如果定期更新自动化运行手册并分配新的默认版本，请选择此选项。
   + **运行时的最新版本** – 如果定期更新自动化运行手册并且想要运行最新更新的版本，请选择此选项。
   + **1（默认）** – 选择此选项可执行文档的第一个版本，即默认版本。

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

1. 在**执行自动化文档页面**上，选择**多账户和区域**。

1. 在**目标账户和区域**部分中，使用**账户和组织单元（OU）和根**字段指定要在其中运行自动化的不同 AWS 账户 或 AWS 组织单元（OU）。使用逗号分隔多个账户或 OU。

   1. （可选）选中**包括子 OU** 复选框以包括指定 OU 中的所有子组织单元。

   1. （可选）在**排除账户和组织单元（OU）**字段中，输入以逗号分隔的账户 ID 和 OU ID 列表，这些账户和组织单元将从上面输入的扩展实体中排除。

1. 使用**区域**列表选择要在其中运行自动化的一个或多个区域。

1. 使用**多区域和账户速率控制**选项将自动化限制为在有限区域中的有限账户运行。这些选项不限制可运行自动化的 AWS 资源的数量。

   1. 在**位置(账户-区域对)并发)**部分中，选择一个选项以限制可同时在多个账户和区域中运行的自动化的数量。例如，如果选择在位于四 (4) 个 AWS 区域 中的五 (5) 个 AWS 账户 账户中运行自动化，则 Systems Manager 在总共 20 个账户-区域对中运行自动化。您可以使用此选项指定一个绝对数量（例如 **2**），以使自动化仅同时在两个账户-区域对中运行。或者，您也可以指定可同时运行的账户-区域对的百分比。例如，对于 20 个账户-区域对，如果您指定 20%，自动化在最多五 (5) 个账户-区域对中同时运行。
      + 选择**目标**，以输入可同时运行自动化的账户-区域对的绝对数量。
      + 选择**百分比**，以输入可同时运行自动化的账户-区域对总数的百分比。

   1. 在**错误阈值**部分中，选择一个选项：
      + 选择**错误**，以输入自动化停止将自动化发送到其他资源之前允许的错误绝对数量。
      + 选择**百分比**，以输入自动化停止将工作流程发送到其他资源之前允许的错误的百分比。

1. 在**目标**部分中，选择希望如何设置要在其中运行自动化的 AWS 资源。这些选项是必需的。

   1. 使用**参数**列表选择一个参数。**参数**列表中的项目由此过程开始时选择的自动化运行手册中的参数确定。通过选择参数，可以定义在其上运行自动化工作流的资源类型。

   1. 使用**目标**列表选择设置目标资源的方式。

      1. 如果选择使用参数值将资源设置为目标，请输入您在**输入参数**部分为参数选择的参数值。

      1. 如果选择使用 AWS Resource Groups 将资源设置为目标，请从**资源组**列表中选择组的名称。

      1. 如果选择使用标签将资源设置为目标，请在提供的字段中输入标签键和（可选）标签值。选择**添加**。

      1. 如果要在当前 AWS 账户 和 AWS 区域 中的所有实例上运行自动化运行手册，则选择**所有实例**。

1. 在**输入参数** 部分中，指定所需的输入。从 **AutomationAssumeRole** 列表选择 `AWS-SystemsManager-AutomationAdministrationRole` IAM 服务角色。
**注意**  
您可能不需要选择**输入参数**部分中的某些选项。原因是您使用标签或资源组将多个区域和账户中的资源设置为目标。例如，如果选择了 `AWS-RestartEC2Instance` 运行手册，则无需在**输入参数**部分中指定或选择实例 ID。自动化使用您指定的标签以查找要重新启动的实例。

1. （可选）选择一个 CloudWatch 警报以应用于您的自动化进行监控。要将 CloudWatch 警报附加到自动化，启动自动化的 IAM 主体必须具有 `iam:createServiceLinkedRole` 操作的权限。有关 CloudWatch 警报的更多信息，请参阅[使用 Amazon CloudWatch 警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)。请注意，如果您的警报激活，自动化将取消，并且您定义的任何 `OnCancel` 步骤都会运行。如果使用 AWS CloudTrail，您将在跟踪中看到 API 调用。

1. 使用**速率控制**部分中的选项限制可在每个账户-区域对中运行自动化的 AWS 资源的数量。

   在**并发**部分中，选择一个选项：
   + 选择**目标**，以输入可同时运行自动化工作流目标的绝对数量。
   + 选择**百分比**，以输入可同时运行自动化工作流的目标集的百分比。

1. 在**错误阈值**部分中，选择一个选项：
   + 选择**错误**，以输入自动化停止将工作流程发送到其他资源之前允许的错误的绝对数量。
   + 选择**百分比**，以输入自动化停止将工作流程发送到其他资源之前允许的错误的百分比。

1. 选择**执行**。

自动化执行完成后，您可以使用相同或修改后的参数重新运行该执行。有关更多信息，请参阅 [重新运行自动化执行](automation-rerun-executions.md)。

## 在多个区域和账户中运行自动化（命令行）


以下过程介绍了如何使用 AWS CLI（在 Linux 或 Windows 上）或 AWS Tools for PowerShell 在自动化管理账户的多个区域和账户中运行自动化。

**开始前的准备工作**  
在完成以下过程之前，请记下以下信息：
+ 要在其中运行自动化的 AWS 账户 账户 ID 或 OU。
+ 将在其中运行自动化的[受 Systems Manager 支持区域](https://docs.aws.amazon.com/general/latest/gr/ssm.html#ssm_region)。
+ 要在其中运行自动化的标签键和标签值或资源组的名称。

**在多个区域和账户中运行自动化**

1. 安装并配置 AWS CLI 或 AWS Tools for PowerShell（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

1. 使用以下格式创建一个命令，以便在多个区域和账户中运行自动化。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name runbook name \
           --parameters AutomationAssumeRole=arn:aws:iam::management account ID:role/AWS-SystemsManager-AutomationAdministrationRole \
           --target-parameter-name parameter name \
           --targets Key=tag key,Values=value \
           --target-locations Accounts=account ID,account ID 2,Regions=Region,Region 2,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name runbook name ^
           --parameters AutomationAssumeRole=arn:aws:iam::management account ID:role/AWS-SystemsManager-AutomationAdministrationRole ^
           --target-parameter-name parameter name ^
           --targets Key=tag key,Values=value ^
           --target-locations Accounts=account ID,account ID 2,Regions=Region,Region 2,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
       $Targets.Key = "tag key"
       $Targets.Values = "value"
       
       Start-SSMAutomationExecution `
           -DocumentName "runbook name" `
           -Parameter @{
           "AutomationAssumeRole"="arn:aws:iam::management account ID:role/AWS-SystemsManager-AutomationAdministrationRole" } `
           -TargetParameterName "parameter name" `
           -Target $Targets `
           -TargetLocation @{
           "Accounts"="account ID","account ID 2";
           "Regions"="Region","Region 2";
           "ExecutionRoleName"="AWS-SystemsManager-AutomationExecutionRole" }
   ```

------

**示例：在多个区域和账户中运行自动化**  
以下示例演示如何使用 AWS CLI 和 PowerShell 通过一条命令在多个账户和区域中运行自动化。

   **示例 1**：此示例重启整个 AWS Organizations 组织中三个区域中的 EC2 实例。这是通过定位组织的根 ID 并包括子 OU 来实现的。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name "AWS-RestartEC2Instance" \
           --target-parameter-name InstanceId \
           --targets '[{"Key":"AWS::EC2::Instance","Values":["*"]}]' \
           --target-locations '[{
               "Accounts": ["r-example"],
               "IncludeChildOrganizationUnits": true,
               "Regions": ["us-east-1", "us-east-2", "us-west-2"]
           }]'
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution \
           --document-name "AWS-RestartEC2Instance" ^
           --target-parameter-name InstanceId ^
           --targets '[{"Key":"AWS::EC2::Instance","Values":["*"]}]' ^
           --target-locations '[{
               "Accounts": ["r-example"],
               "IncludeChildOrganizationUnits": true,
               "Regions": ["us-east-1", "us-east-2", "us-west-2"]
           }]'
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -TargetParameterName "InstanceId" `
           -Targets '[{"Key":"AWS::EC2::Instance","Values":["*"]}]'
           -TargetLocation @{
               "Accounts"="r-example";
               "Regions"="us-east-1", "us-east-2", "us-west-2";
               "IncludeChildOrganizationUnits"=true}
   ```

------

   **示例 2**：此示例重启不同账户和区域中的特定 EC2 实例。
**注意**  
`TargetLocationMaxConcurrency` 选项在使用 AWS CLI 和 AWS SDK 时可用。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name "AWS-RestartEC2Instance" \
           --target-parameter-name InstanceId \
           --target-locations '[{
               "Accounts": ["123456789012"],
               "Targets": [{
                   "Key":"ParameterValues",
                   "Values":["i-02573cafcfEXAMPLE", "i-0471e04240EXAMPLE"]
               }],
               "TargetLocationMaxConcurrency": "100%",
               "Regions": ["us-east-1"]
           }, {
               "Accounts": ["987654321098"],
               "Targets": [{
                   "Key":"ParameterValues",
                   "Values":["i-07782c72faEXAMPLE"]
               }],
               "TargetLocationMaxConcurrency": "100%",
               "Regions": ["us-east-2"]
           }]'
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name "AWS-RestartEC2Instance" ^
           --target-parameter-name InstanceId ^
           --target-locations '[{
               "Accounts": ["123456789012"],
               "Targets": [{
                   "Key":"ParameterValues",
                   "Values":["i-02573cafcfEXAMPLE", "i-0471e04240EXAMPLE"]
               }],
               "TargetLocationMaxConcurrency": "100%",
               "Regions": ["us-east-1"]
           }, {
               "Accounts": ["987654321098"],
               "Targets": [{
                   "Key":"ParameterValues",
                   "Values":["i-07782c72faEXAMPLE"]
               }],
               "TargetLocationMaxConcurrency": "100%",
               "Regions": ["us-east-2"]
           }]'
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -TargetParameterName "InstanceId" `
           -Targets '[{"Key":"AWS::EC2::Instance","Values":["*"]}]'
           -TargetLocation @({
               "Accounts"="123456789012",
               "Targets"= @{
                   "Key":"ParameterValues",
                   "Values":["i-02573cafcfEXAMPLE", "i-0471e04240EXAMPLE"]
               },
               "TargetLocationMaxConcurrency"="100%",
               "Regions"=["us-east-1"]
           }, {
               "Accounts"="987654321098",
               "Targets": @{
                   "Key":"ParameterValues",
                   "Values":["i-07782c72faEXAMPLE"]
               },
               "TargetLocationMaxConcurrency": "100%",
               "Regions"=["us-east-2"]
           })
   ```

------

   **示例 3**：此示例演示如何使用 `--target-locations-url` 选项指定应在其中运行自动化的多个 AWS 账户 和区域。此选项的值必须是可公开访问的[预签名 Amazon S3 URL](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html) 中的 JSON 文件。
**注意**  
`--target-locations-url` 在使用 AWS CLI 和 AWS SDK 时可用。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name "MyCustomAutomationRunbook" \
       --target-locations-url "https://amzn-s3-demo-bucket.s3.amazonaws.com/target-locations.json"
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name "MyCustomAutomationRunbook" ^
       --target-locations-url "https://amzn-s3-demo-bucket.s3.amazonaws.com/target-locations.json"
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
       -DocumentName "MyCustomAutomationRunbook" `
       -TargetLocationsUrl "https://amzn-s3-demo-bucket.s3.amazonaws.com/target-locations.json"
   ```

------

   JSON 文件的示例内容：

   ```
   [
   { 
            "Accounts": [ "123456789012", "987654321098", "456789123012" ],
            "ExcludeAccounts": [ "111222333444", "999888444666" ],
            "ExecutionRoleName": "MyAutomationExecutionRole",
            "IncludeChildOrganizationUnits": true,
            "Regions": [ "us-east-1", "us-west-2", "ap-south-1", "ap-northeast-1" ],
            "Targets": ["Key": "AWS::EC2::Instance", "Values": ["i-2"]],
            "TargetLocationMaxConcurrency": "50%",
            "TargetLocationMaxErrors": "10",
            "TargetsMaxConcurrency": "20",
            "TargetsMaxErrors": "12"
    }
   ]
   ```

   **示例 4**：此示例重启 `123456789012` 和 `987654321098` 账户中的 EC2 实例，它们位于 `us-east-2` 和 `us-west-1` 区域中。必须使用标签键对值 `Env-PROD` 标记这些实例。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name AWS-RestartEC2Instance \
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole \
           --target-parameter-name InstanceId \
           --targets Key=tag:Env,Values=PROD \
           --target-locations Accounts=123456789012,987654321098,Regions=us-east-2,us-west-1,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name AWS-RestartEC2Instance ^
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole ^
           --target-parameter-name InstanceId ^
           --targets Key=tag:Env,Values=PROD ^
           --target-locations Accounts=123456789012,987654321098,Regions=us-east-2,us-west-1,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
       $Targets.Key = "tag:Env"
       $Targets.Values = "PROD"
       
       Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -Parameter @{
           "AutomationAssumeRole"="arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole" } `
           -TargetParameterName "InstanceId" `
           -Target $Targets `
           -TargetLocation @{
           "Accounts"="123456789012","987654321098";
           "Regions"="us-east-2","us-west-1";
           "ExecutionRoleName"="AWS-SystemsManager-AutomationExecutionRole" }
   ```

------

   **示例 5**：此示例重启 `123456789012` 和 `987654321098` 账户中的 EC2 实例，它们位于 `eu-central-1` 区域中。这些实例必须是 `prod-instances` AWS 资源组的成员。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name AWS-RestartEC2Instance \
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole \
           --target-parameter-name InstanceId \
           --targets Key=ResourceGroup,Values=prod-instances \
           --target-locations Accounts=123456789012,987654321098,Regions=eu-central-1,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name AWS-RestartEC2Instance ^
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole ^
           --target-parameter-name InstanceId ^
           --targets Key=ResourceGroup,Values=prod-instances ^
           --target-locations Accounts=123456789012,987654321098,Regions=eu-central-1,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
       $Targets.Key = "ResourceGroup"
       $Targets.Values = "prod-instances"
       
       Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -Parameter @{
           "AutomationAssumeRole"="arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole" } `
           -TargetParameterName "InstanceId" `
           -Target $Targets `
           -TargetLocation @{
           "Accounts"="123456789012","987654321098";
           "Regions"="eu-central-1";
           "ExecutionRoleName"="AWS-SystemsManager-AutomationExecutionRole" }
   ```

------

   **示例 6**：此示例重启 `ou-1a2b3c-4d5e6c` AWS 组织单元（OU）中的 EC2 实例。这些实例位于 `us-west-1` 和 `us-west-2` 区域中。这些实例必须是 `WebServices` AWS 资源组的成员。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
           --document-name AWS-RestartEC2Instance \
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole \
           --target-parameter-name InstanceId \
           --targets Key=ResourceGroup,Values=WebServices \
           --target-locations Accounts=ou-1a2b3c-4d5e6c,Regions=us-west-1,us-west-2,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
           --document-name AWS-RestartEC2Instance ^
           --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole ^
           --target-parameter-name InstanceId ^
           --targets Key=ResourceGroup,Values=WebServices ^
           --target-locations Accounts=ou-1a2b3c-4d5e6c,Regions=us-west-1,us-west-2,ExecutionRoleName=AWS-SystemsManager-AutomationExecutionRole
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
       $Targets.Key = "ResourceGroup"
       $Targets.Values = "WebServices"
       
       Start-SSMAutomationExecution `
           -DocumentName "AWS-RestartEC2Instance" `
           -Parameter @{
           "AutomationAssumeRole"="arn:aws:iam::123456789012:role/AWS-SystemsManager-AutomationAdministrationRole" } `
           -TargetParameterName "InstanceId" `
           -Target $Targets `
           -TargetLocation @{
           "Accounts"="ou-1a2b3c-4d5e6c";
           "Regions"="us-west-1";
           "ExecutionRoleName"="AWS-SystemsManager-AutomationExecutionRole" }
   ```

------

   系统返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
           "AutomationExecutionId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
       }
   ```

------
#### [ Windows ]

   ```
   {
           "AutomationExecutionId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
       }
   ```

------
#### [ PowerShell ]

   ```
   4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------

1. 运行以下命令以查看自动化的详细信息。将 *automation execution ID* 替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-automation-executions \
           --filters Key=ExecutionId,Values=automation execution ID
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-automation-executions ^
           --filters Key=ExecutionId,Values=automation execution ID
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecutionList | `
           Where {$_.AutomationExecutionId -eq "automation execution ID"}
   ```

------

1. 运行以下命令以查看自动化进程的详细信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm get-automation-execution \
           --automation-execution-id 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------
#### [ Windows ]

   ```
   aws ssm get-automation-execution ^
           --automation-execution-id 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationExecution `
           -AutomationExecutionId a4a3c0e9-7efd-462a-8594-01234EXAMPLE
   ```

------
**注意**  
您也可以在控制台中监控自动化的状态。在**自动化执行**列表中，请选择您刚才运行的自动化，然后选择**执行步骤**选项卡。该选项卡显示自动化操作的状态。

**更多信息**  
[通过 AWS Systems Manager 自动化进行集中式多账户和多区域修补](https://aws.amazon.com/blogs/mt/centralized-multi-account-and-multi-region-patching-with-aws-systems-manager-automation/)

# 基于 EventBridge 事件运行自动化


您可以通过指定运行手册作为 Amazon EventBridge 事件的目标来启动自动化。您可以按计划或者在特定 AWS 系统事件发生时启动自动化。例如，假设您创建一个名为 *BootStrapInstances* 的运行手册，该运行手册在实例启动时在实例上安装软件。要指定 *BootStrapInstances* 运行手册（和对应的工作流程）作为 EventBridge 事件的目标，请先创建新的 EventBridge 规则。(以下是示例规则：**Service name**：EC2，**Event Type**：EC2 实例状态更改通知，**Specific state(s)**：正在运行，**Any instance**。) 然后，您使用以下过程指定 *BootStrapInstances* 运行手册作为使用 EventBridge 控制台和 AWS Command Line Interface (AWS CLI) 的事件的目标。当新实例启动时，系统将运行自动化并安装软件。

有关创建运行手册的更多信息，请参阅 [创建您自己的运行手册](automation-documents.md)。

## 创建使用运行手册（控制台）的 EventBridge 事件


使用以下过程将运行手册配置为 EventBridge 事件目标。

**将运行手册配置为 EventBridge 事件规则的目标**

1. 打开位于 [https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/) 的 Amazon EventBridge 控制台。

1. 在导航窗格中，选择**规则**。

1. 选择**创建规则**。

1. 为规则输入名称和描述。

   规则不能与同一区域中的另一个规则和同一事件总线上的名称相同。

1. 对于**事件总线**，请选择要与此规则关联的事件总线。如果您希望此规则响应来自您自己的 AWS 账户的匹配事件，请选择 **defaul**（默认）。当您账户中的某个 AWS 服务发出一个事件时，它始终会发送到您账户的默认事件总线。

1. 选择触发规则的方式。    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/running-automations-event-bridge.html)

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

1. 对于**目标类型**，选择**AWS 服务**。

1. 对于 **Target**（目标），选择 **Systems Manager Automation**。

1. 对于**文档**，选择在调用目标时要使用的运行手册。

1. 在 **Configure automation parameter(s)**（配置自动化参数）部分中，保留默认参数值（如果可用）或输入您自己的值。
**注意**  
要创建目标，您必须为每个所需的参数指定一个值。如果不指定，系统虽然会创建规则，但该规则不会运行。

1. 对于许多目标类型，EventBridge 需要权限以便将事件发送到目标。在这些情况下，EventBridge 可以创建运行事件所需的 IAM 角色：请执行以下操作之一：
   + 若要自动创建 IAM 角色，请选择 **Create a new role for this specific resource（为此特定资源创建新角色）**。
   + 要使用您之前创建的 IAM 角色，请选择 **Use existing role**（使用现有角色），然后从下拉列表中选择现有角色。请注意，您可能需要更新 IAM 角色的信任策略以包括 EventBridge。以下是示例：

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Sid": "",
               "Effect": "Allow",
               "Principal": {
                   "Service": [
                       "events.amazonaws.com",
                       "ssm.amazonaws.com"
                   ]
               },
               "Action": "sts:AssumeRole"
           }
       ]
   }
   ```

------

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

1. （可选）为规则输入一个或多个标签。有关更多信息，请参阅 *Amazon EventBridge 用户指南*中的[标记 Amazon EventBridge 资源](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-tagging.html)。

1. 选择 **Next（下一步）**。

1. 查看规则详细信息并选择**创建规则**。

## 创建一个使用运行手册的 EventBridge 事件（命令行）


以下过程介绍了如何使用 AWS CLI（在 Linux 或 Windows 上）或 AWS Tools for PowerShell 创建 EventBridge 事件规则并将运行手册配置为目标。

**将运行手册配置为 EventBridge 事件规则的目标**

1. 安装并配置 AWS CLI 或 AWS Tools for PowerShell（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

1. 创建一个命令以指定新的 EventBridge 事件规则。将每个*示例资源占位符*替换为您自己的信息。

   *基于计划的触发器*

------
#### [ Linux & macOS ]

   ```
   aws events put-rule \
   --name "rule name" \
   --schedule-expression "cron or rate expression"
   ```

------
#### [ Windows ]

   ```
   aws events put-rule ^
   --name "rule name" ^
   --schedule-expression "cron or rate expression"
   ```

------
#### [ PowerShell ]

   ```
   Write-CWERule `
   -Name "rule name" `
   -ScheduleExpression "cron or rate expression"
   ```

------

   以下示例创建一个 EventBridge 事件规则，将在每天上午 9:00 (UTC) 启动该规则。

------
#### [ Linux & macOS ]

   ```
   aws events put-rule \
   --name "DailyAutomationRule" \
   --schedule-expression "cron(0 9 * * ? *)"
   ```

------
#### [ Windows ]

   ```
   aws events put-rule ^
   --name "DailyAutomationRule" ^
   --schedule-expression "cron(0 9 * * ? *)"
   ```

------
#### [ PowerShell ]

   ```
   Write-CWERule `
   -Name "DailyAutomationRule" `
   -ScheduleExpression "cron(0 9 * * ? *)"
   ```

------

   *基于事件的触发器*

------
#### [ Linux & macOS ]

   ```
   aws events put-rule \
   --name "rule name" \
   --event-pattern "{\"source\":[\"aws.service\"],\"detail-type\":[\"service event detail type\"]}"
   ```

------
#### [ Windows ]

   ```
   aws events put-rule ^
   --name "rule name" ^
   --event-pattern "{\"source\":[\"aws.service\"],\"detail-type\":[\"service event detail type\"]}"
   ```

------
#### [ PowerShell ]

   ```
   Write-CWERule `
   -Name "rule name" `
   -EventPattern '{"source":["aws.service"],"detail-type":["service event detail type"]}'
   ```

------

   以下示例创建一个 EventBridge 事件规则，将在区域中的任何 EC2 实例更改状态时启动该规则。

------
#### [ Linux & macOS ]

   ```
   aws events put-rule \
   --name "EC2InstanceStateChanges" \
   --event-pattern "{\"source\":[\"aws.ec2\"],\"detail-type\":[\"EC2 Instance State-change Notification\"]}"
   ```

------
#### [ Windows ]

   ```
   aws events put-rule ^
   --name "EC2InstanceStateChanges" ^
   --event-pattern "{\"source\":[\"aws.ec2\"],\"detail-type\":[\"EC2 Instance State-change Notification\"]}"
   ```

------
#### [ PowerShell ]

   ```
   Write-CWERule `
   -Name "EC2InstanceStateChanges" `
   -EventPattern '{"source":["aws.ec2"],"detail-type":["EC2 Instance State-change Notification"]}'
   ```

------

   该命令返回新 EventBridge 规则的详细信息，类似于以下内容。

------
#### [ Linux & macOS ]

   ```
   {
   "RuleArn": "arn:aws:events:us-east-1:123456789012:rule/automationrule"
   }
   ```

------
#### [ Windows ]

   ```
   {
   "RuleArn": "arn:aws:events:us-east-1:123456789012:rule/automationrule"
   }
   ```

------
#### [ PowerShell ]

   ```
   arn:aws:events:us-east-1:123456789012:rule/EC2InstanceStateChanges
   ```

------

1. 创建一个命令以将运行手册指定为在步骤 2 中创建的 EventBridge 事件规则的目标。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws events put-targets \
   --rule rule name \
   --targets '{"Arn": " arn:aws:ssm:region:account ID:automation-definition/runbook name","Input":"{\"Message\":[\"{\\\"Key\\\":\\\"key name\\\",\\\"Values\\\":[\\\"value\\\"]}\"]}","Id": "target ID","RoleArn": "arn:aws:iam::123456789012:role/service-role/EventBridge service role"}'
   ```

------
#### [ Windows ]

   ```
   aws events put-targets ^
   --rule rule name ^
   --targets '{"Arn": "arn:aws:ssm:region:account ID:automation-definition/runbook name","Input":"{\"Message\":[\"{\\\"Key\\\":\\\"key name\\\",\\\"Values\\\":[\\\"value\\\"]}\"]}","Id": "target ID","RoleArn": "arn:aws:iam::123456789012:role/service-role/EventBridge service role"}'
   ```

------
#### [ PowerShell ]

   ```
   $Target = New-Object Amazon.CloudWatchEvents.Model.Target
   $Target.Id = "target ID"
   $Target.Arn = "arn:aws:ssm:region:account ID:automation-definition/runbook name"
   $Target.RoleArn = "arn:aws:iam::123456789012:role/service-role/EventBridge service role"
   $Target.Input = '{"input parameter":["value"],"AutomationAssumeRole":["arn:aws:iam::123456789012:role/AutomationServiceRole"]}'
   
   Write-CWETarget `
   -Rule "rule name" `
   -Target $Target
   ```

------

   以下示例创建一个 EventBridge 事件目标，它使用 `AWS-StartEC2Instance` 运行手册启动指定的实例 ID。

------
#### [ Linux & macOS ]

   ```
   aws events put-targets \
   --rule DailyAutomationRule \
   --targets '{"Arn": "arn:aws:ssm:region:*:automation-definition/AWS-StartEC2Instance","Input":"{\"InstanceId\":[\"i-02573cafcfEXAMPLE\"],\"AutomationAssumeRole\":[\"arn:aws:iam::123456789012:role/AutomationServiceRole\"]}","Id": "Target1","RoleArn": "arn:aws:iam::123456789012:role/service-role/AWS_Events_Invoke_Start_Automation_Execution_1213609520"}'
   ```

------
#### [ Windows ]

   ```
   aws events put-targets ^
   --rule DailyAutomationRule ^
   --targets '{"Arn": "arn:aws:ssm:region:*:automation-definition/AWS-StartEC2Instance","Input":"{\"InstanceId\":[\"i-02573cafcfEXAMPLE\"],\"AutomationAssumeRole\":[\"arn:aws:iam::123456789012:role/AutomationServiceRole\"]}","Id": "Target1","RoleArn": "arn:aws:iam::123456789012:role/service-role/AWS_Events_Invoke_Start_Automation_Execution_1213609520"}'
   ```

------
#### [ PowerShell ]

   ```
   $Target = New-Object Amazon.CloudWatchEvents.Model.Target
   $Target.Id = "Target1"
   $Target.Arn = "arn:aws:ssm:region:*:automation-definition/AWS-StartEC2Instance"
   $Target.RoleArn = "arn:aws:iam::123456789012:role/service-role/AWS_Events_Invoke_Start_Automation_Execution_1213609520"
   $Target.Input = '{"InstanceId":["i-02573cafcfEXAMPLE"],"AutomationAssumeRole":["arn:aws:iam::123456789012:role/AutomationServiceRole"]}'
   
   Write-CWETarget `
   -Rule "DailyAutomationRule" `
   -Target $Target
   ```

------

   系统将返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
   "FailedEntries": [],
   "FailedEntryCount": 0
   }
   ```

------
#### [ Windows ]

   ```
   {
   "FailedEntries": [],
   "FailedEntryCount": 0
   }
   ```

------
#### [ PowerShell ]

   如果命令在 PowerShell 中成功，则没有输出。

------

# 要按步骤运行自动化


以下过程介绍了如何通过手动执行模式使用 AWS Systems Manager 控制台和 AWS Command Line Interface (AWS CLI) 运行自动化。通过使用手动执行模式，自动化在两个步骤之间从*等待*状态开始，在*等待*状态暂停。这允许您控制自动化何时继续，如果您需要先查看某个步骤的结果，然后再继续，这会很有用。

自动化在当前用户的上下文中运行。因此，只要您有权使用运行手册和此运行手册调用的任何操作，就无需配置其他 IAM 权限。如果您在 IAM 中拥有管理员权限，则已有权运行此自动化。

## 按步骤运行自动化（控制台）


以下过程介绍了如何使用 Systems Manager 控制台按步骤手动运行自动化。

**要按步骤运行自动化，请执行以下操作**

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

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

1. 在**自动化文档**列表中，请选择运行手册。在**文档类别**窗格中选择一个或多个选项，以便根据 SSM 文档的用途对其进行筛选。要查看您拥有的运行手册，请选择**我拥有的**选项卡。要查看与您的账户共享的运行手册，请选择**与我共享**选项卡。要查看所有运行手册，请选择**所有文档**选项卡。
**注意**  
您可以通过选择运行手册名称来查看有关该手册的信息。

1. 在**文档详细信息**部分中，验证**文档版本**已设置为要运行的版本。系统包括以下版本选项：
   + **运行时的默认版本** – 如果定期更新自动化运行手册并分配新的默认版本，请选择此选项。
   + **运行时的最新版本** – 如果定期更新自动化运行手册并且想要运行最新更新的版本，请选择此选项。
   + **1（默认）** – 选择此选项可执行文档的第一个版本，即默认版本。

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

1. 在**执行模式**部分中，选择**手动执行**。

1. 在**输入参数**部分中，指定所需的输入。或者，您也可以从 **AutomationAssumeRole** 列表选择一个 IAM 服务角色。

1. 选择**执行**。

1. 当您准备好开始自动化的第一步时，选择**执行此步骤**。自动化将执行步骤 1，并在运行您在此过程的步骤 3 中选择的运行手册中指定的任何后续步骤之前暂停。如果运行手册具有多个步骤，则必须为每个步骤选择**执行此步骤**以让自动化继续。每次选择**执行此步骤**，操作就会运行。
**注意**  
控制台将显示自动化的状态。如果自动化无法运行某个步骤，请参阅 [Systems Manager 自动化故障排除](automation-troubleshooting.md)。

1. 在完成运行手册中指定的所有步骤后，选择**完成并查看结果**以完成自动化并查看结果。

自动化执行完成后，您可以使用相同或修改后的参数重新运行该执行。有关更多信息，请参阅 [重新运行自动化执行](automation-rerun-executions.md)。

## 按步骤运行自动化（命令行）


以下过程介绍了如何使用 AWS CLI（在 Linux、macOS 或 Windows 中）或 AWS Tools for PowerShell 按步骤手动运行自动化。

**要按步骤运行自动化，请执行以下操作：**

1. 安装并配置 AWS CLI 或 AWS Tools for PowerShell（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

1. 运行以下命令以启动一个手动自动化。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name runbook name \
       --mode Interactive \
       --parameters runbook parameters
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name runbook name ^
       --mode Interactive ^
       --parameters runbook parameters
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
       -DocumentName runbook name `
       -Mode Interactive `
       -Parameter runbook parameters
   ```

------

   以下是使用 `AWS-RestartEC2Instance` 运行手册重新启动指定 EC2 实例的示例。

------
#### [ Linux & macOS ]

   ```
   aws ssm start-automation-execution \
       --document-name "AWS-RestartEC2Instance" \
       --mode Interactive \
       --parameters "InstanceId=i-02573cafcfEXAMPLE"
   ```

------
#### [ Windows ]

   ```
   aws ssm start-automation-execution ^
       --document-name "AWS-RestartEC2Instance" ^
       --mode Interactive ^
       --parameters "InstanceId=i-02573cafcfEXAMPLE"
   ```

------
#### [ PowerShell ]

   ```
   Start-SSMAutomationExecution `
       -DocumentName AWS-RestartEC2Instance `
       -Mode Interactive 
       -Parameter @{"InstanceId"="i-02573cafcfEXAMPLE"}
   ```

------

   系统将返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
       "AutomationExecutionId": "ba9cd881-1b36-4d31-a698-0123456789ab"
   }
   ```

------
#### [ Windows ]

   ```
   {
       "AutomationExecutionId": "ba9cd881-1b36-4d31-a698-0123456789ab"
   }
   ```

------
#### [ PowerShell ]

   ```
   ba9cd881-1b36-4d31-a698-0123456789ab
   ```

------

1. 在准备好开始执行自动化的第一步时，运行以下命令。将每个*示例资源占位符*替换为您自己的信息。自动化将执行步骤 1，并在运行您在该过程的步骤 1 中选择的运行手册中指定的任何后续步骤之前暂停。如果运行手册具有多个步骤，则必须为每个步骤运行以下命令以使自动化继续执行。

------
#### [ Linux & macOS ]

   ```
   aws ssm send-automation-signal \
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab \
       --signal-type StartStep \
       --payload StepName="stopInstances"
   ```

------
#### [ Windows ]

   ```
   aws ssm send-automation-signal ^
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab ^
       --signal-type StartStep ^
       --payload StepName="stopInstances"
   ```

------
#### [ PowerShell ]

   ```
   Send-SSMAutomationSignal `
       -AutomationExecutionId ba9cd881-1b36-4d31-a698-0123456789ab `
       -SignalType StartStep 
       -Payload @{"StepName"="stopInstances"}
   ```

------

   如果此命令成功，则无任何输出。

1. 运行以下命令以检索自动化中的每个步骤执行的状态。

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-automation-step-executions \
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-automation-step-executions ^
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMAutomationStepExecution `
       -AutomationExecutionId ba9cd881-1b36-4d31-a698-0123456789ab
   ```

------

   系统将返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
       "StepExecutions": [
           {
               "StepName": "stopInstances",
               "Action": "aws:changeInstanceState",
               "ExecutionStartTime": 1557167178.42,
               "ExecutionEndTime": 1557167220.617,
               "StepStatus": "Success",
               "Inputs": {
                   "DesiredState": "\"stopped\"",
                   "InstanceIds": "[\"i-02573cafcfEXAMPLE\"]"
               },
               "Outputs": {
                   "InstanceStates": [
                       "stopped"
                   ]
               },
               "StepExecutionId": "654243ba-71e3-4771-b04f-0123456789ab",
               "OverriddenParameters": {},
               "ValidNextSteps": [
                   "startInstances"
               ]
           },
           {
               "StepName": "startInstances",
               "Action": "aws:changeInstanceState",
               "ExecutionStartTime": 1557167273.754,
               "ExecutionEndTime": 1557167480.73,
               "StepStatus": "Success",
               "Inputs": {
                   "DesiredState": "\"running\"",
                   "InstanceIds": "[\"i-02573cafcfEXAMPLE\"]"
               },
               "Outputs": {
                   "InstanceStates": [
                       "running"
                   ]
               },
               "StepExecutionId": "8a4a1e0d-dc3e-4039-a599-0123456789ab",
               "OverriddenParameters": {}
           }
       ]
   }
   ```

------
#### [ Windows ]

   ```
   {
       "StepExecutions": [
           {
               "StepName": "stopInstances",
               "Action": "aws:changeInstanceState",
               "ExecutionStartTime": 1557167178.42,
               "ExecutionEndTime": 1557167220.617,
               "StepStatus": "Success",
               "Inputs": {
                   "DesiredState": "\"stopped\"",
                   "InstanceIds": "[\"i-02573cafcfEXAMPLE\"]"
               },
               "Outputs": {
                   "InstanceStates": [
                       "stopped"
                   ]
               },
               "StepExecutionId": "654243ba-71e3-4771-b04f-0123456789ab",
               "OverriddenParameters": {},
               "ValidNextSteps": [
                   "startInstances"
               ]
           },
           {
               "StepName": "startInstances",
               "Action": "aws:changeInstanceState",
               "ExecutionStartTime": 1557167273.754,
               "ExecutionEndTime": 1557167480.73,
               "StepStatus": "Success",
               "Inputs": {
                   "DesiredState": "\"running\"",
                   "InstanceIds": "[\"i-02573cafcfEXAMPLE\"]"
               },
               "Outputs": {
                   "InstanceStates": [
                       "running"
                   ]
               },
               "StepExecutionId": "8a4a1e0d-dc3e-4039-a599-0123456789ab",
               "OverriddenParameters": {}
           }
       ]
   }
   ```

------
#### [ PowerShell ]

   ```
   Action: aws:changeInstanceState
   ExecutionEndTime     : 5/6/2019 19:45:46
   ExecutionStartTime   : 5/6/2019 19:45:03
   FailureDetails       : 
   FailureMessage       : 
   Inputs               : {[DesiredState, "stopped"], [InstanceIds, ["i-02573cafcfEXAMPLE"]]}
   IsCritical           : False
   IsEnd                : False
   MaxAttempts          : 0
   NextStep             : 
   OnFailure            : 
   Outputs              : {[InstanceStates, Amazon.Runtime.Internal.Util.AlwaysSendList`1[System.String]]}
   OverriddenParameters : {}
   Response             : 
   ResponseCode         : 
   StepExecutionId      : 8fcc9641-24b7-40b3-a9be-0123456789ab
   StepName             : stopInstances
   StepStatus           : Success
   TimeoutSeconds       : 0
   ValidNextSteps       : {startInstances}
   ```

------

1. 在完成所选运行手册中指定的所有步骤后，运行以下命令以完成自动化。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm stop-automation-execution \
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab \
       --type Complete
   ```

------
#### [ Windows ]

   ```
   aws ssm stop-automation-execution ^
       --automation-execution-id ba9cd881-1b36-4d31-a698-0123456789ab ^
       --type Complete
   ```

------
#### [ PowerShell ]

   ```
   Stop-SSMAutomationExecution `
       -AutomationExecutionId ba9cd881-1b36-4d31-a698-0123456789ab `
       -Type Complete
   ```

------

   如果此命令成功，则无任何输出。

# 使用 State Manager 关联调度自动化


您可以通过创建与运行手册的State Manager关联启动自动化。State Manager是 AWS Systems Manager 中的一项工具。通过创建与运行手册的 State Manager 关联，您可以将不同类型的 AWS 资源设置为目标。例如，您可以创建强制 AWS 资源进入预期状态的关联，包括：
+ 将 Systems Manager 角色附加到 Amazon Elastic Compute Cloud (Amazon EC2) 实例，以使其成为*托管实例*。
+ 对安全组强制实施所需的入口和出口规则。
+ 创建或删除 Amazon DynamoDB 备份。
+ 创建或删除 Amazon Elastic Block Store (Amazon EBS) 快照。
+ 关闭 Amazon Simple Storage Service (Amazon S3) 存储桶的读写权限。
+ 启动、重新启动或停止托管实例和 Amazon Relational Database Service (Amazon RDS) 实例。
+ 将修补程序应用到 Linux、macOS 和 Windows AMIs。

可以使用以下过程通过 AWS Systems Manager 控制台 和 AWS Command Line Interface (AWS CLI) 创建 State Manager 关联以运行自动化。有关关联的一般信息以及有关创建使用 SSM `Command` 文档或 `Policy` 文档的关联的信息，请参阅 [创建关联](state-manager-associations-creating.md)。

**开始前的准备工作**  
请注意以下重要详细信息，然后再使用 State Manager 运行自动化。
+ 您必须先验证是否已为 Automation（AWS Systems Manager 中的一项工具）配置权限，然后才能创建运行某个运行手册的关联。有关更多信息，请参阅 [设置自动化](automation-setup.md)。
+ 运行多个运行手册的 State Manager 关联将计入在您的 AWS 账户 中并发运行的自动化的最大数。一次最多可以运行 100 个并发自动化。有关信息，请参阅《Amazon Web Services 一般参考》**中的 [Systems Manager service quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm)。
+ 运行自动化时，State Manager 不记录自动化在 AWS CloudTrail 中发起的 API 操作。
+ Systems Manager 自动创建服务相关角色，以便 State Manager 有权调用 Systems Manager 自动化 API 操作。如果需要，您可以从 AWS CLI 或 AWS Tools for PowerShell 中运行以下命令以自行创建服务相关角色。

------
#### [ Linux & macOS ]

  ```
  aws iam create-service-linked-role \
  --aws-service-name ssm.amazonaws.com
  ```

------
#### [ Windows ]

  ```
  aws iam create-service-linked-role ^
  --aws-service-name ssm.amazonaws.com
  ```

------
#### [ PowerShell ]

  ```
  New-IAMServiceLinkedRole `
  -AWSServiceName ssm.amazonaws.com
  ```

------

  有关服务相关角色的更多信息，请参阅 [将服务关联角色用于 Systems Manager](using-service-linked-roles.md)。

## 创建运行自动化的关联（控制台）


以下过程介绍了如何使用 Systems Manager 控制台创建运行自动化的 State Manager 关联。

**创建 State Manager 关联以运行自动化**

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

1. 在导航窗格中，选择 **State Manager**，然后选择**创建关联**。

1. 在**名称** 字段中指定名称。您可以自由选择，但我们建议您这样做。

1. 在**文档**列表中，选择运行手册。使用搜索栏来筛选 **Document type : Equal : Automation** 运行手册。使用搜索栏右侧的数字可查看更多运行手册。
**注意**  
您可以通过选择运行手册名称来查看有关该手册的信息。

1. 选择**简单执行**来通过指定一个或多个目标的资源 ID 在这些目标上运行自动化。选择**速率控制**可以通过指定设置目标选项（如标签或 AWS Resource Groups）来在 AWS 资源队列上运行自动化。您还可以通过指定并发和错误阈值来控制跨各个资源的自动化的执行。

   如果您选择**速率控制**，将显示**目标**部分。

1. 在**目标**部分中，选择一种设置资源目标的方法。

   1. （必需）在**参数** 列表中，选择一个参数。**参数**列表中的项目由此过程开始时选择的运行手册中的参数确定。通过选择参数，可以定义自动化运行的资源类型。

   1. （必需）在**目标**列表中，选择一种设置资源目标的方法。
      + **资源组**：从**资源组**列表中选择组的名称。有关在运行手册中将 AWS Resource Groups 设置为目标的更多信息，请参阅 [设置目标 AWS Resource Groups](running-automations-map-targets.md#target-resource-groups)。
      + **标签**：在提供的字段中输入标签键和标签值（可选）。选择**添加**。有关在运行手册中设置标签目标的更多信息，请参阅 [设置目标标签](running-automations-map-targets.md#target-tags)。
      + **参数值**：在**输入参数**部分输入值。如果指定多个值，Systems Manager 将在指定的每个值上运行子自动化。

        例如，假设运行手册包含 **InstanceID** 参数。如果在运行此自动化时将 **InstanceID** 参数值设置为目标，则 Systems Manager 会为指定的每个实例 ID 值运行一个子自动化。当自动化完成每个指定实例的运行或执行失败时，父自动化完成。您最多可以将 50 个参数值设置为目标。有关在运行手册中设置参数值目标的更多信息，请参阅 [设置目标参数值](running-automations-map-targets.md#target-parameter-values)。

1. 在**输入参数**部分，指定所需的输入参数。

   如果选择使用标签或资源组将资源设置为目标，则不需要选择**输入参数**部分中的某些选项。例如，如果选择 `AWS-RestartEC2Instance` 运行手册，并且选择使用标签将实例设置为目标，则无需在**输入参数**部分中指定或选择实例 ID。自动化使用您指定的标签查找要重新启动的实例。
**重要**  
您必须在 **AutomationAssumeRole** 字段中指定一个角色 ARN。State Manager 使用担任角色来调用运行手册中指定的 AWS 服务并代表您运行自动化关联。

1. 如果您希望定期运行关联，请在**指定计划**部分中，选择**按计划**。如果您选择此选项，则使用提供的选项使用 Cron 或 Rate 表达式创建计划。有关 State Manager 的 Cron 和 Rate 表达式的更多信息，请参阅 [适用于关联的 Cron 和 Rate 表达式](reference-cron-and-rate-expressions.md#reference-cron-and-rate-expressions-association)。
**注意**  
Rate 表达式是运行多个运行手册的 State Manager 关联的首选计划机制。如果您达到了并发运行自动化的最大数，Rate 表达式会为运行关联提供更多灵活性。使用速率计划，Systems Manager 可以在收到并发自动化已达最大值并已被节流的通知后，立即重试自动化。

   如果您希望运行关联一次，请选择**无计划**。

1. （可选）在 **Rate Control**（速率控制）部分中，选择 **Concurrency**（并发）和 **Error threshold**（错误阈值）选项来控制跨各个 AWS 资源的自动化部署。

   1. 在**并发**部分中，选择一个选项：
      + 选择**目标**，以输入可同时运行自动化的目标的绝对数量。
      + 选择**百分比**，以输入可同时运行自动化的目标集的百分比。

   1. 在**错误阈值**部分中，选择一个选项：
      + 选择**错误**，以输入自动化停止将自动化发送到其他资源之前允许的错误绝对数量。
      + 选择**百分比**，以输入自动化停止将自动化发送到其他资源之前允许的错误的百分比。

   有关使用自动化的目标和速率控制的更多信息，请参阅 [大规模运行自动化操作](running-automations-scale.md)。

1. 选择**创建关联**。
**重要**  
在创建关联时，将针对指定目标立即运行关联。然后，关联基于您选择的 Cron 或 Rate 表达式运行。如果您选择了**无计划**，则关联不会再次运行。

## 创建关联以运行自动化（命令行）


以下过程介绍了如何使用 AWS CLI（在 Linux 或 Windows Server 上）或 AWS Tools for PowerShell 创建 State Manager 关联以运行自动化。

**开始前的准备工作**  
在您完成以下过程之前，请确保创建了包含运行运行手册所需权限的 IAM 服务角色，并为 Automation（AWS Systems Manager 中的一项工具）配置了信任关系。有关更多信息，请参阅 [任务 1：为自动化创建服务角色](automation-setup-iam.md#create-service-role)。

**创建关联以运行自动化**

1. 安装并配置 AWS CLI 或 AWS Tools for PowerShell（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

1. 运行以下命令以查看文档列表。

------
#### [ Linux & macOS ]

   ```
   aws ssm list-documents
   ```

------
#### [ Windows ]

   ```
   aws ssm list-documents
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentList
   ```

------

   记下要用于关联的运行手册的名称。

1. 运行以下命令以查看有关运行手册的详细信息。在下面的命令中，将 *runbook name* 替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-document \
   --name runbook name
   ```

   记下要用于 `--automation-target-parameter-name` 选项的参数名称（例如 `InstanceId`）。此参数确定在其上运行自动化的资源的类型。

------
#### [ Windows ]

   ```
   aws ssm describe-document ^
   --name runbook name
   ```

   记下要用于 `--automation-target-parameter-name` 选项的参数名称（例如 `InstanceId`）。此参数确定在其上运行自动化的资源的类型。

------
#### [ PowerShell ]

   ```
   Get-SSMDocumentDescription `
   -Name runbook name
   ```

   记下要用于 `AutomationTargetParameterName` 选项的参数名称（例如 `InstanceId`）。此参数确定在其上运行自动化的资源的类型。

------

1. 创建一个命令以使用 State Manager 关联运行自动化。将每个*示例资源占位符*替换为您自己的信息。

   *使用标签设置目标*

------
#### [ Linux & macOS ]

   ```
   aws ssm create-association \
   --association-name association name \
   --targets Key=tag:key name,Values=value \
   --name runbook name \
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole \
   --automation-target-parameter-name target parameter \
   --schedule "cron or rate expression"
   ```

**注意**  
如果您使用 AWS CLI 创建关联，请使用 `--targets` 参数指定关联的目标实例。不要使用 `--instance-id` 参数。`--instance-id` 参数是一个旧参数。

------
#### [ Windows ]

   ```
   aws ssm create-association ^
   --association-name association name ^
   --targets Key=tag:key name,Values=value ^
   --name runbook name ^
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole ^
   --automation-target-parameter-name target parameter ^
   --schedule "cron or rate expression"
   ```

**注意**  
如果您使用 AWS CLI 创建关联，请使用 `--targets` 参数指定关联的目标实例。不要使用 `--instance-id` 参数。`--instance-id` 参数是一个旧参数。

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "tag:key name"
   $Targets.Values = "value"
   
   New-SSMAssociation `
   -AssociationName "association name" `
   -Target $Targets `
   -Name "runbook name" `
   -Parameters @{
   "AutomationAssumeRole"="arn:aws:iam::123456789012:role/RunbookAssumeRole" } `
   -AutomationTargetParameterName "target parameter" `
   -ScheduleExpression "cron or rate expression"
   ```

**注意**  
如果您使用 AWS Tools for PowerShell 创建关联，请使用 `Target` 参数指定关联的目标实例。不要使用 `InstanceId` 参数。`InstanceId` 参数是一个旧参数。

------

   *使用参数值设置目标*

------
#### [ Linux & macOS ]

   ```
   aws ssm create-association \
   --association-name association name \
   --targets Key=ParameterValues,Values=value,value 2,value 3 \
   --name runbook name \
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole \
   --automation-target-parameter-name target parameter \
   --schedule "cron or rate expression"
   ```

------
#### [ Windows ]

   ```
   aws ssm create-association ^
   --association-name association name ^
   --targets Key=ParameterValues,Values=value,value 2,value 3 ^
   --name runbook name ^
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole ^
   --automation-target-parameter-name target parameter ^
   --schedule "cron or rate expression"
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ParameterValues"
   $Targets.Values = "value","value 2","value 3"
   
   New-SSMAssociation `
   -AssociationName "association name" `
   -Target $Targets `
   -Name "runbook name" `
   -Parameters @{
   "AutomationAssumeRole"="arn:aws:iam::123456789012:role/RunbookAssumeRole"} `
   -AutomationTargetParameterName "target parameter" `
   -ScheduleExpression "cron or rate expression"
   ```

------

   *使用 AWS Resource Groups 设置目标*

------
#### [ Linux & macOS ]

   ```
   aws ssm create-association \
   --association-name association name \
   --targets Key=ResourceGroup,Values=resource group name \
   --name runbook name \
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole \
   --automation-target-parameter-name target parameter \
   --schedule "cron or rate expression"
   ```

------
#### [ Windows ]

   ```
   aws ssm create-association ^
   --association-name association name ^
   --targets Key=ResourceGroup,Values=resource group name ^
   --name runbook name ^
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole ^
   --automation-target-parameter-name target parameter ^
   --schedule "cron or rate expression"
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ResourceGroup"
   $Targets.Values = "resource group name"
   
   New-SSMAssociation `
   -AssociationName "association name" `
   -Target $Targets `
   -Name "runbook name" `
   -Parameters @{
   "AutomationAssumeRole"="arn:aws:iam::123456789012:role/RunbookAssumeRole"} `
   -AutomationTargetParameterName "target parameter" `
   -ScheduleExpression "cron or rate expression"
   ```

------

   *将多个账户和区域设置为目标*

------
#### [ Linux & macOS ]

   ```
   aws ssm create-association \
   --association-name association name \
   --targets Key=ResourceGroup,Values=resource group name \
   --name runbook name \
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole \
   --automation-target-parameter-name target parameter \
   --schedule "cron or rate expression" \ 
   --target-locations Accounts=111122223333,444455556666,444455556666,Regions=region,region
   ```

------
#### [ Windows ]

   ```
   aws ssm create-association ^
   --association-name association name ^
   --targets Key=ResourceGroup,Values=resource group name ^
   --name runbook name ^
   --parameters AutomationAssumeRole=arn:aws:iam::123456789012:role/RunbookAssumeRole ^
   --automation-target-parameter-name target parameter ^
   --schedule "cron or rate expression" ^ 
   --target-locations Accounts=111122223333,444455556666,444455556666,Regions=region,region
   ```

------
#### [ PowerShell ]

   ```
   $Targets = New-Object Amazon.SimpleSystemsManagement.Model.Target
   $Targets.Key = "ResourceGroup"
   $Targets.Values = "resource group name"
   
   New-SSMAssociation `
   -AssociationName "association name" `
   -Target $Targets `
   -Name "runbook name" `
   -Parameters @{
   "AutomationAssumeRole"="arn:aws:iam::123456789012:role/RunbookAssumeRole"} `
   -AutomationTargetParameterName "target parameter" `
   -ScheduleExpression "cron or rate expression" `
   -TargetLocations @{
       "Accounts"=["111122223333,444455556666,444455556666"],
       "Regions"=["region,region"]
   ```

------

   该命令返回新关联的详细信息，类似于以下内容。

------
#### [ Linux & macOS ]

   ```
   {
   "AssociationDescription": {
       "ScheduleExpression": "cron(0 7 ? * MON *)",
       "Name": "AWS-StartEC2Instance",
       "Parameters": {
           "AutomationAssumeRole": [
               "arn:aws:iam::123456789012:role/RunbookAssumeRole"
           ]
       },
       "Overview": {
           "Status": "Pending",
           "DetailedStatus": "Creating"
       },
       "AssociationId": "1450b4b7-bea2-4e4b-b340-01234EXAMPLE",
       "DocumentVersion": "$DEFAULT",
       "AutomationTargetParameterName": "InstanceId",
       "LastUpdateAssociationDate": 1564686638.498,
       "Date": 1564686638.498,
       "AssociationVersion": "1",
       "AssociationName": "CLI",
       "Targets": [
           {
               "Values": [
                   "DEV"
               ],
               "Key": "tag:ENV"
           }
       ]
   }
   }
   ```

------
#### [ Windows ]

   ```
   {
   "AssociationDescription": {
       "ScheduleExpression": "cron(0 7 ? * MON *)",
       "Name": "AWS-StartEC2Instance",
       "Parameters": {
           "AutomationAssumeRole": [
               "arn:aws:iam::123456789012:role/RunbookAssumeRole"
           ]
       },
       "Overview": {
           "Status": "Pending",
           "DetailedStatus": "Creating"
       },
       "AssociationId": "1450b4b7-bea2-4e4b-b340-01234EXAMPLE",
       "DocumentVersion": "$DEFAULT",
       "AutomationTargetParameterName": "InstanceId",
       "LastUpdateAssociationDate": 1564686638.498,
       "Date": 1564686638.498,
       "AssociationVersion": "1",
       "AssociationName": "CLI",
       "Targets": [
           {
               "Values": [
                   "DEV"
               ],
               "Key": "tag:ENV"
           }
       ]
   }
   }
   ```

------
#### [ PowerShell ]

   ```
   Name                  : AWS-StartEC2Instance
   InstanceId            : 
   Date                  : 8/1/2019 7:31:38 PM
   Status.Name           : 
   Status.Date           : 
   Status.Message        : 
   Status.AdditionalInfo :
   ```

------

**注意**  
如果使用标签在一个或多个目标实例上创建关联，然后从某一实例中删除标签，则该实例将不再运行该关联。该实例不再与 State Manager 文档关联。

## 对 State Manager 关联运行的自动化进行故障排除


Systems Manager 自动化强制要求每个账户、每个区域最多有 100 个并发自动化和 1000 个排队自动化。如果使用运行手册的 State Manager 关联显示**已失败**状态和详细状态 **AutomationExecutionLimitExceeded**，则表明您的自动化可能已达到了限制。因此，Systems Manager 会限制自动化。要解决此问题，请执行以下操作：
+ 为关联使用不同的 Rate 或 Cron 表达式。例如，如果关联计划为每 30 分钟运行一次，则更改表达式，使其每小时或每两小时运行一次。
+ 删除状态为**待处理**的现有自动化。通过删除这些自动化，将清除当前队列。

# 使用维护窗口计划自动化


您可通过将运行手册配置为维护时段的注册任务来启动自动化。通过将运行手册注册为注册任务，维护时段将在计划维护期间内运行自动化。

例如，假设您创建了一个名为 `CreateAMI` 的运行手册，该运行手册创建了一个注册为维护时段目标的 Amazon Machine Image (AMI）实例。要指定 `CreateAMI` 运行手册（和对应的工作流程）作为维护时段内的注册任务，您首先要创建一个维护时段并注册目标。然后，使用以下过程将 `CreateAMI` 文档指定为维护时段内的注册任务。当维护时段在计划期间内启动时，系统将运行自动化并创建注册目标的 AMI。

有关创建自动化运行手册的信息，请参阅 [创建您自己的运行手册](automation-documents.md)。Automation 是 AWS Systems Manager 中的一项工具。

可以使用以下过程通过 AWS Systems Manager 控制台、AWS Command Line Interface (AWS CLI) 或 AWS Tools for Windows PowerShell 将自动化配置为维护时段的注册任务。

## 在维护时段中注册自动化任务（控制台）


以下过程介绍了如何使用 Systems Manager 控制台将自动化配置为维护时段的注册任务。

**开始前的准备工作**  
在完成以下过程之前，您必须创建维护时段并注册至少一个目标。有关更多信息，请参阅以下流程：
+ [使用控制台创建维护时段](sysman-maintenance-create-mw.md).
+ [使用控制台为维护时段分配目标](sysman-maintenance-assign-targets.md)

**将自动化配置为维护时段的注册任务**

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

1. 在左侧导航窗格中，选择 **Maintenance Windows**，然后选择您要向其注册自动化任务的维护时段。

1. 选择**操作**。然后选择**注册自动化任务**以使用运行手册在目标上运行您选择的自动化。

1. 对于**名称**，输入任务的名称。

1. 对于**说明**，输入说明。

1. 对于**文)**，选择定义要运行的任务的运行手册。

1. 对于**文档版本**，选择要使用的运行手册版本。

1. 对于**任务优先级**，选择一个优先级。`1` 是最高优先级。维护时段中的任务按优先级顺序计划，具有相同优先级的任务则并行计划。

1. 在**目标**部分，如果您选择的运行手册在资源上运行任务，则通过手动指定标签或选择实例来标识您要对其运行此自动化的目标。
**注意**  
如果要通过输入参数而不是目标传递资源，则无需指定维护时段目标。  
在许多情况下，您无需显式指定自动化任务的目标。例如，假设您要创建 自动化 类型的任务，以使用 `AWS-UpdateLinuxAmi` 运行手册为 Linux 更新 Amazon Machine Image (AMI)。在该任务运行时，已使用最新可用的 Linux 分发版本的程序包和 Amazon 软件更新了 AMI。从 AMI 创建的新实例已经安装了这些更新。由于在运行手册的输入参数中指定了要进行更新的 AMI 的 ID，无需在维护时段任务中再次指定目标。

   有关不需要目标的维护时段任务的信息，请参阅 [注册不含目标的维护时段任务](maintenance-windows-targetless-tasks.md)。

1. （可选）对于**速率控制**：
**注意**  
如果您正在运行的任务没有指定目标，则不需要指定速率控制。
   + 对于**并发**，指定要同时对其运行自动化的目标的数量或百分比。

     如果通过选择键值对选择了目标，但不确定有多少个目标使用所选标签，则可以通过指定百分比来限制可同时运行的自动化的数量。

     当维护时段运行时，每个目标将启动一个新的自动化。每个 AWS 账户 限制 100 个并发自动化。如果您指定的并发速率大于 100，会有 100 个以上的并发执行自动添加到执行队列。有关信息，请参阅《Amazon Web Services 一般参考》**中的 [Systems Manager service quotas](https://docs.aws.amazon.com/general/latest/gr/ssm.html#limits_ssm)。
   + 对于**错误阈值**，指定此自动化在一定数量或百分比的目标上失败后何时停止在其他目标上运行这些工作流程。例如，如果您指定三个错误，在收到第四个错误时，Systems Manager 会停止运行自动化。仍在处理自动化的目标也可能发送错误。

1. 在**输入参数**部分中，为运行手册指定参数。对于运行手册，系统将自动填充某些值。您可以保留或更换这些值。
**重要**  
对于运行手册，您可以选择性地指定自动化担任角色。如果您不为此参数指定角色，那么自动化将担任您在步骤 11 中选择的维护时段服务角色。因此，您必须确保所选择的维护时段服务角色具有适当的 AWS Identity and Access Management (IAM) 权限来执行在运行手册中定义的操作。  
例如，Systems Manager 的服务相关角色没有 IAM 权限 `ec2:CreateSnapshot`，而这是运行运行手册 `AWS-CopySnapshot` 所必需的。在这种情况下，您必须使用自定义的维护时段服务角色或指定具有 `ec2:CreateSnapshot` 权限的 Automation 担任角色。有关信息，请参阅[设置自动化](automation-setup.md)。

1. 在 **IAM service role**（IAM 服务角色）区域中，选择一个角色以向 Systems Manager 提供启动自动化的权限。

   要为维护时段任务创建自定义服务角色，请参阅[设置 Maintenance Windows](setting-up-maintenance-windows.md)。

1. 选择**注册自动化任务**。

## 在维护时段中注册自动化任务（命令行）


以下过程介绍了如何使用 AWS CLI（在 Linux 或 Windows Server 上）或 AWS Tools for PowerShell 将自动化配置为维护时段的注册任务。

**开始前的准备工作**  
在完成以下过程之前，您必须创建维护时段并注册至少一个目标。有关更多信息，请参阅以下流程：
+ [步骤 1：使用 AWS CLI 创建维护时段](mw-cli-tutorial-create-mw.md).
+ [步骤 2：使用 AWS CLI 将目标节点注册到维护时段](mw-cli-tutorial-targets.md)

**将自动化配置为维护时段的注册任务**

1. 安装并配置 AWS CLI 或 AWS Tools for PowerShell（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

1. 创建一个命令以将自动化配置为维护时段的注册任务。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm register-task-with-maintenance-window \
   --window-id window ID \
   --name task name \
   --task-arn runbook name \
   --targets Key=targets,Values=value \
   --service-role-arn IAM role arn \
   --task-type AUTOMATION \
   --task-invocation-parameters task parameters \
   --priority task priority \
   --max-concurrency 10% \
   --max-errors 5
   ```

**注意**  
如果使用 AWS CLI 将自动化配置为注册任务，请使用 `--Task-Invocation-Parameters` 参数指定在任务运行时为其传递的参数。不要使用 `--Task-Parameters` 参数。`--Task-Parameters` 参数是一个旧参数。  
对于没有指定目标的维护时段任务，您无法为 `--max-errors` 和 `--max-concurrency` 提供值。作为替代方式，系统会插入一个占位符值 `1`，该值可能会在响应诸如 [https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html) 和 [https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html) 等命令时发出报告。这些值不影响任务的运行，可以忽略。  
有关不需要目标的维护时段任务的信息，请参阅 [注册不含目标的维护时段任务](maintenance-windows-targetless-tasks.md)。

------
#### [ Windows ]

   ```
   aws ssm register-task-with-maintenance-window ^
   --window-id window ID ^
   --name task name ^
   --task-arn runbook name ^
   --targets Key=targets,Values=value ^
   --service-role-arn IAM role arn ^
   --task-type AUTOMATION ^
   --task-invocation-parameters task parameters ^
   --priority task priority ^
   --max-concurrency 10% ^
   --max-errors 5
   ```

**注意**  
如果使用 AWS CLI 将自动化配置为注册任务，请使用 `--task-invocation-parameters` 参数指定在任务运行时为其传递的参数。不要使用 `--task-parameters` 参数。`--task-parameters` 参数是一个旧参数。  
对于没有指定目标的维护时段任务，您无法为 `--max-errors` 和 `--max-concurrency` 提供值。作为替代方式，系统会插入一个占位符值 `1`，该值可能会在响应诸如 [https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-maintenance-window-tasks.html) 和 [https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-maintenance-window-task.html) 等命令时发出报告。这些值不影响任务的运行，可以忽略。  
有关不需要目标的维护时段任务的信息，请参阅 [注册不含目标的维护时段任务](maintenance-windows-targetless-tasks.md)。

------
#### [ PowerShell ]

   ```
   Register-SSMTaskWithMaintenanceWindow `
   -WindowId window ID `
   -Name "task name" `
   -TaskArn "runbook name" `
   -Target @{ Key="targets";Values="value" } `
   -ServiceRoleArn "IAM role arn" `
   -TaskType "AUTOMATION" `
   -Automation_Parameter @{ "task parameter"="task parameter value"} `
   -Priority task priority `
   -MaxConcurrency 10% `
   -MaxError 5
   ```

**注意**  
如果使用 AWS Tools for PowerShell 将自动化配置为注册任务，请使用 `-Automation_Parameter` 参数指定在任务运行时为其传递的参数。不要使用 `-TaskParameters` 参数。`-TaskParameters` 参数是一个旧参数。  
对于没有指定目标的维护时段任务，您无法为 `-MaxError` 和 `-MaxConcurrency` 提供值。作为替代方式，系统会插入一个占位符值 1，该值可能会在响应诸如 `Get-SSMMaintenanceWindowTaskList` 和 `Get-SSMMaintenanceWindowTask` 等命令时发出报告。这些值不影响任务的运行，可以忽略。  
有关不需要目标的维护时段任务的信息，请参阅 [注册不含目标的维护时段任务](maintenance-windows-targetless-tasks.md)。

------

   以下示例将自动化配置为具有优先级 1 的维护时段注册任务。它还演示了省略 `--targets`、`--max-errors` 和 `--max-concurrency` 选项以执行无目标维护时段任务。自动化使用 `AWS-StartEC2Instance` 文档和指定的自动化担任角色启动在维护时段中注册为目标的 EC2 实例。在任何给定时间，维护时段最多在 5 个实例上同时运行自动化。此外，如果错误计数超过 1，注册任务将以特定执行间隔在更多实例上停止运行。

------
#### [ Linux & macOS ]

   ```
   aws ssm register-task-with-maintenance-window \
   --window-id mw-0c50858d01EXAMPLE \
   --name StartEC2Instances \
   --task-arn AWS-StartEC2Instance \
   --service-role-arn arn:aws:iam::123456789012:role/MaintenanceWindowRole \
   --task-type AUTOMATION \
   --task-invocation-parameters "{\"Automation\":{\"Parameters\":{\"InstanceId\":[\"{{TARGET_ID}}\"],\"AutomationAssumeRole\":[\"arn:aws:iam::123456789012:role/AutomationAssumeRole\"]}}}" \
   --priority 1
   ```

------
#### [ Windows ]

   ```
   aws ssm register-task-with-maintenance-window ^
   --window-id mw-0c50858d01EXAMPLE ^
   --name StartEC2Instances ^
   --task-arn AWS-StartEC2Instance ^
   --service-role-arn arn:aws:iam::123456789012:role/MaintenanceWindowRole ^
   --task-type AUTOMATION ^
   --task-invocation-parameters "{\"Automation\":{\"Parameters\":{\"InstanceId\":[\"{{TARGET_ID}}\"],\"AutomationAssumeRole\":[\"arn:aws:iam::123456789012:role/AutomationAssumeRole\"]}}}" ^
   --priority 1
   ```

------
#### [ PowerShell ]

   ```
   Register-SSMTaskWithMaintenanceWindow `
   -WindowId mw-0c50858d01EXAMPLE `
   -Name "StartEC2" `
   -TaskArn "AWS-StartEC2Instance" `
   -ServiceRoleArn "arn:aws:iam::123456789012:role/MaintenanceWindowRole" `
   -TaskType "AUTOMATION" `
   -Automation_Parameter @{ "InstanceId"="{{TARGET_ID}}";"AutomationAssumeRole"="arn:aws:iam::123456789012:role/AutomationAssumeRole" } `
   -Priority 1
   ```

------

   该命令返回新的注册任务的详细信息，类似于以下内容。

------
#### [ Linux & macOS ]

   ```
   {
   "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
   }
   ```

------
#### [ Windows ]

   ```
   {
   "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE"
   }
   ```

------
#### [ PowerShell ]

   ```
   4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------

1. 要查看注册的任务，请运行以下命令。将 *maintenance windows ID* 替换为您自己的信息。

------
#### [ Linux & macOS ]

   ```
   aws ssm describe-maintenance-window-tasks \
   --window-id maintenance window ID
   ```

------
#### [ Windows ]

   ```
   aws ssm describe-maintenance-window-tasks ^
   --window-id maintenance window ID
   ```

------
#### [ PowerShell ]

   ```
   Get-SSMMaintenanceWindowTaskList `
   -WindowId maintenance window ID
   ```

------

   系统将返回类似于以下内容的信息。

------
#### [ Linux & macOS ]

   ```
   {
   "Tasks": [
       {
           "ServiceRoleArn": "arn:aws:iam::123456789012:role/MaintenanceWindowRole",
           "MaxErrors": "1",
           "TaskArn": "AWS-StartEC2Instance",
           "MaxConcurrency": "1",
           "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
           "TaskParameters": {},
           "Priority": 1,
           "WindowId": "mw-0c50858d01EXAMPLE",
           "Type": "AUTOMATION",
           "Targets": [
           ],
           "Name": "StartEC2"
       }
   ]
   }
   ```

------
#### [ Windows ]

   ```
   {
   "Tasks": [
       {
           "ServiceRoleArn": "arn:aws:iam::123456789012:role/MaintenanceWindowRole",
           "MaxErrors": "1",
           "TaskArn": "AWS-StartEC2Instance",
           "MaxConcurrency": "1",
           "WindowTaskId": "4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE",
           "TaskParameters": {},
           "Priority": 1,
           "WindowId": "mw-0c50858d01EXAMPLE",
           "Type": "AUTOMATION",
           "Targets": [
           ],
           "Name": "StartEC2"
       }
   ]
   }
   ```

------
#### [ PowerShell ]

   ```
   Description    : 
   LoggingInfo    : 
   MaxConcurrency : 5
   MaxErrors      : 1
   Name           : StartEC2
   Priority       : 1
   ServiceRoleArn : arn:aws:iam::123456789012:role/MaintenanceWindowRole
   Targets        : {}
   TaskArn        : AWS-StartEC2Instance
   TaskParameters : {}
   Type           : AUTOMATION
   WindowId       : mw-0c50858d01EXAMPLE
   WindowTaskId   : 4f7ca192-7e9a-40fe-9192-5cb15EXAMPLE
   ```

------

# Systems Manager 自动化操作参考
自动化操作参考

此参考介绍可在自动化运行手册中指定的自动化操作。Automation 是 AWS Systems Manager 中的一项工具。这些操作不能用于其他类型的 Systems Manager (SSM) 文档。有关其他 SSM 文档类型插件的信息，请参阅 [命令文档插件参考](documents-command-ssm-plugin-reference.md)。

Systems Manager 自动化会运行自动化运行手册中定义的步骤。每个步骤都与特定操作关联。此操作确定本步的输入、行为和输出。在运行手册的 `mainSteps` 部分定义步骤。

您无需指定操作或步骤的输出。由与本步关联的操作预先确定输出。当您在运行手册中指定步骤输入时，可以引用前面某步中的一个或多个输出。例如，您可以使 `aws:runInstances` 的输出可用于后续的 `aws:runCommand` 操作。还可以在运行手册的 `Output` 部分引用前面步骤中的输出。

**重要**  
如果您运行使用 AWS Identity and Access Management (IAM) 服务角色调用其他服务的自动化工作流程，请注意必须使用权限将该服务角色配置为调用这些服务。该要求适用于所有 AWS 自动化运行手册（`AWS-*` 运行手册），例如 `AWS-ConfigureS3BucketLogging`、`AWS-CreateDynamoDBBackup` 和 `AWS-RestartEC2Instance` 运行手册等。对于您创建的任何自定义自动化运行手册，如果这些文档使用调用其他服务的操作来调用其他 AWS 服务，则此要求同样适用。例如，如果使用 `aws:executeAwsApi`、`aws:createStack` 或 `aws:copyImage` 操作，则您必须配置具有权限的服务角色来调用这些服务。您可以将 IAM 内联策略添加到该角色，从而向其他 AWS 服务授予权限。有关更多信息，请参阅 [（可选）添加自动化内联策略或客户管理型策略来调用其他 AWS 服务](automation-setup-iam.md#add-inline-policy)。

**Topics**
+ [

## 所有操作共享的属性
](#automation-common)
+ [

# `aws:approve` – 暂停自动化以进行手动批准
](automation-action-approve.md)
+ [

# `aws:assertAwsResourceProperty` - 断言 AWS 资源状态或事件状态
](automation-action-assertAwsResourceProperty.md)
+ [

# `aws:branch` – 运行条件自动化步骤
](automation-action-branch.md)
+ [

# `aws:changeInstanceState` – 更改或声明实例状态
](automation-action-changestate.md)
+ [

# `aws:copyImage` – 复制或加密Amazon Machine Image
](automation-action-copyimage.md)
+ [

# `aws:createImage` – 创建亚马逊机器映像
](automation-action-create.md)
+ [

# `aws:createStack` – 创建 CloudFormation 堆栈。
](automation-action-createstack.md)
+ [

# `aws:createTags` - 为 AWS 资源创建标签
](automation-action-createtag.md)
+ [

# `aws:deleteImage` – 删除亚马逊机器映像
](automation-action-delete.md)
+ [

# `aws:deleteStack` - 删除 CloudFormation 堆栈。
](automation-action-deletestack.md)
+ [

# `aws:executeAutomation` - 运行另一个自动化
](automation-action-executeAutomation.md)
+ [

# `aws:executeAwsApi` - 调用并运行 AWS API 操作
](automation-action-executeAwsApi.md)
+ [

# `aws:executeScript` - 运行脚本
](automation-action-executeScript.md)
+ [

# `aws:executeStateMachine` - 运行 AWS Step Functions 状态机。
](automation-action-executeStateMachine.md)
+ [

# `aws:invokeWebhook` – 调用 Automation Webhook 集成
](invoke-webhook.md)
+ [

# `aws:invokeLambdaFunction` – 调用 AWS Lambda 函数
](automation-action-lamb.md)
+ [

# `aws:loop` – 迭代自动化中的步骤
](automation-action-loop.md)
+ [

# `aws:pause` - 暂停自动化
](automation-action-pause.md)
+ [

# `aws:runCommand` - 在托管实例上运行命令
](automation-action-runcommand.md)
+ [

# `aws:runInstances` – 启动 Amazon EC2 实例
](automation-action-runinstance.md)
+ [

# `aws:sleep` - 延迟自动化
](automation-action-sleep.md)
+ [

# `aws:updateVariable` – 更新运行手册变量的值
](automation-action-update-variable.md)
+ [

# `aws:waitForAwsResourceProperty` - 等待 AWS 资源属性
](automation-action-waitForAwsResourceProperty.md)
+ [

# 自动化系统变量
](automation-variables.md)

## 所有操作共享的属性


通用属性是位于所有操作中的参数或选项。一些选项定义了步骤的行为，例如，等待步骤完成的时间以及在步骤失败时采取的措施。以下属性是所有操作的通用属性。

[description](#descriptProp)  
您提供的描述运行手册或步骤目的的信息。  
类型：字符串  
必需：否

[name](#nameProp)  
在运行手册的所有步骤名称中必须唯一的标识符。  
类型：字符串  
允许的模式：[a-zA-Z0-9\$1]\$1\$1  
必需：是

[action](#actProp)  
步骤要运行的操作的名称。[`aws:runCommand` - 在托管实例上运行命令](automation-action-runcommand.md) 是可在此处指定的操作的示例。本文档提供有关所有可用操作的详细信息。  
类型：字符串  
必需：是

[maxAttempts](#maxProp)  
在发生故障的情况下应重试步骤的次数。如果值大于 1，则直到所有重试尝试失败后，才会将此步骤视为失败。默认值是 1。  
类型：整数  
必需：否

[timeoutSeconds](#timeProp)  
步骤的超时值。如果超时并且 `maxAttempts` 的值大于 1，则本步未考虑超时，直至已尝试所有重试。  
类型：整数  
必需：否

[onFailure](#failProp)  
指示自动化在失败时是应停止、继续还是转到其他步骤。该选项的默认值为 abort。  
类型：字符串  
有效值：Abort \$1 Continue \$1 step:*step\$1name*  
必需：否

[onCancel](#canProp)  
指示在用户取消自动化时，自动化应该转到哪个步骤。自动化将最多运行两分钟的取消工作流程。  
类型：字符串  
有效值：Abort \$1 step:*step\$1name*  
必需：否  
`onCancel` 属性不支持移动到以下操作：  
+ `aws:approve`
+ `aws:copyImage`
+ `aws:createImage`
+ `aws:createStack`
+ `aws:createTags`
+ `aws:loop`
+ `aws:pause`
+ `aws:runInstances`
+ `aws:sleep`

[isEnd](#endProp)  
此选项在特定步骤结束时停止自动化。如果步骤失败或成功，自动化执行将停止。默认值为 False。  
类型：布尔值  
有效值：true \$1 false  
必需：否

[nextStep](#nextProp)  
指定在成功完成自动化中的一个步骤后，接下来处理哪个步骤。  
类型：字符串  
必需：否

[isCritical](#critProp)  
将一个步骤指定为成功完成自动化的关键步骤。如果具有此分派的步骤失败，自动化会将自动化的最终状态报告为失败。仅当您在步骤中明确定义此属性时，才会计算该属性。如果 `onFailure` 属性在某个步骤中设定为 `Continue`，则此值默认为 False。否则，该选项的默认值为 True。  
类型：布尔值  
有效值：true \$1 false  
必需：否

[inputs](#inProp)  
特定于操作的属性。  
类型：映射  
必需：是

### 示例


```
---
description: "Custom Automation Example"
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 run this runbook."
    default: ''
  InstanceId:
      type: String
      description: "(Required) The Instance Id whose root EBS volume you want to restore the latest Snapshot."
      default: ''
mainSteps:
- name: getInstanceDetails
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: DescribeInstances
    InstanceIds:
    - "{{ InstanceId }}"
  outputs:
    - Name: availabilityZone
      Selector: "$.Reservations[0].Instances[0].Placement.AvailabilityZone"
      Type: String
    - Name: rootDeviceName
      Selector: "$.Reservations[0].Instances[0].RootDeviceName"
      Type: String
  nextStep: getRootVolumeId
- name: getRootVolumeId
  action: aws:executeAwsApi
  maxAttempts: 3
  onFailure: Abort
  inputs:
    Service: ec2
    Api: DescribeVolumes
    Filters:
    -  Name: attachment.device
       Values: ["{{ getInstanceDetails.rootDeviceName }}"]
    -  Name: attachment.instance-id
       Values: ["{{ InstanceId }}"]
  outputs:
    - Name: rootVolumeId
      Selector: "$.Volumes[0].VolumeId"
      Type: String
  nextStep: getSnapshotsByStartTime
- name: getSnapshotsByStartTime
  action: aws:executeScript
  timeoutSeconds: 45
  onFailure: Abort
  inputs:
    Runtime: python3.8
    Handler: getSnapshotsByStartTime
    InputPayload:
      rootVolumeId : "{{ getRootVolumeId.rootVolumeId }}"
    Script: |-
      def getSnapshotsByStartTime(events,context):
        import boto3

        #Initialize client
        ec2 = boto3.client('ec2')
        rootVolumeId = events['rootVolumeId']
        snapshotsQuery = ec2.describe_snapshots(
          Filters=[
            {
              "Name": "volume-id",
              "Values": [rootVolumeId]
            }
          ]
        )
        if not snapshotsQuery['Snapshots']:
          noSnapshotFoundString = "NoSnapshotFound"
          return { 'noSnapshotFound' : noSnapshotFoundString }
        else:
          jsonSnapshots = snapshotsQuery['Snapshots']
          sortedSnapshots = sorted(jsonSnapshots, key=lambda k: k['StartTime'], reverse=True)
          latestSortedSnapshotId = sortedSnapshots[0]['SnapshotId']
          return { 'latestSnapshotId' : latestSortedSnapshotId }
  outputs:
  - Name: Payload
    Selector: $.Payload
    Type: StringMap
  - Name: latestSnapshotId
    Selector: $.Payload.latestSnapshotId
    Type: String
  - Name: noSnapshotFound
    Selector: $.Payload.noSnapshotFound
    Type: String 
  nextStep: branchFromResults
- name: branchFromResults
  action: aws:branch
  onFailure: Abort
  onCancel: step:startInstance
  inputs:
    Choices:
    - NextStep: createNewRootVolumeFromSnapshot
      Not:
        Variable: "{{ getSnapshotsByStartTime.noSnapshotFound }}"
        StringEquals: "NoSnapshotFound"
  isEnd: true
- name: createNewRootVolumeFromSnapshot
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: CreateVolume
    AvailabilityZone: "{{ getInstanceDetails.availabilityZone }}"
    SnapshotId: "{{ getSnapshotsByStartTime.latestSnapshotId }}"
  outputs:
    - Name: newRootVolumeId
      Selector: "$.VolumeId"
      Type: String
  nextStep: stopInstance
- name: stopInstance
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: StopInstances
    InstanceIds:
    - "{{ InstanceId }}"
  nextStep: verifyVolumeAvailability
- name: verifyVolumeAvailability
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 120
  inputs:
    Service: ec2
    Api: DescribeVolumes
    VolumeIds:
    - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
    PropertySelector: "$.Volumes[0].State"
    DesiredValues:
    - "available"
  nextStep: verifyInstanceStopped
- name: verifyInstanceStopped
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 120
  inputs:
    Service: ec2
    Api: DescribeInstances
    InstanceIds:
    - "{{ InstanceId }}"
    PropertySelector: "$.Reservations[0].Instances[0].State.Name"
    DesiredValues:
    - "stopped"
  nextStep: detachRootVolume
- name: detachRootVolume
  action: aws:executeAwsApi
  onFailure: Abort
  isCritical: true
  inputs:
    Service: ec2
    Api: DetachVolume
    VolumeId: "{{ getRootVolumeId.rootVolumeId }}"
  nextStep: verifyRootVolumeDetached
- name: verifyRootVolumeDetached
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 30
  inputs:
    Service: ec2
    Api: DescribeVolumes
    VolumeIds:
    - "{{ getRootVolumeId.rootVolumeId }}"
    PropertySelector: "$.Volumes[0].State"
    DesiredValues:
    - "available"
  nextStep: attachNewRootVolume
- name: attachNewRootVolume
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: AttachVolume
    Device: "{{ getInstanceDetails.rootDeviceName }}"
    InstanceId: "{{ InstanceId }}"
    VolumeId: "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
  nextStep: verifyNewRootVolumeAttached
- name: verifyNewRootVolumeAttached
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 30
  inputs:
    Service: ec2
    Api: DescribeVolumes
    VolumeIds:
    - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
    PropertySelector: "$.Volumes[0].Attachments[0].State"
    DesiredValues:
    - "attached"
  nextStep: startInstance
- name: startInstance
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: StartInstances
    InstanceIds:
    - "{{ InstanceId }}"
```

# `aws:approve` – 暂停自动化以进行手动批准


临时暂停自动化，直至指定委托人批准或拒绝操作。在达到所需批准数后，自动化执行将恢复。您可以将批准步骤插入到运行手册的 `mainSteps` 部分。

**注意**  
此操作并不支持多账户和区域自动化。此操作的默认超时时间为 7 天（604800 秒），最长时间为 30 天（2592000 秒）。您可以通过指定 `aws:approve` 步骤的 `timeoutSeconds` 参数来限制或延长超时。

在以下示例中，`aws:approve` 操作临时暂停自动化，直至一个审批者接受或拒绝自动化。批准后，此自动化将运行简单的 PowerShell 命令。

------
#### [ YAML ]

```
---
description: RunInstancesDemo1
schemaVersion: '0.3'
assumeRole: "{{ assumeRole }}"
parameters:
  assumeRole:
    type: String
  message:
    type: String
mainSteps:
- name: approve
  action: aws:approve
  timeoutSeconds: 1000
  onFailure: Abort
  inputs:
    NotificationArn: arn:aws:sns:us-east-2:12345678901:AutomationApproval
    Message: "{{ message }}"
    MinRequiredApprovals: 1
    Approvers:
    - arn:aws:iam::12345678901:user/AWS-User-1
- name: run
  action: aws:runCommand
  inputs:
    InstanceIds:
    - i-1a2b3c4d5e6f7g
    DocumentName: AWS-RunPowerShellScript
    Parameters:
      commands:
      - date
```

------
#### [ JSON ]

```
{
   "description":"RunInstancesDemo1",
   "schemaVersion":"0.3",
   "assumeRole":"{{ assumeRole }}",
   "parameters":{
      "assumeRole":{
         "type":"String"
      },
      "message":{
         "type":"String"
      }
   },
   "mainSteps":[
      {
         "name":"approve",
         "action":"aws:approve",
         "timeoutSeconds":1000,
         "onFailure":"Abort",
         "inputs":{
            "NotificationArn":"arn:aws:sns:us-east-2:12345678901:AutomationApproval",
            "Message":"{{ message }}",
            "MinRequiredApprovals":1,
            "Approvers":[
               "arn:aws:iam::12345678901:user/AWS-User-1"
            ]
         }
      },
      {
         "name":"run",
         "action":"aws:runCommand",
         "inputs":{
            "InstanceIds":[
               "i-1a2b3c4d5e6f7g"
            ],
            "DocumentName":"AWS-RunPowerShellScript",
            "Parameters":{
               "commands":[
                  "date"
               ]
            }
         }
      }
   ]
}
```

------

您可以在控制台中批准或拒绝等待批准的自动化。

**批准或拒绝等待的自动化**

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

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

1. 选择状态为**正在等待**的自动化旁边的选项。  
![\[访问批准/拒绝自动化页面\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/automation-approve-action-aws.png)

1. 选择**批准/拒绝**。

1. 查看自动化的详细信息。

1. 选择**批准**或**拒绝**，键入评论（可选），然后选择**提交**。

**输入示例**

------
#### [ YAML ]

```
NotificationArn: arn:aws:sns:us-west-1:12345678901:Automation-ApprovalRequest
Message: Please approve this step of the Automation.
MinRequiredApprovals: 3
Approvers:
- IamUser1
- IamUser2
- arn:aws:iam::12345678901:user/IamUser3
- arn:aws:iam::12345678901:role/IamRole
```

------
#### [ JSON ]

```
{
   "NotificationArn":"arn:aws:sns:us-west-1:12345678901:Automation-ApprovalRequest",
   "Message":"Please approve this step of the Automation.",
   "MinRequiredApprovals":3,
   "Approvers":[
      "IamUser1",
      "IamUser2",
      "arn:aws:iam::12345678901:user/IamUser3",
      "arn:aws:iam::12345678901:role/IamRole"
   ]
}
```

------

NotificationArn  
用于批准自动化的 Amazon Resource Name (即 ARN，属于 Amazon Simple Notification Service (Amazon SNS)) 的主题。当您在运行手册中指定 `aws:approve` 步骤时，自动化 将向此主题发送消息，以让委托人知道必须批准或拒绝自动化步骤。Amazon SNS 主题的标题必须使用前缀“自动化”。  
类型：字符串  
必需：否

消息  
发送批准请求时要包含在 Amazon SNS 主题中的信息。最大消息长度为 4096 个字符。  
类型：字符串  
必需：否

MinRequiredApprovals  
恢复自动化所需的最小批准数。如果您未指定值，系统将默认为 1。此参数的值必须为正数。此参数的值不能超过 `Approvers` 参数定义的审批者数。  
类型：整数  
必需：否

Approvers  
能够批准或拒绝操作的经 AWS 身份验证的委托人的列表。最大审批者数量为 10。您可使用以下任意格式指定委托人：  
+ 一个用户名称
+ 用户 ARN
+ IAM 角色 ARN
+ IAM 担任角色 ARN
类型：StringList  
是否必需：是

EnhancedApprovals  
此输入仅用于 Change Manager 模板。能够批准或拒绝操作的经过 AWS 身份验证的主体、IAM 主体的类型以及最少批准者数量的列表。以下是示例：  

```
schemaVersion: "0.3"
emergencyChange: false
autoApprovable: false
mainSteps:
    - name: ApproveAction1
    action: aws:approve
    timeoutSeconds: 604800
    inputs:
        Message: Please approve this change request
        MinRequiredApprovals: 3
        EnhancedApprovals:
        Approvers:
            - approver: John Stiles
            type: IamUser
            minRequiredApprovals: 0
            - approver: Ana Carolina Silva
            type: IamUser
            minRequiredApprovals: 0
            - approver: GroupOfThree
            type: IamGroup
            minRequiredApprovals: 0
            - approver: RoleOfTen
            type: IamRole
            minRequiredApprovals: 0
```
类型：StringList  
是否必需：是

**输出**

ApprovalStatus  
步骤的批准状态。状态可以为下列状态之一：已批准、已拒绝或正在等待。“正在等待”意味着自动化正在等待来自审批者的输入。  
类型：字符串

ApproverDecisions  
包括每位审批者的批准决定的 JSON 映射。  
类型：MapList

# `aws:assertAwsResourceProperty` - 断言 AWS 资源状态或事件状态


`aws:assertAwsResourceProperty` 操作可用于对特定自动化步骤的资源状态或事件状态进行断言。

**注意**  
`aws:assertAwsResourceProperty` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

有关如何使用此操作的更多示例，请参阅 [其他运行手册示例](automation-document-examples.md)。

**Input**  
由您选择的 API 操作定义的输入。

------
#### [ YAML ]

```
action: aws:assertAwsResourceProperty
inputs:
  Service: The official namespace of the service
  Api: The API operation or method name
  API operation inputs or parameters: A value
  PropertySelector: Response object
  DesiredValues:
  - Desired property values
```

------
#### [ JSON ]

```
{
  "action": "aws:assertAwsResourceProperty",
  "inputs": {
    "Service":"The official namespace of the service",
    "Api":"The API operation or method name",
    "API operation inputs or parameters":"A value",
    "PropertySelector": "Response object",
    "DesiredValues": [
      "Desired property values"
    ]
  }
}
```

------

服务  
包含要运行的 API 操作的 AWS 服务命名空间。例如，Systems Manager 的命名空间为 `ssm`。Amazon EC2 的命名空间为 `ec2`。您可以在《AWS CLI 命令参考》的[可用服务](https://docs.aws.amazon.com/cli/latest/reference/#available-services)部分查看支持的 AWS 服务命名空间列表。  
类型：字符串  
是否必需：是

API  
要运行的 API 操作的名称。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看 API 操作（也称为方法）。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon Relational Database Service (Amazon RDS) 的所有 API 操作（方法）。  
类型：字符串  
是否必需：是

API 操作输入  
一个或多个 API 操作输入。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看可用的输入（也称为参数）。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon RDS 的所有方法。选择 [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) 方法并向下滚动以查看可用的参数，例如 **DBInstanceIdentifier**、**Name** 和 **Values**。使用以下格式指定多个输入。  

```
inputs:
  Service: The official namespace of the service
  Api: The API operation name
  API input 1: A value
  API Input 2: A value
  API Input 3: A value
```

```
"inputs":{
      "Service":"The official namespace of the service",
      "Api":"The API operation name",
      "API input 1":"A value",
      "API Input 2":"A value",
      "API Input 3":"A value"
}
```
类型：由选择的 API 操作决定  
是否必需：是

PropertySelector  
响应对象中特定属性的 JSONPath。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看响应对象。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon RDS 的所有方法：选择 [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) 方法，然后向下滚动到**响应结构**部分。**DBInstances** 被列为响应对象。  
类型：字符串  
是否必需：是

DesiredValues  
要继续自动化的预期状态。如果指定布尔值，则必须使用大写字母，例如 True 或 False。  
类型：StringList  
是否必需：是

# `aws:branch` – 运行条件自动化步骤


`aws:branch` 操作让您能够创建一个动态自动化，该自动化在一个步骤中评估不同选择，然后根据评估结果跳转到运行手册中的另一个步骤。

在为步骤指定 `aws:branch` 操作时，请指定自动化必须评估的 `Choices`。`Choices` 可以基于您在运行手册的 `Parameters` 部分中指定的值，也可以基于上一步的输出生成的动态值。自动化使用布尔表达式评估每个选择。如果第一个选择为真，则自动化跳转到为此选择指定的步骤。如果第一个选择为假，则自动化评估下一个选择。自动化继续评估每个选择，直到遇到结果为真的选择。然后，自动化跳转到为结果为真的选择指定的步骤。

如果所有选择都为假，则自动化检查该步骤是否包含 `default` 值。默认值定义当所有选择都为假时自动化应跳转到的步骤。如果没有为该步骤指定 `default` 值，则自动化处理运行手册中的下一个步骤。

`aws:branch` 操作通过组合使用 `And`、`Not` 和 `Or` 运算符来支持复杂的选择评估。有关如何使用 `aws:branch` 的更多信息，包括使用不同运算符的示例运行手册和示例，请参阅 [在运行手册中使用条件语句](automation-branch-condition.md)。

**Input**  
在步骤中指定一个或多个 `Choices`。`Choices` 可以基于您在运行手册的 `Parameters` 部分中指定的值，也可以基于上一步的输出生成的动态值。下面是一个评估参数的 YAML 示例。

```
mainSteps:
- name: chooseOS
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runWindowsCommand
      Variable: "{{Name of a parameter defined in the Parameters section. For example: OS_name}}"
      StringEquals: windows
    - NextStep: runLinuxCommand
      Variable: "{{Name of a parameter defined in the Parameters section. For example: OS_name}}"
      StringEquals: linux
    Default:
      sleep3
```

下面是一个评估上一步输出的 YAML 示例。

```
mainSteps:
- name: chooseOS
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{Name of a response object. For example: GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{Name of a response object. For example: GetInstance.platform}}"
      StringEquals: Linux
    Default:
      sleep3
```

Choices  
自动化 在确定下一个要处理的步骤时应评估的一个或多个表达式。通过使用布尔表达式对选择进行评估。每个选择都必须定义以下选项：  
+ **NextStep**：当指定的选择为真时，要处理的运行手册中的下一个步骤。
+ **变量**：指定在运行手册的 `Parameters` 部分中定义的参数名称。或指定来自运行手册中上一步的输出对象。有关为 `aws:branch` 创建变量的更多信息，请参阅 [关于创建输出变量](automation-branch-condition.md#branch-action-output)。
+ **运算**：用于评估选择的标准。`aws:branch` 操作支持以下运算：

**字符串运算**
  + 字符串等于
  + EqualsIgnoreCase
  + StartsWith
  + EndsWith
  + 包含

**数值运算**
  + NumericEquals
  + NumericGreater
  + NumericLesser
  + NumericGreaterOrEquals
  + NumericLesser
  + NumericLesserOrEquals

**布尔运算**
  + BooleanEquals
**重要**  
创建运行手册时，系统将验证运行手册中的每个操作。在尝试创建运行手册时，如果某个操作不受支持，系统会返回错误。

默认  
当所有 `Choices` 都为假时，自动化应跳转到的步骤的名称。  
类型：字符串  
必需：否

**注意**  
`aws:branch` 操作支持 `And`、`Or` 和 `Not` 运算符。有关使用运算符的 `aws:branch` 的示例，请参阅 [在运行手册中使用条件语句](automation-branch-condition.md)。

# `aws:changeInstanceState` – 更改或声明实例状态


更改或断言实例的状态。

此操作可在断言模式下使用（不要运行 API 来更改状态，而应验证实例是否处于预期状态。) 要使用断言模式，请将 `CheckStateOnly` 参数设置为 True。在 Windows Server 上运行 Sysprep 命令时，此模式很有用。该命令是一种可在后台长时间运行的异步命令。您可以确保在创建 Amazon Machine Image (AMI) 之前停止实例。

**注意**  
此操作的默认超时值为 3600 秒（1 小时）。您可以通过指定 `aws:changeInstanceState` 步骤的 `timeoutSeconds` 参数来限制或延长超时。

**注意**  
`aws:changeInstanceState` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**输入**

------
#### [ YAML ]

```
name: stopMyInstance
action: aws:changeInstanceState
maxAttempts: 3
timeoutSeconds: 3600
onFailure: Abort
inputs:
  InstanceIds:
  - i-1234567890abcdef0
  CheckStateOnly: true
  DesiredState: stopped
```

------
#### [ JSON ]

```
{
    "name":"stopMyInstance",
    "action": "aws:changeInstanceState",
    "maxAttempts": 3,
    "timeoutSeconds": 3600,
    "onFailure": "Abort",
    "inputs": {
        "InstanceIds": ["i-1234567890abcdef0"],
        "CheckStateOnly": true,
        "DesiredState": "stopped"
    }
}
```

------

InstanceIds  
实例的 ID。  
类型：StringList  
是否必需：是

CheckStateOnly  
如果为 false，请将实例状态设置为预期状态。如果为 true，请使用轮询断言预期状态。  
默认值：`false`  
类型：布尔值  
必需：否

DesiredState  
预期状态。设置为 `running` 时，此操作在完成之前等待 Amazon EC2 的状态变为 `Running`、实例状态变为 `OK`、系统状态变为 `OK`。  
类型：字符串  
有效值：`running` \$1`stopped` \$1`terminated`  
是否必需：是

Force  
如果设置此项，则强制停止实例。则该实例没有机会来刷新文件系统缓存或文件系统元数据。如果您使用此选项，则必须执行文件系统检查和修复流程。我们不建议将该选项用于 Windows Server 的 EC2 实例。  
类型：布尔值  
必需：否

AdditionalInfo  
预留。  
类型：字符串  
必需：否

**Output**  
无

# `aws:copyImage` – 复制或加密Amazon Machine Image


将 Amazon Machine Image (AMI) 从任何 AWS 区域 复制到当前区域中。此操作还可以对新的 AMI 进行加密。

**注意**  
`aws:copyImage` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**Input**  
此操作支持大多数 `CopyImage` 参数。有关更多信息，请参阅 [CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CopyImage.html)。

以下示例是在首尔地区创建 AMI 的副本（`SourceImageID`：ami-0fe10819。`SourceRegion`：ap-northeast-2）。新的 AMI 将复制到您启动自动化操作的区域。将对复制的 AMI 进行加密，因为可选 `Encrypted` 标记将设置为 `true`。

------
#### [ YAML ]

```
name: createEncryptedCopy
action: aws:copyImage
maxAttempts: 3
onFailure: Abort
inputs:
  SourceImageId: ami-0fe10819
  SourceRegion: ap-northeast-2
  ImageName: Encrypted Copy of LAMP base AMI in ap-northeast-2
  Encrypted: true
```

------
#### [ JSON ]

```
{   
    "name": "createEncryptedCopy",
    "action": "aws:copyImage",
    "maxAttempts": 3,
    "onFailure": "Abort",
    "inputs": {
        "SourceImageId": "ami-0fe10819",
        "SourceRegion": "ap-northeast-2",
        "ImageName": "Encrypted Copy of LAMP base AMI in ap-northeast-2",
        "Encrypted": true
    }   
}
```

------

SourceRegion  
源 AMI 当前所在的区域。  
类型：字符串  
是否必需：是

SourceImageId  
要从源区域复制的 AMI ID。  
类型：字符串  
是否必需：是

ImageName  
新映像的名称。  
类型：字符串  
是否必需：是

ImageDescription  
目标映像的描述。  
类型：字符串  
必需：否

已加密  
对目标 AMI 进行加密。  
类型：布尔值  
必需：否

KmsKeyId  
在复制操作期间对映像快照进行加密时要使用的 AWS KMS key 的完整 Amazon Resource Name (ARN)。有关更多信息，请参阅 [CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/api_copyimage.html)。  
类型：字符串  
必需：否

ClientToken  
您为确保请求幂等性而提供的唯一、区分大小写的标识符。有关更多信息，请参阅 [CopyImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/api_copyimage.html)。  
类型：字符串  
必需：否Output

ImageId  
已复制映像的 ID。

ImageState  
已复制映像的状态。  
有效值：`available` \$1`pending` \$1`failed`

# `aws:createImage` – 创建亚马逊机器映像


从正在运行、正在停止或已停止的实例创建 Amazon Machine Image（AMI），并轮询 `ImageState` 是否为 `available`。

**注意**  
`aws:createImage` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**Input**  
此操作支持以下 `CreateImage` 参数。有关更多信息，请参阅 [CreateImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_CreateImage.html)。

------
#### [ YAML ]

```
name: createMyImage
action: aws:createImage
maxAttempts: 3
onFailure: Abort
inputs:
  InstanceId: i-1234567890abcdef0
  ImageName: AMI Created on{{global:DATE_TIME}}
  NoReboot: true
  ImageDescription: My newly created AMI
```

------
#### [ JSON ]

```
{
    "name": "createMyImage",
    "action": "aws:createImage",
    "maxAttempts": 3,
    "onFailure": "Abort",
    "inputs": {
        "InstanceId": "i-1234567890abcdef0",
        "ImageName": "AMI Created on{{global:DATE_TIME}}",
        "NoReboot": true,
        "ImageDescription": "My newly created AMI"
    }
}
```

------

InstanceId  
实例的 ID。  
类型：字符串  
是否必需：是

ImageName  
映像的名称。  
类型：字符串  
是否必需：是

ImageDescription  
映像的描述。  
类型：字符串  
必需：否

NoReboot  
一种布尔文本。  
默认情况下，Amazon Elastic Compute Cloud (Amazon EC2) 会尝试关闭并重新启动实例，然后再创建映像。如果**不重启**选项设置为 `true`，则 Amazon EC2 在创建映像前不会关闭实例。如果使用此选项，则无法保证所创建映像上的文件系统的完整性。  
如果您希望在从实例创建 AMI 映像后，该实例不运行，请先使用 [`aws:changeInstanceState` – 更改或声明实例状态](automation-action-changestate.md) 插件停止实例，然后在 **NoReboot** 选项设置为 `true` 的情况下使用此 `aws:createImage` 操作。  
类型：布尔值  
必需：否

BlockDeviceMappings  
适用于实例的块储存设备。  
类型：映射  
必需：否Output

ImageId  
新建映像的 ID。  
类型：字符串

ImageState  
映像的当前状态。如果状态为可用，则表示映像已成功注册，并且可用于启动实例。  
类型：字符串

# `aws:createStack` – 创建 CloudFormation 堆栈。


从模板创建 AWS CloudFormation 堆栈。

**注意**  
`aws:createStack` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

有关创建 CloudFormation 堆栈的补充信息，请参阅 *AWS CloudFormationAPI 参考*中的 [CreateStack](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html)。

**输入**

------
#### [ YAML ]

```
name: makeStack
action: aws:createStack
maxAttempts: 1
onFailure: Abort
inputs:
  Capabilities:
  - CAPABILITY_IAM
  StackName: myStack
  TemplateURL: http://s3.amazonaws.com/amzn-s3-demo-bucket/myStackTemplate
  TimeoutInMinutes: 5
  Parameters:
    - ParameterKey: LambdaRoleArn
      ParameterValue: "{{LambdaAssumeRole}}"
    - ParameterKey: createdResource
      ParameterValue: createdResource-{{automation:EXECUTION_ID}}
```

------
#### [ JSON ]

```
{
    "name": "makeStack",
    "action": "aws:createStack",
    "maxAttempts": 1,
    "onFailure": "Abort",
    "inputs": {
        "Capabilities": [
            "CAPABILITY_IAM"
        ],
        "StackName": "myStack",
        "TemplateURL": "http://s3.amazonaws.com/amzn-s3-demo-bucket/myStackTemplate",
        "TimeoutInMinutes": 5,
        "Parameters": [
          {
            "ParameterKey": "LambdaRoleArn",
            "ParameterValue": "{{LambdaAssumeRole}}"
          },
          {
            "ParameterKey": "createdResource",
            "ParameterValue": "createdResource-{{automation:EXECUTION_ID}}"
          }
    }
}
```

------

功能  
必须在 CloudFormatio 可以创建某些堆栈之前指定的值列表。一些堆栈模板中包含的资源会影响您的 AWS 账户中的权限。对于这些堆栈，您必须通过指定此参数来明确确认它们的功能。  
有效值包括 `CAPABILITY_IAM`、`CAPABILITY_NAMED_IAM` 和 `CAPABILITY_AUTO_EXPAND`。  
**CAPABILITY\$1IAM 和 CAPABILITY\$1NAMED\$1IAM**  
如果包含 IAM 资源，您可以指定任意一个功能。如果包含具有自定义名称的 IAM 资源，则必须指定 `CAPABILITY_NAMED_IAM`。如果您不指定此参数，则此操作会返回 `InsufficientCapabilities` 错误。以下资源要求您指定 `CAPABILITY_IAM` 或 `CAPABILITY_NAMED_IAM`。
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-accesskey.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-accesskey.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-group.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-group.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-instanceprofile.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-policy.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-policy.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-iam-role.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-user.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-user.html)
+ [https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-addusertogroup.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-iam-addusertogroup.html)
如果您的堆栈模板包含这些资源，我们建议您查看与之关联的所有权限并在必要时编辑其权限。  
有关更多信息，请参阅[确认 CloudFormation 模板中的 IAM 资源](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html#capabilities)。  
**CAPABILITY\$1AUTO\$1EXPAND**  
某些模板包含宏。宏对模板执行自定义处理，包括查找并替换等简单操作，以及整个模板的大幅转换。因此，用户通常会从已处理的模板创建更改集，这样他们便能在实际创建堆栈之前查看宏导致的更改。如果堆栈模板包含一个或多个宏，并且您选择直接从已处理的模板创建堆栈，而不首先查看更改集中生成的更改，则必须确认此功能。
有关更多信息，请参阅 *AWS CloudFormation用户指南*中的[使用 AWS CloudFormation 宏对模板执行自定义处理](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-macros.html)。  
类型：字符串的数组  
有效值：`CAPABILITY_IAM | CAPABILITY_NAMED_IAM | CAPABILITY_AUTO_EXPAND`  
必需：否

ClientRequestToken  
该 CreateStack 请求的唯一标识符。如果将此步骤中的 maxAttempts 设置为大于 1 的值，请指定此令牌。通过指定此令牌，CloudFormation 知道您未在尝试使用相同的名称创建新堆栈。  
类型：字符串  
必需：否  
长度限制：最小长度为 1。最大长度为 128。  
模式：[a-zA-Z0-9][-a-zA-Z0-9]\$1

DisableRollback  
如果堆栈创建失败，请设置为 `true` 以关闭堆栈回滚。  
Conditional：您可以指定 `DisableRollback` 参数或 `OnFailure` 参数，但不能同时指定。  
默认值：`false`  
类型：布尔值  
必需：否

NotificationARNs  
用于发布堆栈相关事件的 Amazon Simple Notification Service (Amazon SNS) 主题 ARN。您可以使用 Amazon SNS 控制台 [https://console.aws.amazon.com/sns/v3/home](https://console.aws.amazon.com/sns/v3/home) 查找 SNS 主题 ARN。  
类型：字符串的数组  
数组成员：最多 5 项。  
必需：否

OnFailure  
如果堆栈创建失败，确定要执行的操作。您必须指定 `DO_NOTHING`、`ROLLBACK` 或 `DELETE`。  
Conditional：您可以指定 `OnFailure` 参数或 `DisableRollback` 参数，但不能同时指定。  
默认值：`ROLLBACK`  
类型：字符串  
有效值:` DO_NOTHING | ROLLBACK | DELETE`  
必需：否

参数  
指定堆栈输入参数的 `Parameter` 结构列表。有关更多信息，请参阅[参数](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html)数据类型。  
类型：[参数](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Parameter.html)对象数组   
必需：否

ResourceTypes  
您有权用于此创建堆栈操作的模板资源类型。例如，`AWS::EC2::Instance`、`AWS::EC2::*` 或 `Custom::MyCustomInstance`。使用以下语法描述模板资源类型。  
+ 对于所有 AWS 资源：

  ```
  AWS::*
  ```
+ 对于所有自定义资源：

  ```
  Custom::*
  ```
+ 对于指定自定义资源：

  ```
  Custom::logical_ID
  ```
+ 对于特定 AWS 服务的所有资源：

  ```
  AWS::service_name::*
  ```
+ 对于特定的 AWS 资源：

  ```
  AWS::service_name::resource_logical_ID
  ```
如果资源类型列表不包括您创建的资源，那么堆栈创建将会失败。默认情况下，CloudFormation 授予对所有资源类型的权限。IAM 将此参数用于 IAM policy 中特定于云的条件密钥。有关更多信息，请参阅[使用 AWS Identity and Access Management 控制访问](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html)。  
类型：字符串的数组  
长度约束：最小长度为 1。最大长度为 256。  
必需：否

RoleARN  
CloudFormation 用于创建堆栈的 IAM 角色的 Amazon Resource Name (ARN)。CloudFormation 使用角色的凭证代表您进行调用。CloudFormation 始终将此角色用于堆栈上的所有未来操作。只要用户有权对堆栈进行操作，CloudFormation 会使用此角色，即使用户无权传递它。确保该角色授予最少的权限。  
如果您不指定值，则 CloudFormation 会使用之前与堆栈关联的角色。如果角色不可用，则 CloudFormation 会使用您的用户凭证生成的一个临时会话。  
类型：字符串  
长度约束：最小长度为 20。最大长度为 2048。  
必需：否

StackName  
与堆栈关联的名称。名称在您创建堆栈的区域中必须是唯一的。  
堆栈名称只能包含字母数字字符（区分大小写）和连字符。该名称必须以字母字符开头，且不得超过 128 个字符。
类型：字符串  
是否必需：是

StackPolicyBody  
包含堆栈策略正文的结构。有关更多信息，请参阅[防止更新堆栈资源](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html)。  
Conditional：您可以指定 `StackPolicyBody` 参数或 `StackPolicyURL` 参数，但不能同时指定。  
类型：字符串  
长度限制：最小长度为 1。长度上限为 16384。  
必需：否

StackPolicyURL  
包含堆栈策略的文件的位置。URL 指向的策略必须位于与堆栈处于同一区域的 S3 存储桶中。堆栈策略允许的最大文件大小为 16 KB。  
Conditional：您可以指定 `StackPolicyBody` 参数或 `StackPolicyURL` 参数，但不能同时指定。  
类型：字符串  
长度限制：最小长度为 1。长度上限为 1350。  
必需：否

Tags  
与此堆栈关联的键值对。CloudFormation 还可以将这些标签传播到堆栈中创建的资源。您可以指定最多 10 个标签。  
类型：[标签](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_Tag.html)对象数组   
必需：否

TemplateBody  
包含最小长度为 1 字节、最大长度为 51200 字节的模板正文的结构。有关更多信息，请参阅[模板剖析](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html)。  
Conditional：您可以指定 `TemplateBody` 参数或 `TemplateURL` 参数，但不能同时指定。  
类型：字符串  
长度限制：最小长度为 1。  
必需：否

TemplateURL  
包含模板正文的文件的位置。URL 必须指向一个位于 S3 存储桶中的模板。模板允许的最大大小为 460800 字节。有关更多信息，请参阅[模板剖析](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-anatomy.html)。  
Conditional：您可以指定 `TemplateBody` 参数或 `TemplateURL` 参数，但不能同时指定。  
类型：字符串  
长度限制：最小长度为 1。最大长度为 1024。  
必需：否

TimeoutInMinutes  
堆栈状态变为 `CREATE_FAILED` 前允许经过的时间。如果未设置 `DisableRollback` 或将其设置为 `false`，堆栈将被回滚。  
类型：整数  
有效范围：最小值为 1。  
必需：否

## 输出


StackId  
堆栈的唯一标识符。  
类型：字符串

StackStatus  
堆栈的当前状态。  
类型：字符串  
有效值：`CREATE_IN_PROGRESS | CREATE_FAILED | CREATE_COMPLETE | ROLLBACK_IN_PROGRESS | ROLLBACK_FAILED | ROLLBACK_COMPLETE | DELETE_IN_PROGRESS | DELETE_FAILED | DELETE_COMPLETE | UPDATE_IN_PROGRESS | UPDATE_COMPLETE_CLEANUP_IN_PROGRESS | UPDATE_COMPLETE | UPDATE_ROLLBACK_IN_PROGRESS | UPDATE_ROLLBACK_FAILED | UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS | UPDATE_ROLLBACK_COMPLETE | REVIEW_IN_PROGRESS`  
是否必需：是

StackStatusReason  
与堆栈状态相关联的成功或失败消息。  
类型：字符串  
必需：否  
有关更多信息，请参阅 [CreateStack](https://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_CreateStack.html)。

## 安全注意事项


您必须将以下策略分配给 IAM 自动化担任角色，才可以使用 `aws:createStack` 操作。有关担任角色的更多信息，请参阅 [任务 1：为自动化创建服务角色](automation-setup-iam.md#create-service-role)。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "sqs:*",
            "cloudformation:CreateStack",
            "cloudformation:DescribeStacks"
         ],
         "Resource":"*"
      }
   ]
}
```

------

# `aws:createTags` - 为 AWS 资源创建标签


为 Amazon Elastic Compute Cloud (Amazon EC2) 实例或 AWS Systems Manager 托管实例创建新标签。

**注意**  
`aws:createTags` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**Input**  
此操作支持大多数 Amazon EC2 `CreateTags` 和 Systems Manager `AddTagsToResource` 参数。有关更多信息，请参阅 [CreateTags](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/api_createtags.html) 和 [AddTagsToResource](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/api_addtagstoresource.html)。

以下示例说明如何为 Amazon Machine Image (AMI) 和实例添加标签以作为特定部门的生产资源。

------
#### [ YAML ]

```
name: createTags
action: aws:createTags
maxAttempts: 3
onFailure: Abort
inputs:
  ResourceType: EC2
  ResourceIds:
  - ami-9a3768fa
  - i-02951acd5111a8169
  Tags:
  - Key: production
    Value: ''
  - Key: department
    Value: devops
```

------
#### [ JSON ]

```
{
    "name": "createTags",
    "action": "aws:createTags",
    "maxAttempts": 3,
    "onFailure": "Abort",
    "inputs": {
        "ResourceType": "EC2",
        "ResourceIds": [
            "ami-9a3768fa",
            "i-02951acd5111a8169"
        ],
        "Tags": [
            {
                "Key": "production",
                "Value": ""
            },
            {
                "Key": "department",
                "Value": "devops"
            }
        ]
    }
}
```

------

ResourceIds  
要为其添加标签的资源的 ID。如果资源类型不是“EC2”，则此字段只能包含单个项目。  
类型：字符串列表  
是否必需：是

标签  
要与资源关联的标签。  
类型：映射列表  
是否必需：是

ResourceType  
要为其添加标签的资源的类型。如果未提供，则使用默认值“EC2”。  
类型：字符串  
必需：否  
有效值: `EC2` \$1 `ManagedInstance` \$1 `MaintenanceWindow` \$1 `Parameter`

**Output**  
无

# `aws:deleteImage` – 删除亚马逊机器映像


删除指定 Amazon Machine Image (AMI) 和所有的相关快照。

**注意**  
`aws:deleteImage` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**Input**  
此操作仅支持一个参数。有关更多信息，请参阅 [DeregisterImage](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeregisterImage.html) 和 [DeleteSnapshot](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_DeleteSnapshot.html) 的相关文档。

------
#### [ YAML ]

```
name: deleteMyImage
action: aws:deleteImage
maxAttempts: 3
timeoutSeconds: 180
onFailure: Abort
inputs:
  ImageId: ami-12345678
```

------
#### [ JSON ]

```
{
    "name": "deleteMyImage",
    "action": "aws:deleteImage",
    "maxAttempts": 3,
    "timeoutSeconds": 180,
    "onFailure": "Abort",
    "inputs": {
        "ImageId": "ami-12345678"
    }
}
```

------

ImageId  
要删除的映像的 ID。  
类型：字符串  
是否必需：是

**Output**  
无

# `aws:deleteStack` - 删除 CloudFormation 堆栈。


删除 AWS CloudFormation 堆栈。

**注意**  
`aws:deleteStack` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**输入**

------
#### [ YAML ]

```
name: deleteStack
action: aws:deleteStack
maxAttempts: 1
onFailure: Abort
inputs:
  StackName: "{{stackName}}"
```

------
#### [ JSON ]

```
{
   "name":"deleteStack",
   "action":"aws:deleteStack",
   "maxAttempts":1,
   "onFailure":"Abort",
   "inputs":{
      "StackName":"{{stackName}}"
   }
}
```

------

ClientRequestToken  
此 `DeleteStack` 请求的唯一标识符。如果您计划重试请求以便 CloudFormation 知道您未在尝试删除同名堆栈，请指定此令牌。您可以重试 `DeleteStack` 请求以验证 CloudFormation 是否收到了它们。  
类型：字符串  
长度限制：最小长度为 1。最大长度为 128。  
模式：[a-zA-Z][-a-zA-Z0-9]\$1  
必需：否

RetainResources.member.N  
此输入仅适用于处于 `DELETE_FAILED` 状态的堆栈。您想要保留的资源的逻辑资源 ID 的列表。在删除时，CloudFormation 删除堆栈，但不删除保留资源。  
如果无法删除某个资源（例如非空 S3 存储桶），但需要删除堆栈，则保留资源会很有用。  
类型：字符串数组  
必需：否

RoleARN  
CloudFormation 用于创建堆栈的 AWS Identity and Access Management (IAM) 角色的 Amazon Resource Name (ARN)。CloudFormation 使用角色的凭证代表您进行调用。CloudFormation 始终将此角色用于堆栈上的所有未来操作。只要用户有权对堆栈进行操作，CloudFormation 会使用此角色，即使用户无权传递它。确保该角色授予最少的权限。  
如果您不指定值，则 CloudFormation 会使用之前与堆栈关联的角色。如果角色不可用，则 CloudFormation 会使用您的用户凭证生成的一个临时会话。  
类型：字符串  
长度约束：最小长度为 20。最大长度为 2048。  
必需：否

StackName  
与堆栈关联的名称或唯一堆栈 ID。  
类型：字符串  
是否必需：是

## 安全注意事项


您必须将以下策略分配给 IAM 自动化担任角色，才可以使用 `aws:deleteStack` 操作。有关担任角色的更多信息，请参阅 [任务 1：为自动化创建服务角色](automation-setup-iam.md#create-service-role)。

------
#### [ JSON ]

****  

```
{
   "Version":"2012-10-17",		 	 	 
   "Statement":[
      {
         "Effect":"Allow",
         "Action":[
            "sqs:*",
            "cloudformation:DeleteStack",
            "cloudformation:DescribeStacks"
         ],
         "Resource":"*"
      }
   ]
}
```

------

# `aws:executeAutomation` - 运行另一个自动化


通过调用辅助运行手册运行辅助自动化。借助此操作，您可以为最常见的操作创建运行手册，并在自动化过程中引用这些运行手册。因为无需跨类似运行手册复制步骤，此操作可以简化您的运行手册。

辅助自动化将在启动主自动化的用户环境中运行。这意味着第二个自动化将使用与启动第一个自动化的用户相同的 AWS Identity and Access Management（IAM）角色或用户。

**重要**  
如果您在使用担任角色（使用 iam:passRole 策略的角色）的辅助自动化中指定参数，则启动主要自动化的用户或角色必须具有在辅助自动化中传递指定的担任角色的权限。有关为自动化设置担任角色的更多信息，请参阅 [使用控制台为 Automation 创建服务角色](automation-setup-iam.md)。

**输入**

------
#### [ YAML ]

```
name: Secondary_Automation
action: aws:executeAutomation
maxAttempts: 3
timeoutSeconds: 3600
onFailure: Abort
inputs:
  DocumentName: secondaryAutomation
  RuntimeParameters:
    instanceIds:
    - i-1234567890abcdef0
```

------
#### [ JSON ]

```
{
   "name":"Secondary_Automation",
   "action":"aws:executeAutomation",
   "maxAttempts":3,
   "timeoutSeconds":3600,
   "onFailure":"Abort",
   "inputs":{
      "DocumentName":"secondaryAutomation",
      "RuntimeParameters":{
         "instanceIds":[
            "i-1234567890abcdef0"
         ]
      }
   }
}
```

------

DocumentName  
要在步骤中运行的辅助运行手册的名称。对于相同 AWS 账户中的运行手册，指定运行手册名称。对于从其他 AWS 账户分享的运行手册，指定运行手册的 Amazon Resource Name (ARN)。有关使用共享运行手册的信息，请参阅 [使用共享 SSM 文档](documents-ssm-sharing.md#using-shared-documents)。  
类型：字符串  
是否必需：是

DocumentVersion  
要运行的辅助运行手册的版本。如果未指定，自动化将运行默认运行手册版本。  
类型：字符串  
必需：否

MaxConcurrency  
此任务可以并行运行的最大目标数。您可以指定一个数字或一个百分比（如 10 或 10%）。  
类型：字符串  
必需：否

MaxErrors  
系统停止在其他目标上运行自动化之前允许的错误数。您可以指定绝对数量的错误（如 10），也可以指定目标集百分比（如 10%）。例如，如果您指定 3，系统将在收到第四个错误时停止运行自动化。如果指定 0，则系统会在返回第一个错误结果后停止在其他资源上运行自动化。如果您在 50 个资源上运行自动化并将 `MaxErrors` 设置为 10%，则系统在收到第六个错误时停止在其他目标上运行自动化。  
当达到 `MaxErrors` 阈值时，允许完成已经运行的自动化，但是其中一些自动化也可能失败。如果您需要确保失败的自动化不会超过指定的 `MaxErrors`，将 `MaxConcurrency` 设置为 1，因此一次进行一个自动化。  
类型：字符串  
必需：否

RuntimeParameters  
辅助运行手册所需的参数。映射使用以下格式：\$1"parameter1" : "value1", "parameter2" : "value2" \$1  
类型：映射  
必需：否

Tags  
分配给资源的可选元数据。您最多可以为自动化指定 5 个标签。  
类型：MapList  
必需：否

TargetLocations  
位置是要在其中运行自动化的 AWS 区域 和/或 AWS 账户 的组合。必须指定至少 1 个项目，最多可以指定 100 个项目。为此参数指定值时，输出不会返回到父自动化。如果需要，则必须后续调用 API 操作，以检索子自动化的输出。  
类型：MapList  
必需：否

TargetMaps  
运行手册参数到目标资源的键-值映射列表。`Targets` 和 `TargetMaps` 不能一起指定。  
类型：MapList  
必需：否

TargetParameterName  
用作速率控制自动化目标资源的参数的名称。当您指定 `Targets` 时需要  
类型：字符串  
必需：否

Targets  
指向目标资源的键-值映射列表。当您指定 `TargetParameterName` 时需要  
类型：MapList  
必需：否Output

Output  
辅助自动化生成的输出。您可以使用以下格式引用输出：*Secondary\$1Automation\$1Step\$1Name*.Output  
类型：StringList  
示例如下：  

```
- name: launchNewWindowsInstance
  action: 'aws:executeAutomation'
  onFailure: Abort
  inputs:
    DocumentName: launchWindowsInstance
  nextStep: getNewInstanceRootVolume
- name: getNewInstanceRootVolume
  action: 'aws:executeAwsApi'
  onFailure: Abort
  inputs:
    Service: ec2
    Api: DescribeVolumes
    Filters:
    - Name: attachment.device
      Values:
      - /dev/sda1
    - Name: attachment.instance-id
      Values:
      - '{{launchNewWindowsInstance.Output}}'
  outputs:
  - Name: rootVolumeId
    Selector: '$.Volumes[0].VolumeId'
    Type: String
  nextStep: snapshotRootVolume
- name: snapshotRootVolume
  action: 'aws:executeAutomation'
  onFailure: Abort
  inputs:
    DocumentName: AWS-CreateSnapshot
    RuntimeParameters:
    VolumeId:
    - '{{getNewInstanceRootVolume.rootVolumeId}}'
    Description:
    - 'Initial root snapshot for {{launchNewWindowsInstance.Output}}'
```

ExecutionId  
辅助自动化的 ID。  
类型：字符串

Status  
辅助自动化的状态。  
类型：字符串

# `aws:executeAwsApi` - 调用并运行 AWS API 操作


调用并运行 AWS API 操作。支持大多数 API 操作，但某些 API 操作未经过测试。不支持流式处理 API 操作，例如 [GetObject](https://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectGET.html) 操作。如果不确定要使用的 API 操作是否属于流式操作，请查看该服务的 [Boto3](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html) 文档，判断该 API 是否需要流式输入或输出。我们会定期更新此操作使用的 Boto3 版本。但是，在新的 Boto3 版本发布后，可能需要长达几周的时间才能将更改反映到此操作中。每个 `aws:executeAwsApi` 操作最多可以运行 25 秒。有关如何使用此操作的更多示例，请参阅 [其他运行手册示例](automation-document-examples.md)。

**注意**  
`aws:executeAwsApi` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**输入**  
由您选择的 API 操作定义的输入。

------
#### [ YAML ]

```
action: aws:executeAwsApi
inputs:
  Service: The official namespace of the service
  Api: The API operation or method name
  API operation inputs or parameters: A value
outputs: # These are user-specified outputs
- Name: The name for a user-specified output key
  Selector: A response object specified by using jsonpath format
  Type: The data type
```

------
#### [ JSON ]

```
{
   "action":"aws:executeAwsApi",
   "inputs":{
      "Service":"The official namespace of the service",
      "Api":"The API operation or method name",
      "API operation inputs or parameters":"A value"
   },
   "outputs":[ These are user-specified outputs
      {
         "Name":"The name for a user-specified output key",
         "Selector":"A response object specified by using JSONPath format",
         "Type":"The data type"
      }
   ]
}
```

------

服务  
包含要运行的 API 操作的 AWS 服务命名空间。您可以在 适用于 Python (Boto3) 的 AWS SDK 的[可用服务](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)中查看支持的 AWS 服务命名空间列表。可以在**客户端**部分找到此命名空间。例如，Systems Manager 的命名空间为 `ssm`。Amazon Elastic Compute Cloud (Amazon EC2) 的命名空间为 `ec2`。  
类型：字符串  
是否必需：是

API  
要运行的 API 操作的名称。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看 API 操作（也称为方法）。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon Relational Database Service (Amazon RDS) 的所有 API 操作（方法）。  
类型：字符串  
是否必需：是

API 操作输入  
一个或多个 API 操作输入。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看可用的输入（也称为参数）。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon RDS 的所有方法。选择 [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) 方法并向下滚动以查看可用的参数，例如 **DBInstanceIdentifier**、**Name** 和 **Values**。  

```
inputs:
  Service: The official namespace of the service
  Api: The API operation name
  API input 1: A value
  API Input 2: A value
  API Input 3: A value
```

```
"inputs":{
      "Service":"The official namespace of the service",
      "Api":"The API operation name",
      "API input 1":"A value",
      "API Input 2":"A value",
      "API Input 3":"A value"
}
```
类型：由选择的 API 操作确定  
是否必需：是

**输出**  
输出由用户根据所选 API 操作的响应指定。

名称  
输出的名称。  
类型：字符串  
是否必需：是

选择器  
响应对象中特定属性的 JSONPath。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看响应对象。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon RDS 的所有方法：选择 [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) 方法，然后向下滚动到**响应结构**部分。**DBInstances** 被列为响应对象。  
类型：Integer、Boolean、String、StringList、StringMap 或 MapList  
是否必需：是

Type  
响应元素的数据类型。  
类型：可变  
是否必需：是

# `aws:executeScript` - 运行脚本


使用指定的运行时和处理程序提供的 Python 或 PowerShell 脚本。每个 `aws:executeScript` 操作最多可以运行 600 秒（10 分钟）时间。您可以通过指定 `aws:executeScript` 步骤的 `timeoutSeconds` 参数来限制超时。

在函数中使用 return 语句将输出添加到输出有效负载中。有关为您的 `aws:executeScript` 操作定义输出的示例，请参阅[示例 2：脚本化运行手册](automation-authoring-runbooks-scripted-example.md)。您还可以将运行手册中 `aws:executeScript` 操作的输出发送到您指定的 Amazon CloudWatch Logs 日志组。有关更多信息，请参阅 [使用 CloudWatch Logs 记录自动化操作输出](automation-action-logging.md)。

如果想要将 `aws:executeScript` 操作的输出发送到 CloudWatch Logs，或者如果您为 `aws:executeScript` 操作指定的脚本调用 AWS API 操作，则始终需要 AWS Identity and Access Management (IAM) 服务角色（或承担角色）运行运行手册。

**注意**  
`aws:executeScript` 操作不支持自动节流重试。如果您的脚本发出的 AWS API 调用可能会受到节流，则必须在脚本代码中实现自己的重试逻辑。

`aws:executeScript` 操作包含以下预安装的 PowerShell 核心模块。
+ Microsoft.PowerShell.Host
+ Microsoft.PowerShell.Management
+ Microsoft.PowerShell.Security
+ Microsoft.PowerShell.Utility
+ PackageManagement
+ PowerShellGet

要使用未预装的 PowerShell 核心模块，脚本必须安装带有 `-Force` 标志的模块，如以下命令所示。不支持 `AWSPowerShell.NetCore` 模块。用您想要安装的模块替换 *ModuleName*。

```
Install-Module ModuleName -Force
```

要在脚本中使用 PowerShell 核心 cmdlet，我们建议您使用 `AWS.Tools` 模块，如以下命令所示。将每个*示例资源占位符*替换为您自己的信息。
+ Amazon S3 cmdlet。

  ```
  Install-Module AWS.Tools.S3 -Force
  Get-S3Bucket -BucketName amzn-s3-demo-bucket
  ```
+ Amazon EC2 cmdlet

  ```
  Install-Module AWS.Tools.EC2 -Force
  Get-EC2InstanceStatus -InstanceId instance-id
  ```
+ 通用或独立于服务的 AWS Tools for Windows PowerShell cmdlet。

  ```
  Install-Module AWS.Tools.Common -Force
  Get-AWSRegion
  ```

如果脚本除了使用 PowerShell 核心 cmdlet 之外还初始化新对象，则还必须导入模块，如以下命令所示。

```
Install-Module AWS.Tools.EC2 -Force
Import-Module AWS.Tools.EC2

$tag = New-Object Amazon.EC2.Model.Tag
$tag.Key = "Tag"
$tag.Value = "TagValue"

New-EC2Tag -Resource i-02573cafcfEXAMPLE -Tag $tag
```

有关安装和导入 `AWS.Tools` 模块以及在运行手册中使用 PowerShell 核心 cmdlet 的示例，请参阅 [自动化运行手册的视觉对象设计体验](automation-visual-designer.md)。

**Input**  
提供运行脚本所需的信息。将每个*示例资源占位符*替换为您自己的信息。

**注意**  
Python 脚本的附件可以是 .py 文件或包含该脚本的 .zip 文件。PowerShell 脚本必须存储在 .zip 文件中。

------
#### [ YAML ]

```
action: "aws:executeScript"
inputs: 
 Runtime: runtime
 Handler: "functionName"
 InputPayload: 
  scriptInput: '{{parameterValue}}'
 Script: |-
   def functionName(events, context):
   ...
 Attachment: "scriptAttachment.zip"
```

------
#### [ JSON ]

```
{
    "action": "aws:executeScript",
    "inputs": {
        "Runtime": "runtime",
        "Handler": "functionName",
        "InputPayload": {
            "scriptInput": "{{parameterValue}}"
        },
        "Attachment": "scriptAttachment.zip"
    }
}
```

------

运行时  
用于运行所提供脚本的运行时语言。`aws:executeScript` 支持下表中的运行时。      
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/automation-action-executeScript.html)
类型：字符串  
是否必需：是  
对于 python 运行时系统，环境提供 512 MB 的内存和 512 MB 的磁盘空间。对于 PowerShell 运行时，环境会提供 1024 MB 的内存和 512 MB 的磁盘空间。

处理程序  
函数的名称。您必须确保在处理程序中定义的函数具有两个参数：`events` 和 `context`。PowerShell 运行时不支持此参数。  
类型：字符串  
必需：是（Python）\$1 不支持（PowerShell）

InputPayload  
将传递给处理程序的第一个参数的 JSON 或 YAML 对象。这可用于将输入数据传递给脚本。  
类型：字符串  
必需：否  

```
description: Tag an instance
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
    AutomationAssumeRole:
        type: String
        description: '(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
    InstanceId:
        type: String
        description: (Required) The ID of the EC2 instance you want to tag.
mainSteps:
  - name: tagInstance
    action: 'aws:executeScript'
    inputs:
        Runtime: "python3.11"
        Handler: tagInstance
        InputPayload:
            instanceId: '{{InstanceId}}'
        Script: |-
          def tagInstance(events,context):
            import boto3

            #Initialize client
            ec2 = boto3.client('ec2')
            instanceId = events['instanceId']
            tag = {
                "Key": "Env",
                "Value": "ExamplePython"
            }
            print(f"Adding tag {tag} to instance id {instanceId}")
            ec2.create_tags(
                Resources=[instanceId],
                Tags=[tag]
            )
            return tag
    outputs:
      - Type: String
        Name: TagKey
        Selector: $.Payload.Key
outputs:
  - tagInstance.TagKey
```

```
description: Tag an instance
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
  AutomationAssumeRole:
    type: String
    description: (Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.
  InstanceId:
    type: String
    description: (Required) The ID of the EC2 instance you want to tag.
mainSteps:
  - name: tagInstance
    action: aws:executeScript
    isEnd: true
    inputs:
      Runtime: PowerShell 7.4
      InputPayload:
        instanceId: '{{InstanceId}}'
      Script: |-
        Install-Module AWS.Tools.EC2 -Force
        Import-Module AWS.Tools.EC2

        $input = $env:InputPayload | ConvertFrom-Json

        $tag = New-Object Amazon.EC2.Model.Tag
        $tag.Key = "Env"
        $tag.Value = "ExamplePowerShell"

        Write-Information "Adding tag key: $($tag.Key) and value: $($tag.Value) to instance id $($input.instanceId)"
        New-EC2Tag -Resource $input.instanceId -Tag $tag

        return $tag
    outputs:
      - Type: String
        Name: TagKey
        Selector: $.Payload.Key
outputs:
  - tagInstance.TagKey
```

Script  
要在自动化期间运行的嵌入式脚本。  
类型：字符串  
必需：否 (Python) \$1 是 (PowerShell)

附件  
可以由操作调用的单独脚本文件或 .zip 文件的名称。指定与您在 `Attachments` 请求参数中指定的文档附件文件的 `Name` 相同的值。有关更多信息，请参阅 *AWS Systems Manager API 参考*中的[附件](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_CreateDocument.html#systemsmanager-CreateDocument-request-Attachments)。如果您使用附件提供脚本，还必须在您的运行手册的顶级元素部分中定义一个 `files` 部分。有关更多信息，请参阅 [架构版本 0.3](documents-schemas-features.md#automation-doc-syntax-examples)。  
要为 Python 调用文件，请在 `Handler` 中使用 `filename.method_name` 格式。  
Python 脚本的附件可以是 .py 文件或包含该脚本的 .zip 文件。PowerShell 脚本必须存储在 .zip 文件中。
当在附件中包含 Python 库时，我们建议在每个模块目录中添加一个空`__init__.py` 文件。这允许您从脚本内容的附件中的库导入模块。例如：`from library import module`  
类型：字符串  
必需：否Output

有效载荷  
函数返回的对象的 JSON 表示形式。返回最多 100KB 的数据。如果输出列表，则最多返回 100 个项目。

## 通过 aws:executeScript 使用附件


附件提供了一种强大的方法，可以将复杂的脚本、多个模块和外部依赖项打包并重复用于 `aws:executeScript` 操作。在您需要执行以下操作时，请使用附件：
+ 将多个 Python 模块或 PowerShell 脚本打包在一起。
+ 在多个运行手册中重复使用相同的脚本逻辑。
+ 在脚本中包含外部库或依赖项。
+ 通过分离复杂的脚本逻辑，保持运行手册定义简洁。
+ 在团队或自动化工作流之间共享脚本包。

### 附件结构和打包


您可以附加单个文件或包含多个文件的 zip 包。具体结构取决于使用案例：

**单个文件附件**  
对于简单的脚本，您可以附加单个 `.py` 文件 (Python) 或包含单个 PowerShell 脚本的 `.zip` 文件。

**多模块包**  
对于需要多个模块的复杂自动化，请创建具有以下建议结构的 zip 包：

```
my-automation-package.zip
├── main.py                    # Entry point script
├── utils/
│   ├── __init__.py           # Required for Python module imports
│   ├── helper_functions.py   # Utility functions
│   └── aws_operations.py     # AWS-specific operations
├── config/
│   ├── __init__.py
│   └── settings.py           # Configuration settings
└── requirements.txt          # Optional: document dependencies
```

**重要**  
对于 Python 包，您必须在每个包含 Python 模块的目录中包含一个空的 `__init__.py` 文件。这样您就可以使用标准的 Python 导入语法（例如 `from utils import helper_functions`）来导入模块。

**PowerShell 包结构**  
PowerShell 附件必须打包为 zip 文件，其结构如下：

```
my-powershell-package.zip
├── Main.ps1                  # Entry point script
├── Modules/
│   ├── HelperFunctions.ps1   # Utility functions
│   └── AWSOperations.ps1     # AWS-specific operations
└── Config/
    └── Settings.ps1          # Configuration settings
```

### 创建带附件的运行手册


请按照以下步骤创建带附件的运行手册：

1. **将附件上传到 Amazon S3**

   将脚本文件或 zip 包上传到自动化角色可访问的 S3 存储桶。请记下 S3 URI，以便在下一步中使用。

   ```
   aws s3 cp my-automation-package.zip s3://my-automation-bucket/scripts/
   ```

1. **计算附件校验和**

   计算附件文件的 SHA-256 校验和以进行安全验证：

   ```
   # Linux/macOS
   shasum -a 256 my-automation-package.zip
   
   # Windows PowerShell
   Get-FileHash -Algorithm SHA256 my-automation-package.zip
   ```

1. **在运行手册中定义 files 部分**

   在运行手册的顶层添加 `files` 部分以引用附件：

   ```
   files:
     my-automation-package.zip:
       checksums:
         sha256: "your-calculated-checksum-here"
   ```

1. **在 executeScript 步骤中引用附件**

   使用 `Attachment` 参数来引用上传的文件：

   ```
   - name: runMyScript
     action: aws:executeScript
     inputs:
       Runtime: python3.11
       Handler: main.process_data
       Attachment: my-automation-package.zip
       InputPayload:
         inputData: "{{InputParameter}}"
   ```

## aws:executeScript 附件示例


以下示例演示了使用附件和 `aws:executeScript` 操作的不同方法。

### 示例 1：单个文件附件


此示例展示如何使用单个 Python 文件作为附件来处理 EC2 实例数据。

**附件文件：process\$1instance.py**  
创建一个包含以下内容的 Python 文件：

```
import boto3
import json

def process_instance_data(events, context):
    """Process EC2 instance data and return formatted results."""
    try:
        instance_id = events.get('instanceId')
        if not instance_id:
            raise ValueError("instanceId is required")
        
        ec2 = boto3.client('ec2')
        
        # Get instance details
        response = ec2.describe_instances(InstanceIds=[instance_id])
        instance = response['Reservations'][0]['Instances'][0]
        
        # Format the response
        result = {
            'instanceId': instance_id,
            'instanceType': instance['InstanceType'],
            'state': instance['State']['Name'],
            'availabilityZone': instance['Placement']['AvailabilityZone'],
            'tags': {tag['Key']: tag['Value'] for tag in instance.get('Tags', [])}
        }
        
        print(f"Successfully processed instance {instance_id}")
        return result
        
    except Exception as e:
        print(f"Error processing instance: {str(e)}")
        raise
```

**完整运行手册**  
以下是使用单个文件附件的完整运行手册：

```
description: Process EC2 instance data using single file attachment
schemaVersion: '0.3'
assumeRole: '{{AutomationAssumeRole}}'
parameters:
  AutomationAssumeRole:
    type: String
    description: (Required) IAM role for automation execution
  InstanceId:
    type: String
    description: (Required) EC2 instance ID to process

files:
  process_instance.py:
    checksums:
      sha256: "abc123def456..."

mainSteps:
  - name: processInstance
    action: aws:executeScript
    inputs:
      Runtime: python3.11
      Handler: process_instance.process_instance_data
      Attachment: process_instance.py
      InputPayload:
        instanceId: '{{InstanceId}}'
    outputs:
      - Type: StringMap
        Name: InstanceData
        Selector: $.Payload

outputs:
  - processInstance.InstanceData
```

### 示例 2：多模块包


此示例演示如何使用包含多个 Python 模块的 zip 包进行复杂的 S3 存储桶操作。

**包结构**  
创建具有以下结构的 zip 包：

```
s3-operations.zip
├── main.py
├── utils/
│   ├── __init__.py
│   ├── s3_helper.py
│   └── validation.py
└── config/
    ├── __init__.py
    └── settings.py
```

**main.py（入口点）**  
编排操作的主脚本：

```
from utils.s3_helper import S3Operations
from utils.validation import validate_bucket_name
from config.settings import get_default_settings

def cleanup_s3_bucket(events, context):
    """Clean up S3 bucket based on specified criteria."""
    try:
        bucket_name = events.get('bucketName')
        max_age_days = events.get('maxAgeDays', 30)
        
        # Validate inputs
        if not validate_bucket_name(bucket_name):
            raise ValueError(f"Invalid bucket name: {bucket_name}")
        
        # Initialize S3 operations
        s3_ops = S3Operations()
        settings = get_default_settings()
        
        # Perform cleanup
        deleted_objects = s3_ops.delete_old_objects(
            bucket_name, 
            max_age_days,
            settings['dry_run']
        )
        
        result = {
            'bucketName': bucket_name,
            'deletedCount': len(deleted_objects),
            'deletedObjects': deleted_objects[:10],  # Return first 10 for brevity
            'dryRun': settings['dry_run']
        }
        
        print(f"Cleanup completed for bucket {bucket_name}")
        return result
        
    except Exception as e:
        print(f"Error during S3 cleanup: {str(e)}")
        raise
```

## aws:executeScript 附件故障排除


使用以下指导来解决 `aws:executeScript` 附件的常见问题：

**模块导入错误**  
如果在使用多模块包时收到导入错误：
+ 确保在包含 Python 模块的每个目录中都包含一个空的 `__init__.py` 文件。
+ 验证导入语句是否与 zip 包中的实际文件和目录结构相匹配。
+ 始终使用相对导入（例如 `from .utils import helper`）或绝对导入（例如 `from utils import helper`）。

**未找到附件错误**  
如果自动化未能找到附件：
+ 验证 `Attachment` 参数值是否与 `files` 部分中的键完全匹配。
+ 在 `files` 部分中检查 S3 存储桶路径和文件名是否正确。
+ 确保自动化角色对附件 S3 位置具有 `s3:GetObject` 权限。
+ 验证运行手册中的校验和是否与实际文件校验和匹配。

**处理程序函数错误**  
如果收到与处理程序相关的错误：
+ 对于 Python：在 `Handler` 参数中使用格式 `filename.function_name`（例如 `main.process_data`）。
+ 确保处理程序函数只接受两个参数：`events` 和 `context`。
+ 对于 PowerShell：请勿指定 `Handler` 参数；脚本将直接运行。

**脚本执行失败**  
如果脚本在执行过程中失败：
+ 检查自动化执行历史记录，获取详细的错误消息和堆栈跟踪。
+ 使用 `print()` 语句 (Python) 或 `Write-Information` (PowerShell) 添加调试输出。
+ 验证自动化角色是否已被授予所有必需的 AWS 权限。
+ 在将脚本逻辑打包为附件之前，请在本地测试脚本逻辑。

**退出代码和错误处理**  
要正确处理错误并返回退出代码：
+ 在 Python 中：使用 `raise Exception("error message")` 指示脚本失败。
+ 在 PowerShell 中：使用 `throw "error message"` 或 `Write-Error` 指示失败。
+ 从函数返回结构化数据以提供详细的成功/失败信息。
+ 使用 try-catch 块优雅地处理异常并提供有意义的错误消息。

# `aws:executeStateMachine` - 运行 AWS Step Functions 状态机。


运行 AWS Step Functions 状态机。

**注意**  
`aws:executeStateMachine` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**输入**

此操作支持 Step Functions [StartExecution](https://docs.aws.amazon.com/step-functions/latest/apireference/API_StartExecution.html) API 操作的大多数参数。

**所需的 AWS Identity and Access Management (IAM) 权限**
+ `states:DescribeExecution`
+ `states:StartExecution`
+ `states:StopExecution`

------
#### [ YAML ]

```
name: executeTheStateMachine
action: aws:executeStateMachine
inputs:
  stateMachineArn: StateMachine_ARN
  input: '{"parameters":"values"}'
  name: name
```

------
#### [ JSON ]

```
{
    "name": "executeTheStateMachine",
    "action": "aws:executeStateMachine",
    "inputs": {
        "stateMachineArn": "StateMachine_ARN",
        "input": "{\"parameters\":\"values\"}",
        "name": "name"
    }
}
```

------

stateMachineArn  
Step Functions 状态机的 Amazon Resource Name (ARN)。  
类型：字符串  
是否必需：是

name  
执行的名称。  
类型：字符串  
必需：否

input  
包含执行的 JSON 输入数据的字符串。  
类型：字符串  
必需：否

**输出**  
此操作预定义了以下输出。

执行 Arn  
执行的 ARN。  
类型：字符串

input  
包含执行的 JSON 输入数据的字符串。长度限制适用于有效负载大小，在 UTF-8 编码中以字节表示。  
类型：字符串

name  
执行的名称。  
类型：字符串

output  
执行的 JSON 输出数据。长度限制适用于有效负载大小，在 UTF-8 编码中以字节表示。  
类型：字符串

startDate  
开始执行的日期。  
类型：字符串

stateMachineArn  
状态机的执行的 ARN。  
类型：字符串

status  
执行的当前状态。  
类型：字符串

停止日期  
如果执行已经结束，则为执行停止的日期。  
类型：字符串

# `aws:invokeWebhook` – 调用 Automation Webhook 集成


调用指定的自动化 Webhook 集成。有关创建 Automation 集成的信息，请参阅 [为 Automation 创建 Webhook 集成](creating-webhook-integrations.md)。

**注意**  
`aws:invokeWebhook` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**注意**  
要使用 `aws:invokeWebhook` 操作，您的用户或服务角色必须允许以下操作：  
ssm:GetParameter
kms:Decrypt
只有当您使用客户托管密钥加密集成的参数时，才需要 AWS Key Management Service (AWS KMS) `Decrypt` 操作的权限。

**Input**  
提供您希望调用的 Automation 集成的信息。

------
#### [ YAML ]

```
action: "aws:invokeWebhook"
inputs: 
 IntegrationName: "exampleIntegration"
 Body: "Request body"
```

------
#### [ JSON ]

```
{
    "action": "aws:invokeWebhook",
    "inputs": {
        "IntegrationName": "exampleIntegration",
        "Body": "Request body"
    }
}
```

------

IntegrationName  
Automation 集成的名称。例如 `exampleIntegration`。您指定的集成必须已存在。  
类型：字符串  
是否必需：是

Body  
调用 Webhook 集成时要发送的有效负载。  
类型：字符串  
必需：否Output

响应  
从 Webhook 提供商响应中收到的文本。

ResponseCode  
从 Webhook 提供商响应中收到的 HTTP 状态代码。

# `aws:invokeLambdaFunction` – 调用 AWS Lambda 函数


调用指定的 AWS Lambda 函数。

**注意**  
每个 `aws:invokeLambdaFunction` 操作最多可以运行 300 秒（5 分钟）。您可以通过指定 `aws:invokeLambdaFunction` 步骤的 `timeoutSeconds` 参数来限制超时。

**注意**  
`aws:invokeLambdaFunction` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**Input**  
此操作支持 Lambda 服务的大多数调用参数。有关更多信息，请参阅[调用](https://docs.aws.amazon.com/lambda/latest/dg/API_Invoke.html)。

------
#### [ YAML ]

```
name: invokeMyLambdaFunction
action: aws:invokeLambdaFunction
maxAttempts: 3
timeoutSeconds: 120
onFailure: Abort
inputs:
  FunctionName: MyLambdaFunction
```

------
#### [ JSON ]

```
{
    "name": "invokeMyLambdaFunction",
    "action": "aws:invokeLambdaFunction",
    "maxAttempts": 3,
    "timeoutSeconds": 120,
    "onFailure": "Abort",
    "inputs": {
        "FunctionName": "MyLambdaFunction"
    }
}
```

------

FunctionName  
Lambda 函数的名称。此函数必须存在。  
类型：字符串  
是否必需：是

限定词  
函数版本或别名。  
类型：字符串  
必需：否

InvocationType  
调用类型。默认值为 `RequestResponse`。  
类型：字符串  
有效值：`Event` \$1`RequestResponse` \$1`DryRun`  
必需：否

LogType  
如果默认值为 `Tail`，则调用类型必须是 `RequestResponse`。Lambda 返回 Lambda 函数生成的最后 4KB 日志数据，采用 base64 编码。  
类型：字符串  
有效值：`None` \$1 `Tail`  
必需：否

ClientContext  
特定于客户端的信息。  
必需：否

InputPayload  
传递给处理程序的第一个参数的 YAML 或 JSON 对象。可以使用此输入将数据传递给函数。与传统 `Payload` 输入相比，此输入提供了更大的灵活性和支持。如果为操作同时定义了 `InputPayload` 和 `Payload`，则 `InputPayload` 优先，不使用 `Payload` 值。  
类型：StringMap  
必需：否

有效载荷  
传递给处理程序的第一个参数的 JSON 字符串。这可以用于将输入数据传递给函数。我们建议使用 `InputPayload` 输入来添加功能性。  
类型：字符串  
必需：否Output

StatusCode  
HTTP 状态代码

FunctionError  
如果存在，则表明执行函数时发生错误。响应负载中包含错误详细信息。

LogResult  
Lambda 函数调用的 base64 编码日志。只有在调用类型为 `RequestResponse` 并且请求了日志时，日志才存在。

有效负载  
Lambda 函数返回的对象的 JSON 表示形式。只有在调用类型为 `RequestResponse` 时才存在有效负载。

以下是来自 `AWS-PatchInstanceWithRollback` 运行手册的部分，演示了如何引用来自 `aws:invokeLambdaFunction` 操作的输出。

------
#### [ YAML ]

```
- name: IdentifyRootVolume
  action: aws:invokeLambdaFunction
  inputs:
    FunctionName: "IdentifyRootVolumeLambda-{{automation:EXECUTION_ID}}"
    Payload: '{"InstanceId": "{{InstanceId}}"}'
- name: PrePatchSnapshot
  action: aws:executeAutomation
  inputs:
    DocumentName: "AWS-CreateSnapshot"
    RuntimeParameters:
      VolumeId: "{{IdentifyRootVolume.Payload}}"
      Description: "ApplyPatchBaseline restoration case contingency"
```

------
#### [ JSON ]

```
{
    "name": "IdentifyRootVolume",
    "action": "aws:invokeLambdaFunction",
    "inputs": {
      "FunctionName": "IdentifyRootVolumeLambda-{{automation:EXECUTION_ID}}",
      "Payload": "{\"InstanceId\": \"{{InstanceId}}\"}"
    }
  },
  {
    "name": "PrePatchSnapshot",
    "action": "aws:executeAutomation",
    "inputs": {
      "DocumentName": "AWS-CreateSnapshot",
      "RuntimeParameters": {
        "VolumeId": "{{IdentifyRootVolume.Payload}}",
        "Description": "ApplyPatchBaseline restoration case contingency"
      }
    }
  }
```

------

# `aws:loop` – 迭代自动化中的步骤


此操作在自动化运行手册中的步骤子集上进行迭代。您可以选择 `do while` 或 `for each` 样式循环。要构造 `do while` 循环，请使用 `LoopCondition` 输入参数。要构造 `for each` 循环，请使用 `Iterators` 和 `IteratorDataType` 输入参数。使用 `aws:loop` 操作时，请仅指定 `Iterators` 或 `LoopCondition` 输入参数。最大迭代次数为 100。

`onCancel` 属性仅可用于在循环中定义的步骤。`aws:loop` 操作不支持 `onCancel` 属性。`onFailure` 属性可用于 `aws:loop` 操作，但只有在出现导致该步骤失败的意外错误时使用该属性。如果您为循环中的步骤定义 `onFailure` 属性，则 `aws:loop` 操作将继承这些属性，并在出现故障时相应做出反应。

**示例**  
以下是如何构造不同类型的循环操作的示例。

------
#### [ do while ]

```
name: RepeatMyLambdaFunctionUntilOutputIsReturned
action: aws:loop
inputs:
    Steps:
    - name: invokeMyLambda
        action: aws:invokeLambdaFunction
        inputs:
        FunctionName: LambdaFunctionName
        outputs:
        - Name: ShouldRetry
            Selector: $.Retry
            Type: Boolean
    LoopCondition:
        Variable: "{{ invokeMyLambda.ShouldRetry }}"
        BooleanEquals: true
    MaxIterations: 3
```

------
#### [ for each ]

```
name: stopAllInstancesWithWaitTime
action: aws:loop
inputs:
    Iterators: "{{ DescribeInstancesStep.InstanceIds }}"
    IteratorDataType: "String"
    Steps:
    - name: stopOneInstance
        action: aws:changeInstanceState
        inputs:
        InstanceIds:
            - "{{stopAllInstancesWithWaitTime.CurrentIteratorValue}}"
        CheckStateOnly: false
        DesiredState: stopped
    - name: wait10Seconds
        action: aws:sleep
        inputs:
        Duration: PT10S
```

------

**Input**  
输入如下。

迭代器  
要迭代的步骤的项目列表。迭代器的最大数为 100。  
类型：StringList  
必需：否

IteratorDataType  
用于指定 `Iterators` 数据类型的可选参数。可将此参数的值与 `Iterators` 输入参数一起提供。如果您没有为此参数和 `Iterators` 指定值，则必须为 `LoopCondition` 参数指定值。  
类型：字符串  
有效值：Boolean \$1 Integer \$1 String \$1 StringMap  
默认：字符串  
必需：否

LoopCondition  
由 `Variable` 和要评估的运算符条件组成。如果您没有为此参数指定值，则必须为 `Iterators` 和 `IteratorDataType` 参数指定值。您可以通过组合使用 `And`、`Not` 和 `Or` 运算符来使用复杂的运算符评估。循环中的步骤完成后会对条件进行评估。如果条件为 `true` 并且尚未达到 `MaxIterations` 值，则循环中的步骤将再次运行。运算符条件如下：  

**字符串运算**
+ 字符串等于
+ EqualsIgnoreCase
+ StartsWith
+ EndsWith
+ 包含

**数值运算**
+ NumericEquals
+ NumericGreater
+ NumericLesser
+ NumericGreaterOrEquals
+ NumericLesser
+ NumericLesserOrEquals

**布尔运算**
+ BooleanEquals
类型：StringMap  
必需：否

MaxIterations  
循环中步骤运行的最大次数。一旦达到为此输入指定的值，即使 `LoopCondition` 仍是 `true`，或者 `Iterators` 参数中仍然存在对象，循环也会停止运行。  
类型：整数  
有效值：1-100  
必需：否

Steps  
要在循环中运行的步骤列表。这些功能类似于嵌套运行手册。在这些步骤中，您可以使用语法 `{{loopStepName.CurrentIteratorValue}}` 访问 `for each` 循环的当前迭代器值。您还可以使用语法 `{{loopStepName.CurrentIteration}}` 访问两种循环类型的当前迭代的整数值。  
类型：步骤列表  
是否必需：是Output

CurrentIteration  
当前循环迭代为整数。迭代值从 1 开始。  
类型：整数

CurrentIteratorValue  
当前迭代器的值为字符串。此输出仅存在于 `for each` 循环中。  
类型：字符串

# `aws:pause` - 暂停自动化


此操作会暂停自动化。暂停后的自动化状态为*正在等待*。要继续自动化，请使用信号类型为 `Resume` 的 [SendAutomationSignal](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_SendAutomationSignal.html) API 操作。我们建议使用 `aws:sleep` 或 `aws:approve` 操作对您的工作流进行更精细的控制。

**注意**  
此操作的默认超时时间为 7 天（604800 秒），最长时间为 30 天（2592000 秒）。您可以通过指定 `aws:pause` 步骤的 `timeoutSeconds` 参数来限制或延长超时。

**Input**  
输入如下。

------
#### [ YAML ]

```
name: pauseThis
action: aws:pause
timeoutSeconds: 1209600
inputs: {}
```

------
#### [ JSON ]

```
{
    "name": "pauseThis",
    "action": "aws:pause",
    "timeoutSeconds": "1209600",
    "inputs": {}
}
```

------Output

无  


# `aws:runCommand` - 在托管实例上运行命令


运行指定的命令。

**注意**  
自动化仅支持 AWS Systems Manager Run Command 操作的一个*output*。一个运行手册可以包括多个 Run Command 操作，但一次仅一个操作支持 output。

**Input**  
此操作支持大多数 send command 参数。有关更多信息，请参阅 [SendCommand](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_SendCommand.html)。

------
#### [ YAML ]

```
- name: checkMembership
  action: 'aws:runCommand'
  inputs:
    DocumentName: AWS-RunPowerShellScript
    InstanceIds:
      - '{{InstanceIds}}'
    Parameters:
      commands:
        - (Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain
```

------
#### [ JSON ]

```
{
    "name": "checkMembership",
    "action": "aws:runCommand",
    "inputs": {
        "DocumentName": "AWS-RunPowerShellScript",
        "InstanceIds": [
            "{{InstanceIds}}"
        ],
        "Parameters": {
            "commands": [
                "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"
            ]
        }
    }
}
```

------

DocumentName  
如果命令类型文档属于您或 AWS，请指定文档的名称。如果您使用的是另一个 AWS 账户与您共享的文档，指定文档的 Amazon Resource Name (ARN)。有关如何使用共享文档的更多信息，请参阅 [使用共享 SSM 文档](documents-ssm-sharing.md#using-shared-documents)。  
类型：字符串  
是否必需：是

InstanceIds  
要在其中运行命令的实例 ID。您可以指定最多 50 个 ID。  
您还可以使用虚拟参数 `{{RESOURCE_ID}}` 代替实例 ID，以便在目标组中的所有实例上运行命令。有关伪参数的更多信息，请参阅[注册维护时段任务时使用伪参数](maintenance-window-tasks-pseudo-parameters.md)。  
另一种替代方法是使用 `Targets` 参数向一组实例发送命令。`Targets` 参数接受 Amazon Elastic Compute Cloud (Amazon EC2) 标签。有关如何使用 `Targets` 参数的更多信息，请参阅 [大规模运行命令](send-commands-multiple.md)。  
类型：StringList  
必需：否（如果未指定实例 ID 或使用 `{{RESOURCE_ID}}` 虚拟参数，则必须指定 `Targets` 参数。）

Targets  
一组搜索条件，使用您指定的键/值组合来设置实例目标。如果未在调用中提供一个或多个实例 ID，则 `Targets` 为必需。有关如何使用 `Targets` 参数的更多信息，请参阅 [大规模运行命令](send-commands-multiple.md)。  
类型：MapList（列表中 map 的架构必须与对象匹配。） 有关更多信息，请参阅 *AWS Systems ManagerAPI 参考*中的[目标](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_Target.html)。  
必需：否（如果未指定 `Targets`，则必须指定实例 ID 或使用 `{{RESOURCE_ID}}` 虚拟参数。）  
以下为示例。  

```
- name: checkMembership
  action: aws:runCommand
  inputs:
    DocumentName: AWS-RunPowerShellScript
    Targets:
      - Key: tag:Stage
        Values:
          - Gamma
          - Beta
      - Key: tag-key
        Values:
          - Suite
    Parameters:
      commands:
        - (Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain
```

```
{
    "name": "checkMembership",
    "action": "aws:runCommand",
    "inputs": {
        "DocumentName": "AWS-RunPowerShellScript",
        "Targets": [                   
            {
                "Key": "tag:Stage",
                "Values": [
                    "Gamma", "Beta"
                ]
            },
            {
                "Key": "tag:Application",
                "Values": [
                    "Suite"
                ]
            }
        ],
        "Parameters": {
            "commands": [
                "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"
            ]
        }
    }
}
```

Parameters  
文档中指定的必需参数和可选参数。  
类型：映射  
必需：否

CloudWatchOutputConfig  
用于将命令输出发送到 Amazon CloudWatch Logs 的配置选项。有关将命令输出发送到 CloudWatch Logs 的更多信息，请参阅 [为 Run Command 配置 Amazon CloudWatch Logs](sysman-rc-setting-up-cwlogs.md)。  
类型：StringMap（映射的架构必须与对象匹配。有关更多信息，请参阅 *AWS Systems ManagerAPI 参考* 中的 [CloudWatchOutputConfig](https://docs.aws.amazon.com/systems-manager/latest/APIReference/API_CloudWatchOutputConfig.html)）。  
必需：否  
以下为示例。  

```
- name: checkMembership
  action: aws:runCommand
  inputs:
    DocumentName: AWS-RunPowerShellScript
    InstanceIds:
      - "{{InstanceIds}}"
    Parameters:
      commands:
        - "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"
    CloudWatchOutputConfig:
      CloudWatchLogGroupName: CloudWatchGroupForSSMAutomationService
      CloudWatchOutputEnabled: true
```

```
{
    "name": "checkMembership",
    "action": "aws:runCommand",
    "inputs": {
        "DocumentName": "AWS-RunPowerShellScript",
        "InstanceIds": [
            "{{InstanceIds}}"
        ],
        "Parameters": {
            "commands": [
                "(Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain"
            ]
        },
        "CloudWatchOutputConfig" : { 
                "CloudWatchLogGroupName": "CloudWatchGroupForSSMAutomationService",
                "CloudWatchOutputEnabled": true
        }
    }
}
```

Comment  
有关此命令的用户定义的信息。  
类型：字符串  
必需：否

DocumentHash  
文档的哈希。  
类型：字符串  
必需：否

DocumentHashType  
哈希的类型。  
类型：字符串  
有效值：`Sha256` \$1 `Sha1`  
必需：否

NotificationConfig  
用于发送通知的配置。  
必需：否

OutputS3BucketName  
命令输出响应的 S3 存储桶的名称。托管式节点必须具有 S3 存储桶的权限才能成功记录输出。  
类型：字符串  
必需：否

OutputS3KeyPrefix  
 前缀。  
类型：字符串  
必需：否

ServiceRoleArn  
AWS Identity and Access Management (IAM) 角色的 ARN。  
类型：字符串  
必需：否

TimeoutSeconds  
等待命令传递到实例上的 AWS Systems Manager SSM Agent 的时间（单位：秒）。如果在达到指定的值之前，命令未被实例上的 SSM Agent 接收，则命令的状态将更改为 `Delivery Timed Out`。  
类型：整数  
必需：否  
有效值：30-2592000Output

CommandId  
命令的 ID。

Status  
命令的状态。

ResponseCode  
命令的响应代码。如果运行的文档有多个步骤，则不会为此输出返回值。

Output  
命令的输出。如果您使用命令定位一个标记或多个实例，则不会返回 output 值。您可以使用 `GetCommandInvocation` 和 `ListCommandInvocations` API 操作来检索单个实例的输出。

# `aws:runInstances` – 启动 Amazon EC2 实例


启动新的 Amazon Elastic Compute Cloud (Amazon EC2) 实例。

**注意**  
`aws:runInstances` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**Input**  
此操作支持大多数 API 参数。有关更多信息，请参阅 [RunInstances](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_RunInstances.html) API 文档。

------
#### [ YAML ]

```
name: launchInstance
action: aws:runInstances
maxAttempts: 3
timeoutSeconds: 1200
onFailure: Abort
inputs:
  ImageId: ami-12345678
  InstanceType: t2.micro
  MinInstanceCount: 1
  MaxInstanceCount: 1
  IamInstanceProfileName: myRunCmdRole
  TagSpecifications:
  - ResourceType: instance
    Tags:
    - Key: LaunchedBy
      Value: SSMAutomation
    - Key: Category
      Value: HighAvailabilityFleetHost
```

------
#### [ JSON ]

```
{
   "name":"launchInstance",
   "action":"aws:runInstances",
   "maxAttempts":3,
   "timeoutSeconds":1200,
   "onFailure":"Abort",
   "inputs":{
      "ImageId":"ami-12345678",
      "InstanceType":"t2.micro",
      "MinInstanceCount":1,
      "MaxInstanceCount":1,
      "IamInstanceProfileName":"myRunCmdRole",
      "TagSpecifications":[
         {
            "ResourceType":"instance",
            "Tags":[
               {
                  "Key":"LaunchedBy",
                  "Value":"SSMAutomation"
               },
               {
                  "Key":"Category",
                  "Value":"HighAvailabilityFleetHost"
               }
            ]
         }
      ]
   }
}
```

------

AdditionalInfo  
预留。  
类型：字符串  
必需：否

BlockDeviceMappings  
适用于实例的块储存设备。  
类型：MapList  
必需：否

ClientToken  
用于确保请求的幂等性的标识符。  
类型：字符串  
必需：否

DisableApiTermination  
打开或关闭实例 API 终止。  
类型：布尔值  
必需：否

EbsOptimized  
打开或关闭 Amazon Elastic Block Store (Amazon EBS) 优化。  
类型：布尔值  
必需：否

IamInstanceProfileArn  
针对实例的 AWS Identity and Access Management (IAM) 实例配置文件的 Amazon Resource Name (ARN)。  
类型：字符串  
必需：否

IamInstanceProfileName  
实例的 IAM 实例配置文件的名称。  
类型：字符串  
必需：否

ImageId  
Amazon Machine Image (AMI) 的 ID。  
类型：字符串  
是否必需：是

InstanceInitiatedShutdownBehavior  
指示此实例是否在系统关闭时停止或终止。  
类型：字符串  
必需：否

InstanceType  
实例类型。  
如果未提供实例类型值，则使用 m1.小型实例类型。
类型：字符串  
必需：否

KernelId  
内核的 ID。  
类型：字符串  
必需：否

KeyName  
密钥对的名称。  
类型：字符串  
必需：否

MaxInstanceCount  
要启动的实例的最大数量。  
类型：字符串  
必需：否

MetadataOptions  
实例的元数据选项。有关更多信息，请参阅 [InstanceMetadataOptionsRequest](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_InstanceMetadataOptionsRequest.html)。  
类型：StringMap  
必需：否

MinInstanceCount  
要启动的实例的最小数量。  
类型：字符串  
必需：否

监控  
打开或关闭详细监控。  
类型：布尔值  
必需：否

NetworkInterfaces  
网络接口。  
类型：MapList  
必需：否

放置  
实例的置放。  
类型：StringMap  
必需：否

PrivateIpAddress  
主要 IPv4 地址。  
类型：字符串  
必需：否

RamdiskId  
RAM 磁盘的 ID。  
类型：字符串  
必需：否

SecurityGroupIds  
实例的安全组的 ID。  
类型：StringList  
必需：否

SecurityGroups  
实例的安全组的名称。  
类型：StringList  
必需：否

SubnetId  
子网 ID。  
类型：字符串  
必需：否

TagSpecifications  
在启动期间应用于资源的标签。您只能在启动时标记实例和卷。指定的标签将应用于在启动期间创建的所有实例或卷。要在启动实例后对其进行标记，请使用 [`aws:createTags` - 为 AWS 资源创建标签](automation-action-createtag.md) 操作。  
类型：MapList（有关更多信息，请参阅 [TagSpecification](https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_TagSpecification.html)。）  
必需：否

UserData  
作为字符串文本值提供的脚本。如果输入文本值，则必须为 Base64 编码。  
类型：字符串  
必需：否Output

InstanceIds  
实例的 ID。

InstanceState  
实例的当前状态。

# `aws:sleep` - 延迟自动化


将自动化延迟指定的时间。此操作使用国际标准化组织 (ISO) 8601 日期和时间格式。有关此日期和时间格式的更多信息，请参阅 [ISO 8601](https://www.iso.org/iso-8601-date-and-time-format.html)。

**Input**  
您可将自动化延迟指定的时间。

------
#### [ YAML ]

```
name: sleep
action: aws:sleep
inputs:
  Duration: PT10M
```

------
#### [ JSON ]

```
{
   "name":"sleep",
   "action":"aws:sleep",
   "inputs":{
      "Duration":"PT10M"
   }
}
```

------

还可以将自动化延迟到指定日期和时间。如果指定日期和时间已过，操作将立即执行。

------
#### [ YAML ]

```
name: sleep
action: aws:sleep
inputs:
  Timestamp: '2020-01-01T01:00:00Z'
```

------
#### [ JSON ]

```
{
    "name": "sleep",
    "action": "aws:sleep",
    "inputs": {
        "Timestamp": "2020-01-01T01:00:00Z"
    }
}
```

------

**注意**  
自动化支持的最大延迟为 604799 秒（7 天）。

Duration  
ISO 8601 持续时间。您不能指定负数持续时间。  
类型：字符串  
必需：否

Timestamp  
ISO 8601 时间戳。如果您没有为此参数指定值，那么必须为 `Duration` 参数指定一个值。  
类型：字符串  
必需：否Output

无  


# `aws:updateVariable` – 更新运行手册变量的值


此操作会更新运行手册变量的值。值的数据类型必须与要更新的变量的数据类型相匹配。不支持数据类型转换。`aws:updateVariable` 操作不支持 `onCancel` 属性。

**Input**  
输入如下。

------
#### [ YAML ]

```
name: updateStringList
action: aws:updateVariable
inputs:
    Name: variable:variable name
    Value:
    - "1"
    - "2"
```

------
#### [ JSON ]

```
{
    "name": "updateStringList",
    "action": "aws:updateVariable",
    "inputs": {
        "Name": "variable:variable name",
        "Value": ["1","2"]
    }
}
```

------

名称  
要更新其值的变量名称。必须使用格式 `variable:variable name`  
类型：字符串  
是否必需：是

值  
要分配给变量的新值。值必须与变量的数据类型相匹配。不支持数据类型转换。  
类型：Boolean \$1 Integer \$1 MapList \$1 String \$1 StringList \$1 StringMap  
是否必需：是  
约束：  
+ MapList 最多可以包含 200 个项目。
+ 密钥长度的最小长度可以为 1，最大长度可以为 50。
+ StringList 最少可以为 0 项，最多可以为 50 项。
+ 字符串长度的最小长度可以为 1，最大长度可以为 512。Output

无  


# `aws:waitForAwsResourceProperty` - 等待 AWS 资源属性


`aws:waitForAwsResourceProperty` 操作可以让自动化等待特定的资源状态或事件状态，然后才继续自动化。有关如何使用此操作的更多示例，请参阅 [其他运行手册示例](automation-document-examples.md)。

**注意**  
此操作的默认超时值为 3600 秒（1 小时）。您可以通过指定 `aws:waitForAwsResourceProperty` 步骤的 `timeoutSeconds` 参数来限制或延长超时。有关如何使用此操作的更多信息和示例，请参阅 [处理运行手册中的超时](automation-handling-timeouts.md)。

**注意**  
`aws:waitForAwsResourceProperty` 操作支持自动节流重试。有关更多信息，请参阅 [为节流的操作配置自动重试](automation-throttling-retry.md)。

**Input**  
由您选择的 API 操作定义的输入。

------
#### [ YAML ]

```
action: aws:waitForAwsResourceProperty
inputs:
  Service: The official namespace of the service
  Api: The API operation or method name
  API operation inputs or parameters: A value
  PropertySelector: Response object
  DesiredValues:
  - Desired property value
```

------
#### [ JSON ]

```
{
  "action": "aws:waitForAwsResourceProperty",
  "inputs": {
    "Service":"The official namespace of the service",
    "Api":"The API operation or method name",
    "API operation inputs or parameters":"A value",
    "PropertySelector": "Response object",
    "DesiredValues": [
      "Desired property value"
    ]
  }
}
```

------

服务  
包含要运行的 API 操作的 AWS 服务命名空间。例如，AWS Systems Manager 的命名空间为 `ssm`。Amazon Elastic Compute Cloud (Amazon EC2) 的命名空间为 `ec2`。您可以在《AWS CLI 命令参考》的[可用服务](https://docs.aws.amazon.com/cli/latest/reference/#available-services)部分查看支持的 AWS 服务命名空间列表。  
类型：字符串  
是否必需：是

API  
要运行的 API 操作的名称。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看 API 操作（也称为方法）。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon Relational Database Service (Amazon RDS) 的所有 API 操作（方法）。  
类型：字符串  
是否必需：是

API 操作输入  
一个或多个 API 操作输入。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看可用的输入（也称为参数）。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon RDS 的所有方法。选择 [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) 方法并向下滚动以查看可用的参数，例如 **DBInstanceIdentifier**、**Name** 和 **Values**。  

```
inputs:
  Service: The official namespace of the service
  Api: The API operation name
  API input 1: A value
  API Input 2: A value
  API Input 3: A value
```

```
"inputs":{
      "Service":"The official namespace of the service",
      "Api":"The API operation name",
      "API input 1":"A value",
      "API Input 2":"A value",
      "API Input 3":"A value"
}
```
类型：由选择的 API 操作确定  
是否必需：是

PropertySelector  
响应对象中特定属性的 JSONPath。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看响应对象。在要调用的服务的**客户端**部分中选择一种方法。例如，下面的 [Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)页面中列出了 Amazon RDS 的所有方法：选择 [describe\$1db\$1instances](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html#RDS.Client.describe_db_instances) 方法，然后向下滚动到**响应结构**部分。**DBInstances** 被列为响应对象。  
类型：字符串  
是否必需：是

DesiredValues  
要继续自动化的预期状态。  
类型：MapList、StringList  
是否必需：是

# 自动化系统变量


AWS Systems Manager 自动化运行手册使用以下变量。有关如何使用这些变量的示例，请查看 `AWS-UpdateWindowsAmi` 运行手册的 JSON 源。

**查看 `AWS-UpdateWindowsAmi` 运行手册的 JSON 源**

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

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

1. 在文档列表中，使用“搜索栏”或“搜索栏”右侧的数字选择运行手册 `AWS-UpdateWindowsAmi`。

1. 选择**内容**选项卡。

**系统变量**  
自动化运行手册目前支持以下系统变量。


****  

| Variable | 详细信息 | 
| --- | --- | 
|  `global:ACCOUNT_ID`  |  在其中运行自动化的用户或角色的 AWS 账户 ID。  | 
|  `global:DATE`  |  格式为 yyyy-MM-dd 的日期（运行时间）。  | 
|  `global:DATE_TIME`  |  格式为 yyyy-MM-dd\$1HH.mm.ss 的日期和时间（运行时间）。  | 
|  `global:AWS_PARTITION`  |  资源所处的分区。对于标准 AWS 区域，分区是 `aws`。对于位于其他分区中的资源，则分区是 `aws-partitionname`。例如，AWS GovCloud (US-West) 区域中资源的区域为 `aws-us-gov`。  | 
|  `global:REGION`  |  运行手册在其中运行的区域。例如，us-east-2。  | 

**自动化变量**  
自动化运行手册支持以下自动化变量。


****  

| Variable | 详细信息 | 
| --- | --- | 
|  `automation:EXECUTION_ID`  |  分配给当前自动化的唯一标识符。例如，`1a2b3c-1a2b3c-1a2b3c-1a2b3c1a2b3c1a2b3c`。  | 

**Topics**
+ [

## 术语
](#automation-terms)
+ [

## 支持的场景
](#automation-variables-support)
+ [

## 不支持的场景
](#automation-variables-unsupported)

## 术语


以下术语描述了如何解析变量和参数。


****  

| 租期 | 定义 | 示例 | 
| --- | --- | --- | 
|  常量 ARN  |  无变量的有效 Amazon Resource Name (ARN)。  |  `arn:aws:iam::123456789012:role/roleName`  | 
|  运行手册参数  |  在运行手册级别定义的参数（例如 `instanceId`）。可在替换基本字符串时使用该参数。系统会在启动执行时间提供该参数的值。  |  <pre>{ <br />   "description": "Create Image Demo",<br />   "version": "0.3",<br />   "assumeRole": "Your_Automation_Assume_Role_ARN",<br />   "parameters":{ <br />      "instanceId": { <br />         "type": "String",<br />         "description": "Instance to create image from"<br />   }<br />}</pre>  | 
|  系统变量  |  在评估运行手册的任何部分时，被替换到运行手册中的常规变量。  |  <pre>"activities": [ <br />   { <br />      "id": "copyImage",<br />      "activityType": "AWS-CopyImage",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": { <br />         "ImageName": "{{imageName}}",<br />         "SourceImageId": "{{sourceImageId}}",<br />         "SourceRegion": "{{sourceRegion}}",<br />         "Encrypted": true,<br />         "ImageDescription": "Test CopyImage Description created on {{global:DATE}}"<br />      }<br />   }<br />]</pre>  | 
|  自动化变量  |  在评估运行手册的任何部分时，被替换到运行手册中且与自动化执行相关的变量。  |  <pre>{ <br />   "name": "runFixedCmds",<br />   "action": "aws:runCommand",<br />   "maxAttempts": 1,<br />   "onFailure": "Continue",<br />   "inputs": { <br />      "DocumentName": "AWS-RunPowerShellScript",<br />      "InstanceIds": [ <br />         "{{LaunchInstance.InstanceIds}}"<br />      ],<br />      "Parameters": { <br />         "commands": [ <br />            "dir",<br />            "date",<br />            "“{{outputFormat}}” -f “left”,”right”,”{{global:DATE}}”,”{{automation:EXECUTION_ID}}”<br />         ]<br />      }<br />   }<br />}</pre>  | 
|  Systems Manager 参数  |  在 AWS Systems Manager Parameter Store 内定义的变量。该参数不能在步骤输入中直接引用。访问该参数可能需要权限。  |  <pre><br />description: Launch new Windows test instance<br />schemaVersion: '0.3'<br />assumeRole: '{{AutomationAssumeRole}}'<br />parameters:<br />  AutomationAssumeRole:<br />    type: String<br />    default: ''<br />    description: >-<br />      (Required) The ARN of the role that allows Automation to perform the<br />      actions on your behalf. If no role is specified, Systems Manager<br />      Automation uses your IAM permissions to run this runbook.<br />  LatestAmi:<br />    type: String<br />    default: >-<br />      {{ssm:/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base}}<br />    description: The latest Windows Server 2016 AMI queried from the public parameter.<br />mainSteps:<br />  - name: launchInstance<br />    action: 'aws:runInstances'<br />    maxAttempts: 3<br />    timeoutSeconds: 1200<br />    onFailure: Abort<br />    inputs:<br />      ImageId: '{{LatestAmi}}'<br />...</pre>  | 

## 支持的场景



****  

| 场景 | 注释 | 示例 | 
| --- | --- | --- | 
|  创建时的常量 ARN `assumeRole`。  |  执行授权检查来验证是否允许调用用户传递给定的 `assumeRole`。  |  <pre>{<br />  "description": "Test all Automation resolvable parameters",<br />  "schemaVersion": "0.3",<br />  "assumeRole": "arn:aws:iam::123456789012:role/roleName",<br />  "parameters": { <br />  ...</pre>  | 
|  启动自动化时为 `AssumeRole` 提供的运行手册参数。  |  必须在运行手册的参数列表中定义。  |  <pre>{<br />  "description": "Test all Automation resolvable parameters",<br />  "schemaVersion": "0.3",<br />  "assumeRole": "{{dynamicARN}}",<br />  "parameters": {<br /> ...</pre>  | 
|  启动时为运行手册参数提供的值。  |  客户提供要用于参数的值。需在运行手册的参数列表中定义在启动时提供的所有输入。  |  <pre>...<br />"parameters": {<br />    "amiId": {<br />      "type": "String",<br />      "default": "ami-12345678",<br />      "description": "list of commands to run as part of first step"<br />    },<br />...</pre> “启动自动化执行”的输入包括：`{"amiId" : ["ami-12345678"] }`  | 
|  在运行手册内容中引用的 Systems Manager 参数。  |  变量存在于客户账户中，或者是公开访问的参数，并且运行手册的 `AssumeRole` 有权访问该变量。创建时将执行检查，以确认 `AssumeRole` 都不能访问它。不能在步骤输入中直接引用参数。  |  <pre><br />...<br />parameters:<br />    LatestAmi:<br />    type: String<br />    default: >-<br />      {{ssm:/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base}}<br />    description: The latest Windows Server 2016 AMI queried from the public parameter.<br />mainSteps:<br />  - name: launchInstance<br />    action: 'aws:runInstances'<br />    maxAttempts: 3<br />    timeoutSeconds: 1200<br />    onFailure: Abort<br />    inputs:<br />      ImageId: '{{LatestAmi}}'<br />...</pre>  | 
|  在步骤定义中引用的系统变量  |  启动自动化时被替换到运行手册中的系统变量。注入到运行手册中的值与替换发生的时间相关。换言之，由于在运行步骤之间需要花费一定时间，因此在步骤 1 中注入的时间变量的值将与在步骤 3 中注入的值不同。无需在运行手册的参数列表中设置系统变量。  |  <pre>...<br />  "mainSteps": [<br />    {<br />      "name": "RunSomeCommands",<br />      "action": "aws:runCommand",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "DocumentName": "AWS:RunPowerShell",<br />        "InstanceIds": ["{{LaunchInstance.InstanceIds}}"],<br />        "Parameters": {<br />            "commands" : [<br />                "echo {The time is now {{global:DATE_TIME}}}"<br />            ]<br />        }<br />    }<br />}, ... </pre>  | 
|  在步骤定义中引用的自动化变量。  |  无需在运行手册的参数列表中设置自动化变量。唯一的受支持自动化变量是 **自动化:EXECUTION\$1ID**。  |  <pre>...<br />"mainSteps": [<br />    {<br />      "name": "invokeLambdaFunction",<br />      "action": "aws:invokeLambdaFunction",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "FunctionName": "Hello-World-LambdaFunction",<br /><br />"Payload" : "{ "executionId" : "{{automation:EXECUTION_ID}}" }"<br />      }<br />    }<br />... </pre>  | 
|  在下一步的定义中参考上一步的输出。  |  这是一个参数重定向。可使用语法 `{{stepName.OutputName}}` 引用上一步的输出。客户不能将该语法用于运行手册参数。在引用步骤运行时解决此问题。运行手册的参数中未列出该参数。  |  <pre>...<br />"mainSteps": [<br />    {<br />      "name": "LaunchInstance",<br />      "action": "aws:runInstances",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "ImageId": "{{amiId}}",<br />        "MinInstanceCount": 1,<br />        "MaxInstanceCount": 2<br />      }<br />    },<br />    {<br />      "name":"changeState",<br />      "action": "aws:changeInstanceState",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "InstanceIds": ["{{LaunchInstance.InstanceIds}}"],<br />        "DesiredState": "terminated"<br />      }<br />    }<br /><br />... </pre>  | 

## 不支持的场景



****  

| 场景 | 注释 | 示例 | 
| --- | --- | --- | 
|  为 `assumeRole` 提供的 Systems Manager 参数创建时  |  不支持。  |  <pre>...<br /><br />{<br />  "description": "Test all Automation resolvable parameters",<br />  "schemaVersion": "0.3",<br />  "assumeRole": "{{ssm:administratorRoleARN}}",<br />  "parameters": {<br /><br />... </pre>  | 
|  步骤输入中直接引用的 Systems Manager 参数。  |  在创建时返回 `InvalidDocumentContent` 异常。  |  <pre><br />...<br />mainSteps:<br />  - name: launchInstance<br />    action: 'aws:runInstances'<br />    maxAttempts: 3<br />    timeoutSeconds: 1200<br />    onFailure: Abort<br />    inputs:<br />      ImageId: '{{ssm:/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base}}'<br />...</pre>  | 
|  变量步骤定义  |  运行手册中步骤的定义由变量构建而成。  |  <pre>...<br /><br />"mainSteps": [<br />    {<br />      "name": "LaunchInstance",<br />      "action": "aws:runInstances",<br />      "{{attemptModel}}": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "ImageId": "ami-12345678",<br />        "MinInstanceCount": 1,<br />        "MaxInstanceCount": 2<br />      }<br /><br />...<br /><br />User supplies input : { "attemptModel" : "minAttempts" } </pre>  | 
|  交叉引用运行手册参数  |  用户在启动时提供了输入参数，而该参数引用了运行手册中的另一参数。  |  <pre>...<br />"parameters": {<br />    "amiId": {<br />      "type": "String",<br />      "default": "ami-7f2e6015",<br />      "description": "list of commands to run as part of first step"<br />    },<br />    "alternateAmiId": {<br />      "type": "String",<br />      "description": "The alternate AMI to try if this first fails".<br /><br />"default" : "{{amiId}}"<br />    },<br /><br />... </pre>  | 
|  多层扩展  |  运行手册定义了评估变量名称的变量。它位于变量分隔符（即 *\$1\$1 \$1\$1*）内，并扩展为变量/参数的值。  |  <pre>...<br />  "parameters": {<br />    "firstParameter": {<br />      "type": "String",<br />      "default": "param2",<br />      "description": "The parameter to reference"<br />    },<br />    "secondParameter": {<br />      "type": "String",<br />      "default" : "echo {Hello world}",<br />      "description": "What to run"<br />    }<br />  },<br />  "mainSteps": [{<br />      "name": "runFixedCmds",<br />      "action": "aws:runCommand",<br />      "maxAttempts": 1,<br />      "onFailure": "Continue",<br />      "inputs": {<br />        "DocumentName": "AWS-RunPowerShellScript",<br /><br />"InstanceIds" : "{{LaunchInstance.InstanceIds}}",<br />        "Parameters": {<br />          "commands": [ "{{ {{firstParameter}} }}"]<br /><br />}<br /><br />...<br /><br />Note: The customer intention here would be to run a command of "echo {Hello world}" </pre>  | 
|  引用属于不同变量类型的运行手册步骤的输出  |  用户在后续步骤中引用前面运行手册步骤的输出。输出是一个不符合后续步骤中的操作要求的变量类型。  |  <pre>...<br />mainSteps:<br />- name: getImageId<br />  action: aws:executeAwsApi<br />  inputs:<br />    Service: ec2<br />    Api: DescribeImages<br />    Filters:  <br />    - Name: "name"<br />      Values: <br />      - "{{ImageName}}"<br />  outputs:<br />  - Name: ImageIdList<br />    Selector: "$.Images"<br />    Type: "StringList"<br />- name: copyMyImages<br />  action: aws:copyImage<br />  maxAttempts: 3<br />  onFailure: Abort<br />  inputs:<br />    SourceImageId: {{getImageId.ImageIdList}}<br />    SourceRegion: ap-northeast-2<br />    ImageName: Encrypted Copies of LAMP base AMI in ap-northeast-2<br />    Encrypted: true <br />... <br />Note: You must provide the type required by the Automation action. <br />In this case, aws:copyImage requires a "String" type variable but the preceding step outputs a "StringList" type variable.<br />                                        </pre>  | 

# 创建您自己的运行手册


自动化运行手册定义了自动化运行时 Systems Manager 在托管实例和其他 AWS 资源上执行的*操作*。Automation 是 AWS Systems Manager 中的一项工具。运行手册包含一个或多个按顺序运行的步骤。每个步骤是根据单个操作生成的。可以将一个步骤的输出作为后面步骤的输入。

运行这些操作及其步骤的过程称为*自动化*。

让您可以在 AWS 环境中自动完成各种不同操作的运行手册支持的操作类型。例如，通过使用 `executeScript` 操作类型，您可以直接在运行手册中嵌入 Python 或 PowerShell 脚本。（在创建自定义运行手册时，您可以按内联方式添加脚本，或者从 S3 存储桶或本地计算机中附加脚本。） 您可以使用 `createStack` 和 `deleteStack` 操作类型自动管理 AWS CloudFormation 资源。此外，通过使用 `executeAwsApi` 操作类型，步骤可以在任意 AWS 服务中运行*任意* API 操作，包括创建或删除 AWS 资源、启动其他进程、触发通知等。

有关自动化支持的所有 20 种操作类型的列表，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)。

AWS Systems Manager 自动化提供了几个包含预定义步骤的文档，您可以使用这些步骤执行常见任务，例如重新启动一个或多个 Amazon Elastic Compute Cloud (Amazon EC2) 实例或创建 Amazon Machine Image (AMI)。您还可以创建自己的运行手册并与其他 AWS 账户 共享，或者向所有自动化用户公开。

运行手册是使用 YAML 或 JSON 编写的。但是，通过使用 Systems Manager 自动化中的**文档生成器**，您可以创建运行手册，而无需使用本机 JSON 或 YAML 创作。

**重要**  
如果您运行使用 AWS Identity and Access Management (IAM) 服务角色调用其他服务的自动化工作流程，请注意必须使用权限将该服务角色配置为调用这些服务。该要求适用于所有 AWS 自动化运行手册（`AWS-*` 运行手册），例如 `AWS-ConfigureS3BucketLogging`、`AWS-CreateDynamoDBBackup` 和 `AWS-RestartEC2Instance` 运行手册等。对于您创建的任何自定义自动化运行手册，如果这些文档使用调用其他服务的操作来调用其他 AWS 服务，则此要求同样适用。例如，如果使用 `aws:executeAwsApi`、`aws:createStack` 或 `aws:copyImage` 操作，则您必须配置具有权限的服务角色来调用这些服务。您可以将 IAM 内联策略添加到该角色，从而向其他 AWS 服务授予权限。有关更多信息，请参阅 [（可选）添加自动化内联策略或客户管理型策略来调用其他 AWS 服务](automation-setup-iam.md#add-inline-policy)。

有关可在运行手册中指定的操作的信息，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)。

有关使用 AWS Toolkit for Visual Studio Code 创建运行手册的信息，请参阅 *《AWS Toolkit for Visual Studio Code 用户指南》* 中的 [使用 Systems Manager 自动化文档](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/systems-manager-automation-docs.html)。

有关使用视觉设计器创建自定义运行手册的信息，请参阅 [自动化运行手册的视觉对象设计体验](automation-visual-designer.md)。

**Contents**
+ [

# 自动化运行手册的视觉对象设计体验
](automation-visual-designer.md)
  + [

# 视觉对象设计体验界面概述
](visual-designer-interface-overview.md)
    + [

## 操作浏览器
](visual-designer-interface-overview.md#visual-designer-actions)
    + [

## Canvas
](visual-designer-interface-overview.md#visual-designer-canvas)
    + [

## 表单
](visual-designer-interface-overview.md#visual-designer-form)
    + [

## 键盘快捷键
](visual-designer-interface-overview.md#visual-designer-keyboard-shortcuts)
  + [

# 使用视觉对象设计体验
](visual-designer-use.md)
    + [

## 创建运行手册工作流程
](visual-designer-use.md#visual-designer-create-runbook-workflow)
    + [

## 设计运行手册
](visual-designer-use.md#visual-designer-build)
    + [

## 更新运行手册
](visual-designer-use.md#visual-designer-update-runbook)
    + [

## 导出运行手册
](visual-designer-use.md#visual-designer-export-runbook)
  + [

# 配置操作的输入和输出
](visual-designer-action-inputs-outputs.md)
    + [

## 为操作提供输入数据
](visual-designer-action-inputs-outputs.md#providing-input)
    + [

## 定义操作的输出数据
](visual-designer-action-inputs-outputs.md#defining-output)
  + [

# 视觉对象设计体验中的错误处理
](visual-designer-error-handling.md)
    + [

## 出现错误时重试操作
](visual-designer-error-handling.md#retry-actions)
    + [

## 超时
](visual-designer-error-handling.md#timeout-seconds)
    + [

## 失败的操作
](visual-designer-error-handling.md#failure-actions)
    + [

## 取消的操作
](visual-designer-error-handling.md#cancel-actions)
    + [

## 关键操作
](visual-designer-error-handling.md#critical-actions)
    + [

## 结束操作
](visual-designer-error-handling.md#end-actions)
  + [

# 教程：使用视觉对象设计体验创建运行手册
](visual-designer-tutorial.md)
    + [

## 步骤 1：导航到视觉对象设计体验
](visual-designer-tutorial.md#navigate-console)
    + [

## 步骤 2：创建工作流程
](visual-designer-tutorial.md#create-workflow)
    + [

## 步骤 3：查看自动生成的代码
](visual-designer-tutorial.md#view-generated-code)
    + [

## 步骤 4：运行新的运行手册
](visual-designer-tutorial.md#use-tutorial-runbook)
    + [

## 第 5 步：清理
](visual-designer-tutorial.md#cleanup-tutorial-runbook)
+ [

# 创作自动化运行手册
](automation-authoring-runbooks.md)
  + [

## 识别您的使用案例
](automation-authoring-runbooks.md#automation-authoring-runbooks-use-case)
  + [

## 设置开发环境
](automation-authoring-runbooks.md#automation-authoring-runbooks-environment)
  + [

## 开发运行手册内容
](automation-authoring-runbooks.md#automation-authoring-runbooks-developing-content)
  + [

# 示例 1：创建父子运行手册
](automation-authoring-runbooks-parent-child-example.md)
    + [

## 创建子运行手册
](automation-authoring-runbooks-parent-child-example.md#automation-authoring-runbooks-child-runbook)
    + [

## 创建父运行手册
](automation-authoring-runbooks-parent-child-example.md#automation-authoring-runbooks-parent-runbook)
  + [

# 示例 2：脚本化运行手册
](automation-authoring-runbooks-scripted-example.md)
  + [

# 其他运行手册示例
](automation-document-examples.md)
    + [

# 部署 VPC 架构和 Microsoft Active Directory 域控制器
](automation-document-architecture-deployment-example.md)
    + [

# 从最新快照还原根卷
](automation-document-instance-recovery-example.md)
    + [

# 创建 AMI 和跨区域副本
](automation-document-backup-maintenance-example.md)
+ [

# 创建填充 AWS 资源的输入参数
](populating-input-parameters.md)
+ [

# 正在使用文档生成器创建运行手册
](automation-document-builder.md)
  + [

## 使用文档生成器创建运行手册
](automation-document-builder.md#create-runbook)
  + [

## 创建运行脚本的运行手册
](automation-document-builder.md#create-runbook-scripts)
+ [

# 在运行手册中使用脚本
](automation-document-script-considerations.md)
  + [

## 使用运行手册的权限
](automation-document-script-considerations.md#script-permissions)
  + [

## 将脚本添加到运行手册
](automation-document-script-considerations.md#adding-scripts)
  + [

## 运行手册的脚本限制
](automation-document-script-considerations.md#script-constraints)
+ [

# 在运行手册中使用条件语句
](automation-branch-condition.md)
  + [

## 使用 `aws:branch` 操作
](automation-branch-condition.md#branch-action-explained)
    + [

### 在运行手册中创建 `aws:branch` 步骤
](automation-branch-condition.md#create-branch-action)
      + [

#### 关于创建输出变量
](automation-branch-condition.md#branch-action-output)
    + [

### 示例 `aws:branch` 运行手册
](automation-branch-condition.md#branch-runbook-examples)
    + [

### 使用运算符创建复杂的分支自动化
](automation-branch-condition.md#branch-operators)
  + [

## 如何使用条件选项的示例
](automation-branch-condition.md#conditional-examples)
+ [

# 使用操作输出作为输入
](automation-action-outputs-inputs.md)
  + [

## 在运行手册中使用 JSONPath
](automation-action-outputs-inputs.md#automation-action-json-path)
+ [

# 为 Automation 创建 Webhook 集成
](creating-webhook-integrations.md)
  + [

## 创建集成（控制台）
](creating-webhook-integrations.md#creating-integrations-console)
  + [

## 创建集成（命令行）
](creating-webhook-integrations.md#creating-integrations-commandline)
  + [

## 为集成创建 Webhooks
](creating-webhook-integrations.md#creating-webhooks)
+ [

# 处理运行手册中的超时
](automation-handling-timeouts.md)

# 自动化运行手册的视觉对象设计体验


AWS Systems Manager Automation 提供低代码的视觉对象设计体验，可帮助您创建自动化运行手册。视觉对象设计体验提供拖放界面，可以选择添加自己的代码，这样您就可以更轻松地创建和编辑运行手册。借助视觉对象设计体验，您可以执行以下操作：
+ 控制条件语句。
+ 控制如何筛选或转换每个操作的输入和输出。
+ 配置错误处理。
+ 制作新运行手册的原型。
+ 使用原型运行手册作为采用 AWS Toolkit for Visual Studio Code 进行本地开发的起点。

创建或编辑运行手册时，您可以从 [Automation 控制台](https://console.aws.amazon.com/systems-manager/automation/home?region=us-east-1#/)访问视觉对象设计体验。创建运行手册时，视觉对象设计体验会验证您的工作并自动生成代码。您可以查看生成的代码，也可以将其导出以供本地开发。完成后，您可以保存并运行运行手册以及在 Systems Manager Automation 控制台中检查结果。

**Topics**
+ [界面概述](visual-designer-interface-overview.md)
+ [

# 使用视觉对象设计体验
](visual-designer-use.md)
+ [配置输入和输出](visual-designer-action-inputs-outputs.md)
+ [

# 视觉对象设计体验中的错误处理
](visual-designer-error-handling.md)
+ [

# 教程：使用视觉对象设计体验创建运行手册
](visual-designer-tutorial.md)

# 视觉对象设计体验界面概述
界面概述

Systems Manager Automation 的视觉对象设计体验是一种低代码的视觉对象工作流程设计器，可帮助您创建自动化运行手册。

通过界面组件的概述了解视觉对象设计体验：

![\[视觉对象设计体验组件\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_overview.png)

+ **操作**浏览器包含**操作**、**AWS API** 和**运行手册**选项卡。
+ 在*画布*中，您可以将操作拖放到工作流程图中、更改操作顺序以及选择要配置或查看的操作。
+ 在**表单**面板中，您可以查看和编辑在画布上选择的任何操作的属性。选择**内容**开关以查看运行手册的 YAML 或 JSON，并突出显示当前选定的操作。

当您需要帮助时，**信息**链接会打开一个包含上下文信息的面板。这些面板还包括指向 Systems Manager Automation 文档中相关主题的链接。

## 操作浏览器


在**操作**浏览器中，您可以选择要拖放到工作流程图中的操作。您可以使用**操作**浏览器顶部的搜索字段搜索所有操作。**操作**浏览器包含以下选项卡：
+ **操作**选项卡提供了自动化操作列表，您可以将这些操作拖放到画布中运行手册的工作流程图中。
+ **AWS API** 选项卡提供了 AWS API 列表，您可以将这些 API 拖放到画布中运行手册的工作流程图中。
+ **运行手册**选项卡提供了几个随时可用、可重复使用的运行手册作为构建块，您可以将其用于各种用例。例如，您可以使用运行手册在工作流程中对 Amazon EC2 实例执行常见的修复任务，而无需重新创建相同的操作。

![\[视觉对象设计体验操作浏览器\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_actions_multi_view.png)


## Canvas


选择要添加到自动化中的操作后，将其拖动到画布并放入工作流程图中。您还可以拖放操作，将其移动到运行手册工作流程中的不同位置。如果您的工作流程很复杂，您可能无法在画布面板上查看其所有内容。使用画布顶部的控件来放大或缩小。要查看工作流程的不同部分，您可以在画布中拖动工作流程图。

在**操作**浏览器中拖动一项操作，将其放入运行手册的工作流程图中。有一条线将显示其在您工作流程中的放置位置。要更改操作的顺序，您可以将其拖动到工作流程中的其他位置。新操作已添加到您的工作流程中，其代码已自动生成。

![\[视觉对象设计体验画布\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_canvas.png)


## 表单


在运行手册工作流程中添加操作后，您可以对其进行配置以满足您的用例。选择希望配置的操作，您将在**表单**面板中看到其参数和选项。您还可以通过选择**内容**开关来查看 YAML 或 JSON 代码。与您所选操作关联的代码会突出显示。

![\[视觉对象设计体验表单面板\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_form.png)


![\[视觉对象设计体验内容面板\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_content.png)


## 键盘快捷键


视觉对象设计体验支持下表中所示的键盘快捷键。


| 键盘快捷键 | 函数 | 
| --- | --- | 
| Ctrl\$1Z | 撤销上次的操作。 | 
| Ctrl\$1Shift\$1Z | 重做上次的操作。 | 
| Alt\$1C | 将工作流程置于画布中心。 | 
| 退格键 | 删除所有选定状态。 | 
| 删除 | 删除所有选定状态。 | 
| Ctrl\$1D | 复制所选状态。 | 

# 使用视觉对象设计体验


学习使用视觉对象设计体验创建、编辑和运行运行手册工作流程。工作流程准备就绪后，您可以将其保存或导出。您还可以使用视觉对象设计体验进行快速原型制作。

## 创建运行手册工作流程


1. 登录 [Systems Manager Automation 控制台](https://console.aws.amazon.com/systems-manager/automation/home?region=us-east-1#/)。

1. 选择**创建运行手册**。

1. 在**名称**方框中，输入运行手册的名称，例如 `MyNewRunbook`。

1. 在**设计**和**代码**切换开关旁边，选择铅笔图标并输入运行手册的名称。

现在，您可以为新的运行手册设计工作流程。

## 设计运行手册


 要使用视觉对象设计体验设计运行手册工作流程，您可以将自动化操作从**操作**浏览器拖动到画布中，将其放置在运行手册工作流程中所需的位置。您也可以通过将操作拖动到不同的位置来重新排序工作流程中的操作。当您将操作拖动到画布上时，工作流程中可以放置该操作的任何位置都会显示一条线。将操作放入画布后，其代码将自动生成并添加到运行手册的内容中。

如果您知道希望添加的操作的名称，请使用**操作**浏览器顶部的搜索框来查找该操作。

将操作放入画布后，使用右侧的**表单**面板对其进行配置。此面板包含您在画布上放置的每个自动化操作或 API 操作的**常规**、**输入**、**输出**和**配置**选项卡。例如，**常规**选项卡由以下部分组成：
+ **步骤名称**用于标识该步骤。为步骤名称指定唯一值。
+ **描述**可帮助您描述在运行手册的工作流程中操作正在执行的内容。

**输入**选项卡包含因操作而异的字段。例如，`aws:executeScript` 自动化操作由以下部分组成：
+ **运行时系统**是运行所提供脚本的语言。
+ **处理程序**是函数的名称。您必须确保在处理程序中定义的函数具有两个参数：`events` 和 `context`。PowerShell 运行时系统不支持此参数。
+ **脚本**是您想要在工作流程期间运行的嵌入式脚本。
+ （可选）**附件**适用于可由操作调用的独立脚本或 .zip 文件。对于 JSON 运行手册，此参数为必需项。

**输出**选项卡可帮助您指定希望从操作中输出的值。您可以在工作流程的后续操作中引用输出值，也可以根据操作生成输出以用于日志记录。并非所有操作都将有**输出**选项卡，因为并非所有操作都支持输出。例如，`aws:pause` 操作就不支持输出。对于支持输出的操作，**输出**选项卡由以下部分组成：
+ **名称**是用于输出值的名称。您可以在工作流程的后续操作中引用输出。
+ **选择器**是以 `"$."` 开头的 JSONPath 表达式字符串，用于选择 JSON 元素中的一个或多个组件。
+ **类型**是输出值的数据类型。例如，`String` 或 `Integer` 数据类型。

**配置**选项卡包含所有自动化操作均可使用的属性和选项。该操作由以下部分组成：
+ **最大尝试次数**属性是操作失败时重试的次数。
+ **超时秒数**属性指定操作的超时值。
+ **至关重要**属性确定操作失败是否会停止整个自动化。
+ **下一步**属性确定自动化在运行手册中接下来要执行的操作。
+ **失败时**属性确定操作失败时自动化在运行手册中接下来要执行的操作。
+ **取消时**属性确定用户取消自动操作时自动化在运行手册中接下来要执行的操作。

要删除操作，您可以使用画布上方工具栏中的退格键，或者右键单击并选择**删除操作**。

随着工作流程的发展，其可能不适合画布。为帮助使工作流程适合画布，请尝试以下选项之一：
+ 使用侧面板上的控件调整面板大小或关闭面板。
+ 使用画布顶部的工具栏放大或缩小工作流程图。

## 更新运行手册


您可以通过创建新版本的运行手册来更新现有的运行手册工作流程。可以通过使用视觉对象设计体验或直接编辑代码来更新运行手册。要更新现有运行手册，请参照以下过程：

1. 登录 [Systems Manager Automation 控制台](https://console.aws.amazon.com/systems-manager/automation/home?region=us-east-1#/)。

1. 选择要更新的运行手册。

1. 选择 **Create new version**。

1. 视觉对象设计体验有两个窗格：代码窗格和视觉对象工作流程窗格。在视觉对象工作流程窗格中选择**设计**，以使用视觉对象设计体验编辑您的工作流程。完成后，选择**创建新版本**以保存更改并退出。

1. （可选）使用代码窗格以 YAML 或 JSON 格式编辑运行手册内容。

## 导出运行手册


要导出运行手册的工作流程 YAML 或 JSON 代码以及工作流程图，请参照以下过程：

1. 在**文档**控制台中选择您的运行手册。

1. 选择 **Create new version**。

1. 在**操作**下拉菜单中，选择是否要导出图表或运行手册，以及您喜欢的格式。

# 配置操作的输入和输出
配置输入和输出

每个自动化操作都会根据其收到的输入进行响应。在大多数情况下，您随后会将输出传递给后续操作。在视觉对象设计体验中，您可以在**表单**面板的**输入**和**输出**选项卡中配置操作的输入和输出数据。

有关如何定义和使用自动化操作输出的详细信息，请参阅 [使用操作输出作为输入](automation-action-outputs-inputs.md)。

## 为操作提供输入数据


每个自动化操作都有一个或多个输入，您必须为其提供值。您为操作输入提供的值由操作接受的数据类型和格式决定。例如，这些 `aws:sleep` 操作要求 `Duration` 输入采用 ISO 8601 格式的字符串值。

通常，您在运行手册的工作流程中使用操作，这些操作将返回要在后续操作中使用的输出。请务必确保输入值正确，以避免运行手册的工作流程出现错误。输入值也很重要，因为其决定了操作是否返回预期的输出。例如，在使用 `aws:executeAwsApi` 操作时，您需要确保为 API 操作提供了正确的值。

## 定义操作的输出数据


一些自动化操作在执行其定义的操作后会返回输出。返回输出的操作要么具有预定义的输出，要么允许您自己定义输出。例如，`aws:createImage` 操作具有返回 `ImageId` 和 `ImageState` 的预定义输出。相比之下，通过 `aws:executeAwsApi` 操作，您可以定义您想要从指定 API 操作中获得的输出。因此，您可以从单个 API 操作中返回一个或多个值，以便在后续操作中使用。

为自动化操作定义自己的输出需要您指定输出的名称、数据类型和输出值。要继续使用 `aws:executeAwsApi` 操作作为示例，假设您正在从 Amazon EC2 调用 `DescribeInstances` API 操作。在此示例中，您想要返回或输出 Amazon EC2 实例的 `State`，并根据输出对运行手册的工作流程进行分支。您可以选择命名输出 **InstanceState**，然后使用 **String** 数据类型。

定义输出实际值的过程因操作而异。例如，如果您使用的是 `aws:executeScript` 操作，则必须在函数中使用 `return` 语句为输出提供数据。对于 `aws:executeAwsApi`、`aws:waitForAwsResourceProperty` 和 `aws:assertAwsResourceProperty` 等其他操作，则需要 `Selector`。`Selector`（或某些操作所指的 `PropertySelector`），是一个 JSONPath 字符串，用于处理来自 API 操作的 JSON 响应。了解 API 操作的 JSON 响应对象的结构至关重要，这样您才能为输出选择正确的值。使用前面提到 `DescribeInstances` API 操作，请参阅以下 JSON 响应示例：

```
{
  "reservationSet": {
    "item": {
      "reservationId": "r-1234567890abcdef0",
      "ownerId": 123456789012,
      "groupSet": "",
      "instancesSet": {
        "item": {
          "instanceId": "i-1234567890abcdef0",
          "imageId": "ami-bff32ccc",
          "instanceState": {
            "code": 16,
            "name": "running"
          },
          "privateDnsName": "ip-192-168-1-88.eu-west-1.compute.internal",
          "dnsName": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com",
          "reason": "",
          "keyName": "my_keypair",
          "amiLaunchIndex": 0,
          "productCodes": "",
          "instanceType": "t2.micro",
          "launchTime": "2018-05-08T16:46:19.000Z",
          "placement": {
            "availabilityZone": "eu-west-1c",
            "groupName": "",
            "tenancy": "default"
          },
          "monitoring": {
            "state": "disabled"
          },
          "subnetId": "subnet-56f5f000",
          "vpcId": "vpc-11112222",
          "privateIpAddress": "192.168.1.88",
          "ipAddress": "54.194.252.215",
          "sourceDestCheck": true,
          "groupSet": {
            "item": {
              "groupId": "sg-e4076000",
              "groupName": "SecurityGroup1"
            }
          },
          "architecture": "x86_64",
          "rootDeviceType": "ebs",
          "rootDeviceName": "/dev/xvda",
          "blockDeviceMapping": {
            "item": {
              "deviceName": "/dev/xvda",
              "ebs": {
                "volumeId": "vol-1234567890abcdef0",
                "status": "attached",
                "attachTime": "2015-12-22T10:44:09.000Z",
                "deleteOnTermination": true
              }
            }
          },
          "virtualizationType": "hvm",
          "clientToken": "xMcwG14507example",
          "tagSet": {
            "item": {
              "key": "Name",
              "value": "Server_1"
            }
          },
          "hypervisor": "xen",
          "networkInterfaceSet": {
            "item": {
              "networkInterfaceId": "eni-551ba000",
              "subnetId": "subnet-56f5f000",
              "vpcId": "vpc-11112222",
              "description": "Primary network interface",
              "ownerId": 123456789012,
              "status": "in-use",
              "macAddress": "02:dd:2c:5e:01:69",
              "privateIpAddress": "192.168.1.88",
              "privateDnsName": "ip-192-168-1-88.eu-west-1.compute.internal",
              "sourceDestCheck": true,
              "groupSet": {
                "item": {
                  "groupId": "sg-e4076000",
                  "groupName": "SecurityGroup1"
                }
              },
              "attachment": {
                "attachmentId": "eni-attach-39697adc",
                "deviceIndex": 0,
                "status": "attached",
                "attachTime": "2018-05-08T16:46:19.000Z",
                "deleteOnTermination": true
              },
              "association": {
                "publicIp": "54.194.252.215",
                "publicDnsName": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com",
                "ipOwnerId": "amazon"
              },
              "privateIpAddressesSet": {
                "item": {
                  "privateIpAddress": "192.168.1.88",
                  "privateDnsName": "ip-192-168-1-88.eu-west-1.compute.internal",
                  "primary": true,
                  "association": {
                    "publicIp": "54.194.252.215",
                    "publicDnsName": "ec2-54-194-252-215.eu-west-1.compute.amazonaws.com",
                    "ipOwnerId": "amazon"
                  }
                }
              },
              "ipv6AddressesSet": {
                "item": {
                  "ipv6Address": "2001:db8:1234:1a2b::123"
                }
              }
            }
          },
          "iamInstanceProfile": {
            "arn": "arn:aws:iam::123456789012:instance-profile/AdminRole",
            "id": "ABCAJEDNCAA64SSD123AB"
          },
          "ebsOptimized": false,
          "cpuOptions": {
            "coreCount": 1,
            "threadsPerCore": 1
          }
        }
      }
    }
  }
}
```

在 JSON 响应对象中，实例 `State` 嵌套在 `Instances` 对象中，而该对象嵌套在 `Reservations` 对象中。要返回实例 `State` 的值，请使用以下字符串作为 `Selector`，以便可以在输出中使用该值：**\$1.Reservations[0].Instances[0].State.Name**。

要在运行手册工作流程的后续操作中引用输出值，请使用以下格式：`{{ StepName.NameOfOutput }}`。例如 **\$1\$1 GetInstanceState.InstanceState \$1\$1**。在视觉对象设计体验中，您可以使用输入下拉菜单选择要在后续操作中使用的输出值。在后续操作中使用输出时，输出的数据类型必须与输入的数据类型相匹配。在此示例中，`InstanceState` 输出为 `String`。因此，要在后续操作的输入中使用该值，输入必须接受 `String`。

# 视觉对象设计体验中的错误处理


默认情况下，当操作报告错误时，自动化会完全停止运行手册的工作流程。这是因为所有操作 `onFailure` 属性的默认值为 `Abort`。您可以配置自动化如何处理运行手册工作流程中错误。即使您配置了错误处理，某些错误仍可能导致自动化失败。有关更多信息，请参阅 [Systems Manager 自动化故障排除](automation-troubleshooting.md)。在视觉对象设计体验中，您可以在**配置**面板中配置错误处理。

![\[错误处理选项\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_error_handling.png)


## 出现错误时重试操作


要在出现错误时重试操作，请为**最大尝试次数**属性指定一个值。默认值是 1。如果您指定的值大于 1，则直到所有重试尝试失败后，才会将此操作视为失败。

## 超时


您可以为操作配置超时，以设置操作在失败之前可以运行的最大秒数。要配置超时，请在**超时秒数**属性中输入操作在失败之前应等待的秒数。如果达到超时并且操作的 `Max attempts` 值大于 1，则在重试完成之前该步骤不会被视为已超时。

## 失败的操作


默认情况下，当操作失败时，自动化会完全停止运行手册的工作流程。您可以通过为运行手册中操作的**失败时**属性指定替代值来修改此行为。如果您希望工作流程继续到运行手册中的下一步，请选择**继续**。如果您希望工作流程跳至运行手册中的其他后续步骤，请选择**步骤**，然后输入该步骤的名称。

## 取消的操作


默认情况下，当用户取消操作时，自动化会完全停止运行手册的工作流程。您可以通过为运行手册中操作的**取消时**属性指定替代值来修改此行为。如果您希望工作流程跳至运行手册中的其他后续步骤，请选择**步骤**，然后输入该步骤的名称。

## 关键操作


您可以将某项操作指定为*关键*操作，这意味着其决定了自动化的总体报告状态。如果具有此指定的步骤失败，则无论其他操作是否成功，自动化都会将最终状态报告为 `Failed`。要将某项操作配置为关键，请将**至关重要**属性的默认值保留为 **True**。

## 结束操作


**结束**属性在指定操作结束时停止自动化。此属性的默认值为 `false`。如果您为操作配置此属性，则无论操作成功还是失败，自动化都会停止。此属性最常与 `aws:branch` 操作一起使用，以处理意外或未定义的输入值。以下示例显示了期望实例状态为 `running`、`stopping` 或 `stopped` 的运行手册。如果实例处于不同的状态，则自动化结束。

![\[视觉对象设计体验就是结束示例\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_is_end_example.png)


# 教程：使用视觉对象设计体验创建运行手册


在本教程中，您将学习使用 Systems Manager Automation 提供的视觉对象设计体验的基础知识。在视觉对象设计体验中，您可以创建使用多个操作的运行手册。您可以使用拖放功能在画布上排列操作。您还可以搜索、选择和配置这些操作。然后，您可以查看为运行手册工作流程自动生成的 YAML 代码、退出视觉对象设计体验、运行运行手册并查看执行详情。

本教程还向您展示了如何更新运行手册和查看新版本。在本教程的最后，您将执行清理步骤并删除运行手册。

完成本教程的学习后，您将知道如何使用视觉对象设计体验来创建运行手册。您还将了解如何更新、运行和删除运行手册。

**注意**  
在开始学习本教程之前，请确保完成 [设置自动化](automation-setup.md)。

**Topics**
+ [

## 步骤 1：导航到视觉对象设计体验
](#navigate-console)
+ [

## 步骤 2：创建工作流程
](#create-workflow)
+ [

## 步骤 3：查看自动生成的代码
](#view-generated-code)
+ [

## 步骤 4：运行新的运行手册
](#use-tutorial-runbook)
+ [

## 第 5 步：清理
](#cleanup-tutorial-runbook)

## 步骤 1：导航到视觉对象设计体验


1. 登录 [Systems Manager Automation 控制台](https://console.aws.amazon.com/systems-manager/automation/home?region=us-east-1#/)。

1. 选择**创建自动化运行手册**。

## 步骤 2：创建工作流程


在视觉对象设计体验中，工作流程是画布上运行手册的图形表示。您可以使用视觉对象设计体验来定义、配置和检查运行手册的各个操作。

**创建工作流程**

1. 在**设计**和**代码**切换开关旁边，选择铅笔图标并输入运行手册的名称。在本教程中，请输入 **VisualDesignExperienceTutorial**。  
![\[视觉对象设计体验为您的运行手册命名\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_tutorial_name.png)

1. 在**表单**面板的**文档属性**部分，展开**输入参数**下拉菜单，然后选择**添加参数**。

   1. 在**参数名称**字段中，输入 **InstanceId**。

   1. 在**类型**下拉菜单中，选择 **AWS::EC2::Instance**。

   1. 选择**必需**开关。  
![\[创建运行手册的参数\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_actions_tutorial_parameter.png)

1. 在 **AWS API** 浏览器中，在搜索栏中输入 **DescribeInstances**。

1. 将 **Amazon EC2 – DescribeInstances** 操作拖动到空白画布上。

1. 对于**步骤名称**，请输入一个值。在本教程中，您可以使用名称 **GetInstanceState**。  
![\[选择 Amazon EC2 描述实例 API 操作。\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_tutorial_api_action.png)

   1. 展开**其他输入**下拉菜单，然后在**输入名称**字段中输入 **InstanceIds**。

   1. 选择**输入**选项卡。

   1. 在**输入值**字段中，选择 **InstanceId** 文档输入。这将引用在过程开始时创建的输入参数的值。鉴于 `DescribeInstances` 操作的 **InstanceIds** 输入接受 `StringList` 值，必须将 **InstanceId** 输入用方括号括起来。**输入值**的 YAML 应与以下内容匹配：**['\$1\$1 InstanceId \$1\$1']**。

   1. 在**输出**选项卡中，请选择**添加输出**，然后在**名称**字段中输入 **InstanceState**。

   1. 在**选择器**字段中，请输入 **\$1.Reservations[0].Instances[0].State.Name**。

   1. 在**类型**下拉菜单中，请选择**字符串**。

1. 从**操作**浏览器中拖动**分支**操作，然后将其放入 **`GetInstanceState`** 步骤下方。

1. 对于**步骤名称**，请输入一个值。在本教程中，请使用名称 `BranchOnInstanceState`。

   要定义分支逻辑，请执行以下操作：

   1. 在画布上选择 **`Branch`** 状态。然后，在**输入**和**选择**下，选择铅笔图标以编辑**规则 \$11**。

   1. 选择**添加条件**。

   1. 在**规则 \$11 的条件**对话框中，从**变量**下拉菜单中选择 **GetInstanceState.InstanceState** 步骤输出。

   1. 对于**运算符**，请选择**等于**。

   1. 对于**值**，请从下拉列表中选择**字符串**。输入 **stopped**。  
![\[定义分支操作的条件。\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_tutorial_condition.png)

   1. 选择**保存条件**。

   1. 选择**添加新的选择规则**。

   1. 为**规则 \$12** 选择**添加条件**。

   1. 在**规则 \$12 的条件**对话框中，从**变量**下拉菜单中选择 **GetInstanceState.InstanceState** 步骤输出。

   1. 对于**运算符**，请选择**等于**。

   1. 对于**值**，请从下拉列表中选择**字符串**。输入 **stopping**。

   1. 选择**保存条件**。

   1. 选择**添加新的选择规则**。

   1. 对于**规则 \$13**，请选择**添加条件**。

   1. 在**规则 \$13 的条件**对话框中，从**变量**下拉菜单中选择 **GetInstanceState.InstanceState** 步骤输出。

   1. 对于**运算符**，请选择**等于**。

   1. 对于**值**，请从下拉列表中选择**字符串**。输入 **running**。

   1. 选择**保存条件**。

   1. 在**默认规则**中，选择**转到结尾**作为**默认步骤**。

1. 将**更改实例状态**操作拖动到 **\$1\$1 GetInstanceState.InstanceState \$1\$1 == "stopped"** 条件下的**将操作拖动到此处**空白框中。

   1. 对于**步骤名称**，请输入 **StartInstance**。

   1. 在**输入**选项卡的**实例 ID** 下，从下拉菜单中选择 **InstanceId** 文档输入值。

   1. 对于**期望状态**，请指定 **`running`**。

1. 将**等待 AWS 资源**操作拖动到 **\$1\$1 GetInstanceState.InstanceState \$1\$1 == "stopping"** 条件下的**将操作拖动到此处**空白框中。

1. 对于**步骤名称**，请输入一个值。在本教程中，请使用名称 `WaitForInstanceStop`。

   1. 对于**服务**字段，请选择 **Amazon EC2**。

   1. 对于 **API** 字段，请选择 **DescribeInstances**。

   1. 对于**属性选择器**字段，请输入 **\$1.Reservations[0].Instances[0].State.Name**。

   1. 对于**期望值**参数，请输入 **`["stopped"]`**。

   1. 在 **WaitForInstanceStop** 操作的**配置**选项卡中，从**下一步**下拉菜单中选择 **StartInstance**。

1. 将**在实例上运行命令**操作拖动到 **\$1\$1 GetInstanceState.InstanceState \$1\$1 == "running"** 条件下的**将操作拖动到此处**空白框中。

1. 对于**步骤名称**，请输入 **SayHello**。

   1. 在**输入**选项卡中，输入 **AWS-RunShellScript** 作为**文档名称**参数。

   1. 对于 **InstanceId**，请从下拉菜单中选择 **InstanceId** 文档输入值。

   1. 展开**其他输入**下拉菜单，在**输入名称**下拉菜单中，选择**参数**。

   1. 在**输入值**字段中，请输入 **`{"commands": "echo 'Hello World'"}`**。

1. 在画布中查看已完成的运行手册，然后选择**创建运行手册**以保存教程运行手册。  
![\[查看和创建运行手册。\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/visual_designer_tutorial_complete.png)

## 步骤 3：查看自动生成的代码


当您将操作从**操作**浏览器拖放到画布上时，视觉对象设计体验会自动实时编写运行手册的 YAML 或 JSON 内容。您可以查看和编辑此代码。要查看自动生成的代码，在**设计**和**代码**切换开关中选择**代码**。

## 步骤 4：运行新的运行手册


创建运行手册后，您可以运行自动化。

**运行新的自动化运行手册**

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

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

1. 在**自动化文档**列表中，请选择运行手册。在**文档类别**窗格中选择一个或多个选项，以便根据 SSM 文档的用途对其进行筛选。要查看您拥有的运行手册，请选择**我拥有的**选项卡。要查看与您的账户共享的运行手册，请选择**与我共享**选项卡。要查看所有运行手册，请选择**所有文档**选项卡。
**注意**  
您可以通过选择运行手册名称来查看有关该手册的信息。

1. 在**文档详细信息**部分中，验证**文档版本**已设置为要运行的版本。系统包括以下版本选项：
   + **运行时的默认版本** – 如果定期更新自动化运行手册并分配新的默认版本，请选择此选项。
   + **运行时的最新版本** – 如果定期更新自动化运行手册并且想要运行最新更新的版本，请选择此选项。
   + **1（默认）** – 选择此选项可执行文档的第一个版本，即默认版本。

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

1. 在**执行自动化运行手册**部分，请选择**简单执行**。

1. 在 **输入参数** 部分中，指定所需的输入。或者，您也可以从 **AutomationAssumeRole** 列表选择一个 IAM 服务角色。

1. （可选）选择一个 Amazon CloudWatch 警报应用于您的自动化，以便进行监控。要将 CloudWatch 警报附加到自动化，启动自动化的 IAM 主体必须具有 `iam:createServiceLinkedRole` 操作的权限。有关 CloudWatch 警报的更多信息，请参阅[使用 Amazon CloudWatch 警报](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/AlarmThatSendsEmail.html)。如果您的警报激活，自动化将停止。如果使用 AWS CloudTrail，您将在跟踪中看到 API 调用。

1. 选择**执行**。

## 第 5 步：清理


**删除您的运行手册**

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

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

1. 选择**我拥有的**选项卡。

1. 找到 **VisualDesignExperienceTutorial** 运行手册。

1. 在文档卡页面上选择按钮，然后从**操作**下拉菜单中选择**删除文档**。

# 创作自动化运行手册


Automation 是 AWS Systems Manager 中的一项工具，其中的每个运行手册定义了一个自动化。自动化运行手册定义了在自动化过程中执行的操作。在运行手册内容中，您可以定义 Systems Manager 对托管实例和 AWS 资源执行的输入参数、输出和操作。

自动化包含几个预定义的运行手册，您可以用它们来执行常见任务，例如重启一个或多个 Amazon Elastic Compute Cloud (Amazon EC2) 实例，或创建 Amazon Machine Image (AMI)。但是，您的使用案例可能会超出预定义运行手册的功能。如果是这种情况，您可以创建自己的运行手册并根据需要修改它们。

运行手册由自动化操作、这些操作的参数以及您指定的输入参数组成。运行手册的内容是以 YAML 或 JSON 格式编写的。如果不熟悉 YAML 或 JSON，建议使用视觉设计器，或者在尝试创作自己的运行手册之前了解更多关于任一标记语言的信息。有关视觉设计器的更多信息，请参阅 [自动化运行手册的视觉对象设计体验](automation-visual-designer.md)。

以下部分将帮助您创作第一个运行手册。

## 识别您的使用案例


创作运行手册的第一步是确定您的使用案例。例如，您计划了 `AWS-CreateImage` 运行手册，以便每天在您的所有生产 Amazon EC2 实例上运行。月底时，您决定拥有的映像数量超过恢复点所需的映像。接下来，您希望在创建新 AMI 时，自动删除 Amazon EC2 实例的最早 AMI。为了实现此目的，您可以创建执行以下操作的新运行手册：

1. 运行 `aws:createImage` 操作，并在映像描述中指定实例 ID。

1. 运行 `aws:waitForAwsResourceProperty` 操作来轮询图像的状态，直到此状态为 `available`。

1. 在图像状态变为 `available` 后，`aws:executeScript` 操作会运行一个自定义 Python 脚本，用于收集与 Amazon EC2 实例关联的所有映像的 ID。脚本使用您在创建时指定的映像描述中的实例 ID 进行筛选，完成此操作。然后，脚本根据图像的 `creationDate` 对图像 ID 列表进行排序，并输出最早的 AMI。

1. 最后，`aws:deleteImage` 操作运行，使用上一步输出中的 ID 删除最早的 AMI。

在这种情况下，您已经使用 `AWS-CreateImage` 运行手册，但发现您的使用案例需要更大的灵活性。这是一种常见的情况，因为运行手册和自动化操作之间可能存在重叠。因此，您可能需要调整用于解决您的使用案例的运行手册或操作。

例如，`aws:executeScript` 和 `aws:invokeLambdaFunction` 操作都允许您在自动化过程中运行自定义脚本。要在它们之间进行选择，您可能更喜欢 `aws:invokeLambdaFunction`，因为它还支持其他运行时语言。但是，您可能更喜欢 `aws:executeScript`，因为它允许您直接在 YAML 运行手册中创作脚本内容，并提供脚本内容作为 JSON 运行手册的附件。您也可以考虑 `aws:executeScript`，因为其 AWS Identity and Access Management (IAM) 设置更简单。因为它使用 `AutomationAssumeRole` 提供的权限，`aws:executeScript` 不需要使用额外的 AWS Lambda 函数执行角色。

在任何给定的情况下，一个操作可能会比另一个操作提供更大的灵活性或更多功能。因此，我们建议您查看要使用的运行手册或操作的可用输入参数，以确定哪些参数最适合您的使用案例和首选项。

## 设置开发环境


确定您的使用案例以及要在运行手册中使用的预定义运行手册或自动化操作后，请为运行手册的内容设置开发环境。要开发您的运行手册内容，我们建议使用 AWS Toolkit for Visual Studio Code 而不是 Systems Manager 文档控制台。

Toolkit for VS Code 是 Visual Studio 代码（VS 代码）的开源扩展，提供了比 Systems Manager 文档控制台更多的功能。有用的功能包括针对 YAML 和 JSON 的模式验证、自动化操作类型的代码片段以及对各种 YAML 和 JSON 格式选项的自动完成支持。

有关安装 Toolkit for VS Code 的更多信息，请参阅[安装 AWS Toolkit for Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/setup-toolkit.html)。有关使用适用于 Toolkit for VS Code 开发运行手册的更多信息，请参阅 *AWS Toolkit for Visual Studio Code 用户指南*中的[使用 Systems Manager 运行手册](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/systems-manager-automation-docs.html)

## 开发运行手册内容


确定使用案例并设置环境后，您便做好了开发适用于运行手册内容的准备。您的使用案例和首选项在很大程度上决定了您在运行手册内容中使用的自动化操作或运行手册。与允许您完成类似任务的其他操作相比，某些操作仅支持输入参数的子集。其他操作具有特定的输出，例如 `aws:createImage`，其中一些操作允许您定义自己的输出，例如 `aws:executeAwsApi`。

如果您不确定如何在运行手册中使用特定操作，我们建议您查看 [Systems Manager 自动化操作参考](automation-actions.md) 中的操作对应条目。我们还建议您查看预定义运行手册的内容，以查看有关如何使用这些操作的实例。有关运行手册的实际应用程序的更多实例，请参阅 [其他运行手册示例](automation-document-examples.md)。

为了展示运行手册内容在简单性和灵活性方面的差异，以下教程提供了如何分阶段修补 Amazon EC2 实例组的示例：
+ [示例 1：创建父子运行手册](automation-authoring-runbooks-parent-child-example.md) - 在此示例中，父子关系中使用了两个运行手册。父运行手册启动子运行手册的速率控制自动化。
+ [示例 2：脚本化运行手册](automation-authoring-runbooks-scripted-example.md) - 此示例演示如何通过将内容压缩到单个运行手册中并使用运行手册中的脚本来完成示例 1 的相同任务。

# 示例 1：创建父子运行手册


以下示例演示如何创建两个运行手册，以便分阶段修补已标记的 Amazon Elastic Compute Cloud (Amazon EC2) 实例组。这些运行手册用于父子关系，其中父运行手册用于启动子运行手册的速率控制自动化。有关使用速率控制自动化的更多信息，请参阅 [大规模运行自动化操作](running-automations-scale.md)。有关此示例中使用的自动化操作的更多信息，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)。

## 创建子运行手册


此示例运行手册解决以下情形。Emily 是 AnyCompany Consultants, LLC 的系统工程师。她需要为托管主数据库和辅助数据库的 Amazon Elastic Compute Cloud (Amazon EC2) 实例组配置补丁程序。应用程序每天 24 小时访问这些数据库，因此两个数据库实例中必须有一个始终可用。

她确定分阶段修补实例是最佳方法。首先将对数据库实例的主组进行修补，然后修补数据库实例的辅助组。此外，为了避免由于使之前已停止的实例运行而产生额外的成本，Emily 希望在进行修补之前将修补的实例返回到其原始状态。

Emily 通过与实例关联的标签来标识数据库实例的主组和辅助组。她决定创建一个父运行手册，用于启动子运行手册的速率控制自动化。通过这种方法，她可以将与数据库实例的主组和辅助组关联的标签设置为目标，并管理子自动化的并发性。查看了可用于修补的 Systems Manager (SSM) 文档后，她选择了 `AWS-RunPatchBaseline` 文档。通过使用此 SSM 文档，她的同事可以在修补操作完成后查看相关的修补程序合规性信息。

为了开始创建运行手册内容，Emily 查看了可用的自动化操作，并开始为子运行手册创作内容，如下所示：

1. 首先，她为运行手册的架构和描述提供值，并定义子运行手册的输入参数。

   通过使用 `AutomationAssumeRole` 参数，Emily 和她的同事可以使用现有的 IAM 角色，以允许自动化代表他们执行运行手册中的操作。Emily 使用 `InstanceId` 参数来确定应修补的实例。（可选）`Operation`、`RebootOption` 和 `SnapshotId` 参数可用于为 `AWS-RunPatchBaseline` 的文档参数提供值。为了防止向这些运行手册参数提供无效值，她根据需要定义了 `allowedValues`。

------
#### [ YAML ]

   ```
   schemaVersion: '0.3'
   description: 'An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: >-
         '(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the
         actions on your behalf. If no role is specified, Systems Manager
         Automation uses your IAM permissions to operate this runbook.'
       default: ''
     InstanceId:
       type: String
       description: >-
         '(Required) The instance you want to patch.'
     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
   ```

------
#### [ JSON ]

   ```
   {
      "schemaVersion":"0.3",
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.",
            "default":""
         },
         "InstanceId":{
            "type":"String",
            "description":"(Required) The instance you want to patch."
         },
         "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"
         }
      }
   },
   ```

------

1. 定义完顶层元素后，Emily 继续创作构成运行手册的 `mainSteps` 的操作。第一步使用 `aws:executeAwsApi` 操作输出 `InstanceId` 输入参数中指定的目标实例的当前状态。此操作的输出将用于后续操作。

------
#### [ YAML ]

   ```
   mainSteps:
     - name: getInstanceState
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
       outputs:
         - Name: instanceState
           Selector: '$.Reservations[0].Instances[0].State.Name'
           Type: String
       nextStep: branchOnInstanceState
   ```

------
#### [ JSON ]

   ```
   "mainSteps":[
         {
            "name":"getInstanceState",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "inputs":null,
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            },
            "outputs":[
               {
                  "Name":"instanceState",
                  "Selector":"$.Reservations[0].Instances[0].State.Name",
                  "Type":"String"
               }
            ],
            "nextStep":"branchOnInstanceState"
         },
   ```

------

1. Emily 没有手动启动和跟踪需要修补的每个实例的原始状态，而是根据目标实例的状态使用上一操作的输出对自动化进行分支。这允许自动化根据 `aws:branch` 操作中定义的条件运行不同的步骤，并提高了自动化的整体效率，无需人工干预。

   如果实例状态已为 `running`，则自动化将继续使用 `aws:runCommand` 操作，利用 `AWS-RunPatchBaseline` 文档修补实例。

   如果实例的状态为 `stopping`，则自动化使用 `aws:waitForAwsResourceProperty` 操作轮询实例以达到 `stopped` 状态，使用 `executeAwsApi` 操作启动实例，并轮询实例以达到 `running` 状态，然后再修补实例。

   如果实例的状态为 `stopped`，则自动化将启动实例并轮询实例以达到 `running` 状态，然后再使用相同的操作修补实例。

------
#### [ YAML ]

   ```
   - name: branchOnInstanceState
       action: 'aws:branch'
       onFailure: Abort
       inputs:
         Choices:
           - NextStep: startInstance
              Variable: '{{getInstanceState.instanceState}}'
              StringEquals: stopped
            - NextStep: verifyInstanceStopped
              Variable: '{{getInstanceState.instanceState}}'
              StringEquals: stopping
            - NextStep: patchInstance
              Variable: '{{getInstanceState.instanceState}}'
              StringEquals: running
       isEnd: true
     - name: startInstance
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         Service: ec2
         Api: StartInstances
         InstanceIds:
           - '{{InstanceId}}'
       nextStep: verifyInstanceRunning
     - name: verifyInstanceRunning
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 120
       inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
         PropertySelector: '$.Reservations[0].Instances[0].State.Name'
         DesiredValues:
           - running
       nextStep: patchInstance
     - name: verifyInstanceStopped
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 120
       inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
         PropertySelector: '$.Reservations[0].Instances[0].State.Name'
         DesiredValues:
           - stopped
         nextStep: startInstance
     - name: patchInstance
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 5400
       inputs:
         DocumentName: 'AWS-RunPatchBaseline'
         InstanceIds: 
         - '{{InstanceId}}'
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
   ```

------
#### [ JSON ]

   ```
   {
            "name":"branchOnInstanceState",
            "action":"aws:branch",
            "onFailure":"Abort",
            "inputs":{
               "Choices":[
                  {
                     "NextStep":"startInstance",
                     "Variable":"{{getInstanceState.instanceState}}",
                     "StringEquals":"stopped"
                  },
                  {
                     "Or":[
                        {
                           "Variable":"{{getInstanceState.instanceState}}",
                           "StringEquals":"stopping"
                        }
                     ],
                     "NextStep":"verifyInstanceStopped"
                  },
                  {
                     "NextStep":"patchInstance",
                     "Variable":"{{getInstanceState.instanceState}}",
                     "StringEquals":"running"
                  }
               ]
            },
            "isEnd":true
         },
         {
            "name":"startInstance",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "Service":"ec2",
               "Api":"StartInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            },
            "nextStep":"verifyInstanceRunning"
         },
         {
            "name":"verifyInstanceRunning",
            "action":"aws:waitForAwsResourceProperty",
            "timeoutSeconds":120,
            "inputs":{
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "PropertySelector":"$.Reservations[0].Instances[0].State.Name",
               "DesiredValues":[
                  "running"
               ]
            },
            "nextStep":"patchInstance"
         },
         {
            "name":"verifyInstanceStopped",
            "action":"aws:waitForAwsResourceProperty",
            "timeoutSeconds":120,
            "inputs":{
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "PropertySelector":"$.Reservations[0].Instances[0].State.Name",
               "DesiredValues":[
                  "stopped"
               ],
               "nextStep":"startInstance"
            }
         },
         {
            "name":"patchInstance",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":5400,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               }
            }
         },
   ```

------

1. 修补操作完成后，Emily 希望自动化将目标实例返回到自动化开始之前的状态。她通过再次使用第一个动作的输出来完成此操作。自动化根据目标实例的原始状态，使用 `aws:branch` 操作进行分支。如果实例之前处于 `running` 以外的任何状态，实例将停止。否则，如果实例状态为 `running`，则自动化结束。

------
#### [ YAML ]

   ```
   - name: branchOnOriginalInstanceState
       action: 'aws:branch'
       onFailure: Abort
       inputs:
         Choices:
           - NextStep: stopInstance
             Not: 
               Variable: '{{getInstanceState.instanceState}}'
               StringEquals: running
       isEnd: true
     - name: stopInstance
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         Service: ec2
         Api: StopInstances
         InstanceIds:
           - '{{InstanceId}}'
   ```

------
#### [ JSON ]

   ```
   {
            "name":"branchOnOriginalInstanceState",
            "action":"aws:branch",
            "onFailure":"Abort",
            "inputs":{
               "Choices":[
                  {
                     "NextStep":"stopInstance",
                     "Not":{
                        "Variable":"{{getInstanceState.instanceState}}",
                        "StringEquals":"running"
                     }
                  }
               ]
            },
            "isEnd":true
         },
         {
            "name":"stopInstance",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "Service":"ec2",
               "Api":"StopInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            }
         }
      ]
   }
   ```

------

1. Emily 检查完成的子运行手册内容，并在同一 AWS 账户 和 AWS 区域 中创建运行手册作为目标实例。现在，她已经准备好继续创建父运行手册的内容。下面是完成的子运行手册内容。

------
#### [ YAML ]

   ```
   schemaVersion: '0.3'
   description: 'An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: >-
         '(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the
         actions on your behalf. If no role is specified, Systems Manager
         Automation uses your IAM permissions to operate this runbook.'
       default: ''
     InstanceId:
       type: String
       description: >-
         '(Required) The instance you want to patch.'
     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: getInstanceState
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
       outputs:
         - Name: instanceState
           Selector: '$.Reservations[0].Instances[0].State.Name'
           Type: String
       nextStep: branchOnInstanceState
     - name: branchOnInstanceState
       action: 'aws:branch'
       onFailure: Abort
       inputs:
         Choices:
           - NextStep: startInstance
             Variable: '{{getInstanceState.instanceState}}'
             StringEquals: stopped
           - Or:
               - Variable: '{{getInstanceState.instanceState}}'
                 StringEquals: stopping
             NextStep: verifyInstanceStopped
           - NextStep: patchInstance
             Variable: '{{getInstanceState.instanceState}}'
             StringEquals: running
       isEnd: true
     - name: startInstance
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         Service: ec2
         Api: StartInstances
         InstanceIds:
           - '{{InstanceId}}'
       nextStep: verifyInstanceRunning
     - name: verifyInstanceRunning
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 120
       inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
         PropertySelector: '$.Reservations[0].Instances[0].State.Name'
         DesiredValues:
           - running
       nextStep: patchInstance
     - name: verifyInstanceStopped
       action: 'aws:waitForAwsResourceProperty'
       timeoutSeconds: 120
       inputs:
         Service: ec2
         Api: DescribeInstances
         InstanceIds:
           - '{{InstanceId}}'
         PropertySelector: '$.Reservations[0].Instances[0].State.Name'
         DesiredValues:
           - stopped
         nextStep: startInstance
     - name: patchInstance
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 5400
       inputs:
         DocumentName: 'AWS-RunPatchBaseline'
         InstanceIds: 
         - '{{InstanceId}}'
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
     - name: branchOnOriginalInstanceState
       action: 'aws:branch'
       onFailure: Abort
       inputs:
         Choices:
           - NextStep: stopInstance
             Not: 
               Variable: '{{getInstanceState.instanceState}}'
               StringEquals: running
       isEnd: true
     - name: stopInstance
       action: 'aws:executeAwsApi'
       onFailure: Abort
       inputs:
         Service: ec2
         Api: StopInstances
         InstanceIds:
           - '{{InstanceId}}'
   ```

------
#### [ JSON ]

   ```
   {
      "schemaVersion":"0.3",
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"'(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'",
            "default":""
         },
         "InstanceId":{
            "type":"String",
            "description":"'(Required) The instance you want to patch.'"
         },
         "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":"getInstanceState",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "inputs":null,
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            },
            "outputs":[
               {
                  "Name":"instanceState",
                  "Selector":"$.Reservations[0].Instances[0].State.Name",
                  "Type":"String"
               }
            ],
            "nextStep":"branchOnInstanceState"
         },
         {
            "name":"branchOnInstanceState",
            "action":"aws:branch",
            "onFailure":"Abort",
            "inputs":{
               "Choices":[
                  {
                     "NextStep":"startInstance",
                     "Variable":"{{getInstanceState.instanceState}}",
                     "StringEquals":"stopped"
                  },
                  {
                     "Or":[
                        {
                           "Variable":"{{getInstanceState.instanceState}}",
                           "StringEquals":"stopping"
                        }
                     ],
                     "NextStep":"verifyInstanceStopped"
                  },
                  {
                     "NextStep":"patchInstance",
                     "Variable":"{{getInstanceState.instanceState}}",
                     "StringEquals":"running"
                  }
               ]
            },
            "isEnd":true
         },
         {
            "name":"startInstance",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "Service":"ec2",
               "Api":"StartInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            },
            "nextStep":"verifyInstanceRunning"
         },
         {
            "name":"verifyInstanceRunning",
            "action":"aws:waitForAwsResourceProperty",
            "timeoutSeconds":120,
            "inputs":{
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "PropertySelector":"$.Reservations[0].Instances[0].State.Name",
               "DesiredValues":[
                  "running"
               ]
            },
            "nextStep":"patchInstance"
         },
         {
            "name":"verifyInstanceStopped",
            "action":"aws:waitForAwsResourceProperty",
            "timeoutSeconds":120,
            "inputs":{
               "Service":"ec2",
               "Api":"DescribeInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "PropertySelector":"$.Reservations[0].Instances[0].State.Name",
               "DesiredValues":[
                  "stopped"
               ],
               "nextStep":"startInstance"
            }
         },
         {
            "name":"patchInstance",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":5400,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "InstanceIds":[
                  "{{InstanceId}}"
               ],
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               }
            }
         },
         {
            "name":"branchOnOriginalInstanceState",
            "action":"aws:branch",
            "onFailure":"Abort",
            "inputs":{
               "Choices":[
                  {
                     "NextStep":"stopInstance",
                     "Not":{
                        "Variable":"{{getInstanceState.instanceState}}",
                        "StringEquals":"running"
                     }
                  }
               ]
            },
            "isEnd":true
         },
         {
            "name":"stopInstance",
            "action":"aws:executeAwsApi",
            "onFailure":"Abort",
            "inputs":{
               "Service":"ec2",
               "Api":"StopInstances",
               "InstanceIds":[
                  "{{InstanceId}}"
               ]
            }
         }
      ]
   }
   ```

------

有关此示例中使用的自动化操作的更多信息，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)。

## 创建父运行手册


此示例运行手册继续了上一节介绍的场景。现在 Emily 已经创建了子运行手册，她开始为父运行手册创作内容，如下所示：

1. 首先，她为运行手册的架构和描述提供值，并定义父运行手册的输入参数。

   通过使用 `AutomationAssumeRole` 参数，Emily 和她的同事可以使用现有的 IAM 角色，使自动化代表他们执行运行手册中的操作。Emily 使用 `PatchGroupPrimaryKey` 和 `PatchGroupPrimaryValue` 参数来指定与将要修补的数据库实例的主组关联的标签。她使用 `PatchGroupSecondaryKey` 和 `PatchGroupSecondaryValue` 参数来指定与将要修补的数据库实例的辅助组关联的标签。

------
#### [ YAML ]

   ```
   description: 'An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.'
   schemaVersion: '0.3'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
       default: ''
     PatchGroupPrimaryKey:
       type: String
       description: '(Required) The key of the tag for the primary group of instances you want to patch.''
     PatchGroupPrimaryValue:
       type: String
       description: '(Required) The value of the tag for the primary group of instances you want to patch.'
     PatchGroupSecondaryKey:
       type: String
       description: '(Required) The key of the tag for the secondary group of instances you want to patch.'
     PatchGroupSecondaryValue:
       type: String
       description: '(Required) The value of the tag for the secondary group of instances you want to patch.'
   ```

------
#### [ JSON ]

   ```
   {
      "schemaVersion": "0.3",
      "description": "An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "assumeRole": "{{AutomationAssumeRole}}",
      "parameters": {
         "AutomationAssumeRole": {
            "type": "String",
            "description": "(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.",
            "default": ""
         },
         "PatchGroupPrimaryKey": {
            "type": "String",
            "description": "(Required) The key of the tag for the primary group of instances you want to patch."
         },
         "PatchGroupPrimaryValue": {
            "type": "String",
            "description": "(Required) The value of the tag for the primary group of instances you want to patch."
         },
         "PatchGroupSecondaryKey": {
            "type": "String",
            "description": "(Required) The key of the tag for the secondary group of instances you want to patch."
         },
         "PatchGroupSecondaryValue": {
            "type": "String",
            "description": "(Required) The value of the tag for the secondary group of instances you want to patch."
         }
      }
   },
   ```

------

1. 定义顶层元素后，Emily 继续创作构成运行手册的 `mainSteps` 的操作。

   第一个操作使用她刚刚创建的子运行手册启动速率控制自动化，该子运行手册将与在 `PatchGroupPrimaryKey` 和 `PatchGroupPrimaryValue` 输入参数中所指定标签关联的实例设置为目标。她使用提供给输入参数的值来指定与要修补的主数据库实例组相关联的标签的键和值。

   第一个自动化完成后，第二个操作将使用子运行手册启动另一个速率控制自动化，该子运行手册将与在 `PatchGroupSecondaryKey` 和 `PatchGroupSecondaryValue` 输入参数中所指定标签关联的实例设置为目标。她使用提供给输入参数的值来指定与要修补的辅助数据库实例组相关联的标签的键和值。

------
#### [ YAML ]

   ```
   mainSteps:
     - name: patchPrimaryTargets
       action: 'aws:executeAutomation'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: RunbookTutorialChildAutomation
         Targets:
           - Key: 'tag:{{PatchGroupPrimaryKey}}'
             Values:
               - '{{PatchGroupPrimaryValue}}'
         TargetParameterName: 'InstanceId'
     - name: patchSecondaryTargets
       action: 'aws:executeAutomation'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: RunbookTutorialChildAutomation
         Targets:
           - Key: 'tag:{{PatchGroupSecondaryKey}}'
             Values:
               - '{{PatchGroupSecondaryValue}}'
         TargetParameterName: 'InstanceId'
   ```

------
#### [ JSON ]

   ```
   "mainSteps":[
         {
            "name":"patchPrimaryTargets",
            "action":"aws:executeAutomation",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"RunbookTutorialChildAutomation",
               "Targets":[
                  {
                     "Key":"tag:{{PatchGroupPrimaryKey}}",
                     "Values":[
                        "{{PatchGroupPrimaryValue}}"
                     ]
                  }
               ],
               "TargetParameterName":"InstanceId"
            }
         },
         {
            "name":"patchSecondaryTargets",
            "action":"aws:executeAutomation",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"RunbookTutorialChildAutomation",
               "Targets":[
                  {
                     "Key":"tag:{{PatchGroupSecondaryKey}}",
                     "Values":[
                        "{{PatchGroupSecondaryValue}}"
                     ]
                  }
               ],
               "TargetParameterName":"InstanceId"
            }
         }
      ]
   }
   ```

------

1. Emily 检查完成的父运行手册内容，并在相同的 AWS 账户和 AWS 区域中创建运行手册作为目标实例。现在，她已经准备好测试自己的运行手册，以确保在将自动化实施到生产环境之前，自动化能够按需运行。下面是完成的父运行手册内容。

------
#### [ YAML ]

   ```
   description: An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.
   schemaVersion: '0.3'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
       default: ''
     PatchGroupPrimaryKey:
       type: String
       description: (Required) The key of the tag for the primary group of instances you want to patch.
     PatchGroupPrimaryValue:
       type: String
       description: '(Required) The value of the tag for the primary group of instances you want to patch. '
     PatchGroupSecondaryKey:
       type: String
       description: (Required) The key of the tag for the secondary group of instances you want to patch.
     PatchGroupSecondaryValue:
       type: String
       description: '(Required) The value of the tag for the secondary group of instances you want to patch.  '
   mainSteps:
     - name: patchPrimaryTargets
       action: 'aws:executeAutomation'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: RunbookTutorialChildAutomation
         Targets:
           - Key: 'tag:{{PatchGroupPrimaryKey}}'
             Values:
               - '{{PatchGroupPrimaryValue}}'
         TargetParameterName: 'InstanceId'
     - name: patchSecondaryTargets
       action: 'aws:executeAutomation'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: RunbookTutorialChildAutomation
         Targets:
           - Key: 'tag:{{PatchGroupSecondaryKey}}'
             Values:
               - '{{PatchGroupSecondaryValue}}'
         TargetParameterName: 'InstanceId'
   ```

------
#### [ JSON ]

   ```
   {
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "schemaVersion":"0.3",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"(Optional) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.",
            "default":""
         },
         "PatchGroupPrimaryKey":{
            "type":"String",
            "description":"(Required) The key of the tag for the primary group of instances you want to patch."
         },
         "PatchGroupPrimaryValue":{
            "type":"String",
            "description":"(Required) The value of the tag for the primary group of instances you want to patch. "
         },
         "PatchGroupSecondaryKey":{
            "type":"String",
            "description":"(Required) The key of the tag for the secondary group of instances you want to patch."
         },
         "PatchGroupSecondaryValue":{
            "type":"String",
            "description":"(Required) The value of the tag for the secondary group of instances you want to patch.  "
         }
      },
      "mainSteps":[
         {
            "name":"patchPrimaryTargets",
            "action":"aws:executeAutomation",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"RunbookTutorialChildAutomation",
               "Targets":[
                  {
                     "Key":"tag:{{PatchGroupPrimaryKey}}",
                     "Values":[
                        "{{PatchGroupPrimaryValue}}"
                     ]
                  }
               ],
               "TargetParameterName":"InstanceId"
            }
         },
         {
            "name":"patchSecondaryTargets",
            "action":"aws:executeAutomation",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"RunbookTutorialChildAutomation",
               "Targets":[
                  {
                     "Key":"tag:{{PatchGroupSecondaryKey}}",
                     "Values":[
                        "{{PatchGroupSecondaryValue}}"
                     ]
                  }
               ],
               "TargetParameterName":"InstanceId"
            }
         }
      ]
   }
   ```

------

有关此示例中使用的自动化操作的更多信息，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)。

# 示例 2：脚本化运行手册


此示例运行手册解决以下情形。Emily 是 AnyCompany Consultants, LLC 的系统工程师。她之前创建了两个运行手册，这两个运行手册用于父子关系，以修补托管主数据库和辅助数据库的 Amazon Elastic Compute Cloud (Amazon EC2) 实例的组。应用程序每天 24 小时访问这些数据库，因此这两个数据库实例中必须有一个始终可用。

基于此要求，她构建了一个解决方案，使用 `AWS-RunPatchBaseline` Systems Manager (SSM) 文档分阶段修补实例。通过使用此 SSM 文档，她的同事可以在修补操作完成后查看相关的修补程序合规性信息。

首先修补数据库实例的主组，然后修补数据库实例的辅助组。此外，为了避免由于运行之前已停止的实例而产生额外的成本，Emily 确保自动化将修补的实例恢复到修补之前的原始状态。Emily 使用与数据库实例的主组和辅助组关联的标签来确定应按照所需顺序修补哪些实例。

她现有的自动化解决方案有效，但她希望尽可能改进自己的解决方案。为了帮助维护运行手册内容并简化故障排除工作，她希望将自动化压缩到一个运行手册中，并简化输入参数的数量。此外，她希望避免创建多个子自动化。

在审查了可用的自动化操作后，Emily 确定可以使用 `aws:executeScript` 操作来运行她的自定义 Python 脚本，从而改进她的解决方案。她现在开始创作运行手册的内容，如下所示：

1. 首先，她为运行手册的架构和描述提供值，并定义父运行手册的输入参数。

   通过使用 `AutomationAssumeRole` 参数，Emily 和她的同事可以使用现有的 IAM 角色，使自动化代表他们执行运行手册中的操作。与[示例 1](automation-authoring-runbooks-parent-child-example.md) 不同的是，`AutomationAssumeRole` 参数现在是必需的，而不是可选的。因为这个运行手册包括 `aws:executeScript` 操作，所以始终需要一个 AWS Identity and Access Management (IAM) 服务角色（或担任角色）。此要求是必要的，因为某些为操作指定的 Python 脚本调用 AWS API 操作。

   Emily 使用 `PrimaryPatchGroupTag` 和 `SecondaryPatchGroupTag` 参数指定与要修补的数据库实例的主要和辅助组关联的标签。为了简化所需的输入参数，她决定使用 `StringMap` 参数，而不是使用多个 `String`参数，因为她在示例 1 运行手册中使用了后者。（可选）`Operation`、`RebootOption` 和 `SnapshotId` 参数可用于为 `AWS-RunPatchBaseline` 的文档参数提供值。为了防止向这些运行手册参数提供无效值，她根据需要定义了 `allowedValues`。

------
#### [ YAML ]

   ```
   description: 'An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.'
   schemaVersion: '0.3'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
     PrimaryPatchGroupTag:
       type: StringMap
       description: '(Required) The tag for the primary group of instances you want to patch. Specify a key-value pair. Example: {"key" : "value"}'
     SecondaryPatchGroupTag:
       type: StringMap
       description: '(Required) The tag for the secondary group of instances you want to patch. Specify a key-value pair. Example: {"key" : "value"}'
     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
   ```

------
#### [ JSON ]

   ```
   {
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "schemaVersion":"0.3",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook."
         },
         "PrimaryPatchGroupTag":{
            "type":"StringMap",
            "description":"(Required) The tag for the primary group of instances you want to patch. Specify a key-value pair. Example: {\"key\" : \"value\"}"
         },
         "SecondaryPatchGroupTag":{
            "type":"StringMap",
            "description":"(Required) The tag for the secondary group of instances you want to patch. Specify a key-value pair. Example: {\"key\" : \"value\"}"
         },
         "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"
         }
      }
   },
   ```

------

1. 定义顶层元素后，Emily 继续创作构成运行手册的 `mainSteps` 的操作。第一步收集与 `PrimaryPatchGroupTag` 参数中指定的标签关联的所有实例的 ID，并输出 `StringMap` 参数，其中包含实例 ID 和实例的当前状态。此操作的输出将用于后续操作。

   请注意，`script` 输入参数不支持 JSON 运行手册。JSON 运行手册必须使用 `attachment` 输入参数提供脚本内容。

------
#### [ YAML ]

   ```
   mainSteps:
     - name: getPrimaryInstanceState
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: getInstanceStates
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def getInstanceStates(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             tag = events['primaryTag']
             tagKey, tagValue = list(tag.items())[0]
             instanceQuery = ec2.describe_instances(
             Filters=[
                 {
                     "Name": "tag:" + tagKey,
                     "Values": [tagValue]
                 }]
             )
             if not instanceQuery['Reservations']:
                 noInstancesForTagString = "No instances found for specified tag."
                 return({ 'noInstancesFound' : noInstancesForTagString })
             else:
                 queryResponse = instanceQuery['Reservations']
                 originalInstanceStates = {}
                 for results in queryResponse:
                     instanceSet = results['Instances']
                     for instance in instanceSet:
                         instanceId = instance['InstanceId']
                         originalInstanceStates[instanceId] = instance['State']['Name']
                 return originalInstanceStates
       outputs:
         - Name: originalInstanceStates
           Selector: $.Payload
           Type: StringMap
       nextStep: verifyPrimaryInstancesRunning
   ```

------
#### [ JSON ]

   ```
   "mainSteps":[
         {
            "name":"getPrimaryInstanceState",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"getInstanceStates",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"originalInstanceStates",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               }
            ],
            "nextStep":"verifyPrimaryInstancesRunning"
         },
   ```

------

1. Emily 将上一个操作的输出用于另一个 `aws:executeScript` 操作，以验证与 `PrimaryPatchGroupTag` 参数中所指定标签相关联的所有实例均处于 `running` 状态。

   如果实例状态已处于 `running` 或者 `shutting-down` 状态，则脚本将继续遍历剩余的实例。

   如果实例的状态为 `stopping`，则脚本轮询实例以达到 `stopped` 状态并启动实例。

   如果实例的状态为 `stopped`，脚本将启动实例。

------
#### [ YAML ]

   ```
   - name: verifyPrimaryInstancesRunning
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: verifyInstancesRunning
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def verifyInstancesRunning(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped':
                   print("The target instance " + instance + " is stopped. The instance will now be started.")
                   ec2.start_instances(
                       InstanceIds=[instance]
                       )
               elif instanceDict[instance] == 'stopping':
                   print("The target instance " + instance + " is stopping. Polling for instance to reach stopped state.")
                   while instanceDict[instance] != 'stopped':
                       poll = ec2.get_waiter('instance_stopped')
                       poll.wait(
                           InstanceIds=[instance]
                       )
                   ec2.start_instances(
                       InstanceIds=[instance]
                   )
               else:
                 pass
       nextStep: waitForPrimaryRunningInstances
   ```

------
#### [ JSON ]

   ```
   {
            "name":"verifyPrimaryInstancesRunning",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"verifyInstancesRunning",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"waitForPrimaryRunningInstances"
         },
   ```

------

1. Emily 验证与 `PrimaryPatchGroupTag` 参数中指定的标签相关联的所有实例已启动或已处于 `running` 状态。然后，她使用另一个脚本来验证所有实例（包括在上一操作中启动的实例）已处于 `running` 状态。

------
#### [ YAML ]

   ```
   - name: waitForPrimaryRunningInstances
       action: 'aws:executeScript'
       timeoutSeconds: 300
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: waitForRunningInstances
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def waitForRunningInstances(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
                 poll = ec2.get_waiter('instance_running')
                 poll.wait(
                     InstanceIds=[instance]
                 )
       nextStep: returnPrimaryTagKey
   ```

------
#### [ JSON ]

   ```
   {
            "name":"waitForPrimaryRunningInstances",
            "action":"aws:executeScript",
            "timeoutSeconds":300,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"waitForRunningInstances",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"returnPrimaryTagKey"
         },
   ```

------

1. Emily 使用两个脚本来返回键的单个 `String` 值和 `PrimaryPatchGroupTag` 参数中指定的标签的值。这些操作返回的值允许她直接向 `Targets` 文档的参数 `AWS-RunPatchBaseline` 提供值。然后，自动化将继续使用 `aws:runCommand` 操作，利用 `AWS-RunPatchBaseline` 文档修补实例。

------
#### [ YAML ]

   ```
   - name: returnPrimaryTagKey
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['primaryTag']
             tagKey = list(tag)[0]
             stringKey = "tag:" + tagKey
             return {'tagKey' : stringKey}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: primaryPatchGroupKey
           Selector: $.Payload.tagKey
           Type: String
       nextStep: returnPrimaryTagValue
     - name: returnPrimaryTagValue
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['primaryTag']
             tagKey = list(tag)[0]
             tagValue = tag[tagKey]
             return {'tagValue' : tagValue}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: primaryPatchGroupValue
           Selector: $.Payload.tagValue
           Type: String
       nextStep: patchPrimaryInstances
     - name: patchPrimaryInstances
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         Targets:
           - Key: '{{returnPrimaryTagKey.primaryPatchGroupKey}}'
             Values:
               - '{{returnPrimaryTagValue.primaryPatchGroupValue}}'
         MaxConcurrency: 10%
         MaxErrors: 10%
       nextStep: returnPrimaryToOriginalState
   ```

------
#### [ JSON ]

   ```
   {
            "name":"returnPrimaryTagKey",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"primaryPatchGroupKey",
                  "Selector":"$.Payload.tagKey",
                  "Type":"String"
               }
            ],
            "nextStep":"returnPrimaryTagValue"
         },
         {
            "name":"returnPrimaryTagValue",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"primaryPatchGroupValue",
                  "Selector":"$.Payload.tagValue",
                  "Type":"String"
               }
            ],
            "nextStep":"patchPrimaryInstances"
         },
         {
            "name":"patchPrimaryInstances",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               },
               "Targets":[
                  {
                     "Key":"{{returnPrimaryTagKey.primaryPatchGroupKey}}",
                     "Values":[
                        "{{returnPrimaryTagValue.primaryPatchGroupValue}}"
                     ]
                  }
               ],
               "MaxConcurrency":"10%",
               "MaxErrors":"10%"
            },
            "nextStep":"returnPrimaryToOriginalState"
         },
   ```

------

1. 修补操作完成后，Emily 希望自动化将与 `PrimaryPatchGroupTag` 参数中所指定标签相关联的目标实例返回到自动化开始之前的状态。她通过再次使用脚本中第一个操作的输出来完成此操作。根据目标实例的原始状态，如果该实例以前处于 `running` 以外的任何状态，则实例将停止。否则，如果实例状态为 `running`，则脚本将继续遍历剩余的实例。

------
#### [ YAML ]

   ```
   - name: returnPrimaryToOriginalState
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnToOriginalState
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def returnToOriginalState(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped' or instanceDict[instance] == 'stopping':
                   ec2.stop_instances(
                       InstanceIds=[instance]
                       )
               else:
                 pass
       nextStep: getSecondaryInstanceState
   ```

------
#### [ JSON ]

   ```
   {
            "name":"returnPrimaryToOriginalState",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnToOriginalState",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"getSecondaryInstanceState"
         },
   ```

------

1. 针对与 `PrimaryPatchGroupTag` 参数中所指定标签相关联的实例的修补操作已完成。现在 Emily 复制了运行手册内容中以前的所有操作，将与 `SecondaryPatchGroupTag` 参数中所指定标签相关联的实例设置为目标。

------
#### [ YAML ]

   ```
   - name: getSecondaryInstanceState
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: getInstanceStates
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def getInstanceStates(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             tag = events['secondaryTag']
             tagKey, tagValue = list(tag.items())[0]
             instanceQuery = ec2.describe_instances(
             Filters=[
                 {
                     "Name": "tag:" + tagKey,
                     "Values": [tagValue]
                 }]
             )
             if not instanceQuery['Reservations']:
                 noInstancesForTagString = "No instances found for specified tag."
                 return({ 'noInstancesFound' : noInstancesForTagString })
             else:
                 queryResponse = instanceQuery['Reservations']
                 originalInstanceStates = {}
                 for results in queryResponse:
                     instanceSet = results['Instances']
                     for instance in instanceSet:
                         instanceId = instance['InstanceId']
                         originalInstanceStates[instanceId] = instance['State']['Name']
                 return originalInstanceStates
       outputs:
         - Name: originalInstanceStates
           Selector: $.Payload
           Type: StringMap
       nextStep: verifySecondaryInstancesRunning
     - name: verifySecondaryInstancesRunning
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: verifyInstancesRunning
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def verifyInstancesRunning(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped':
                   print("The target instance " + instance + " is stopped. The instance will now be started.")
                   ec2.start_instances(
                       InstanceIds=[instance]
                       )
               elif instanceDict[instance] == 'stopping':
                   print("The target instance " + instance + " is stopping. Polling for instance to reach stopped state.")
                   while instanceDict[instance] != 'stopped':
                       poll = ec2.get_waiter('instance_stopped')
                       poll.wait(
                           InstanceIds=[instance]
                       )
                   ec2.start_instances(
                       InstanceIds=[instance]
                   )
               else:
                 pass
       nextStep: waitForSecondaryRunningInstances
     - name: waitForSecondaryRunningInstances
       action: 'aws:executeScript'
       timeoutSeconds: 300
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: waitForRunningInstances
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def waitForRunningInstances(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
                 poll = ec2.get_waiter('instance_running')
                 poll.wait(
                     InstanceIds=[instance]
                 )
       nextStep: returnSecondaryTagKey
     - name: returnSecondaryTagKey
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['secondaryTag']
             tagKey = list(tag)[0]
             stringKey = "tag:" + tagKey
             return {'tagKey' : stringKey}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: secondaryPatchGroupKey
           Selector: $.Payload.tagKey
           Type: String
       nextStep: returnSecondaryTagValue
     - name: returnSecondaryTagValue
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['secondaryTag']
             tagKey = list(tag)[0]
             tagValue = tag[tagKey]
             return {'tagValue' : tagValue}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: secondaryPatchGroupValue
           Selector: $.Payload.tagValue
           Type: String
       nextStep: patchSecondaryInstances
     - name: patchSecondaryInstances
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         Targets:
           - Key: '{{returnSecondaryTagKey.secondaryPatchGroupKey}}'
             Values:
             - '{{returnSecondaryTagValue.secondaryPatchGroupValue}}'
         MaxConcurrency: 10%
         MaxErrors: 10%
       nextStep: returnSecondaryToOriginalState
     - name: returnSecondaryToOriginalState
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnToOriginalState
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def returnToOriginalState(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped' or instanceDict[instance] == 'stopping':
                   ec2.stop_instances(
                       InstanceIds=[instance]
                       )
               else:
                 pass
   ```

------
#### [ JSON ]

   ```
   {
            "name":"getSecondaryInstanceState",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"getInstanceStates",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"originalInstanceStates",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               }
            ],
            "nextStep":"verifySecondaryInstancesRunning"
         },
         {
            "name":"verifySecondaryInstancesRunning",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"verifyInstancesRunning",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"waitForSecondaryRunningInstances"
         },
         {
            "name":"waitForSecondaryRunningInstances",
            "action":"aws:executeScript",
            "timeoutSeconds":300,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"waitForRunningInstances",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"returnSecondaryTagKey"
         },
         {
            "name":"returnSecondaryTagKey",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"secondaryPatchGroupKey",
                  "Selector":"$.Payload.tagKey",
                  "Type":"String"
               }
            ],
            "nextStep":"returnSecondaryTagValue"
         },
         {
            "name":"returnSecondaryTagValue",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"secondaryPatchGroupValue",
                  "Selector":"$.Payload.tagValue",
                  "Type":"String"
               }
            ],
            "nextStep":"patchSecondaryInstances"
         },
         {
            "name":"patchSecondaryInstances",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               },
               "Targets":[
                  {
                     "Key":"{{returnSecondaryTagKey.secondaryPatchGroupKey}}",
                     "Values":[
                        "{{returnSecondaryTagValue.secondaryPatchGroupValue}}"
                     ]
                  }
               ],
               "MaxConcurrency":"10%",
               "MaxErrors":"10%"
            },
            "nextStep":"returnSecondaryToOriginalState"
         },
         {
            "name":"returnSecondaryToOriginalState",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnToOriginalState",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            }
         }
      ]
   }
   ```

------

1. Emily 查看已完成的脚本化运行手册内容，并在同一 AWS 账户和 AWS 区域中创建运行手册作为目标实例。现在，她已经准备好测试运行手册，以确保在将自动化实施到生产环境之前自动化能够按需运行。下面是完成的脚本化运行手册内容。

------
#### [ YAML ]

   ```
   description: An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.
   schemaVersion: '0.3'
   assumeRole: '{{AutomationAssumeRole}}'
   parameters:
     AutomationAssumeRole:
       type: String
       description: '(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook.'
     PrimaryPatchGroupTag:
       type: StringMap
       description: '(Required) The tag for the primary group of instances you want to patch. Specify a key-value pair. Example: {"key" : "value"}'
     SecondaryPatchGroupTag:
       type: StringMap
       description: '(Required) The tag for the secondary group of instances you want to patch. Specify a key-value pair. Example: {"key" : "value"}'
     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: getPrimaryInstanceState
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: getInstanceStates
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def getInstanceStates(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             tag = events['primaryTag']
             tagKey, tagValue = list(tag.items())[0]
             instanceQuery = ec2.describe_instances(
             Filters=[
                 {
                     "Name": "tag:" + tagKey,
                     "Values": [tagValue]
                 }]
             )
             if not instanceQuery['Reservations']:
                 noInstancesForTagString = "No instances found for specified tag."
                 return({ 'noInstancesFound' : noInstancesForTagString })
             else:
                 queryResponse = instanceQuery['Reservations']
                 originalInstanceStates = {}
                 for results in queryResponse:
                     instanceSet = results['Instances']
                     for instance in instanceSet:
                         instanceId = instance['InstanceId']
                         originalInstanceStates[instanceId] = instance['State']['Name']
                 return originalInstanceStates
       outputs:
         - Name: originalInstanceStates
           Selector: $.Payload
           Type: StringMap
       nextStep: verifyPrimaryInstancesRunning
     - name: verifyPrimaryInstancesRunning
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: verifyInstancesRunning
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def verifyInstancesRunning(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped':
                   print("The target instance " + instance + " is stopped. The instance will now be started.")
                   ec2.start_instances(
                       InstanceIds=[instance]
                       )
               elif instanceDict[instance] == 'stopping':
                   print("The target instance " + instance + " is stopping. Polling for instance to reach stopped state.")
                   while instanceDict[instance] != 'stopped':
                       poll = ec2.get_waiter('instance_stopped')
                       poll.wait(
                           InstanceIds=[instance]
                       )
                   ec2.start_instances(
                       InstanceIds=[instance]
                   )
               else:
                 pass
       nextStep: waitForPrimaryRunningInstances
     - name: waitForPrimaryRunningInstances
       action: 'aws:executeScript'
       timeoutSeconds: 300
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: waitForRunningInstances
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def waitForRunningInstances(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
                 poll = ec2.get_waiter('instance_running')
                 poll.wait(
                     InstanceIds=[instance]
                 )
       nextStep: returnPrimaryTagKey
     - name: returnPrimaryTagKey
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['primaryTag']
             tagKey = list(tag)[0]
             stringKey = "tag:" + tagKey
             return {'tagKey' : stringKey}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: primaryPatchGroupKey
           Selector: $.Payload.tagKey
           Type: String
       nextStep: returnPrimaryTagValue
     - name: returnPrimaryTagValue
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           primaryTag: '{{PrimaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['primaryTag']
             tagKey = list(tag)[0]
             tagValue = tag[tagKey]
             return {'tagValue' : tagValue}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: primaryPatchGroupValue
           Selector: $.Payload.tagValue
           Type: String
       nextStep: patchPrimaryInstances
     - name: patchPrimaryInstances
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         Targets:
           - Key: '{{returnPrimaryTagKey.primaryPatchGroupKey}}'
             Values:
               - '{{returnPrimaryTagValue.primaryPatchGroupValue}}'
         MaxConcurrency: 10%
         MaxErrors: 10%
       nextStep: returnPrimaryToOriginalState
     - name: returnPrimaryToOriginalState
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnToOriginalState
         InputPayload:
           targetInstances: '{{getPrimaryInstanceState.originalInstanceStates}}'
         Script: |-
           def returnToOriginalState(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped' or instanceDict[instance] == 'stopping':
                   ec2.stop_instances(
                       InstanceIds=[instance]
                       )
               else:
                 pass
       nextStep: getSecondaryInstanceState
     - name: getSecondaryInstanceState
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: getInstanceStates
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def getInstanceStates(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             tag = events['secondaryTag']
             tagKey, tagValue = list(tag.items())[0]
             instanceQuery = ec2.describe_instances(
             Filters=[
                 {
                     "Name": "tag:" + tagKey,
                     "Values": [tagValue]
                 }]
             )
             if not instanceQuery['Reservations']:
                 noInstancesForTagString = "No instances found for specified tag."
                 return({ 'noInstancesFound' : noInstancesForTagString })
             else:
                 queryResponse = instanceQuery['Reservations']
                 originalInstanceStates = {}
                 for results in queryResponse:
                     instanceSet = results['Instances']
                     for instance in instanceSet:
                         instanceId = instance['InstanceId']
                         originalInstanceStates[instanceId] = instance['State']['Name']
                 return originalInstanceStates
       outputs:
         - Name: originalInstanceStates
           Selector: $.Payload
           Type: StringMap
       nextStep: verifySecondaryInstancesRunning
     - name: verifySecondaryInstancesRunning
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: verifyInstancesRunning
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def verifyInstancesRunning(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped':
                   print("The target instance " + instance + " is stopped. The instance will now be started.")
                   ec2.start_instances(
                       InstanceIds=[instance]
                       )
               elif instanceDict[instance] == 'stopping':
                   print("The target instance " + instance + " is stopping. Polling for instance to reach stopped state.")
                   while instanceDict[instance] != 'stopped':
                       poll = ec2.get_waiter('instance_stopped')
                       poll.wait(
                           InstanceIds=[instance]
                       )
                   ec2.start_instances(
                       InstanceIds=[instance]
                   )
               else:
                 pass
       nextStep: waitForSecondaryRunningInstances
     - name: waitForSecondaryRunningInstances
       action: 'aws:executeScript'
       timeoutSeconds: 300
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: waitForRunningInstances
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def waitForRunningInstances(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
                 poll = ec2.get_waiter('instance_running')
                 poll.wait(
                     InstanceIds=[instance]
                 )
       nextStep: returnSecondaryTagKey
     - name: returnSecondaryTagKey
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['secondaryTag']
             tagKey = list(tag)[0]
             stringKey = "tag:" + tagKey
             return {'tagKey' : stringKey}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: secondaryPatchGroupKey
           Selector: $.Payload.tagKey
           Type: String
       nextStep: returnSecondaryTagValue
     - name: returnSecondaryTagValue
       action: 'aws:executeScript'
       timeoutSeconds: 120
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnTagValues
         InputPayload:
           secondaryTag: '{{SecondaryPatchGroupTag}}'
         Script: |-
           def returnTagValues(events,context):
             tag = events['secondaryTag']
             tagKey = list(tag)[0]
             tagValue = tag[tagKey]
             return {'tagValue' : tagValue}
       outputs:
         - Name: Payload
           Selector: $.Payload
           Type: StringMap
         - Name: secondaryPatchGroupValue
           Selector: $.Payload.tagValue
           Type: String
       nextStep: patchSecondaryInstances
     - name: patchSecondaryInstances
       action: 'aws:runCommand'
       onFailure: Abort
       timeoutSeconds: 7200
       inputs:
         DocumentName: AWS-RunPatchBaseline
         Parameters:
           SnapshotId: '{{SnapshotId}}'
           RebootOption: '{{RebootOption}}'
           Operation: '{{Operation}}'
         Targets:
           - Key: '{{returnSecondaryTagKey.secondaryPatchGroupKey}}'
             Values:
             - '{{returnSecondaryTagValue.secondaryPatchGroupValue}}'
         MaxConcurrency: 10%
         MaxErrors: 10%
       nextStep: returnSecondaryToOriginalState
     - name: returnSecondaryToOriginalState
       action: 'aws:executeScript'
       timeoutSeconds: 600
       onFailure: Abort
       inputs:
         Runtime: python3.11
         Handler: returnToOriginalState
         InputPayload:
           targetInstances: '{{getSecondaryInstanceState.originalInstanceStates}}'
         Script: |-
           def returnToOriginalState(events,context):
             import boto3
   
             #Initialize client
             ec2 = boto3.client('ec2')
             instanceDict = events['targetInstances']
             for instance in instanceDict:
               if instanceDict[instance] == 'stopped' or instanceDict[instance] == 'stopping':
                   ec2.stop_instances(
                       InstanceIds=[instance]
                       )
               else:
                 pass
   ```

------
#### [ JSON ]

   ```
   {
      "description":"An example of an Automation runbook that patches groups of Amazon EC2 instances in stages.",
      "schemaVersion":"0.3",
      "assumeRole":"{{AutomationAssumeRole}}",
      "parameters":{
         "AutomationAssumeRole":{
            "type":"String",
            "description":"(Required) The Amazon Resource Name (ARN) of the IAM role that allows Automation to perform the actions on your behalf. If no role is specified, Systems Manager Automation uses your IAM permissions to operate this runbook."
         },
         "PrimaryPatchGroupTag":{
            "type":"StringMap",
            "description":"(Required) The tag for the primary group of instances you want to patch. Specify a key-value pair. Example: {\"key\" : \"value\"}"
         },
         "SecondaryPatchGroupTag":{
            "type":"StringMap",
            "description":"(Required) The tag for the secondary group of instances you want to patch. Specify a key-value pair. Example: {\"key\" : \"value\"}"
         },
         "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":"getPrimaryInstanceState",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"getInstanceStates",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"originalInstanceStates",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               }
            ],
            "nextStep":"verifyPrimaryInstancesRunning"
         },
         {
            "name":"verifyPrimaryInstancesRunning",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"verifyInstancesRunning",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"waitForPrimaryRunningInstances"
         },
         {
            "name":"waitForPrimaryRunningInstances",
            "action":"aws:executeScript",
            "timeoutSeconds":300,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"waitForRunningInstances",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"returnPrimaryTagKey"
         },
         {
            "name":"returnPrimaryTagKey",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"primaryPatchGroupKey",
                  "Selector":"$.Payload.tagKey",
                  "Type":"String"
               }
            ],
            "nextStep":"returnPrimaryTagValue"
         },
         {
            "name":"returnPrimaryTagValue",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "primaryTag":"{{PrimaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"primaryPatchGroupValue",
                  "Selector":"$.Payload.tagValue",
                  "Type":"String"
               }
            ],
            "nextStep":"patchPrimaryInstances"
         },
         {
            "name":"patchPrimaryInstances",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               },
               "Targets":[
                  {
                     "Key":"{{returnPrimaryTagKey.primaryPatchGroupKey}}",
                     "Values":[
                        "{{returnPrimaryTagValue.primaryPatchGroupValue}}"
                     ]
                  }
               ],
               "MaxConcurrency":"10%",
               "MaxErrors":"10%"
            },
            "nextStep":"returnPrimaryToOriginalState"
         },
         {
            "name":"returnPrimaryToOriginalState",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnToOriginalState",
               "InputPayload":{
                  "targetInstances":"{{getPrimaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"getSecondaryInstanceState"
         },
         {
            "name":"getSecondaryInstanceState",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"getInstanceStates",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"originalInstanceStates",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               }
            ],
            "nextStep":"verifySecondaryInstancesRunning"
         },
         {
            "name":"verifySecondaryInstancesRunning",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"verifyInstancesRunning",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"waitForSecondaryRunningInstances"
         },
         {
            "name":"waitForSecondaryRunningInstances",
            "action":"aws:executeScript",
            "timeoutSeconds":300,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"waitForRunningInstances",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            },
            "nextStep":"returnSecondaryTagKey"
         },
         {
            "name":"returnSecondaryTagKey",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"secondaryPatchGroupKey",
                  "Selector":"$.Payload.tagKey",
                  "Type":"String"
               }
            ],
            "nextStep":"returnSecondaryTagValue"
         },
         {
            "name":"returnSecondaryTagValue",
            "action":"aws:executeScript",
            "timeoutSeconds":120,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnTagValues",
               "InputPayload":{
                  "secondaryTag":"{{SecondaryPatchGroupTag}}"
               },
               "Script":"..."
            },
            "outputs":[
               {
                  "Name":"Payload",
                  "Selector":"$.Payload",
                  "Type":"StringMap"
               },
               {
                  "Name":"secondaryPatchGroupValue",
                  "Selector":"$.Payload.tagValue",
                  "Type":"String"
               }
            ],
            "nextStep":"patchSecondaryInstances"
         },
         {
            "name":"patchSecondaryInstances",
            "action":"aws:runCommand",
            "onFailure":"Abort",
            "timeoutSeconds":7200,
            "inputs":{
               "DocumentName":"AWS-RunPatchBaseline",
               "Parameters":{
                  "SnapshotId":"{{SnapshotId}}",
                  "RebootOption":"{{RebootOption}}",
                  "Operation":"{{Operation}}"
               },
               "Targets":[
                  {
                     "Key":"{{returnSecondaryTagKey.secondaryPatchGroupKey}}",
                     "Values":[
                        "{{returnSecondaryTagValue.secondaryPatchGroupValue}}"
                     ]
                  }
               ],
               "MaxConcurrency":"10%",
               "MaxErrors":"10%"
            },
            "nextStep":"returnSecondaryToOriginalState"
         },
         {
            "name":"returnSecondaryToOriginalState",
            "action":"aws:executeScript",
            "timeoutSeconds":600,
            "onFailure":"Abort",
            "inputs":{
               "Runtime":"python3.11",
               "Handler":"returnToOriginalState",
               "InputPayload":{
                  "targetInstances":"{{getSecondaryInstanceState.originalInstanceStates}}"
               },
               "Script":"..."
            }
         }
      ]
   }
   ```

------

有关此示例中使用的自动化操作的更多信息，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)。

# 其他运行手册示例


以下示例运行手册演示了如何使用 AWS Systems Manager 自动化操作来自动执行常见部署、故障排除和维护任务。

**注意**  
本部分提供的示例运行手册旨在演示如何创建自定义运行手册以支持您的特定操作需求。这些运行手册并非供您在生产环境中原样使用。但是，您可以自定义这些文档来满足自己的使用需求。

**Topics**
+ [

# 部署 VPC 架构和 Microsoft Active Directory 域控制器
](automation-document-architecture-deployment-example.md)
+ [

# 从最新快照还原根卷
](automation-document-instance-recovery-example.md)
+ [

# 创建 AMI 和跨区域副本
](automation-document-backup-maintenance-example.md)

# 部署 VPC 架构和 Microsoft Active Directory 域控制器


要提高效率并实现常见任务的标准化，可以选择自动执行部署。如果您定期在多个账户和 AWS 区域 中部署相同的架构，此操作会很有帮助。自动进行架构部署还可以降低在手动部署架构时发生人为错误的可能性。AWS Systems Manager自动化操作可帮助您做到这一点。Automation 是 AWS Systems Manager 中的一项工具。

以下示例 AWS Systems Manager 运行手册执行这些操作：
+ 使用 Systems Manager Parameter Store 检索最新的 Windows Server 2016 Amazon Machine Image（AMI），在启动将配置作为域控制器的 EC2 实例时使用。Parameter Store 是 AWS Systems Manager 中的一项工具。
+ 使用 `aws:executeAwsApi` 自动化操作调用多个 AWS API 操作来创建 VPC 架构。域控制器实例在私有子网中启动，使用 NAT 网关连接到 Internet。这允许实例上的 SSM Agent 以访问必需的 Systems Manager 端点。
+ 使用 `aws:waitForAwsResourceProperty` 自动化操作确认上一个操作所启动的实例对于 `Online` 处于 AWS Systems Manager 状态。
+ 使用 `aws:runCommand` 自动化操作配置作为 Microsoft Active Directory 域控制器启动的实例。

------
#### [ YAML ]

```
    ---
    description: Custom Automation Deployment Example
    schemaVersion: '0.3'
    parameters:
      AutomationAssumeRole:
        type: String
        default: ''
        description: >-
          (Optional) 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 run this runbook.
    mainSteps:
      - name: getLatestWindowsAmi
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ssm
          Api: GetParameter
          Name: >-
            /aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base
        outputs:
          - Name: amiId
            Selector: $.Parameter.Value
            Type: String
        nextStep: createSSMInstanceRole
      - name: createSSMInstanceRole
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: iam
          Api: CreateRole
          AssumeRolePolicyDocument: >-
            {"Version": "2012-10-17",		 	 	 "Statement":[{"Effect":"Allow","Principal":{"Service":["ec2.amazonaws.com"]},"Action":["sts:AssumeRole"]}]}
          RoleName: sampleSSMInstanceRole
        nextStep: attachManagedSSMPolicy
      - name: attachManagedSSMPolicy
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: iam
          Api: AttachRolePolicy
          PolicyArn: 'arn:aws:iam::aws:policy/service-role/AmazonSSMManagedInstanceCore'
          RoleName: sampleSSMInstanceRole
        nextStep: createSSMInstanceProfile
      - name: createSSMInstanceProfile
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: iam
          Api: CreateInstanceProfile
          InstanceProfileName: sampleSSMInstanceRole
        outputs:
          - Name: instanceProfileArn
            Selector: $.InstanceProfile.Arn
            Type: String
        nextStep: addSSMInstanceRoleToProfile
      - name: addSSMInstanceRoleToProfile
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: iam
          Api: AddRoleToInstanceProfile
          InstanceProfileName: sampleSSMInstanceRole
          RoleName: sampleSSMInstanceRole
        nextStep: createVpc
      - name: createVpc
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateVpc
          CidrBlock: 10.0.100.0/22
        outputs:
          - Name: vpcId
            Selector: $.Vpc.VpcId
            Type: String
        nextStep: getMainRtb
      - name: getMainRtb
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: DescribeRouteTables
          Filters:
            - Name: vpc-id
              Values:
                - '{{ createVpc.vpcId }}'
        outputs:
          - Name: mainRtbId
            Selector: '$.RouteTables[0].RouteTableId'
            Type: String
        nextStep: verifyMainRtb
      - name: verifyMainRtb
        action: aws:assertAwsResourceProperty
        onFailure: Abort
        inputs:
          Service: ec2
          Api: DescribeRouteTables
          RouteTableIds:
            - '{{ getMainRtb.mainRtbId }}'
          PropertySelector: '$.RouteTables[0].Associations[0].Main'
          DesiredValues:
            - 'True'
        nextStep: createPubSubnet
      - name: createPubSubnet
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateSubnet
          CidrBlock: 10.0.103.0/24
          AvailabilityZone: us-west-2c
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: pubSubnetId
            Selector: $.Subnet.SubnetId
            Type: String
        nextStep: createPubRtb
      - name: createPubRtb
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateRouteTable
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: pubRtbId
            Selector: $.RouteTable.RouteTableId
            Type: String
        nextStep: createIgw
      - name: createIgw
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateInternetGateway
        outputs:
          - Name: igwId
            Selector: $.InternetGateway.InternetGatewayId
            Type: String
        nextStep: attachIgw
      - name: attachIgw
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AttachInternetGateway
          InternetGatewayId: '{{ createIgw.igwId }}'
          VpcId: '{{ createVpc.vpcId }}'
        nextStep: allocateEip
      - name: allocateEip
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AllocateAddress
          Domain: vpc
        outputs:
          - Name: eipAllocationId
            Selector: $.AllocationId
            Type: String
        nextStep: createNatGw
      - name: createNatGw
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateNatGateway
          AllocationId: '{{ allocateEip.eipAllocationId }}'
          SubnetId: '{{ createPubSubnet.pubSubnetId }}'
        outputs:
          - Name: natGwId
            Selector: $.NatGateway.NatGatewayId
            Type: String
        nextStep: verifyNatGwAvailable
      - name: verifyNatGwAvailable
        action: aws:waitForAwsResourceProperty
        timeoutSeconds: 150
        inputs:
          Service: ec2
          Api: DescribeNatGateways
          NatGatewayIds:
            - '{{ createNatGw.natGwId }}'
          PropertySelector: '$.NatGateways[0].State'
          DesiredValues:
            - available
        nextStep: createNatRoute
      - name: createNatRoute
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateRoute
          DestinationCidrBlock: 0.0.0.0/0
          NatGatewayId: '{{ createNatGw.natGwId }}'
          RouteTableId: '{{ getMainRtb.mainRtbId }}'
        nextStep: createPubRoute
      - name: createPubRoute
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateRoute
          DestinationCidrBlock: 0.0.0.0/0
          GatewayId: '{{ createIgw.igwId }}'
          RouteTableId: '{{ createPubRtb.pubRtbId }}'
        nextStep: setPubSubAssoc
      - name: setPubSubAssoc
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AssociateRouteTable
          RouteTableId: '{{ createPubRtb.pubRtbId }}'
          SubnetId: '{{ createPubSubnet.pubSubnetId }}'
      - name: createDhcpOptions
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateDhcpOptions
          DhcpConfigurations:
            - Key: domain-name-servers
              Values:
                - '10.0.100.50,10.0.101.50'
            - Key: domain-name
              Values:
                - sample.com
        outputs:
          - Name: dhcpOptionsId
            Selector: $.DhcpOptions.DhcpOptionsId
            Type: String
        nextStep: createDCSubnet1
      - name: createDCSubnet1
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateSubnet
          CidrBlock: 10.0.100.0/24
          AvailabilityZone: us-west-2a
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: firstSubnetId
            Selector: $.Subnet.SubnetId
            Type: String
        nextStep: createDCSubnet2
      - name: createDCSubnet2
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateSubnet
          CidrBlock: 10.0.101.0/24
          AvailabilityZone: us-west-2b
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: secondSubnetId
            Selector: $.Subnet.SubnetId
            Type: String
        nextStep: createDCSecGroup
      - name: createDCSecGroup
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: CreateSecurityGroup
          GroupName: SampleDCSecGroup
          Description: Security Group for Sample Domain Controllers
          VpcId: '{{ createVpc.vpcId }}'
        outputs:
          - Name: dcSecGroupId
            Selector: $.GroupId
            Type: String
        nextStep: authIngressDCTraffic
      - name: authIngressDCTraffic
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AuthorizeSecurityGroupIngress
          GroupId: '{{ createDCSecGroup.dcSecGroupId }}'
          IpPermissions:
            - FromPort: -1
              IpProtocol: '-1'
              IpRanges:
                - CidrIp: 0.0.0.0/0
                  Description: Allow all traffic between Domain Controllers
        nextStep: verifyInstanceProfile
      - name: verifyInstanceProfile
        action: aws:waitForAwsResourceProperty
        maxAttempts: 5
        onFailure: Abort
        inputs:
          Service: iam
          Api: ListInstanceProfilesForRole
          RoleName: sampleSSMInstanceRole
          PropertySelector: '$.InstanceProfiles[0].Arn'
          DesiredValues:
            - '{{ createSSMInstanceProfile.instanceProfileArn }}'
        nextStep: iamEventualConsistency
      - name: iamEventualConsistency
        action: aws:sleep
        inputs:
          Duration: PT2M
        nextStep: launchDC1
      - name: launchDC1
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: RunInstances
          BlockDeviceMappings:
            - DeviceName: /dev/sda1
              Ebs:
                DeleteOnTermination: true
                VolumeSize: 50
                VolumeType: gp2
            - DeviceName: xvdf
              Ebs:
                DeleteOnTermination: true
                VolumeSize: 100
                VolumeType: gp2
          IamInstanceProfile:
            Arn: '{{ createSSMInstanceProfile.instanceProfileArn }}'
          ImageId: '{{ getLatestWindowsAmi.amiId }}'
          InstanceType: t2.micro
          MaxCount: 1
          MinCount: 1
          PrivateIpAddress: 10.0.100.50
          SecurityGroupIds:
            - '{{ createDCSecGroup.dcSecGroupId }}'
          SubnetId: '{{ createDCSubnet1.firstSubnetId }}'
          TagSpecifications:
            - ResourceType: instance
              Tags:
                - Key: Name
                  Value: SampleDC1
        outputs:
          - Name: pdcInstanceId
            Selector: '$.Instances[0].InstanceId'
            Type: String
        nextStep: launchDC2
      - name: launchDC2
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: RunInstances
          BlockDeviceMappings:
            - DeviceName: /dev/sda1
              Ebs:
                DeleteOnTermination: true
                VolumeSize: 50
                VolumeType: gp2
            - DeviceName: xvdf
              Ebs:
                DeleteOnTermination: true
                VolumeSize: 100
                VolumeType: gp2
          IamInstanceProfile:
            Arn: '{{ createSSMInstanceProfile.instanceProfileArn }}'
          ImageId: '{{ getLatestWindowsAmi.amiId }}'
          InstanceType: t2.micro
          MaxCount: 1
          MinCount: 1
          PrivateIpAddress: 10.0.101.50
          SecurityGroupIds:
            - '{{ createDCSecGroup.dcSecGroupId }}'
          SubnetId: '{{ createDCSubnet2.secondSubnetId }}'
          TagSpecifications:
            - ResourceType: instance
              Tags:
                - Key: Name
                  Value: SampleDC2
        outputs:
          - Name: adcInstanceId
            Selector: '$.Instances[0].InstanceId'
            Type: String
        nextStep: verifyDCInstanceState
      - name: verifyDCInstanceState
        action: aws:waitForAwsResourceProperty
        inputs:
          Service: ec2
          Api: DescribeInstanceStatus
          IncludeAllInstances: true
          InstanceIds:
            - '{{ launchDC1.pdcInstanceId }}'
            - '{{ launchDC2.adcInstanceId }}'
          PropertySelector: '$.InstanceStatuses..InstanceState.Name'
          DesiredValues:
            - running
        nextStep: verifyInstancesOnlineSSM
      - name: verifyInstancesOnlineSSM
        action: aws:waitForAwsResourceProperty
        timeoutSeconds: 600
        inputs:
          Service: ssm
          Api: DescribeInstanceInformation
          InstanceInformationFilterList:
            - key: InstanceIds
              valueSet:
                - '{{ launchDC1.pdcInstanceId }}'
                - '{{ launchDC2.adcInstanceId }}'
          PropertySelector: '$.InstanceInformationList..PingStatus'
          DesiredValues:
            - Online
        nextStep: installADRoles
      - name: installADRoles
        action: aws:runCommand
        inputs:
          DocumentName: AWS-RunPowerShellScript
          InstanceIds:
            - '{{ launchDC1.pdcInstanceId }}'
            - '{{ launchDC2.adcInstanceId }}'
          Parameters:
            commands: |-
              try {
                  Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools
              }
              catch {
                  Write-Error "Failed to install ADDS Role."
              }
        nextStep: setAdminPassword
      - name: setAdminPassword
        action: aws:runCommand
        inputs:
          DocumentName: AWS-RunPowerShellScript
          InstanceIds:
            - '{{ launchDC1.pdcInstanceId }}'
          Parameters:
            commands:
              - net user Administrator "sampleAdminPass123!"
        nextStep: createForest
      - name: createForest
        action: aws:runCommand
        inputs:
          DocumentName: AWS-RunPowerShellScript
          InstanceIds:
            - '{{ launchDC1.pdcInstanceId }}'
          Parameters:
            commands: |-
              $dsrmPass = 'sample123!' | ConvertTo-SecureString -asPlainText -Force
              try {
                  Install-ADDSForest -DomainName "sample.com" -DomainMode 6 -ForestMode 6 -InstallDNS -DatabasePath "D:\NTDS" -SysvolPath "D:\SYSVOL" -SafeModeAdministratorPassword $dsrmPass -Force
              }
              catch {
                  Write-Error $_
              }
              try {
                  Add-DnsServerForwarder -IPAddress "10.0.100.2"
              }
              catch {
                  Write-Error $_
              }
        nextStep: associateDhcpOptions
      - name: associateDhcpOptions
        action: aws:executeAwsApi
        onFailure: Abort
        inputs:
          Service: ec2
          Api: AssociateDhcpOptions
          DhcpOptionsId: '{{ createDhcpOptions.dhcpOptionsId }}'
          VpcId: '{{ createVpc.vpcId }}'
        nextStep: waitForADServices
      - name: waitForADServices
        action: aws:sleep
        inputs:
          Duration: PT1M
        nextStep: promoteADC
      - name: promoteADC
        action: aws:runCommand
        inputs:
          DocumentName: AWS-RunPowerShellScript
          InstanceIds:
            - '{{ launchDC2.adcInstanceId }}'
          Parameters:
            commands: |-
              ipconfig /renew
              $dsrmPass = 'sample123!' | ConvertTo-SecureString -asPlainText -Force
              $domAdminUser = "sample\Administrator"
              $domAdminPass = "sampleAdminPass123!" | ConvertTo-SecureString -asPlainText -Force
              $domAdminCred = New-Object System.Management.Automation.PSCredential($domAdminUser,$domAdminPass)
    
              try {
                  Install-ADDSDomainController -DomainName "sample.com" -InstallDNS -DatabasePath "D:\NTDS" -SysvolPath "D:\SYSVOL" -SafeModeAdministratorPassword $dsrmPass -Credential $domAdminCred -Force
              }
              catch {
                  Write-Error $_
              }
```

------
#### [ JSON ]

```
{
      "description": "Custom Automation Deployment Example",
      "schemaVersion": "0.3",
      "assumeRole": "{{ AutomationAssumeRole }}",
      "parameters": {
        "AutomationAssumeRole": {
          "type": "String",
          "description": "(Optional) 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 run this runbook.",
          "default": ""
        }
      },
      "mainSteps": [
        {
          "name": "getLatestWindowsAmi",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ssm",
            "Api": "GetParameter",
            "Name": "/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base"
          },
          "outputs": [
            {
              "Name": "amiId",
              "Selector": "$.Parameter.Value",
              "Type": "String"
            }
          ],
          "nextStep": "createSSMInstanceRole"
        },
        {
          "name": "createSSMInstanceRole",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "CreateRole",
            "AssumeRolePolicyDocument": "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"Service\":[\"ec2.amazonaws.com\"]},\"Action\":[\"sts:AssumeRole\"]}]}",
            "RoleName": "sampleSSMInstanceRole"
          },
          "nextStep": "attachManagedSSMPolicy"
        },
        {
          "name": "attachManagedSSMPolicy",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "AttachRolePolicy",
            "PolicyArn": "arn:aws:iam::aws:policy/service-role/AmazonSSMManagedInstanceCore",
            "RoleName": "sampleSSMInstanceRole"
          },
          "nextStep": "createSSMInstanceProfile"
        },
        {
          "name": "createSSMInstanceProfile",
          "action":"aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "CreateInstanceProfile",
            "InstanceProfileName": "sampleSSMInstanceRole"
          },
          "outputs": [
            {
              "Name": "instanceProfileArn",
              "Selector": "$.InstanceProfile.Arn",
              "Type": "String"
            }
          ],
          "nextStep": "addSSMInstanceRoleToProfile"
        },
        {
          "name": "addSSMInstanceRoleToProfile",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "AddRoleToInstanceProfile",
            "InstanceProfileName": "sampleSSMInstanceRole",
            "RoleName": "sampleSSMInstanceRole"
          },
          "nextStep": "createVpc"
        },
        {
          "name": "createVpc",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateVpc",
            "CidrBlock": "10.0.100.0/22"
          },
          "outputs": [
            {
              "Name": "vpcId",
              "Selector": "$.Vpc.VpcId",
              "Type": "String"
            }
          ],
          "nextStep": "getMainRtb"
        },
        {
          "name": "getMainRtb",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "DescribeRouteTables",
            "Filters": [
              {
                "Name": "vpc-id",
                "Values": ["{{ createVpc.vpcId }}"]
              }
            ]
          },
          "outputs": [
            {
              "Name": "mainRtbId",
              "Selector": "$.RouteTables[0].RouteTableId",
              "Type": "String"
            }
          ],
          "nextStep": "verifyMainRtb"
        },
        {
          "name": "verifyMainRtb",
          "action": "aws:assertAwsResourceProperty",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "DescribeRouteTables",
            "RouteTableIds": ["{{ getMainRtb.mainRtbId }}"],
            "PropertySelector": "$.RouteTables[0].Associations[0].Main",
            "DesiredValues": ["True"]
          },
          "nextStep": "createPubSubnet"
        },
        {
          "name": "createPubSubnet",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateSubnet",
            "CidrBlock": "10.0.103.0/24",
            "AvailabilityZone": "us-west-2c",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs":[
            {
              "Name": "pubSubnetId",
              "Selector": "$.Subnet.SubnetId",
              "Type": "String"
            }
          ],
          "nextStep": "createPubRtb"
        },
        {
          "name": "createPubRtb",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateRouteTable",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs": [
            {
              "Name": "pubRtbId",
              "Selector": "$.RouteTable.RouteTableId",
              "Type": "String"
            }
          ],
          "nextStep": "createIgw"
        },
        {
          "name": "createIgw",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateInternetGateway"
          },
          "outputs": [
            {
              "Name": "igwId",
              "Selector": "$.InternetGateway.InternetGatewayId",
              "Type": "String"
            }
          ],
          "nextStep": "attachIgw"
        },
        {
          "name": "attachIgw",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AttachInternetGateway",
            "InternetGatewayId": "{{ createIgw.igwId }}",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "nextStep": "allocateEip"
        },
        {
          "name": "allocateEip",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AllocateAddress",
            "Domain": "vpc"
          },
          "outputs": [
            {
              "Name": "eipAllocationId",
              "Selector": "$.AllocationId",
              "Type": "String"
            }
          ],
          "nextStep": "createNatGw"
        },
        {
          "name": "createNatGw",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateNatGateway",
            "AllocationId": "{{ allocateEip.eipAllocationId }}",
            "SubnetId": "{{ createPubSubnet.pubSubnetId }}"
          },
          "outputs":[
            {
              "Name": "natGwId",
              "Selector": "$.NatGateway.NatGatewayId",
              "Type": "String"
            }
          ],
          "nextStep": "verifyNatGwAvailable"
        },
        {
          "name": "verifyNatGwAvailable",
          "action": "aws:waitForAwsResourceProperty",
          "timeoutSeconds": 150,
          "inputs": {
            "Service": "ec2",
            "Api": "DescribeNatGateways",
            "NatGatewayIds": [
              "{{ createNatGw.natGwId }}"
            ],
            "PropertySelector": "$.NatGateways[0].State",
            "DesiredValues": [
              "available"
            ]
          },
          "nextStep": "createNatRoute"
        },
        {
          "name": "createNatRoute",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateRoute",
            "DestinationCidrBlock": "0.0.0.0/0",
            "NatGatewayId": "{{ createNatGw.natGwId }}",
            "RouteTableId": "{{ getMainRtb.mainRtbId }}"
          },
          "nextStep": "createPubRoute"
        },
        {
          "name": "createPubRoute",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateRoute",
            "DestinationCidrBlock": "0.0.0.0/0",
            "GatewayId": "{{ createIgw.igwId }}",
            "RouteTableId": "{{ createPubRtb.pubRtbId }}"
          },
          "nextStep": "setPubSubAssoc"
        },
        {
          "name": "setPubSubAssoc",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AssociateRouteTable",
            "RouteTableId": "{{ createPubRtb.pubRtbId }}",
            "SubnetId": "{{ createPubSubnet.pubSubnetId }}"
          }
        },
        {
          "name": "createDhcpOptions",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateDhcpOptions",
            "DhcpConfigurations": [
              {
                "Key": "domain-name-servers",
                "Values": ["10.0.100.50,10.0.101.50"]
              },
              {
                "Key": "domain-name",
                "Values": ["sample.com"]
              }
            ]
          },
          "outputs": [
            {
              "Name": "dhcpOptionsId",
              "Selector": "$.DhcpOptions.DhcpOptionsId",
              "Type": "String"
            }
          ],
          "nextStep": "createDCSubnet1"
        },
        {
          "name": "createDCSubnet1",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateSubnet",
            "CidrBlock": "10.0.100.0/24",
            "AvailabilityZone": "us-west-2a",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs": [
            {
              "Name": "firstSubnetId",
              "Selector": "$.Subnet.SubnetId",
              "Type": "String"
            }
          ],
          "nextStep": "createDCSubnet2"
        },
        {
          "name": "createDCSubnet2",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateSubnet",
            "CidrBlock": "10.0.101.0/24",
            "AvailabilityZone": "us-west-2b",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs": [
            {
              "Name": "secondSubnetId",
              "Selector": "$.Subnet.SubnetId",
              "Type": "String"
            }
          ],
          "nextStep": "createDCSecGroup"
        },
        {
          "name": "createDCSecGroup",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "CreateSecurityGroup",
            "GroupName": "SampleDCSecGroup",
            "Description": "Security Group for Example Domain Controllers",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "outputs": [
            {
              "Name": "dcSecGroupId",
              "Selector": "$.GroupId",
              "Type": "String"
            }
          ],
          "nextStep": "authIngressDCTraffic"
        },
        {
          "name": "authIngressDCTraffic",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AuthorizeSecurityGroupIngress",
            "GroupId": "{{ createDCSecGroup.dcSecGroupId }}",
            "IpPermissions": [
              {
                "FromPort": -1,
                "IpProtocol": "-1",
                "IpRanges": [
                  {
                    "CidrIp": "0.0.0.0/0",
                    "Description": "Allow all traffic between Domain Controllers"
                  }
                ]
              }
            ]
          },
          "nextStep": "verifyInstanceProfile"
        },
        {
          "name": "verifyInstanceProfile",
          "action": "aws:waitForAwsResourceProperty",
          "maxAttempts": 5,
          "onFailure": "Abort",
          "inputs": {
            "Service": "iam",
            "Api": "ListInstanceProfilesForRole",
            "RoleName": "sampleSSMInstanceRole",
            "PropertySelector": "$.InstanceProfiles[0].Arn",
            "DesiredValues": [
              "{{ createSSMInstanceProfile.instanceProfileArn }}"
            ]
          },
          "nextStep": "iamEventualConsistency"
        },
        {
          "name": "iamEventualConsistency",
          "action": "aws:sleep",
          "inputs": {
            "Duration": "PT2M"
          },
          "nextStep": "launchDC1"
        },
        {
          "name": "launchDC1",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "RunInstances",
            "BlockDeviceMappings": [
              {
                "DeviceName": "/dev/sda1",
                "Ebs": {
                  "DeleteOnTermination": true,
                  "VolumeSize": 50,
                  "VolumeType": "gp2"
                }
              },
              {
                "DeviceName": "xvdf",
                "Ebs": {
                  "DeleteOnTermination": true,
                  "VolumeSize": 100,
                  "VolumeType": "gp2"
                }
              }
            ],
            "IamInstanceProfile": {
              "Arn": "{{ createSSMInstanceProfile.instanceProfileArn }}"
            },
            "ImageId": "{{ getLatestWindowsAmi.amiId }}",
            "InstanceType": "t2.micro",
            "MaxCount": 1,
            "MinCount": 1,
            "PrivateIpAddress": "10.0.100.50",
            "SecurityGroupIds": [
              "{{ createDCSecGroup.dcSecGroupId }}"
            ],
            "SubnetId": "{{ createDCSubnet1.firstSubnetId }}",
            "TagSpecifications": [
              {
                "ResourceType": "instance",
                "Tags": [
                  {
                    "Key": "Name",
                    "Value": "SampleDC1"
                  }
                ]
              }
            ]
          },
          "outputs": [
            {
              "Name": "pdcInstanceId",
              "Selector": "$.Instances[0].InstanceId",
              "Type": "String"
            }
          ],
          "nextStep": "launchDC2"
        },
        {
          "name": "launchDC2",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "RunInstances",
            "BlockDeviceMappings": [
              {
                "DeviceName": "/dev/sda1",
                "Ebs": {
                  "DeleteOnTermination": true,
                  "VolumeSize": 50,
                  "VolumeType": "gp2"
                }
              },
              {
                "DeviceName": "xvdf",
                "Ebs": {
                  "DeleteOnTermination": true,
                  "VolumeSize": 100,
                  "VolumeType": "gp2"
                }
              }
            ],
            "IamInstanceProfile": {
              "Arn": "{{ createSSMInstanceProfile.instanceProfileArn }}"
            },
            "ImageId": "{{ getLatestWindowsAmi.amiId }}",
            "InstanceType": "t2.micro",
            "MaxCount": 1,
            "MinCount": 1,
            "PrivateIpAddress": "10.0.101.50",
            "SecurityGroupIds": [
              "{{ createDCSecGroup.dcSecGroupId }}"
            ],
            "SubnetId": "{{ createDCSubnet2.secondSubnetId }}",
            "TagSpecifications": [
              {
                "ResourceType": "instance",
                "Tags": [
                  {
                    "Key": "Name",
                    "Value": "SampleDC2"
                  }
                ]
              }
            ]
          },
          "outputs": [
            {
              "Name": "adcInstanceId",
              "Selector": "$.Instances[0].InstanceId",
              "Type": "String"
            }
          ],
          "nextStep": "verifyDCInstanceState"
        },
        {
          "name": "verifyDCInstanceState",
          "action": "aws:waitForAwsResourceProperty",
          "inputs": {
            "Service": "ec2",
            "Api": "DescribeInstanceStatus",
            "IncludeAllInstances": true,
            "InstanceIds": [
              "{{ launchDC1.pdcInstanceId }}",
              "{{ launchDC2.adcInstanceId }}"
            ],
            "PropertySelector": "$.InstanceStatuses[0].InstanceState.Name",
            "DesiredValues": [
              "running"
            ]
          },
          "nextStep": "verifyInstancesOnlineSSM"
        },
        {
          "name": "verifyInstancesOnlineSSM",
          "action": "aws:waitForAwsResourceProperty",
          "timeoutSeconds": 600,
          "inputs": {
            "Service": "ssm",
            "Api": "DescribeInstanceInformation",
            "InstanceInformationFilterList": [
              {
                "key": "InstanceIds",
                "valueSet": [
                  "{{ launchDC1.pdcInstanceId }}",
                  "{{ launchDC2.adcInstanceId }}"
                ]
              }
            ],
            "PropertySelector": "$.InstanceInformationList[0].PingStatus",
            "DesiredValues": [
              "Online"
            ]
          },
          "nextStep": "installADRoles"
        },
        {
          "name": "installADRoles",
          "action": "aws:runCommand",
          "inputs": {
            "DocumentName": "AWS-RunPowerShellScript",
            "InstanceIds": [
              "{{ launchDC1.pdcInstanceId }}",
              "{{ launchDC2.adcInstanceId }}"
            ],
            "Parameters": {
              "commands": [
                "try {",
                "  Install-WindowsFeature -Name AD-Domain-Services -IncludeManagementTools",
                "}",
                "catch {",
                "  Write-Error \"Failed to install ADDS Role.\"",
                "}"
              ]
            }
          },
          "nextStep": "setAdminPassword"
        },
        {
          "name": "setAdminPassword",
          "action": "aws:runCommand",
          "inputs": {
            "DocumentName": "AWS-RunPowerShellScript",
            "InstanceIds": [
              "{{ launchDC1.pdcInstanceId }}"
            ],
            "Parameters": {
              "commands": [
                "net user Administrator \"sampleAdminPass123!\""
              ]
            }
          },
          "nextStep": "createForest"
        },
        {
          "name": "createForest",
          "action": "aws:runCommand",
          "inputs": {
            "DocumentName": "AWS-RunPowerShellScript",
            "InstanceIds": [
              "{{ launchDC1.pdcInstanceId }}"
            ],
            "Parameters": {
              "commands": [
                "$dsrmPass = 'sample123!' | ConvertTo-SecureString -asPlainText -Force",
                "try {",
                "   Install-ADDSForest -DomainName \"sample.com\" -DomainMode 6 -ForestMode 6 -InstallDNS -DatabasePath \"D:\\NTDS\" -SysvolPath \"D:\\SYSVOL\" -SafeModeAdministratorPassword $dsrmPass -Force",
                "}",
                "catch {",
                "   Write-Error $_",
                "}",
                "try {",
                "   Add-DnsServerForwarder -IPAddress \"10.0.100.2\"",
                "}",
                "catch {",
                "   Write-Error $_",
                "}"
              ]
            }
          },
          "nextStep": "associateDhcpOptions"
        },
        {
          "name": "associateDhcpOptions",
          "action": "aws:executeAwsApi",
          "onFailure": "Abort",
          "inputs": {
            "Service": "ec2",
            "Api": "AssociateDhcpOptions",
            "DhcpOptionsId": "{{ createDhcpOptions.dhcpOptionsId }}",
            "VpcId": "{{ createVpc.vpcId }}"
          },
          "nextStep": "waitForADServices"
        },
        {
          "name": "waitForADServices",
          "action": "aws:sleep",
          "inputs": {
            "Duration": "PT1M"
          },
          "nextStep": "promoteADC"
        },
        {
          "name": "promoteADC",
          "action": "aws:runCommand",
          "inputs": {
            "DocumentName": "AWS-RunPowerShellScript",
            "InstanceIds": [
              "{{ launchDC2.adcInstanceId }}"
            ],
            "Parameters": {
              "commands": [
                "ipconfig /renew",
                "$dsrmPass = 'sample123!' | ConvertTo-SecureString -asPlainText -Force",
                "$domAdminUser = \"sample\\Administrator\"",
                "$domAdminPass = \"sampleAdminPass123!\" | ConvertTo-SecureString -asPlainText -Force",
                "$domAdminCred = New-Object System.Management.Automation.PSCredential($domAdminUser,$domAdminPass)",
                "try {",
                "   Install-ADDSDomainController -DomainName \"sample.com\" -InstallDNS -DatabasePath \"D:\\NTDS\" -SysvolPath \"D:\\SYSVOL\" -SafeModeAdministratorPassword $dsrmPass -Credential $domAdminCred -Force",
                "}",
                "catch {",
                "   Write-Error $_",
                "}"
              ]
            }
          }
        }
      ]
    }
```

------

# 从最新快照还原根卷


根卷上的操作系统可能会出于各种原因而受损。例如，在执行修补操作后，实例可能会因内核或注册表损坏而无法成功启动。自动执行常见故障排除任务（例如，从修补操作前拍摄的最新快照还原根卷）可以减少停机时间并加快故障排除工作。AWS Systems Manager自动化操作可帮助您做到这一点。Automation 是 AWS Systems Manager 中的一项工具。

以下示例 AWS Systems Manager 运行手册执行这些操作：
+ 使用 `aws:executeAwsApi` 自动化操作从实例的根卷检索详细信息。
+ 使用 `aws:executeScript` 自动化操作检索根卷的最新快照。
+ 如果找到了根卷的快照，则使用 `aws:branch` 自动化操作继续执行自动化。

------
#### [ YAML ]

```
    ---
    description: Custom Automation Troubleshooting Example
    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 use this runbook."
        default: ''
      InstanceId:
          type: String
          description: "(Required) The Instance Id whose root EBS volume you want to restore the latest Snapshot."
          default: ''
    mainSteps:
    - name: getInstanceDetails
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: DescribeInstances
        InstanceIds:
        - "{{ InstanceId }}"
      outputs:
        - Name: availabilityZone
          Selector: "$.Reservations[0].Instances[0].Placement.AvailabilityZone"
          Type: String
        - Name: rootDeviceName
          Selector: "$.Reservations[0].Instances[0].RootDeviceName"
          Type: String
      nextStep: getRootVolumeId
    - name: getRootVolumeId
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: DescribeVolumes
        Filters:
        -  Name: attachment.device
           Values: ["{{ getInstanceDetails.rootDeviceName }}"]
        -  Name: attachment.instance-id
           Values: ["{{ InstanceId }}"]
      outputs:
        - Name: rootVolumeId
          Selector: "$.Volumes[0].VolumeId"
          Type: String
      nextStep: getSnapshotsByStartTime
    - name: getSnapshotsByStartTime
      action: aws:executeScript
      timeoutSeconds: 45
      onFailure: Abort
      inputs:
        Runtime: python3.11
        Handler: getSnapshotsByStartTime
        InputPayload:
          rootVolumeId : "{{ getRootVolumeId.rootVolumeId }}"
        Script: |-
          def getSnapshotsByStartTime(events,context):
            import boto3
    
            #Initialize client
            ec2 = boto3.client('ec2')
            rootVolumeId = events['rootVolumeId']
            snapshotsQuery = ec2.describe_snapshots(
              Filters=[
                {
                  "Name": "volume-id",
                  "Values": [rootVolumeId]
                }
              ]
            )
            if not snapshotsQuery['Snapshots']:
              noSnapshotFoundString = "NoSnapshotFound"
              return { 'noSnapshotFound' : noSnapshotFoundString }
            else:
              jsonSnapshots = snapshotsQuery['Snapshots']
              sortedSnapshots = sorted(jsonSnapshots, key=lambda k: k['StartTime'], reverse=True)
              latestSortedSnapshotId = sortedSnapshots[0]['SnapshotId']
              return { 'latestSnapshotId' : latestSortedSnapshotId }
      outputs:
      - Name: Payload
        Selector: $.Payload
        Type: StringMap
      - Name: latestSnapshotId
        Selector: $.Payload.latestSnapshotId
        Type: String
      - Name: noSnapshotFound
        Selector: $.Payload.noSnapshotFound
        Type: String 
      nextStep: branchFromResults
    - name: branchFromResults
      action: aws:branch
      onFailure: Abort
      inputs:
        Choices:
        - NextStep: createNewRootVolumeFromSnapshot
          Not:
            Variable: "{{ getSnapshotsByStartTime.noSnapshotFound }}"
            StringEquals: "NoSnapshotFound"
      isEnd: true
    - name: createNewRootVolumeFromSnapshot
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: CreateVolume
        AvailabilityZone: "{{ getInstanceDetails.availabilityZone }}"
        SnapshotId: "{{ getSnapshotsByStartTime.latestSnapshotId }}"
      outputs:
        - Name: newRootVolumeId
          Selector: "$.VolumeId"
          Type: String
      nextStep: stopInstance
    - name: stopInstance
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: StopInstances
        InstanceIds:
        - "{{ InstanceId }}"
      nextStep: verifyVolumeAvailability
    - name: verifyVolumeAvailability
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 120
      inputs:
        Service: ec2
        Api: DescribeVolumes
        VolumeIds:
        - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
        PropertySelector: "$.Volumes[0].State"
        DesiredValues:
        - "available"
      nextStep: verifyInstanceStopped
    - name: verifyInstanceStopped
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 120
      inputs:
        Service: ec2
        Api: DescribeInstances
        InstanceIds:
        - "{{ InstanceId }}"
        PropertySelector: "$.Reservations[0].Instances[0].State.Name"
        DesiredValues:
        - "stopped"
      nextStep: detachRootVolume
    - name: detachRootVolume
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: DetachVolume
        VolumeId: "{{ getRootVolumeId.rootVolumeId }}"
      nextStep: verifyRootVolumeDetached
    - name: verifyRootVolumeDetached
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 30
      inputs:
        Service: ec2
        Api: DescribeVolumes
        VolumeIds:
        - "{{ getRootVolumeId.rootVolumeId }}"
        PropertySelector: "$.Volumes[0].State"
        DesiredValues:
        - "available"
      nextStep: attachNewRootVolume
    - name: attachNewRootVolume
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: AttachVolume
        Device: "{{ getInstanceDetails.rootDeviceName }}"
        InstanceId: "{{ InstanceId }}"
        VolumeId: "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
      nextStep: verifyNewRootVolumeAttached
    - name: verifyNewRootVolumeAttached
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 30
      inputs:
        Service: ec2
        Api: DescribeVolumes
        VolumeIds:
        - "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
        PropertySelector: "$.Volumes[0].Attachments[0].State"
        DesiredValues:
        - "attached"
      nextStep: startInstance
    - name: startInstance
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: StartInstances
        InstanceIds:
        - "{{ InstanceId }}"
```

------
#### [ JSON ]

```
    {
       "description": "Custom Automation Troubleshooting Example",
       "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 run this runbook.",
             "default": ""
          },
          "InstanceId": {
             "type": "String",
             "description": "(Required) The Instance Id whose root EBS volume you want to restore the latest Snapshot.",
             "default": ""
          }
       },
       "mainSteps": [
          {
             "name": "getInstanceDetails",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeInstances",
                "InstanceIds": [
                   "{{ InstanceId }}"
                ]
             },
             "outputs": [
                {
                   "Name": "availabilityZone",
                   "Selector": "$.Reservations[0].Instances[0].Placement.AvailabilityZone",
                   "Type": "String"
                },
                {
                   "Name": "rootDeviceName",
                   "Selector": "$.Reservations[0].Instances[0].RootDeviceName",
                   "Type": "String"
                }
             ],
             "nextStep": "getRootVolumeId"
          },
          {
             "name": "getRootVolumeId",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeVolumes",
                "Filters": [
                   {
                      "Name": "attachment.device",
                      "Values": [
                         "{{ getInstanceDetails.rootDeviceName }}"
                      ]
                   },
                   {
                      "Name": "attachment.instance-id",
                      "Values": [
                         "{{ InstanceId }}"
                      ]
                   }
                ]
             },
             "outputs": [
                {
                   "Name": "rootVolumeId",
                   "Selector": "$.Volumes[0].VolumeId",
                   "Type": "String"
                }
             ],
             "nextStep": "getSnapshotsByStartTime"
          },
          {
             "name": "getSnapshotsByStartTime",
             "action": "aws:executeScript",
             "timeoutSeconds": 45,
             "onFailure": "Continue",
             "inputs": {
                "Runtime": "python3.11",
                "Handler": "getSnapshotsByStartTime",
                "InputPayload": {
                   "rootVolumeId": "{{ getRootVolumeId.rootVolumeId }}"
                },
                "Attachment": "getSnapshotsByStartTime.py"
             },
             "outputs": [
                {
                   "Name": "Payload",
                   "Selector": "$.Payload",
                   "Type": "StringMap"
                },
                {
                   "Name": "latestSnapshotId",
                   "Selector": "$.Payload.latestSnapshotId",
                   "Type": "String"
                },
                {
                   "Name": "noSnapshotFound",
                   "Selector": "$.Payload.noSnapshotFound",
                   "Type": "String"
                }
             ],
             "nextStep": "branchFromResults"
          },
          {
             "name": "branchFromResults",
             "action": "aws:branch",
             "onFailure": "Abort",
             "inputs": {
                "Choices": [
                   {
                      "NextStep": "createNewRootVolumeFromSnapshot",
                      "Not": {
                         "Variable": "{{ getSnapshotsByStartTime.noSnapshotFound }}",
                         "StringEquals": "NoSnapshotFound"
                      }
                   }
                ]
             },
             "isEnd": true
          },
          {
             "name": "createNewRootVolumeFromSnapshot",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "CreateVolume",
                "AvailabilityZone": "{{ getInstanceDetails.availabilityZone }}",
                "SnapshotId": "{{ getSnapshotsByStartTime.latestSnapshotId }}"
             },
             "outputs": [
                {
                   "Name": "newRootVolumeId",
                   "Selector": "$.VolumeId",
                   "Type": "String"
                }
             ],
             "nextStep": "stopInstance"
          },
          {
             "name": "stopInstance",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "StopInstances",
                "InstanceIds": [
                   "{{ InstanceId }}"
                ]
             },
             "nextStep": "verifyVolumeAvailability"
          },
          {
             "name": "verifyVolumeAvailability",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 120,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeVolumes",
                "VolumeIds": [
                   "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
                ],
                "PropertySelector": "$.Volumes[0].State",
                "DesiredValues": [
                   "available"
                ]
             },
             "nextStep": "verifyInstanceStopped"
          },
          {
             "name": "verifyInstanceStopped",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 120,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeInstances",
                "InstanceIds": [
                   "{{ InstanceId }}"
                ],
                "PropertySelector": "$.Reservations[0].Instances[0].State.Name",
                "DesiredValues": [
                   "stopped"
                ]
             },
             "nextStep": "detachRootVolume"
          },
          {
             "name": "detachRootVolume",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "DetachVolume",
                "VolumeId": "{{ getRootVolumeId.rootVolumeId }}"
             },
             "nextStep": "verifyRootVolumeDetached"
          },
          {
             "name": "verifyRootVolumeDetached",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 30,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeVolumes",
                "VolumeIds": [
                   "{{ getRootVolumeId.rootVolumeId }}"
                ],
                "PropertySelector": "$.Volumes[0].State",
                "DesiredValues": [
                   "available"
                ]
             },
             "nextStep": "attachNewRootVolume"
          },
          {
             "name": "attachNewRootVolume",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "AttachVolume",
                "Device": "{{ getInstanceDetails.rootDeviceName }}",
                "InstanceId": "{{ InstanceId }}",
                "VolumeId": "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
             },
             "nextStep": "verifyNewRootVolumeAttached"
          },
          {
             "name": "verifyNewRootVolumeAttached",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 30,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeVolumes",
                "VolumeIds": [
                   "{{ createNewRootVolumeFromSnapshot.newRootVolumeId }}"
                ],
                "PropertySelector": "$.Volumes[0].Attachments[0].State",
                "DesiredValues": [
                   "attached"
                ]
             },
             "nextStep": "startInstance"
          },
          {
             "name": "startInstance",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "StartInstances",
                "InstanceIds": [
                   "{{ InstanceId }}"
                ]
             }
          }
       ],
       "files": {
            "getSnapshotsByStartTime.py": {
                "checksums": {
                    "sha256": "sampleETagValue"
                }
            }
        }
    }
```

------

# 创建 AMI 和跨区域副本


创建实例的 Amazon Machine Image (AMI) 是备份和恢复操作中的常用过程。也可以选择将 AMI 作为灾难恢复架构的一部分复制到另一个 AWS 区域。如果问题需要进行故障转移，则自动执行常见的维护任务可以减少停机时间。AWS Systems Manager自动化操作可帮助您做到这一点。Automation 是 AWS Systems Manager 中的一项工具。

以下示例 AWS Systems Manager 运行手册执行这些操作：
+ 使用 `aws:executeAwsApi` 自动化操作创建 AMI。
+ 使用 `aws:waitForAwsResourceProperty` 自动化操作确认 AMI 的可用性。
+ 使用 `aws:executeScript` 自动化操作将 AMI 复制到目标区域。

------
#### [ YAML ]

```
    ---
    description: Custom Automation Backup and Recovery Example
    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 use this runbook."
        default: ''
      InstanceId:
        type: String
        description: "(Required) The ID of the EC2 instance."
        default: ''
    mainSteps:
    - name: createImage
      action: aws:executeAwsApi
      onFailure: Abort
      inputs:
        Service: ec2
        Api: CreateImage
        InstanceId: "{{ InstanceId }}"
        Name: "Automation Image for {{ InstanceId }}"
        NoReboot: false
      outputs:
        - Name: newImageId
          Selector: "$.ImageId"
          Type: String
      nextStep: verifyImageAvailability
    - name: verifyImageAvailability
      action: aws:waitForAwsResourceProperty
      timeoutSeconds: 600
      inputs:
        Service: ec2
        Api: DescribeImages
        ImageIds:
        - "{{ createImage.newImageId }}"
        PropertySelector: "$.Images[0].State"
        DesiredValues:
        - available
      nextStep: copyImage
    - name: copyImage
      action: aws:executeScript
      timeoutSeconds: 45
      onFailure: Abort
      inputs:
        Runtime: python3.11
        Handler: crossRegionImageCopy
        InputPayload:
          newImageId : "{{ createImage.newImageId }}"
        Script: |-
          def crossRegionImageCopy(events,context):
            import boto3
    
            #Initialize client
            ec2 = boto3.client('ec2', region_name='us-east-1')
            newImageId = events['newImageId']
    
            ec2.copy_image(
              Name='DR Copy for ' + newImageId,
              SourceImageId=newImageId,
              SourceRegion='us-west-2'
            )
```

------
#### [ JSON ]

```
    {
       "description": "Custom Automation Backup and Recovery Example",
       "schemaVersion": "0.3",
       "assumeRole": "{{ AutomationAssumeRole }}",
       "parameters": {
          "AutomationAssumeRole": {
             "type": "String",
             "description": "(Required) The ARN of the role that allows Automation to perform\nthe actions on your behalf. If no role is specified, Systems Manager Automation\nuses your IAM permissions to run this runbook.",
             "default": ""
          },
          "InstanceId": {
             "type": "String",
             "description": "(Required) The ID of the EC2 instance.",
             "default": ""
          }
       },
       "mainSteps": [
          {
             "name": "createImage",
             "action": "aws:executeAwsApi",
             "onFailure": "Abort",
             "inputs": {
                "Service": "ec2",
                "Api": "CreateImage",
                "InstanceId": "{{ InstanceId }}",
                "Name": "Automation Image for {{ InstanceId }}",
                "NoReboot": false
             },
             "outputs": [
                {
                   "Name": "newImageId",
                   "Selector": "$.ImageId",
                   "Type": "String"
                }
             ],
             "nextStep": "verifyImageAvailability"
          },
          {
             "name": "verifyImageAvailability",
             "action": "aws:waitForAwsResourceProperty",
             "timeoutSeconds": 600,
             "inputs": {
                "Service": "ec2",
                "Api": "DescribeImages",
                "ImageIds": [
                   "{{ createImage.newImageId }}"
                ],
                "PropertySelector": "$.Images[0].State",
                "DesiredValues": [
                   "available"
                ]
             },
             "nextStep": "copyImage"
          },
          {
             "name": "copyImage",
             "action": "aws:executeScript",
             "timeoutSeconds": 45,
             "onFailure": "Abort",
             "inputs": {
                "Runtime": "python3.11",
                "Handler": "crossRegionImageCopy",
                "InputPayload": {
                   "newImageId": "{{ createImage.newImageId }}"
                },
                "Attachment": "crossRegionImageCopy.py"
             }
          }
       ],
       "files": {
            "crossRegionImageCopy.py": {
                "checksums": {
                    "sha256": "sampleETagValue"
                }
            }
        }
    }
```

------

# 创建填充 AWS 资源的输入参数


Automation 是 Systems Manager 中的一项工具，可在 AWS 管理控制台中填充与您为输入参数定义的资源类型相匹配的 AWS 资源。与资源类型匹配的 AWS 账户 中的资源将显示在下拉列表中供您选择。您可以为 Amazon Elastic Compute Cloud (Amazon EC2) 实例、Amazon Simple Storage Service (Amazon S3) 存储桶以及 AWS Identity and Access Management (IAM) 角色定义输入参数类型。支持的类型定义与用于查找匹配资源的正则表达式如下：
+ `AWS::EC2::Instance::Id` - `^m?i-([a-z0-9]{8}|[a-z0-9]{17})$`
+ `List<AWS::EC2::Instance::Id>` - `^m?i-([a-z0-9]{8}|[a-z0-9]{17})$`
+ `AWS::S3::Bucket::Name` - `^[0-9a-z][a-z0-9\\-\\.]{3,63}$`
+ `List<AWS::S3::Bucket::Name>` - `^[0-9a-z][a-z0-9\\-\\.]{3,63}$`
+ `AWS::IAM::Role::Arn` - `^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b):iam::[0-9]{12}:role/.*$`
+ `List<AWS::IAM::Role::Arn>` - `^arn:(aws|aws-cn|aws-us-gov|aws-iso|aws-iso-b):iam::[0-9]{12}:role/.*$`

以下是在运行手册内容中定义的输入参数类型的示例。

------
#### [ YAML ]

```
description: Enables encryption on an Amazon S3 bucket
schemaVersion: '0.3'
assumeRole: '{{ AutomationAssumeRole }}'
parameters:
  BucketName:
    type: 'AWS::S3::Bucket::Name'
    description: (Required) The name of the Amazon S3 bucket you want to encrypt.
  SSEAlgorithm:
    type: String
    description: (Optional) The server-side encryption algorithm to use for the default encryption.
    default: AES256
  AutomationAssumeRole:
    type: 'AWS::IAM::Role::Arn'
    description: (Optional) The Amazon Resource Name (ARN) of the role that allows Automation to perform the actions on your behalf.
    default: ''
mainSteps:
  - name: enableBucketEncryption
    action: 'aws:executeAwsApi'
    inputs:
      Service: s3
      Api: PutBucketEncryption
      Bucket: '{{BucketName}}'
      ServerSideEncryptionConfiguration:
        Rules:
          - ApplyServerSideEncryptionByDefault:
              SSEAlgorithm: '{{SSEAlgorithm}}'
    isEnd: true
```

------
#### [ JSON ]

```
{
   "description": "Enables encryption on an Amazon S3 bucket",
   "schemaVersion": "0.3",
   "assumeRole": "{{ AutomationAssumeRole }}",
   "parameters": {
      "BucketName": {
         "type": "AWS::S3::Bucket::Name",
         "description": "(Required) The name of the Amazon S3 bucket you want to encrypt."
      },
      "SSEAlgorithm": {
         "type": "String",
         "description": "(Optional) The server-side encryption algorithm to use for the default encryption.",
         "default": "AES256"
      },
      "AutomationAssumeRole": {
         "type": "AWS::IAM::Role::Arn",
         "description": "(Optional) The Amazon Resource Name (ARN) of the role that allows Automation to perform the actions on your behalf.",
         "default": ""
      }
   },
   "mainSteps": [
      {
         "name": "enableBucketEncryption",
         "action": "aws:executeAwsApi",
         "inputs": {
            "Service": "s3",
            "Api": "PutBucketEncryption",
            "Bucket": "{{BucketName}}",
            "ServerSideEncryptionConfiguration": {
               "Rules": [
                  {
                     "ApplyServerSideEncryptionByDefault": {
                        "SSEAlgorithm": "{{SSEAlgorithm}}"
                     }
                  }
               ]
            }
         },
         "isEnd": true
      }
   ]
}
```

------

# 正在使用文档生成器创建运行手册


如果 AWS Systems Manager 公有运行手册不支持您希望在 AWS 资源上执行的操作，您可以创建自己的运行手册。要创建自定义运行手册，您可以手动创建包含相应自动化操作的本地 YAML 或 JSON 格式文件。或者，您也可以使用 Systems Manager Automation 控制台中的文档生成器来构建自定义运行手册。

通过使用文档生成器，您可以将自动化操作添加到自定义运行手册中，并提供所需的参数，而无需使用 JSON 或 YAML 语法。在添加步骤并创建运行手册后，系统将您添加的操作转换为 Systems Manager 可用于运行自动化的 YAML 格式。

自动化文档支持使用 Markdown（一种标记语言），它允许您为运行手册和其中的各个步骤添加 Wiki 样式的描述。有关使用 Markdown 的更多信息，请参阅[在 AWS 中使用 Markdown](https://docs.aws.amazon.com/general/latest/gr/aws-markdown.html)。

## 使用文档生成器创建运行手册


**开始前的准备工作**  
我们建议您阅读可在运行手册中使用的各种操作。有关更多信息，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)。

**使用文档生成器创建运行手册**

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

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

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

1. 对于**名称**，为运行手册输入一个描述性名称。

1. 对于**文档描述**，请提供运行手册的 markdown 样式描述。您可以提供使用运行手册的说明、编号的步骤或描述运行手册的任何其他类型的信息。请参阅默认文本以了解设置内容格式的信息。
**提示**  
在**隐藏预览**和**显示预览**之间切换，以便在编写时查看描述内容的效果。

1. （可选）对于 **Assume role (担任角色)**，请输入代表您执行操作的服务角色的名称或 ARN。如果未指定角色，自动化使用运行自动化的用户的访问权限。
**重要**  
对于不归 Amazon 所有并使用 `aws:executeScript` 操作的运行手册，必须指定一个角色。有关信息，请参阅[使用运行手册的权限](automation-document-script-considerations.md#script-permissions)。

1. （可选）对于**输出**，请输入执行该运行手册的自动化的任何输出以供其他进程使用。

   例如，如果文档创建新的 AMI，您可以指定 ["CreateImage.ImageId"]，然后使用该输出以在后续自动化中创建新的实例。

1. （可选）展开**输入参数**部分，然后执行以下操作。

   1. 对于**参数名称**，请输入要创建的运行手册参数的描述性名称。

   1. 对于**类型**，请选择参数的类型，例如 `String` 或 `MapList`。

   1. 对于**必需**，请执行以下操作之一：
      + 如果必须在运行时提供该运行手册参数的值，请选择**是**。
      + 如果该参数不是必需的，请选择**否**，然后（可选）在**默认值**中输入默认参数值。

   1. 对于**描述**，请输入运行手册参数的描述。
**注意**  
要添加更多运行手册参数，请选择**添加参数**。要删除运行手册参数，请选择 **X**（删除）按钮。

1. （可选）展开**目标类型**部分，然后选择一种目标类型以定义可以运行自动化的资源的类型。例如，要在 EC2 实例上使用运行手册，请选择 `/AWS::EC2::Instance`。
**注意**  
如果指定“`/`”值，则运行文档可以在所有类型的资源上运行。有关有效资源类型列表，请参阅 *AWS CloudFormation 用户指南* 中的 [AWS 资源类型参考](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)。

1. （可选）展开**文档标签**部分，然后输入一个或多个标签键值对以应用于运行手册。标签可以轻松标识、划分和搜索资源。

1. 在**步骤 1** 部分中，提供以下信息。
   + 对于**步骤名称**，请输入自动化的第一步的描述性名称。
   + 对于**操作类型**，请选择用于该步骤的操作类型。

     有关可用操作类型的列表和信息，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)。
   + 对于**描述**，请输入自动化步骤的描述。您可以使用 Markdown 设置文本格式。
   + 根据选定的**操作类型**，在**步骤输入**部分中输入操作类型所需的输入。例如，如果选择了 `aws:approve` 操作，您必须为 `Approvers` 属性指定一个值。

     有关步骤输入字段的信息，请参阅 [Systems Manager 自动化操作参考](automation-actions.md)中的选定操作类型的条目。例如：[`aws:executeStateMachine` - 运行 AWS Step Functions 状态机。](automation-action-executeStateMachine.md)。
   + （可选）对于**其他输入**，请提供运行手册所需的任何其他输入值。可用的输入类型取决于您为步骤选择的操作类型。（请注意，某些操作类型需要使用输入值。）
**注意**  
要添加更多输入，请选择 **Add optional input (添加可选的输入)**。要删除输入，请选择 **X**（删除）按钮。
   + （可选）对于**输出**，请输入执行该步骤的任何输出以供其他进程使用。
**注意**  
**输出**并非适用于所有操作类型。
   + （可选）展开**通用属性**部分，然后指定所有自动化操作的通用操作属性。例如，对于**超时秒数**，您可以提供一个值以指定步骤在停止之前可以运行多长时间（以秒为单位）。

     有关更多信息，请参阅 [所有操作共享的属性](automation-actions.md#automation-common)。
**注意**  
要添加更多步骤，请选择**添加步骤**，然后重复创建步骤的过程。要删除步骤，请选择**删除步骤**。

1. 选择**创建自动化**以保存运行手册。

## 创建运行脚本的运行手册


以下过程展示了如何在 AWS Systems Manager Automation 控制台中使用文档生成器创建运行脚本的自定义运行手册。

您创建的运行手册的第一步运行一个脚本以启动 Amazon Elastic Compute Cloud (Amazon EC2) 实例。第二步运行另一个脚本来监控要更改为 `ok` 的实例状态检查。然后，报告自动化的整体状态 `Success`。

**开始前的准备工作**  
确保您已完成以下步骤：
+ 确认您具有管理员权限，或为您授予了相应的权限以在 AWS Identity and Access Management (IAM) 中访问 Systems Manager。

  有关信息，请参阅[验证用户的运行手册访问权限](automation-setup.md#automation-setup-user-access)。
+ 确认在您的 AWS 账户 账户中具有自动化的 IAM 服务角色（也称为*担任角色*）。该角色是必需的，因为该演练使用 `aws:executeScript` 操作。

  有关创建此角色的信息，请参阅 [为自动化配置服务角色（担任角色）访问权限](automation-setup.md#automation-setup-configure-role)。

  有关用于运行 `aws:executeScript` 的 IAM 服务角色要求的信息，请参阅 [使用运行手册的权限](automation-document-script-considerations.md#script-permissions)。
+ 确认您具有启动 EC2 实例的权限。

  有关更多信息，请参阅《Amazon EC2 用户指南》**中的 [IAM 与 Amazon EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/UsingIAM.html#intro-to-iam)。

**创建使用文档生成器运行脚本的自定义运行手册**

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

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

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

1. 对于**名称**，请为运行手册键入以下描述性名称：**LaunchInstanceAndCheckStatus**。

1. （可选）对于**文档描述)**，请使用 Markdown 将默认文本替换为该运行手册的描述。示例如下：

   ```
   ##Title: LaunchInstanceAndCheckState
       -----
       **Purpose**: This runbook first launches an EC2 instance using the AMI ID provided in the parameter ```imageId```. The second step of this runbook continuously checks the instance status check value for the launched instance until the status ```ok``` is returned.
       
       ##Parameters:
       -----
       Name | Type | Description | Default Value
       ------------- | ------------- | ------------- | -------------
       assumeRole | String | (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. | -
       imageId  | String | (Optional) The AMI ID to use for launching the instance. The default value uses the latest Amazon Linux 2023 AMI ID available. | {{ ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-arm64 }}
   ```

1. 对于**担任角色**，请使用 **arn:aws:iam::111122223333:role/AutomationServiceRole** 格式输入自动化的自动化 IAM 服务角色（担任角色）的 ARN。使用您的 AWS 账户 ID 替代 111122223333。

   您指定的角色用于提供启动自动化执行所需的权限。
**重要**  
对于不归 Amazon 所有并使用 `aws:executeScript` 操作的运行手册，必须指定一个角色。有关信息，请参阅[使用运行手册的权限](automation-document-script-considerations.md#script-permissions)。

1. 展开**输入参数**，然后执行以下操作。

   1. 对于**参数名称**，请输入 **imageId**。

   1. 对于**类型**，选择 **String**。

   1. 对于**必需**，请选择 `No`。

   1. 对于**默认值**，请输入以下内容。

      ```
      {{ ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-6.1-arm64 }}
      ```
**注意**  
该值使用最新的 Amazon Linux 2023 Amazon Machine Image（AMI）ID 启动 Amazon EC2 实例。如果要使用不同的 AMI，请将该值替换为您的 AMI ID。

   1. 对于**描述**，请输入以下内容。

      ```
      (Optional) The AMI ID to use for launching the instance. The default value uses the latest released Amazon Linux 2023 AMI ID.
      ```

1. 选择**添加参数)**以创建第二个参数 **tagValue**，然后输入以下内容。

   1. 对于**参数名称**，请输入 **tagValue**。

   1. 对于**类型**，选择 **String**。

   1. 对于**必需**，请选择 `No`。

   1. 对于**默认值**，请输入 **LaunchedBySsmAutomation**。这会将标签键对值 `Name:LaunchedBySsmAutomation` 添加到实例中。

   1. 对于**描述**，请输入以下内容。

      ```
      (Optional) The tag value to add to the instance. The default value is LaunchedBySsmAutomation.
      ```

1. 选择**添加参数** 以创建第三个参数 **instanceType**，然后输入以下信息。

   1. 对于**参数名称**，请输入 **instanceType**。

   1. 对于**类型**，选择 **String**。

   1. 对于**必需**，请选择 `No`。

   1. 对于**默认值**，请输入 **t2.micro**。

   1. 对于**参数描述**，请输入以下内容。

      ```
      (Optional) The instance type to use for the instance. The default value is t2.micro.
      ```

1. 展开**目标类型**，然后选择 **"/"**。

1. （可选）展开**文档标签**以将资源标签应用于运行手册。为**标签键** 输入 **Purpose**，并为**标签值**输入 **LaunchInstanceAndCheckState**。

1. 在**步骤 1** 部分中，完成以下步骤。

   1. 对于**步骤名称**，为自动化的第一步输入以下描述性步骤名称：**LaunchEc2Instance**。

   1. 对于**操作类型**，请选择**运行脚本)** (**aws:executeScript**)。

   1. 对于**描述**，请输入自动化步骤的描述，例如以下内容。

      ```
      **About This Step**
          
          This step first launches an EC2 instance using the ```aws:executeScript``` action and the provided script.
      ```

   1. 展开**输入**。

   1. 对于**运行时**，请选择运行提供的脚本所使用的运行时语言。

   1. 对于**处理程序**，输入 **launch\$1instance**。这是在以下脚本中声明的函数名称。
**注意**  
这对于 PowerShell 不是必需的。

   1. 对于**脚本**，请将默认内容替换为以下内容。请确保将脚本与相应的运行时值匹配。

------
#### [ Python ]

      ```
      def launch_instance(events, context):
            import boto3
            ec2 = boto3.client('ec2')
          
            image_id = events['image_id']
            tag_value = events['tag_value']
            instance_type = events['instance_type']
          
            tag_config = {'ResourceType': 'instance', 'Tags': [{'Key':'Name', 'Value':tag_value}]}
          
            res = ec2.run_instances(ImageId=image_id, InstanceType=instance_type, MaxCount=1, MinCount=1, TagSpecifications=[tag_config])
          
            instance_id = res['Instances'][0]['InstanceId']
          
            print('[INFO] 1 EC2 instance is successfully launched', instance_id)
          
            return { 'InstanceId' : instance_id }
      ```

------
#### [ PowerShell ]

      ```
      Install-Module AWS.Tools.EC2 -Force
          Import-Module AWS.Tools.EC2
          
          $payload = $env:InputPayload | ConvertFrom-Json
          
          $imageid = $payload.image_id
          
          $tagvalue = $payload.tag_value
          
          $instanceType = $payload.instance_type
          
          $type = New-Object Amazon.EC2.InstanceType -ArgumentList $instanceType
          
          $resource = New-Object Amazon.EC2.ResourceType -ArgumentList 'instance'
          
          $tag = @{Key='Name';Value=$tagValue}
          
          $tagSpecs = New-Object Amazon.EC2.Model.TagSpecification
          
          $tagSpecs.ResourceType = $resource
          
          $tagSpecs.Tags.Add($tag)
          
          $res = New-EC2Instance -ImageId $imageId -MinCount 1 -MaxCount 1 -InstanceType $type -TagSpecification $tagSpecs
          
          return @{'InstanceId'=$res.Instances.InstanceId}
      ```

------

   1. 展开**其他输入**。

   1. 对于**输入名称**，请选择 **InputPayload**。对于**输入值**，请输入以下 YAML 数据。

      ```
      image_id: "{{ imageId }}"
          tag_value: "{{ tagValue }}"
          instance_type: "{{ instanceType }}"
      ```

1. 展开**输出**，然后执行以下操作：
   + 对于**名称**，请输入 **payload**。
   + 对于**选择器**，请输入 **\$1.Payload**。
   + 对于**类型**，选择 `StringMap`。

1. 选择**添加步骤**将第二步添加到运行手册中。第二步查询在步骤 1 中启动的实例的状态，并等到返回的状态为 `ok`。

1. 在 **Step 2 (步骤 2)** 部分中，执行以下操作。

   1. 对于**步骤名称**，请为自动化的第二步输入以下描述性名称：**WaitForInstanceStatusOk**。

   1. 对于**操作类型**，请选择**运行脚本** (**aws:executeScript**)。

   1. 对于**描述**，请输入自动化步骤的描述，例如以下内容。

      ```
      **About This Step**
          
          The script continuously polls the instance status check value for the instance launched in Step 1 until the ```ok``` status is returned.
      ```

   1. 对于**运行时**，选择用于执行提供的脚本的运行时语言。

   1. 对于**处理程序**，输入 **poll\$1instance**。这是在以下脚本中声明的函数名称。
**注意**  
这对于 PowerShell 不是必需的。

   1. 对于**脚本**，请将默认内容替换为以下内容。请确保将脚本与相应的运行时值匹配。

------
#### [ Python ]

      ```
      def poll_instance(events, context):
            import boto3
            import time
          
            ec2 = boto3.client('ec2')
          
            instance_id = events['InstanceId']
          
            print('[INFO] Waiting for instance status check to report ok', instance_id)
          
            instance_status = "null"
          
            while True:
              res = ec2.describe_instance_status(InstanceIds=[instance_id])
          
              if len(res['InstanceStatuses']) == 0:
                print("Instance status information is not available yet")
                time.sleep(5)
                continue
          
              instance_status = res['InstanceStatuses'][0]['InstanceStatus']['Status']
          
              print('[INFO] Polling to get status of the instance', instance_status)
          
              if instance_status == 'ok':
                break
          
              time.sleep(10)
          
            return {'Status': instance_status, 'InstanceId': instance_id}
      ```

------
#### [ PowerShell ]

      ```
          Install-Module AWS.Tools.EC2 -Force
          
          $inputPayload = $env:InputPayload | ConvertFrom-Json
          
          $instanceId = $inputPayload.payload.InstanceId
          
          $status = Get-EC2InstanceStatus -InstanceId $instanceId
          
          while ($status.Status.Status -ne 'ok'){
             Write-Host 'Polling get status of the instance', $instanceId
          
             Start-Sleep -Seconds 5
          
             $status = Get-EC2InstanceStatus -InstanceId $instanceId
          }
          
          return @{Status = $status.Status.Status; InstanceId = $instanceId}
      ```

------

   1. 展开**其他输入**。

   1. 对于**输入名称**，请选择 **InputPayload**。对于**输入值**，请输入以下内容：

      ```
      {{ LaunchEc2Instance.payload }}
      ```

1. 选择**创建自动化**以保存运行手册。

# 在运行手册中使用脚本


自动化运行手册支持将脚本作为自动化的一部分运行。Automation 是 AWS Systems Manager 中的一项工具。通过使用运行手册，您可以直接在 AWS 中运行脚本，而无需创建单独的计算环境来运行脚本。由于运行手册可以将脚本步骤与其他自动化步骤类型（例如批准）一起运行，因此您能够在紧急或不明确的情况下手动进行干预。您可以把来自运行手册中 `aws:executeScript` 操作的输出添加到 Amazon CloudWatch Logs。有关更多信息，请参阅 [使用 CloudWatch Logs 记录自动化操作输出](automation-action-logging.md)。

## 使用运行手册的权限


要使用运行手册，Systems Manager 必须使用 AWS Identity and Access Management (IAM) 角色的权限。自动化用于确定使用哪个角色的权限的方法取决于一些因素，以及步骤是否使用 `aws:executeScript` 操作。

对于不使用 `aws:executeScript` 的运行手册，自动化将使用以下两种权限来源之一：
+ 在运行手册中指定或作为参数传递的 IAM 服务角色或担任角色的权限。
+ 如果未指定 IAM 服务角色，则为启动自动化的用户的权限。

不过，如果运行手册中的步骤包含 `aws:executeScript` 操作，并且为该操作指定的 Python 或 PowerShell 脚本调用任何 AWS API 操作，则始终需要使用 IAM 服务角色（担任角色）。自动化按以下顺序检查该角色：
+ 在运行手册中指定或作为参数传递的 IAM 服务角色或担任角色的权限。
+ 如果找不到任何角色，自动化尝试在没有任何权限的情况下运行为 `aws:executeScript` 指定的 Python 或 PowerShell 脚本。如果脚本调用 AWS API 操作（例如，Amazon EC2 `CreateImage` 操作）或者尝试对 AWS 资源（例如 EC2 实例）执行操作，则包含脚本的步骤将失败，并且 Systems Manager 返回一条错误消息以报告失败。

## 将脚本添加到运行手册


您可以通过内联方式将脚本作为运行手册中的步骤的一部分，从而将其添加到运行手册中。您还可以从本地计算机中上传脚本或指定脚本所在的 Amazon Simple Storage Service (Amazon S3) 存储桶，以将脚本附加到运行手册。在运行脚本的步骤完成后，脚本的输出将作为 JSON 对象提供，您可以将其作为运行手册中的后续步骤的输入。有关 `aws:executeScript` 操作以及如何使用脚本附件的更多信息，请参阅 [`aws:executeScript` - 运行脚本](automation-action-executeScript.md)。

## 运行手册的脚本限制


运行手册强制执行 5 个文件附加文件的限制。脚本可以采用 Python 脚本 (.py) 或 PowerShell Core 脚本 (.ps1) 的形式，也可以作为 .zip 文件中的内容附加。

# 在运行手册中使用条件语句


默认情况下，在运行手册的 `mainSteps` 部分中定义的步骤将按先后顺序运行。在一个操作完成后，`mainSteps` 部分中指定的下一个操作将开始。此外，如果一个操作无法运行，则整个自动化将失败（默认情况下）。可以使用本节所述的 `aws:branch` 自动化操作和运行手册选项来创建执行*条件分支*的自动化。也就是说，您可以创建在评估不同选项后跳转到不同步骤或在某个步骤完成时动态响应更改的自动化。以下是可用于创建动态自动化的选项的列表：
+ **`aws:branch`**：此自动化操作让您能够创建一个动态自动化，该自动化可以在一个步骤中评估多个选项，然后根据评估结果跳转到运行手册中的不同步骤。
+ **`nextStep`**：此选项指定在成功完成一个步骤后，接下来处理自动化中的哪个步骤。
+ **`isEnd`**：此选项在特定步骤结束时停止自动化。该选项的默认值为 false。
+ **`isCritical`**：此选项将一个步骤指定为成功完成自动化的关键步骤。如果具有此分派的步骤失败，自动化会将自动化的最终状态报告为 `Failed`。该选项的默认值为 `true`。
+ **`onFailure`**：此选项指示自动化在失败时是应中止、继续还是转到其他步骤。该选项的默认值为 abort。

下一节介绍 `aws:branch` 自动化操作。有关 `nextStep`、`isEnd`、`isCritical` 和 `onFailure` 选项的更多信息，请参阅 [示例 `aws:branch` 运行手册](#branch-runbook-examples)。

## 使用 `aws:branch` 操作


`aws:branch` 操作提供适用于自动化的大部分动态条件分支选项。如前所述，此操作让自动化能够在一个步骤中评估多个条件，然后根据评估结果跳转到新的步骤。`aws:branch` 操作的功能类似于编程中的 `IF-ELIF-ELSE` 语句。

下面是一个 `aws:branch` 步骤的 YAML 示例：

```
- name: ChooseOSforCommands
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Linux
    Default:
      PostProcessing
```

在为步骤指定 `aws:branch` 操作时，请指定自动化必须评估的 `Choices`。自动化可以根据在运行手册的 `Parameters` 部分中指定的参数值来评估 `Choices`。自动化也可以基于上一步的输出来评估 `Choices`。

自动化使用布尔表达式评估每个选择。如果评估确定第一个选择为 `true`，自动化跳转到为该选择指定的步骤。如果评估确定第一个选择为 `false`，自动化程评估下一个选择。如果您的步骤包含三个或更多的 `Choices`，自动化按顺序评估每个选择，直到某个选择的评估结果为 `true`。然后，自动化跳转到为结果为 `true` 的选择指定的步骤。

如果所有 `Choices` 都为 `true`，则工作流程检查该步骤是否包含 `Default` 值。`Default` 值定义当所有选择都为 `true` 时工作流程应跳转到的步骤。如果没有为该步骤指定 `Default` 值，自动化处理文档中的下一个步骤。

以下是 YAML 的 `aws:branch` 步骤，命名为 **chooseOSfromParameter**。此步骤包含两个 `Choices`：(`NextStep: runWindowsCommand`) 和 (`NextStep: runLinuxCommand`)。自动化评估这些 `Choices`，以确定应为适当的操作系统运行哪个命令。每个选择的 `Variable` 都使用 `{{OSName}}`，这是运行手册作者在运行手册的 `Parameters` 部分中定义的参数。

```
mainSteps:
- name: chooseOSfromParameter
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runWindowsCommand
      Variable: "{{OSName}}"
      StringEquals: Windows
    - NextStep: runLinuxCommand
      Variable: "{{OSName}}"
      StringEquals: Linux
```

以下是 YAML 的 `aws:branch` 步骤，命名为 **chooseOSfromOutput**。此步骤包含两个 `Choices`：(`NextStep: runPowerShellCommand`) 和 (`NextStep: runShellCommand`)。自动化评估这些 `Choices`，以确定应为适当的操作系统运行哪个命令。每个选择的 `Variable` 都使用 `{{GetInstance.platform}}`，这是文档中上一步的输出。此示例还包含一个名为 `Default` 的选项。如果自动化评估两个的结果都为 `Choices`，而且两个选择均为 `true`，自动化跳转到名为 `PostProcessing` 的步骤。

```
mainSteps:
- name: chooseOSfromOutput
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Linux
    Default:
      PostProcessing
```

### 在运行手册中创建 `aws:branch` 步骤


在运行手册中创建 `aws:branch` 步骤时，请定义自动化应对其进行评估的 `Choices` 以确定自动化应跳转到哪个步骤。如前所述，`Choices` 使用布尔表达式进行评估。每个选择都必须定义以下选项：
+ **NextStep**：当指定的选择为 `true` 时，运行手册要处理的下一个步骤。
+ **变量**：指定在运行手册的 `Parameters` 部分中定义的参数的名称（在 `Variables` 部分中定义的参数），或指定上一步的输出对象。

  使用以下格式指定变量值。

  `Variable: "{{variable name}}"`

  使用以下格式指定参数值。

  `Variable: "{{parameter name}}"`

  使用以下格式指定输出对象变量：

  `Variable: "{{previousStepName.outputName}}"`
**注意**  
下一节[关于创建输出变量](#branch-action-output)更详细地介绍如何创建输出变量。
+ **Operation**：用于评估选择的标准，例如 `StringEquals: Linux`。`aws:branch` 操作支持以下运算：

**字符串运算**
  + 字符串等于
  + EqualsIgnoreCase
  + StartsWith
  + EndsWith
  + 包含

**数值运算**
  + NumericEquals
  + NumericGreater
  + NumericLesser
  + NumericGreaterOrEquals
  + NumericLesser
  + NumericLesserOrEquals

**布尔运算**
  + BooleanEquals
**重要**  
创建运行手册时，系统将验证运行手册中的每个操作。在尝试创建运行手册时，如果某个操作不受支持，系统会返回错误。
+ **Default**：指定当所有 `Choices` 都为 `true` 时自动化应跳转到的回退步骤。
**注意**  
如果不想指定 `Default` 值，则可以指定 `isEnd` 选项。如果所有 `Choices` 都为 `true` 并且未指定 `Default` 值，自动化在此步骤结束时停止。

使用以下模板可以帮助您在运行手册中构建 `aws:branch` 步骤：将每个*示例资源占位符*替换为您自己的信息。

------
#### [ YAML ]

```
mainSteps:
- name: step name
  action: aws:branch
  inputs:
    Choices:
    - NextStep: step to jump to if evaluation for this choice is true
      Variable: "{{parameter name or output from previous step}}"
      Operation type: Operation value
    - NextStep: step to jump to if evaluation for this choice is true
      Variable: "{{parameter name or output from previous step}}"
      Operation type: Operation value
    Default:
      step to jump to if all choices are false
```

------
#### [ JSON ]

```
{
   "mainSteps":[
      {
         "name":"a name for the step",
         "action":"aws:branch",
         "inputs":{
            "Choices":[
               {
                  "NextStep":"step to jump to if evaluation for this choice is true",
                  "Variable":"{{parameter name or output from previous step}}",
                  "Operation type":"Operation value"
               },
               {
                  "NextStep":"step to jump to if evaluation for this choice is true",
                  "Variable":"{{parameter name or output from previous step}}",
                  "Operation type":"Operation value"
               }
            ],
            "Default":"step to jump to if all choices are false"
         }
      }
   ]
}
```

------

#### 关于创建输出变量


要创建引用上一步输出的 `aws:branch` 选择，您需要标识上一步的名称和输出字段的名称。然后，使用以下格式组合步骤和字段的名称：

`Variable: "{{previousStepName.outputName}}"`

例如，以下示例中的第一个步骤名为 `GetInstance`。然后，在 `outputs` 下，有一个名为 `platform` 的字段。在第二个步骤 (`ChooseOSforCommands`) 中，作者希望将平台字段的输出引用为变量。要创建变量，只需将步骤名称 (GetInstance) 与输出字段名称 (platform) 组合在一起即可创建 `Variable: "{{GetInstance.platform}}"`。

```
mainSteps:
- Name: GetInstance
  action: aws:executeAwsApi
  inputs:
    Service: ssm
    Api: DescribeInstanceInformation
    Filters:
    - Key: InstanceIds
      Values: ["{{ InstanceId }}"]
  outputs:
  - Name: myInstance
    Selector: "$.InstanceInformationList[0].InstanceId"
    Type: String
  - Name: platform
    Selector: "$.InstanceInformationList[0].PlatformType"
    Type: String
- name: ChooseOSforCommands
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Linux
    Default:
      Sleep
```

这是一个示例，展示了从上一步和输出创建 *"Variable": "\$1\$1 describeInstance.Platform \$1\$1"* 的方法。

```
- name: describeInstance
  action: aws:executeAwsApi
  onFailure: Abort
  inputs:
    Service: ec2
    Api: DescribeInstances
    InstanceIds:
    - "{{ InstanceId }}"
  outputs:
  - Name: Platform
    Selector: "$.Reservations[0].Instances[0].Platform"
    Type: String
  nextStep: branchOnInstancePlatform
- name: branchOnInstancePlatform
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runEC2RescueForWindows
      Variable: "{{ describeInstance.Platform }}"
      StringEquals: windows
    Default: runEC2RescueForLinux
```

### 示例 `aws:branch` 运行手册


下面是一些使用 `aws:branch` 的示例运行手册。

**示例 1：使用 `aws:branch` 和输出变量基于操作系统类型运行命令**

在此示例的第一步（`GetInstance`）中，运行手册作者使用 `aws:executeAwsApi` 操作来调用 `ssm` `DescribeInstanceInformation` API 操作。作者使用此操作确定实例使用的操作系统的类型。`aws:executeAwsApi` 操作输出实例 ID 和平台类型。

在第二个步骤 (`ChooseOSforCommands`) 中，作者使用了 `aws:branch` 操作和两个 `Choices`：(`NextStep: runPowerShellCommand`) 和 (`NextStep: runShellCommand`)。自动化使用上一步 (`Variable: "{{GetInstance.platform}}"`) 的输出评估实例的操作系统。自动化跳转到指定操作系统的步骤。

```
---
schemaVersion: '0.3'
assumeRole: "{{AutomationAssumeRole}}"
parameters:
  AutomationAssumeRole:
    default: ""
    type: String
mainSteps:
- name: GetInstance
  action: aws:executeAwsApi
  inputs:
    Service: ssm
    Api: DescribeInstanceInformation
  outputs:
  - Name: myInstance
    Selector: "$.InstanceInformationList[0].InstanceId"
    Type: String
  - Name: platform
    Selector: "$.InstanceInformationList[0].PlatformType"
    Type: String
- name: ChooseOSforCommands
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runPowerShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Windows
    - NextStep: runShellCommand
      Variable: "{{GetInstance.platform}}"
      StringEquals: Linux
    Default:
      Sleep
- name: runShellCommand
  action: aws:runCommand
  inputs:
    DocumentName: AWS-RunShellScript
    InstanceIds:
    - "{{GetInstance.myInstance}}"
    Parameters:
      commands:
      - ls
  isEnd: true
- name: runPowerShellCommand
  action: aws:runCommand
  inputs:
    DocumentName: AWS-RunPowerShellScript
    InstanceIds:
    - "{{GetInstance.myInstance}}"
    Parameters:
      commands:
      - ls
  isEnd: true
- name: Sleep
  action: aws:sleep
  inputs:
    Duration: PT3S
```

**示例 2：使用 `aws:branch` 和参数变量基于操作系统类型运行命令**

运行手册作者在 `parameters` 部分的运行手册开头定义了几个参数选项。一个参数名为 `OperatingSystemName`。在第一个步骤 (`ChooseOS`) 中，作者使用了 `aws:branch` 操作和两个 `Choices`：(`NextStep: runWindowsCommand`) 和 (`NextStep: runLinuxCommand`)。这些 `Choices` 的变量引用在参数部分 (`Variable: "{{OperatingSystemName}}"`) 中指定的参数选项。当用户运行此自动化时，他们在运行时为 `OperatingSystemName` 指定值。自动化在 `Choices` 评估期间使用运行时参数。自动化基于为 `OperatingSystemName` 指定的运行时参数跳转到指定操作系统的步骤。

```
---
schemaVersion: '0.3'
assumeRole: "{{AutomationAssumeRole}}"
parameters:
  AutomationAssumeRole:
    default: ""
    type: String
  OperatingSystemName:
    type: String
  LinuxInstanceId:
    type: String
  WindowsInstanceId:
    type: String
mainSteps:
- name: ChooseOS
  action: aws:branch
  inputs:
    Choices:
    - NextStep: runWindowsCommand
      Variable: "{{OperatingSystemName}}"
      StringEquals: windows
    - NextStep: runLinuxCommand
      Variable: "{{OperatingSystemName}}"
      StringEquals: linux
    Default:
      Sleep
- name: runLinuxCommand
  action: aws:runCommand
  inputs:
    DocumentName: "AWS-RunShellScript"
    InstanceIds:
    - "{{LinuxInstanceId}}"
    Parameters:
      commands:
      - ls
  isEnd: true
- name: runWindowsCommand
  action: aws:runCommand
  inputs:
    DocumentName: "AWS-RunPowerShellScript"
    InstanceIds:
    - "{{WindowsInstanceId}}"
    Parameters:
      commands:
      - date
  isEnd: true
- name: Sleep
  action: aws:sleep
  inputs:
    Duration: PT3S
```

### 使用运算符创建复杂的分支自动化


您可以在 `aws:branch` 步骤中使用 `And`、`Or` 和 `Not` 运算符来创建复杂的分支自动化。

**“And”运算符**  
如果某个选择的多个变量需要为 `true`，可以使用 `And` 运算符。在下面的示例中，第一个选择评估实例是否 `running` 并且使用的是 `Windows` 操作系统。如果这*两个*变量的评估结果都为真，自动化跳转到 `runPowerShellCommand` 步骤。如果一个或多个变量为 `false`，自动化评估第二个选择的变量。

```
mainSteps:
- name: switch2
  action: aws:branch
  inputs:
    Choices:
    - And:
      - Variable: "{{GetInstance.pingStatus}}"
        StringEquals: running
      - Variable: "{{GetInstance.platform}}"
        StringEquals: Windows
      NextStep: runPowerShellCommand

    - And:
      - Variable: "{{GetInstance.pingStatus}}"
        StringEquals: running
      - Variable: "{{GetInstance.platform}}"
        StringEquals: Linux
      NextStep: runShellCommand
    Default:
      sleep3
```

**“Or”运算符**  
如果*某个*选择的多个变量需要为真，可以使用 `Or` 运算符。在下面的示例中，第一个选择评估参数字符串是不是 `Windows` 和 AWS Lambda 步骤的输出是不是真。如果*任意一个*变量的评估结果都为真，自动化跳转到 `RunPowerShellCommand` 步骤。如果两个变量都为假，自动化评估第二个选择的变量。

```
- Or:
  - Variable: "{{parameter1}}"
    StringEquals: Windows
  - Variable: "{{BooleanParam1}}"
    BooleanEquals: true
  NextStep: RunPowershellCommand
- Or:
  - Variable: "{{parameter2}}"
    StringEquals: Linux
  - Variable: "{{BooleanParam2}}"
    BooleanEquals: true
  NextStep: RunShellScript
```

**“Not”运算符**  
当变量*不*为真时，如果您想要跳转到定义的步骤，则使用 `Not` 运算符。在下面的示例中，第一个选择评估参数字符串是不是 `Not Linux`。如果变量的评估结果不为 Linux，自动化跳转到 `sleep2` 步骤。如果第一个选择的评估结果*为* Linux，自动化评估下一个选择。

```
mainSteps:
- name: switch
  action: aws:branch
  inputs:
    Choices:
    - NextStep: sleep2
      Not:
        Variable: "{{testParam}}"
        StringEquals: Linux
    - NextStep: sleep1
      Variable: "{{testParam}}"
      StringEquals: Windows
    Default:
      sleep3
```

## 如何使用条件选项的示例


本部分包括有关如何使用运行手册中的动态选项的其他示例。本部分中的每个示例均扩展以下运行手册。该运行手册包含两个操作。第一个操作名为 `InstallMsiPackage`。它使用 `aws:runCommand` 操作将应用程序安装到 Windows Server 实例上。第二个操作名为 `TestInstall`。它使用 `aws:invokeLambdaFunction` 操作在成功安装应用程序后测试该应用程序。步骤 1 指定 `onFailure: Abort`。这意味着，如果应用程序未成功安装，自动化会在进入步骤 2 前停止。

**示例 1：包含两个线性操作的运行手册**

```
---
schemaVersion: '0.3'
description: Install MSI package and run validation.
assumeRole: "{{automationAssumeRole}}"
parameters:
  automationAssumeRole:
    type: String
    description: "(Required) Assume role."
  packageName:
    type: String
    description: "(Required) MSI package to be installed."
  instanceIds:
    type: String
    description: "(Required) Comma separated list of instances."
mainSteps:
- name: InstallMsiPackage
  action: aws:runCommand
  maxAttempts: 2
  onFailure: Abort
  inputs:
    InstanceIds:
    - "{{instanceIds}}"
    DocumentName: AWS-RunPowerShellScript
    Parameters:
      commands:
      - msiexec /i {{packageName}}
- name: TestInstall
  action: aws:invokeLambdaFunction
  maxAttempts: 1
  timeoutSeconds: 500
  inputs:
    FunctionName: TestLambdaFunction
...
```

**使用 `onFailure` 选项创建跳转到不同步骤的动态自动化**

下面的示例使用 `onFailure: step:step name`、`nextStep` 和 `isEnd` 选项创建一个动态自动化。在此示例中，如果 `InstallMsiPackage` 操作失败，自动化将跳转到名为 *PostFailure* (`onFailure: step:PostFailure`) 的操作以运行 AWS Lambda 函数，从而在安装失败时执行某个操作。如果安装成功，自动化将跳转到 TestInstall 操作 (`nextStep: TestInstall`)。`TestInstall` 和 `PostFailure` 步骤都使用 `isEnd` 选项 (`isEnd: true`)，以便自动化在任一步骤完成时结束。

**注意**  
可以选择在 `mainSteps` 部分的最后一步中使用 `isEnd` 选项。如果最后一个步骤未跳转到其他步骤，自动化会在最后一步中运行操作后停止。

**示例 2：跳转到不同步骤的动态自动化**

```
mainSteps
- name: InstallMsiPackage
  action: aws:runCommand
  onFailure: step:PostFailure
  maxAttempts: 2
  inputs:
    InstanceIds:
    - "{{instanceIds}}"
    DocumentName: AWS-RunPowerShellScript
    Parameters:
      commands:
      - msiexec /i {{packageName}}
  nextStep: TestInstall
- name: TestInstall
  action: aws:invokeLambdaFunction
  maxAttempts: 1
  timeoutSeconds: 500
  inputs:
    FunctionName: TestLambdaFunction
  isEnd: true
- name: PostFailure
  action: aws:invokeLambdaFunction
  maxAttempts: 1
  timeoutSeconds: 500
  inputs:
    FunctionName: PostFailureRecoveryLambdaFunction
  isEnd: true
...
```

**注意**  
在处理运行手册之前，系统将验证运行手册不会创建无限循环。如果检测到无限循环，自动化将返回一个错误和一个显示哪些步骤创建循环的循环跟踪。

**创建定义关键步骤的动态自动化**

您可以指定一个对于自动化的整体成功很重要的步骤。如果关键步骤失败，自动化会将自动化状态报告为 `Failed`，即使已成功运行一个或多个步骤也是如此。在以下示例中，用户在 *InstallMsiPackage* 步骤失败 (`onFailure: step:VerifyDependencies`) 时标识 *VerifyDependencies* 步骤。用户指定 `InstallMsiPackage` 步骤为非关键步骤 (`isCritical: false`)。在此示例中，如果应用程序安装失败，自动化处理 `VerifyDependencies` 步骤以确定是否因一个或多个依赖项缺失而导致应用程序安装失败。

**示例 3：定义自动化的关键步骤**

```
---
name: InstallMsiPackage
action: aws:runCommand
onFailure: step:VerifyDependencies
isCritical: false
maxAttempts: 2
inputs:
  InstanceIds:
  - "{{instanceIds}}"
  DocumentName: AWS-RunPowerShellScript
  Parameters:
    commands:
    - msiexec /i {{packageName}}
nextStep: TestPackage
...
```

# 使用操作输出作为输入


多个自动化操作会返回预定义的输出。您可以使用格式 `{{stepName.outputName}}` 将这些输出作为输入传递到运行手册的后续步骤。您还可以在运行手册中为自动化操作定义自定义输出。让您可以运行脚本，或调用其他 AWS 服务 的 API 操作一次，以便您在后续操作中重复使用这些值作为输入。运行手册中的参数类型是静态的。这意味着参数类型在定义后无法更改。要定义步骤输出，请提供以下字段：
+ 名称：（必需）输出名称，用于在后续步骤中引用输出值。
+ 选择器：（必需）用于确定输出值的 JSONPath 表达式。
+ 类型：（可选）选择器字段返回的值的数据类型。有效的类型值为 `String`、`Integer`、`Boolean`、`StringList`、`StringMap`、`MapList`。默认值为 `String`。

如果输出的值与您指定的数据类型不匹配，自动化会尝试转换该数据类型。例如，如果返回的值是 `Integer`，但指定的 `Type` 是 `String`，则最终输出值为 `String` 值。支持以下类型转换：
+ `String` 值可以转换为 `StringList`、`Integer` 和 `Boolean`。
+ `Integer` 值可以转换为 `String` 和 `StringList`。
+ `Boolean` 值可以转换为 `String` 和 `StringList`。
+ 包含一个元素的 `StringList`、`IntegerList` 或 `BooleanList` 值可以转换为 `String`、`Integer` 或 `Boolean`。

将参数或输出与自动化操作一起使用时，不能在操作的输入中动态更改数据类型。

这份示例运行手册演示了如何定义操作输出，并将该值引用为后续操作的输入。运行手册执行以下操作：
+ 使用 `aws:executeAwsApi` 操作调用 Amazon EC2 DescribeImages API 操作来获取特定 Windows Server 2016 AMI 的名称。它将映像 ID 输出为 `ImageId`。
+ 使用 `aws:executeAwsApi` 操作调用 Amazon EC2 RunInstances API 操作来启动一个实例，它使用上一步中的 `ImageId`。它将实例 ID 输出为 `InstanceId`。
+ 使用 ` aws:waitForAwsResourceProperty` 操作轮询 Amazon EC2 DescribeInstanceStatus API 操作来等待实例进入 `running` 状态。此操作的超时时间为 60 秒。如果实例在轮询 60 秒后未能进入 `running` 状态，则此步骤超时。
+ 使用 `aws:assertAwsResourceProperty` 操作调用 Amazon EC2 `DescribeInstanceStatus` API 操作来断言实例处于 `running` 状态。如果实例状态不为 `running`，则此步骤失败。

```
---
description: Sample runbook using AWS API operations
schemaVersion: '0.3'
assumeRole: "{{ AutomationAssumeRole }}"
parameters:
  AutomationAssumeRole:
    type: String
    description: "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf."
    default: ''
  ImageName:
    type: String
    description: "(Optional) Image Name to launch EC2 instance with."
    default: "Windows_Server-2022-English-Full-Base*"
mainSteps:
- name: getImageId
  action: aws:executeAwsApi
  inputs:
    Service: ec2
    Api: DescribeImages
    Filters:  
    - Name: "name"
      Values: 
      - "{{ ImageName }}"
  outputs:
  - Name: ImageId
    Selector: "$.Images[0].ImageId"
    Type: "String"
- name: launchOneInstance
  action: aws:executeAwsApi
  inputs:
    Service: ec2
    Api: RunInstances
    ImageId: "{{ getImageId.ImageId }}"
    MaxCount: 1
    MinCount: 1
  outputs:
  - Name: InstanceId
    Selector: "$.Instances[0].InstanceId"
    Type: "String"
- name: waitUntilInstanceStateRunning
  action: aws:waitForAwsResourceProperty
  timeoutSeconds: 60
  inputs:
    Service: ec2
    Api: DescribeInstanceStatus
    InstanceIds:
    - "{{ launchOneInstance.InstanceId }}"
    PropertySelector: "$.InstanceStatuses[0].InstanceState.Name"
    DesiredValues:
    - running
- name: assertInstanceStateRunning
  action: aws:assertAwsResourceProperty
  inputs:
    Service: ec2
    Api: DescribeInstanceStatus
    InstanceIds:
    - "{{ launchOneInstance.InstanceId }}"
    PropertySelector: "$.InstanceStatuses[0].InstanceState.Name"
    DesiredValues:
    - running
outputs:
- "launchOneInstance.InstanceId"
...
```

前面介绍的每个自动化操作都允许您通过指定服务命名空间、API 操作名称、输入参数和输出参数来调用特定的 API 操作。输入由您选择的 API 操作定义。您可以在以下[服务参考](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/index.html)页面的左侧导航栏中选择服务来查看 API 操作（也称为方法）。在要调用的服务的**客户端**部分中选择一种方法。例如，以下页面中列出了 Amazon Relational Database Service (Amazon RDS) 的所有 API 操作（方法）：[Amazon RDS 方法](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/rds.html)。

您可以在以下位置查看每个自动化操作的架构：
+ [`aws:assertAwsResourceProperty` - 断言 AWS 资源状态或事件状态](automation-action-assertAwsResourceProperty.md)
+ [`aws:executeAwsApi` - 调用并运行 AWS API 操作](automation-action-executeAwsApi.md)
+ [`aws:waitForAwsResourceProperty` - 等待 AWS 资源属性](automation-action-waitForAwsResourceProperty.md)

架构包括使用每个操作所需字段的描述。

**使用 Selector/PropertySelector 字段**  
每个自动化操作都要求您指定一个输出 `Selector`（用于 `aws:executeAwsApi`）或 `PropertySelector`（用于 `aws:assertAwsResourceProperty` 和 `aws:waitForAwsResourceProperty`)。这些字段用于处理 AWS API 操作的 JSON 响应。这些字段使用 JSONPath 语法。

以下是帮助说明这一概念的 `aws:executeAwsAPi` 操作的示例：

```
---
mainSteps:
- name: getImageId
  action: aws:executeAwsApi
  inputs:
    Service: ec2
    Api: DescribeImages
    Filters:  
      - Name: "name"
        Values: 
          - "{{ ImageName }}"
  outputs:
    - Name: ImageId
      Selector: "$.Images[0].ImageId"
      Type: "String"
...
```

在 `aws:executeAwsApi` 步骤 `getImageId` 中，自动化将调用 `DescribeImages` API 操作并接收来自 `ec2` 的响应。然后，自动化将 `Selector - "$.Images[0].ImageId"` 应用于 API 响应，并将所选值分配给输出 `ImageId` 变量。通过指定 `"{{ getImageId.ImageId }}"`，同一自动化中的其他步骤可以使用 `ImageId` 的值。

以下是帮助说明这一概念的 `aws:waitForAwsResourceProperty` 操作的示例：

```
---
- name: waitUntilInstanceStateRunning
  action: aws:waitForAwsResourceProperty
  # timeout is strongly encouraged for action - aws:waitForAwsResourceProperty
  timeoutSeconds: 60
  inputs:
    Service: ec2
    Api: DescribeInstanceStatus
    InstanceIds:
    - "{{ launchOneInstance.InstanceId }}"
    PropertySelector: "$.InstanceStatuses[0].InstanceState.Name"
    DesiredValues:
    - running
...
```

在 `aws:waitForAwsResourceProperty` 步骤 `waitUntilInstanceStateRunning` 中，自动化将调用 `DescribeInstanceStatus` API 操作并接收来自 `ec2` 的响应。然后，自动化将 `PropertySelector - "$.InstanceStatuses[0].InstanceState.Name"` 应用于响应，并检查指定的返回值是否与 `DesiredValues` 列表中的值匹配（在本例中为 `running`）。此步骤重复这一过程，直到响应返回 `running` 实例状态。

## 在运行手册中使用 JSONPath


JSONPath 表达式是以“\$1”开头的字符串。用于选择 JSON 元素中的一个或多个组件。下面的列表包含有关 Systems Manager 自动化支持的 JSONPath 运算符的信息：
+ **点表示的子字段 (.)**：用于 JSON 对象。此运算符选择特定键的值。
+ **深层扫描 (..)**：用于 JSON 元素。此运算符逐级扫描 JSON 元素，并使用特定键选择值列表。此运算符的返回类型始终为 JSON 数组。在自动化步骤输出类型上下文中，运算符可以是 StringList 或 MapList。
+ **数组索引 ([ ])**：用于 JSON 数组。此运算符获取特定索引的值。
+ **筛选条件 ([?(*expression*)])**：与 JSON 数组一起使用。此运算符筛选条件 JSON 数组值与筛选条件表达式中定义的标准相匹配。筛选条件表达式只能使用以下运算符：==、\$1=、>、<、>= 或 <=。不支持将多个筛选条件表达式与 AND (&&) 或 OR (\$1\$1) 组合使用。此运算符的返回类型始终为 JSON 数组。

为了更好地理解 JSONPath 运算符，请查看以下 ec2 `DescribeInstances` API 操作的 JSON 响应。此响应下面提供了几个示例，它们说明通过向 `DescribeInstances` API 操作响应应用不同的 JSONPath 表达式获取的不同结果。

```
{
    "NextToken": "abcdefg",
    "Reservations": [
        {
            "OwnerId": "123456789012",
            "ReservationId": "r-abcd12345678910",
            "Instances": [
                {
                    "ImageId": "ami-12345678",
                    "BlockDeviceMappings": [
                        {
                            "Ebs": {
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-000000000000"
                            },
                            "DeviceName": "/dev/xvda"
                        }
                    ],
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    }
                }
            ],
            "Groups": []
        },
        {
            "OwnerId": "123456789012",
            "ReservationId": "r-12345678910abcd",
            "Instances": [
                {
                    "ImageId": "ami-12345678",
                    "BlockDeviceMappings": [
                        {
                            "Ebs": {
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-111111111111"
                            },
                            "DeviceName": "/dev/xvda"
                        }
                    ],
                    "State": {
                        "Code": 80,
                        "Name": "stopped"
                    }
                }
            ],
            "Groups": []
        }
    ]
}
```

**JSONPath 示例 1：从 JSON 响应获取特定的 String**

```
JSONPath: 
$.Reservations[0].Instances[0].ImageId 

Returns:
"ami-12345678"

Type: String
```

**JSONPath 示例 2：从 JSON 响应获取特定的 Boolean**

```
JSONPath:
$.Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.DeleteOnTermination
        
Returns:
true

Type: Boolean
```

**JSONPath 示例 3：从 JSON 响应获取特定的 Integer**

```
JSONPath:
$.Reservations[0].Instances[0].State.Code
        
Returns:
16

Type: Integer
```

**JSONPath 示例 4：深层扫描 JSON 响应，然后以 StringList 的形式获取 VolumeId 的所有值** 

```
JSONPath:
$.Reservations..BlockDeviceMappings..VolumeId
        
Returns:
[
   "vol-000000000000",
   "vol-111111111111"
]

Type: StringList
```

**JSONPath 示例 5：以 StringMap 的形式获取特定的 BlockDeviceMappings 对象**

```
JSONPath:
$.Reservations[0].Instances[0].BlockDeviceMappings[0]
        
Returns:
{
   "Ebs" : {
      "DeleteOnTermination" : true,
      "Status" : "attached",
      "VolumeId" : "vol-000000000000"
   },
   "DeviceName" : "/dev/xvda"
}

Type: StringMap
```

**JSONPath 示例 6：深层扫描 JSON 响应，然后以 MapList 的形式获取所有 State 对象**

```
JSONPath:
$.Reservations..Instances..State 
    
Returns:
[
   {
      "Code" : 16,
      "Name" : "running"
   },
   {
      "Code" : 80,
      "Name" : "stopped"
   }
]

Type: MapList
```

**JSONPath 示例 7：筛选处于 `running` 状态的实例**

```
JSONPath:
$.Reservations..Instances[?(@.State.Name == 'running')]

Returns:
[
  {
    "ImageId": "ami-12345678",
    "BlockDeviceMappings": [
      {
        "Ebs": {
          "DeleteOnTermination": true,
          "Status": "attached",
          "VolumeId": "vol-000000000000"
        },
        "DeviceName": "/dev/xvda"
      }
    ],
    "State": {
      "Code": 16,
      "Name": "running"
    }
  }
]

Type: MapList
```

**JSONPath 示例 8：返回未处于 `running` 状态实例的 `ImageId`**

```
JSONPath:
$.Reservations..Instances[?(@.State.Name != 'running')].ImageId

Returns:
[
  "ami-12345678"
]

Type: StringList | String
```

# 为 Automation 创建 Webhook 集成


要在自动化期间使用 Webhooks 发送消息，请创建集成。可以在自动化过程中使用您的运行手册中的 `aws:invokeWebhook` 操作调用集成。如果尚未创建 Webhook，请参阅 [为集成创建 Webhooks](#creating-webhooks)。要了解有关 `aws:invokeWebhook` 操作的更多信息，请参阅 [`aws:invokeWebhook` – 调用 Automation Webhook 集成](invoke-webhook.md)。

如以下程序所示，您可以使用 Systems Manager Automation 控制台或您的首选命令行工具来创建集成。

## 创建集成（控制台）


**要为 Automation 创建集成（控制台）**

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

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

1. 请选择 **Integrations**（集成）选项卡。

1. 请选择 **Add integration**（添加集成），然后选择 **Webhook**。

1. 请输入要为集成包括的所需值和任何可选值。

1. 请选择 **Add**（添加）来创建集成。

## 创建集成（命令行）


要使用命令行工具创建集成，您必须为集成创建所需的 `SecureString` 参数。Automation 使用 Parameter Store（Systems Manager 中的一项工具）中的预留命名空间来存储有关集成的信息。如果您使用 AWS 管理控制台 创建集成，Automation 会为您处理此过程。在命名空间之后，您必须指定要创建的集成类型，然后指定集成的名称。目前，Automation 支持 `webhook` 类型集成。

`webhook` 类型集成支持的字段如下：
+ 说明
+ headers
+ payload
+ URL

**开始前的准备工作**  
安装并配置 AWS Command Line Interface (AWS CLI) 或 AWS Tools for PowerShell（如果尚未这样做）。有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)以及[安装 AWS Tools for PowerShell](https://docs.aws.amazon.com/powershell/latest/userguide/pstools-getting-set-up.html)。

**要为 Automation 创建集成（命令行）**
+ 运行下列命令以为集成创建所需的 `SecureString` 参数。将每个*示例资源占位符*替换为您自己的信息。`/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/` 命名空间在 Parameter Store 中为集成预留。参数的名称必须使用此命名空间，后跟集成的名称。例如 `/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/myWebhookIntegration`。

------
#### [ Linux & macOS ]

  ```
  aws ssm put-parameter \
      --name "/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/myWebhookIntegration" \
      --type "SecureString" \
      --data-type "aws:ssm:integration" \
      --value '{"description": "My first webhook integration for Automation.", "url": "myWebHookURL"}'
  ```

------
#### [ Windows ]

  ```
  aws ssm put-parameter ^
      --name "/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/myWebhookIntegration" ^
      --type "SecureString" ^
      --data-type "aws:ssm:integration" ^
      --value  "{\"description\":\"My first webhook integration for Automation.\",\"url\":\"myWebHookURL\"}"
  ```

------
#### [ PowerShell ]

  ```
  Write-SSMParameter `
      -Name "/d9d01087-4a3f-49e0-b0b4-d568d7826553/ssm/integrations/webhook/myWebhookIntegration" `
      -Type "SecureString"
      -DataType "aws:ssm:integration"
      -Value '{"description": "My first webhook integration for Automation.", "url": "myWebHookURL"}'
  ```

------

## 为集成创建 Webhooks


在使用您的提供商创建 Webhooks 时，请注意以下几点：
+ 协议必须是 HTTPS。
+ 支持自定义请求标头。
+ 可以指定默认的请求正文。
+ 当使用 `aws:invokeWebhook` 操作调用集成时，可以覆盖默认的请求正文。

# 处理运行手册中的超时


`timeoutSeconds` 属性由所有自动化操作共享。您可以使用此属性指定操作的执行超时值。此外，您还可以更改操作超时如何影响自动化和整体执行状态。另外，您可以通过定义操作的 `onFailure` 和 `isCritical` 共享属性来完成此操作。

例如，根据您的使用案例，您可能希望自动化继续执行其他操作，并且在操作超时的情况下不影响自动化的整体状态。在此示例中，您可以使用 `timeoutSeconds` 属性指定操作超时之前等待的时间长度。然后，您可以指定存在超时的情况下自动化应转到的操作（即步骤）。使用 `onFailure` 属性的格式 `step:step name` 指定值，而不是指定默认值 `Abort`。默认情况下，如果操作超时，在自动化执行状态将为 `Timed Out`。要防止超时影响自动化执行状态，请为 `false` 属性指定 `isCritical`。

以下示例演示如何为此情况中描述的操作定义共享属性。

------
#### [ YAML ]

```
- name: verifyImageAvailability
  action: 'aws:waitForAwsResourceProperty'
  timeoutSeconds: 600
  isCritical: false
  onFailure: 'step:getCurrentImageState'
  inputs:
    Service: ec2
    Api: DescribeImages
    ImageIds:
      - '{{ createImage.newImageId }}'
    PropertySelector: '$.Images[0].State'
    DesiredValues:
      - available
  nextStep: copyImage
```

------
#### [ JSON ]

```
{
    "name": "verifyImageAvailability",
    "action": "aws:waitForAwsResourceProperty",
    "timeoutSeconds": 600,
    "isCritical": false,
    "onFailure": "step:getCurrentImageState",
    "inputs": {
        "Service": "ec2",
        "Api": "DescribeImages",
        "ImageIds": [
            "{{ createImage.newImageId }}"
        ],
        "PropertySelector": "$.Images[0].State",
        "DesiredValues": [
            "available"
        ]
    },
    "nextStep": "copyImage"
}
```

------

有关所有自动化操作共享的属性的更多信息，请参阅 [所有操作共享的属性](automation-actions.md#automation-common)。

# Systems Manager 自动化运行手册参考
自动化运行手册参考

为了帮助您快速入门，AWS Systems Manager 提供了预定义运行手册。这些运行手册由 Amazon Web Services、AWS 支持 和 AWS Config 维护。运行手册参考描述了 Systems Manager、支持 和 AWS Config 提供的每个预定义运行手册。有关更多信息，请参阅 [Systems Manager 自动化运行手册参考](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide)。

# 教程


以下教程可帮助您使用 AWS Systems Manager Automation 来解决常见应用场景的问题。这些教程演示了如何将自己的运行手册、Automation 提供的预定义运行手册以及别的 Systems Manager 工具与其他 AWS 服务一起使用。

**Contents**
+ [

# 更新 AMIs
](automation-tutorial-update-ami.md)
  + [

# 更新 Linux AMI
](automation-tutorial-update-patch-linux-ami.md)
  + [

## 更新 Linux AMI（AWS CLI）
](automation-tutorial-update-ami.md#update-patch-linux-ami-cli)
  + [

# 更新 Windows Server AMI
](automation-tutorial-update-patch-windows-ami.md)
  + [

# 使用 Automation、AWS Lambda 和 Parameter Store 来更新黄金 AMI
](automation-tutorial-update-patch-golden-ami.md)
    + [

## 任务 1：在 Systems Manager Parameter Store 中创建一个参数
](automation-tutorial-update-patch-golden-ami.md#create-parameter-ami)
    + [

## 任务 2：为 AWS Lambda 创建 IAM 角色
](automation-tutorial-update-patch-golden-ami.md#create-lambda-role)
    + [

## 任务 3：创建 AWS Lambda 函数
](automation-tutorial-update-patch-golden-ami.md#create-lambda-function)
    + [

## 任务 4：创建运行手册并修补 AMI
](automation-tutorial-update-patch-golden-ami.md#create-custom-ami-update-runbook)
  + [

# 使用 Automation 和 Jenkins 更新 AMIs
](automation-tutorial-update-patch-ami-jenkins-integration.md)
  + [

# 更新自动扩缩组的 AMIs
](automation-tutorial-update-patch-windows-ami-autoscaling.md)
    + [

## 创建 **PatchAMIAndUpdateASG** 运行手册
](automation-tutorial-update-patch-windows-ami-autoscaling.md#create-autoscaling-update-runbook)
+ [

# 使用 AWS 支持 自助服务运行手册
](automation-tutorial-support-runbooks.md)
  + [

# 在无法访问的实例上运行 EC2Rescue 工具
](automation-ec2rescue.md)
    + [

## 工作原理
](automation-ec2rescue.md#automation-ec2rescue-how)
    + [

## 开始前的准备工作
](automation-ec2rescue.md#automation-ec2rescue-begin)
      + [

### 向 `AWSSupport-EC2Rescue` 授予在您的实例上执行操作的权限
](automation-ec2rescue.md#automation-ec2rescue-access)
        + [

#### 使用 IAM policy 授予权限
](automation-ec2rescue.md#automation-ec2rescue-access-iam)
        + [

#### 使用 CloudFormation 模板授予权限
](automation-ec2rescue.md#automation-ec2rescue-access-cfn)
    + [

## 运行自动化
](automation-ec2rescue.md#automation-ec2rescue-executing)
  + [

# 在 EC2 实例上重置密码和 SSH 密钥
](automation-ec2reset.md)
    + [

## 工作原理
](automation-ec2reset.md#automation-ec2reset-how)
    + [

## 开始前的准备工作
](automation-ec2reset.md#automation-ec2reset-begin)
      + [

### 向 AWSSupport-EC2Rescue 授予在您的实例上执行操作的权限
](automation-ec2reset.md#automation-ec2reset-access)
        + [

#### 使用 IAM policy 授予权限
](automation-ec2reset.md#automation-ec2reset-access-iam)
        + [

#### 使用 CloudFormation 模板授予权限
](automation-ec2reset.md#automation-ec2reset-access-cfn)
    + [

## 运行自动化
](automation-ec2reset.md#automation-ec2reset-executing)
+ [

# 使用输入变压器将数据传递到 Automation
](automation-tutorial-eventbridge-input-transformers.md)

# 更新 AMIs


以下教程说明了如何更新 Amazon Machine Image（AMIs）以包含最新补丁。

**Topics**
+ [

# 更新 Linux AMI
](automation-tutorial-update-patch-linux-ami.md)
+ [

## 更新 Linux AMI（AWS CLI）
](#update-patch-linux-ami-cli)
+ [

# 更新 Windows Server AMI
](automation-tutorial-update-patch-windows-ami.md)
+ [

# 使用 Automation、AWS Lambda 和 Parameter Store 来更新黄金 AMI
](automation-tutorial-update-patch-golden-ami.md)
+ [

# 使用 Automation 和 Jenkins 更新 AMIs
](automation-tutorial-update-patch-ami-jenkins-integration.md)
+ [

# 更新自动扩缩组的 AMIs
](automation-tutorial-update-patch-windows-ami-autoscaling.md)

# 更新 Linux AMI


本 Systems Manager Automation 演练向您展示了如何使用控制台或 AWS CLI 和 `AWS-UpdateLinuxAmi` 运行手册，使用您指定的最新软件包补丁更新Linux AMI。Automation 是 AWS Systems Manager 中的一项工具。`AWS-UpdateLinuxAmi` 运行手册也能自动安装其他具体站点相关的软件包和配置。您可以使用该演练更新各种 Linux 分发版，包括 Ubuntu Server、Red Hat Enterprise Linux（RHEL）或 Amazon Linux AMIs。有关支持的 Linux 版本的完整列表，请参阅 [Patch Manager 先决条件](patch-manager-prerequisites.md)。

使用 `AWS-UpdateLinuxAmi` 运行手册可以自动完成映像维护任务，而无需使用 JSON 或 YAML 编写运行手册。您可以使用 `AWS-UpdateLinuxAmi` 运行手册执行以下类型的任务。
+ 在 Amazon Linux、Red Hat Enterprise Linux 或 Ubuntu Server Amazon Machine Image（AMI）上升级所有分发版本程序包和 Amazon 软件。这是默认运行手册行为。
+ 在现有映像上安装 AWS Systems Manager SSM Agent 可启用 Systems Manager 的各项工具，例如使用 AWS Systems Manager Run Command 执行远程命令，或者使用 Inventory 收集软件清单。
+ 安装其他软件包。

**开始前的准备工作**  
在您开始使用运行手册之前，请先为自动化配置角色和 EventBridge（后者可选）。有关更多信息，请参阅 [设置自动化](automation-setup.md)。此演练还要求您指定 AWS Identity and Access Management (IAM) 实例配置文件的名称。有关创建 IAM 实例配置文件的更多信息，请参阅[配置 Systems Manager 所需的实例权限](setup-instance-permissions.md)。

`AWS-UpdateLinuxAmi` 运行手册接受以下输入参数。


****  

| 参数 | 类型 | 说明 | 
| --- | --- | --- | 
|  SourceAmiId  |  字符串  |  （必需）源 AMI ID。  | 
|  IamInstanceProfileName  |  字符串  |  （必需）您在[配置 Systems Manager 所需的实例权限](setup-instance-permissions.md)中创建的 IAM 实例配置文件角色的名称。实例配置文件角色为自动化提供在您实例上执行操作的权限，例如运行命令或启动和停止服务。运行手册仅使用实例配置文件角色的名称。如果您指定 Amazon Resource Name (ARN)，则自动化会失败。  | 
|  AutomationAssumeRole  |  字符串  |  （必需）您在 [设置自动化](automation-setup.md) 中创建的 IAM 服务角色的名称。服务角色（也称为担任角色）为自动化提供权限，用于担任您的 IAM 角色和代表您执行操作。例如，在运行手册中运行 `aws:createImage` 操作时，服务角色允许自动化创建新的 AMI。对于此参数，必须指定完整的 ARN。  | 
|  TargetAmiName  |  字符串  |  （可选）新 AMI 在创建之后的名称。默认名称是系统生成的字符串，其中包括源 AMI ID 以及创建时间和日期。  | 
|  InstanceType  |  字符串  |  (可选) 启动作为工作区主机的实例的类型。实例类型因区域而异。默认类型为 t2.micro。  | 
|  PreUpdateScript  |  字符串  |  (可选) 在应用更新前要运行的脚本的 URL。默认值 (\$1"none\$1") 不运行脚本。  | 
|  PostUpdateScript  |  字符串  |  (可选) 在应用软件包更新后要运行的脚本的 URL。默认值 (\$1"none\$1") 不运行脚本。  | 
|  IncludePackages  |  字符串  |  (可选) 仅更新这些指定的软件包。默认值 (\$1"all\$1") 将应用所有可用的更新。  | 
|  ExcludePackages  |  字符串  |  (可选) 在所有情况下从更新中排除的软件包的名称。默认值 (\$1"none\$1") 不排除任何软件包。  | 

**自动化步骤**  
`AWS-UpdateLinuxAmi` 运行手册默认情况下包括以下自动化操作。

**步骤 1：launchInstance（`aws:runInstances` 操作） **  
此步骤使用 Amazon Elastic Compute Cloud (Amazon EC2) 用户数据和 IAM 实例配置文件角色启动实例。用户数据根据操作系统安装相应的 SSM Agent。安装 SSM Agent 后，即可使用 Systems Manager 工具，例如 Run Command、State Manager和 Inventory。

**步骤 2：updateOSSoftware（`aws:runCommand`操作） **  
此步骤在已启动实例上运行以下命令：  
+ 从 Amazon S3 下载更新脚本。
+ 运行可选的更新前脚本。
+ 更新分发软件包和 Amazon 软件。
+ 运行可选的更新后脚本。
执行日志存储在 /tmp 文件夹中，供用户以后查看。  
如果您希望升级特定软件包集，则可以使用 `IncludePackages` 参数提供列表。在提供时，系统仅尝试更新这些软件包及其依赖项。不执行任何其他更新。默认情况下，如果未指定*包含* 软件包，则程序将更新所有可用软件包。  
如果要在升级中排除特定软件包集，则可以向 `ExcludePackages` 参数提供列表。如果提供，这些软件包保持其当前版本，与任何其他指定的选项无关。默认情况下，在未指定任何*排除*软件包时，将不排除软件包。

**步骤 3：stopInstance（`aws:changeInstanceState` 操作）**  
此步骤停止已更新实例。

**步骤 4：createImage（`aws:createImage` 操作） **  
此步骤创建一个新 AMI，带有可将其链接到源 ID 和创建时间的描述性名称。例如：“EC2 自动化在 \$1\$1global:DATE\$1TIME\$1\$1 从 \$1\$1SourceAmiId\$1\$1 生成了 AMI”，其中 DATE\$1TIME 和 SourceID 表示自动化变量。

**步骤 5：terminateInstance（`aws:changeInstanceState` 操作） **  
此步骤通过终止正在运行的实例来清除执行过程。

**Output**  
自动化返回新的 AMI ID 作为输出。

**注意**  
默认情况下，当自动化运行 `AWS-UpdateLinuxAmi` 运行手册时，系统会在默认 VPC (172.30.0.0/16) 中创建一个临时实例。如果您删除了默认 VPC，会收到以下错误：  
`VPC not defined 400`  
要解决此问题，您必须复制 `AWS-UpdateLinuxAmi` 运行手册并指定子网 ID。有关更多信息，请参阅 [VPC not defined 400](automation-troubleshooting.md#automation-trbl-common-vpc)。

**使用自动化创建经过修补的 AMI (AWS Systems Manager)**

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

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

1. 选择**执行自动化**。

1. 在**自动化文档**列表中，选择 `AWS-UpdateLinuxAmi`。

1. 在**文档详细信息**部分，验证**文档版本**是否设置为**运行时的默认版本**。

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

1. 在**执行模式**部分中，选择**简单执行**。

1. 在**输入参数**部分，输入在**开始前的准备工作**部分收集的信息。

1. 选择**执行**。控制台将显示自动化执行的状态。

在自动化完成后，请从更新后的 AMI 启动测试实例以验证更改。

**注意**  
如果自动化有任何步骤失败，**自动化执行**页面上会列出有关失败的信息。自动化设计为在成功完成所有任务后终止临时实例。如果步骤失败，系统可能不会终止实例。因此，如果某个步骤失败，请手动终止临时实例。

## 更新 Linux AMI（AWS CLI）


此 AWS Systems Manager 自动化演练介绍如何使用 AWS Command Line Interface (AWS CLI) 和 Systems Manager `AWS-UpdateLinuxAmi` 运行手册通过指定的最新版本软件包自动修补 Linux Amazon Machine Image (AMI)。Automation 是 AWS Systems Manager 中的一项工具。`AWS-UpdateLinuxAmi` 运行手册也能自动安装其他具体站点相关的软件包和配置。您可以使用该演练更新各种 Linux 分发版，包括 Ubuntu Server、Red Hat Enterprise Linux（RHEL）或 Amazon Linux AMIs。有关支持的 Linux 版本的完整列表，请参阅 [Patch Manager 先决条件](patch-manager-prerequisites.md)。

使用 `AWS-UpdateLinuxAmi` 运行手册可以自动完成映像维护任务，而无需使用 JSON 或 YAML 编写运行手册。您可以使用 `AWS-UpdateLinuxAmi` 运行手册执行以下类型的任务。
+ 在 Amazon Linux、RHEL 或 Ubuntu Server Amazon Machine Image（AMI）上升级所有分发版本程序包和 Amazon 软件。这是默认运行手册行为。
+ 在现有映像上安装 AWS Systems Manager SSM Agent 以启用 Systems Manager 功能，例如使用 AWS Systems Manager Run Command 的远程命令执行，或者使用 Inventory 的软件清单收集。
+ 安装其他软件包。

**开始前的准备工作**  
在您开始使用运行手册之前，请先为自动化配置角色和 EventBridge（后者可选）。有关更多信息，请参阅 [设置自动化](automation-setup.md)。此演练还要求您指定 AWS Identity and Access Management (IAM) 实例配置文件的名称。有关创建 IAM 实例配置文件的更多信息，请参阅[配置 Systems Manager 所需的实例权限](setup-instance-permissions.md)。

`AWS-UpdateLinuxAmi` 运行手册接受以下输入参数。


****  

| 参数 | 类型 | 描述 | 
| --- | --- | --- | 
|  SourceAmiId  |  字符串  |  （必需）源 AMI ID。您可以使用 AWS Systems Manager Parameter Store *公有*参数自动引用最新的 Linux Amazon EC2 AMI ID。有关更多信息，请参阅[使用 AWS Systems Manager Parameter Store 查询最新 Amazon Linux AMI ID](https://aws.amazon.com/blogs/compute/query-for-the-latest-amazon-linux-ami-ids-using-aws-systems-manager-parameter-store/)。  | 
|  IamInstanceProfileName  |  字符串  |  （必需）您在[配置 Systems Manager 所需的实例权限](setup-instance-permissions.md)中创建的 IAM 实例配置文件角色的名称。实例配置文件角色为自动化提供在您实例上执行操作的权限，例如运行命令或启动和停止服务。运行手册仅使用实例配置文件角色的名称。  | 
|  AutomationAssumeRole  |  字符串  |  （必需）您在 [设置自动化](automation-setup.md) 中创建的 IAM 服务角色的名称。服务角色（也称为担任角色）为自动化提供权限，用于担任您的 IAM 角色和代表您执行操作。例如，在运行手册中运行 `aws:createImage` 操作时，服务角色允许自动化创建新的 AMI。对于此参数，必须指定完整的 ARN。  | 
|  TargetAmiName  |  字符串  |  （可选）新 AMI 在创建之后的名称。默认名称是系统生成的字符串，其中包括源 AMI ID 以及创建时间和日期。  | 
|  InstanceType  |  字符串  |  (可选) 启动作为工作区主机的实例的类型。实例类型因区域而异。默认类型为 t2.micro。  | 
|  PreUpdateScript  |  字符串  |  (可选) 在应用更新前要运行的脚本的 URL。默认值 (\$1"none\$1") 不运行脚本。  | 
|  PostUpdateScript  |  字符串  |  (可选) 在应用软件包更新后要运行的脚本的 URL。默认值 (\$1"none\$1") 不运行脚本。  | 
|  IncludePackages  |  字符串  |  (可选) 仅更新这些指定的软件包。默认值 (\$1"all\$1") 将应用所有可用的更新。  | 
|  ExcludePackages  |  字符串  |  (可选) 在所有情况下从更新中排除的软件包的名称。默认值 (\$1"none\$1") 不排除任何软件包。  | 

**自动化步骤**  
默认情况下，`AWS-UpdateLinuxAmi` 运行手册包括以下步骤。

**步骤 1：launchInstance（`aws:runInstances` 操作） **  
此步骤使用 Amazon Elastic Compute Cloud (Amazon EC2) 用户数据和 IAM 实例配置文件角色启动实例。用户数据根据操作系统安装相应的 SSM Agent。安装 SSM Agent 后，即可使用 Systems Manager 工具，例如 Run Command、State Manager和 Inventory。

**步骤 2：updateOSSoftware（`aws:runCommand`操作） **  
此步骤在已启动实例上运行以下命令：  
+ 从 Amazon Simple Storage Service (Amazon S3) 下载更新脚本。
+ 运行可选的更新前脚本。
+ 更新分发软件包和 Amazon 软件。
+ 运行可选的更新后脚本。
执行日志存储在 /tmp 文件夹中，供用户以后查看。  
如果您希望升级特定软件包集，则可以使用 `IncludePackages` 参数提供列表。在提供时，系统仅尝试更新这些软件包及其依赖项。不执行任何其他更新。默认情况下，如果未指定*包含* 软件包，则程序将更新所有可用软件包。  
如果要在升级中排除特定软件包集，则可以向 `ExcludePackages` 参数提供列表。如果提供，这些软件包保持其当前版本，与任何其他指定的选项无关。默认情况下，在未指定任何*排除*软件包时，将不排除软件包。

**步骤 3：stopInstance（`aws:changeInstanceState` 操作）**  
此步骤停止已更新实例。

**步骤 4：createImage（`aws:createImage` 操作） **  
此步骤创建一个新 AMI，带有可将其链接到源 ID 和创建时间的描述性名称。例如：“EC2 自动化在 \$1\$1global:DATE\$1TIME\$1\$1 从 \$1\$1SourceAmiId\$1\$1 生成了 AMI”，其中 DATE\$1TIME 和 SourceID 表示自动化变量。

**步骤 5：terminateInstance（`aws:changeInstanceState` 操作） **  
此步骤通过终止正在运行的实例来清除执行过程。

**输出**  
自动化返回新的 AMI ID 作为输出。

**注意**  
默认情况下，当自动化运行 `AWS-UpdateLinuxAmi` 运行手册时，系统会在默认 VPC (172.30.0.0/16) 中创建一个临时实例。如果您删除了默认 VPC，会收到以下错误：  
`VPC not defined 400`  
要解决此问题，您必须复制 `AWS-UpdateLinuxAmi` 运行手册并指定子网 ID。有关更多信息，请参阅 [VPC not defined 400](automation-troubleshooting.md#automation-trbl-common-vpc)。

**使用自动化创建经过修补的 AMI**

1. 安装并配置 AWS Command Line Interface（AWS CLI）（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

1. 运行以下命令来运行 `AWS-UpdateLinuxAmi` 运行手册。将每个*示例资源占位符*替换为您自己的信息。

   ```
   aws ssm start-automation-execution \
       --document-name "AWS-UpdateLinuxAmi" \
       --parameters \
       SourceAmiId=AMI ID, \
       IamInstanceProfileName=IAM instance profile, \
       AutomationAssumeRole='arn:aws:iam::{{global:ACCOUNT_ID}}:role/AutomationServiceRole'
   ```

   该命令将会返回执行 ID。请将该 ID 复制到剪贴板。您将使用该 ID 查看自动化的状态。

   ```
   {
       "AutomationExecutionId": "automation execution ID"
   }
   ```

1. 要使用 AWS CLI 查看自动化，请运行以下命令：

   ```
   aws ssm describe-automation-executions
   ```

1. 运行以下命令以查看有关运行手册进程的详细信息。将 *automation execution ID* 替换为您自己的信息。

   ```
   aws ssm get-automation-execution --automation-execution-id automation execution ID
   ```

   更新过程可能需要 30 分钟或者更久。
**注意**  
您也可以在控制台中监控自动化的状态。在列表中，选择您刚才运行的自动化，然后选择**步骤**选项卡。该选项卡将显示自动化操作的状态。

在自动化完成后，请从更新后的 AMI 启动测试实例以验证更改。

**注意**  
如果自动化有任何步骤失败，**自动化执行**页面上会列出有关失败的信息。自动化设计为在成功完成所有任务后终止临时实例。如果步骤失败，系统可能不会终止实例。因此，如果某个步骤失败，请手动终止临时实例。

# 更新 Windows Server AMI


使用 `AWS-UpdateWindowsAmi` 运行手册可以在 Amazon Windows Amazon Machine Image (AMI) 上自动完成映像维护任务，而无需使用 JSON 或 YAML 编写工作流程。本运行手册在 Windows Server 2008 R2 或更高版本中受支持。您可以使用 `AWS-UpdateWindowsAmi` 运行手册执行以下类型的任务。
+ 安装所有 Windows 更新并升级 Amazon 软件 (默认行为)。
+ 安装特定 Windows 更新并升级 Amazon 软件。
+ 使用您的脚本自定义 AMI。

**开始前的准备工作**  
在开始使用运行手册之前，[为自动化配置角色](automation-setup-iam.md)以添加 `iam:PassRole` 策略，此策略引用要授予其访问权限的实例配置文件的 ARN。也可选择为 Automation（AWS Systems Manager 中的一项工具）配置 Amazon EventBridge。有关更多信息，请参阅 [设置自动化](automation-setup.md)。此演练还要求您指定 AWS Identity and Access Management (IAM) 实例配置文件的名称。有关创建 IAM 实例配置文件的更多信息，请参阅[配置 Systems Manager 所需的实例权限](setup-instance-permissions.md)。

**注意**  
AWS Systems Manager SSM Agent 的更新通常会在不同时间向不同区域推广。自定义或更新 AMI 时，请仅使用为您工作所在的区域发布的源 AMI。这将确保您使用该区域发布的最新 SSM Agent并避免兼容性问题。

`AWS-UpdateWindowsAmi` 运行手册接受以下输入参数。


****  

| 参数 | 类型 | 说明 | 
| --- | --- | --- | 
|  SourceAmiId  |  字符串  |  （必需）源 AMI ID。您可以使用 Systems Manager Parameter Store *公有*参数自动引用最新的 Windows Server AMI ID。有关更多信息，请参阅[使用 AWS Systems ManagerParameter Store 查询最新的 Windows AMI ID](https://aws.amazon.com/blogs/mt/query-for-the-latest-windows-ami-using-systems-manager-parameter-store/)。  | 
|  SubnetId  |  字符串  |  （可选）要在其中启动临时实例的子网。如果您已删除默认 VPC，则必须为此参数指定值。  | 
|  IamInstanceProfileName  |  字符串  |  （必需）您在[配置 Systems Manager 所需的实例权限](setup-instance-permissions.md)中创建的 IAM 实例配置文件角色的名称。实例配置文件角色为自动化提供在您实例上执行操作的权限，例如运行命令或启动和停止服务。运行手册仅使用实例配置文件角色的名称。  | 
|  AutomationAssumeRole  |  字符串  |  （必需）您在 [设置自动化](automation-setup.md) 中创建的 IAM 服务角色的名称。服务角色（也称为担任角色）为自动化提供权限，用于担任您的 IAM 角色和代表您执行操作。例如，在运行手册中运行 `aws:createImage` 操作时，服务角色允许自动化创建新的 AMI。对于此参数，必须指定完整的 ARN。  | 
|  TargetAmiName  |  字符串  |  （可选）新 AMI 在创建之后的名称。默认名称是系统生成的字符串，其中包括源 AMI ID 以及创建时间和日期。  | 
|  InstanceType  |  字符串  |  (可选) 启动作为工作区主机的实例的类型。实例类型因区域而异。默认类型为 t2.medium。  | 
|  PreUpdateScript  |  字符串  |  (可选) 要在更新 AMI 之前运行的脚本。在运行手册中或在运行时输入脚本作为参数。  | 
|  PostUpdateScript  |  字符串  |  （可选）要在更新 AMI 之后运行的脚本。在运行手册中或在运行时输入脚本作为参数。  | 
|  IncludeKbs  |  字符串  |  (可选) 指定一个或多个要包括的 Microsoft 知识库 (KB) 文章 ID。可以使用逗号分隔值安装多个 ID。有效格式：KB9876543 或 9876543。  | 
|  ExcludeKbs  |  字符串  |  (可选) 指定一个或多个要排除的 Microsoft 知识库 (KB) 文章 ID。可以使用逗号分隔值排除多个 ID。有效格式：KB9876543 或 9876543。  | 
|  类别  |  字符串  |  (可选) 指定一个或多个更新类别。可以使用逗号分隔值筛选类别。选项：关键更新、安全更新、定义更新、Update Rollup、Service Pack、工具、更新或驱动程序。有效格式包括单个条目，例如：关键更新。或者，可以指定逗号分隔列表：关键更新,安全更新,定义更新。  | 
|  SeverityLevels  |  字符串  |  (可选) 指定一个或多个与更新关联的 MSRC 严重性级别。可以使用逗号分隔值筛选严重性级别。选项：关键、重要、低、中或未指定。有效格式包括单个条目，例如：关键。或者，可以指定逗号分隔列表：关键,重要,低。  | 

**自动化步骤**  
默认情况下，`AWS-UpdateWindowsAmi` 运行手册包括以下步骤。

**步骤 1：launchInstance（`aws:runInstances` 操作）**  
此步骤以从指定的 `SourceAmiID` 启动一个具有 IAM 实例配置文件角色的实例。

**步骤 2：runPreUpdateScript（`aws:runCommand` 操作）**  
此步骤可让您以字符串形式指定一个在安装更新前运行的脚本。

**步骤 3：更新 EC2Config（`aws:runCommand` 操作）**  
此步骤使用 `AWS-InstallPowerShellModule` 运行手册下载 AWS 共有 PowerShell 模块。Systems Manager 使用 SHA-256 哈希验证模块的完整性。然后，Systems Manager 将检查操作系统，以确定是更新 EC2Config 还是 EC2Launch。EC2Config 通过 Windows Server 2012 R2 在 Windows Server 2008 R2 上运行。EC2Launch 在 Windows Server 2016 上运行。

**步骤 4：updateSSMAgent（`aws:runCommand`操作）**  
此步骤通过使用 `AWS-UpdateSSMAgent` 运行手册更新 SSM Agent。

**步骤 5：updateAWSPVDriver（`aws:runCommand`操作）**  
此步骤通过使用 `AWS-ConfigureAWSPackage` 运行手册更新 AWS PV 驱动程序。

**步骤 6：updateAwsEnaNetworkDriver（`aws:runCommand`操作）**  
此步骤通过使用 `AWS-ConfigureAWSPackage` 运行手册更新 AWS ENA 网络驱动程序。

**步骤 7：installWindowsUpdates（`aws:runCommand` 操作） **  
此步骤使用 `AWS-InstallWindowsUpdates` 运行手册安装 Windows 更新。默认情况下，Systems Manager 搜索并安装任何缺失的更新。可以通过指定下列参数之一更改默认行为：`IncludeKbs`、`ExcludeKbs`、`Categories` 或 `SeverityLevels`。

**步骤 8：runPostUpdateScript（`aws:runCommand` 操作)**  
此步骤可让您以字符串形式指定一个在安装更新后运行的脚本。

**步骤 9：runSysprepGeneralize（`aws:runCommand` 操作) **  
此步骤使用 `AWS-InstallPowerShellModule` 运行手册下载 AWS 共有 PowerShell 模块。Systems Manager 使用 SHA-256 哈希验证模块的完整性。然后 Systems Manager 使用 AWS 支持的方法针对 EC2Launch (Windows Server 2016) 或 EC2Config（Windows Server 2008 R2 到 2012 R2）运行 sysprep。

**步骤 10：stopInstance（`aws:changeInstanceState` 操作） **  
此步骤停止已更新实例。

**步骤 11：createImage（`aws:createImage` 操作） **  
此步骤创建一个新 AMI，带有可将其链接到源 ID 和创建时间的描述性名称。例如：“EC2自动化在 \$1\$1global:DATE\$1TIME\$1\$1 从 \$1\$1SourceAmiId\$1\$1 生成了 AMI”，其中 DATE\$1TIME 和 SourceID 表示自动化变量。

**步骤 12：TerminateInstance（`aws:changeInstanceState` 操作） **  
此步骤通过终止正在运行的实例来清除自动化。

**Output**  
此部分可让您将各个步骤的输出或任何参数的值指定为自动化输出。默认情况下，输出是由执行创建的已更新 Windows AMI 的 ID。

**注意**  
默认情况下，当自动化运行 `AWS-UpdateWindowsAmi` 运行手册并创建一个临时实例时，系统会使用默认 VPC (172.30.0.0/16)。如果您删除了默认 VPC，会收到以下错误：  
VPC not defined 400  
要解决此问题，您必须复制 `AWS-UpdateWindowsAmi` 运行手册并指定子网 ID。有关更多信息，请参阅 [VPC not defined 400](automation-troubleshooting.md#automation-trbl-common-vpc)。

**使用自动化创建经过修补的 Windows AMI**

1. 安装并配置 AWS Command Line Interface（AWS CLI）（如果尚未执行该操作）。

   有关信息，请参阅[安装或更新 AWS CLI 的最新版本](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)。

1. 运行以下命令来运行 `AWS-UpdateWindowsAmi` 运行手册。将每个*示例资源占位符*替换为您自己的信息。以下示例命令使用的是最新的 Amazon EC2 AMI，以最大限度减少需应用的补丁数量。如果您多次运行此命令，则必须为 `targetAMIname` 指定唯一的值。AMI 名称必须唯一。

   ```
   aws ssm start-automation-execution \
       --document-name="AWS-UpdateWindowsAmi" \
       --parameters SourceAmiId='AMI ID',IamInstanceProfileName='IAM instance profile',AutomationAssumeRole='arn:aws:iam::{{global:ACCOUNT_ID}}:role/AutomationServiceRole'
   ```

   该命令将会返回执行 ID。请将该 ID 复制到剪贴板。您将使用该 ID 查看自动化的状态。

   ```
   {
       "AutomationExecutionId": "automation execution ID"
   }
   ```

1. 要使用 AWS CLI 查看自动化，请运行以下命令：

   ```
   aws ssm describe-automation-executions
   ```

1. 要查看有关自动化进程的详细信息，请运行以下命令。

   ```
   aws ssm get-automation-execution 
       --automation-execution-id automation execution ID
   ```

**注意**  
根据应用的补丁数量，在该示例自动化中运行的 Windows 修补过程可能需要 30 分钟或更长时间才能完成。

# 使用 Automation、AWS Lambda 和 Parameter Store 来更新黄金 AMI


以下示例使用组织维护和定期修补自己专有 AMIs 的模型，而非构建自 Amazon Elastic Compute Cloud (Amazon EC2) AMIs。

以下过程说明了如何将操作系统（OS）补丁自动应用到已被视为最新的 AMI 或*最新* AMI。在示例中，参数 `SourceAmiId` 的默认值由名为 `latestAmi` 的 AWS Systems Manager Parameter Store 参数定义。`latestAmi` 的值由调用的 AWS Lambda 函数在自动化结束时更新。由于采用了此自动化流程，修补 AMIs 所需的时间和工作量可最大限度减少，因为修补操作始终都应用到最新的 AMI。Parameter Store 和 Automation 都是 AWS Systems Manager 的工具。

**开始前的准备工作**  
配置自动化角色以及（可选）为自动化配置 Amazon EventBridge。有关更多信息，请参阅 [设置自动化](automation-setup.md)。

**Topics**
+ [

## 任务 1：在 Systems Manager Parameter Store 中创建一个参数
](#create-parameter-ami)
+ [

## 任务 2：为 AWS Lambda 创建 IAM 角色
](#create-lambda-role)
+ [

## 任务 3：创建 AWS Lambda 函数
](#create-lambda-function)
+ [

## 任务 4：创建运行手册并修补 AMI
](#create-custom-ami-update-runbook)

## 任务 1：在 Systems Manager Parameter Store 中创建一个参数


在 Parameter Store 中创建一个使用以下信息的字符串参数：
+ **名称**：`latestAmi`。
+ **值**：AMI ID。例如：` ami-188d6e0e`。

有关如何创建 Parameter Store 字符串参数的信息，请参阅 [在 Systems Manager 中创建 Parameter Store 参数](sysman-paramstore-su-create.md)。

## 任务 2：为 AWS Lambda 创建 IAM 角色


使用以下过程为 AWS Lambda 创建 IAM 服务角色。这些策略授予 Lambda 权限，以便使用 Lambda 函数和 Systems Manager 来更新 `latestAmi` 参数的值。

**为 Lambda 创建 IAM 服务角色**

1. 登录 AWS 管理控制台，然后通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在导航窗格中选择**策略**，然后选择**创建策略**。

1. 选择 **JSON** 选项卡。

1. 将默认内容替换为以下策略。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "logs:CreateLogGroup",
               "Resource": "arn:aws:logs:us-east-1:111122223333:*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "logs:CreateLogStream",
                   "logs:PutLogEvents"
               ],
               "Resource": [
                   "arn:aws:logs:us-east-1:111122223333:log-group:/aws/lambda/function name:*"
               ]
           }
       ]
   }
   ```

------

1. 选择**下一步：标签**。

1. （可选）添加一个或多个标签键值对，以组织、跟踪或控制此策略的访问权限。

1. 选择**下一步：审核**。

1. 在**查看策略**页面上，对于**名称**，输入内联策略的名称，例如 **amiLambda**。

1. 选择**创建策略**。

1. 重复步骤 2 和 3。

1. 粘贴以下策略。将每个*示例资源占位符*替换为您自己的信息。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "ssm:PutParameter",
               "Resource": "arn:aws:ssm:us-east-1:111122223333:parameter/latestAmi"
           },
           {
               "Effect": "Allow",
               "Action": "ssm:DescribeParameters",
               "Resource": "*"
           }
       ]
   }
   ```

------

1. 选择**下一步：标签**。

1. （可选）添加一个或多个标签键值对，以组织、跟踪或控制此策略的访问权限。

1. 选择**下一步：审核**。

1. 在**查看策略**页面上，对于**名称**，输入内联策略的名称，例如 **amiParameter**。

1. 选择**创建策略**。

1. 在导航窗格中，选择 **Roles（角色）**，然后选择 **Create role（创建角色）**。

1. 直接在**使用案例**下，选择 **Lambda**，然后选择**下一步**。

1. 在**添加权限**页面上，使用**搜索**字段查找之前创建的两个策略。

1. 选中策略旁边的复选框，然后选择**下一步**。

1. 对于**角色名称**，请输入新角色的名称，如 **lambda-ssm-role**或所需其他名称。
**注意**  
由于多个实体可能引用该角色，因此创建角色后无法更改角色的名称。

1. （可选）添加一个或多个标签键值对，以组织、追踪或控制对此角色的访问，然后选择**创建角色**。

## 任务 3：创建 AWS Lambda 函数


使用以下过程创建 Lambda 函数，该函数自动更新 `latestAmi` 参数的值。

**创建 Lambda 函数**

1. 通过以下网址登录 AWS 管理控制台 并打开 AWS Lambda 控制台：[https://console.aws.amazon.com/lambda/](https://console.aws.amazon.com/lambda/)。

1. 选择**创建函数**。

1. 在**创建函数**页面上，选择**从头开始创作**。

1. 对于**函数名称**，请输入 **Automation-UpdateSsmParam**。

1. 对于**运行时系统**，选择 **Python 3.11**。

1. 对于**架构**，选择 Lambda 用于运行该函数的计算机处理器类型，即 **x86\$164** 或 **arm64**，

1. 在**权限**部分中，展开**更改默认执行角色**。

1. 选择**使用现有角色**，然后为您在任务 2 中创建的 Lambda 选择服务角色。

1. 选择**创建函数**。

1. 在**代码源**区域中的 **lambda\$1function** 选项卡上，删除该字段中的预填充代码，然后粘贴以下代码示例。

   ```
   from __future__ import print_function
   
   import json
   import boto3
   
   print('Loading function')
   
   
   #Updates an SSM parameter
   #Expects parameterName, parameterValue
   def lambda_handler(event, context):
       print("Received event: " + json.dumps(event, indent=2))
   
       # get SSM client
       client = boto3.client('ssm')
   
       #confirm  parameter exists before updating it
       response = client.describe_parameters(
          Filters=[
             {
              'Key': 'Name',
              'Values': [ event['parameterName'] ]
             },
           ]
       )
   
       if not response['Parameters']:
           print('No such parameter')
           return 'SSM parameter not found.'
   
       #if parameter has a Description field, update it PLUS the Value
       if 'Description' in response['Parameters'][0]:
           description = response['Parameters'][0]['Description']
           
           response = client.put_parameter(
             Name=event['parameterName'],
             Value=event['parameterValue'],
             Description=description,
             Type='String',
             Overwrite=True
           )
       
       #otherwise just update Value
       else:
           response = client.put_parameter(
             Name=event['parameterName'],
             Value=event['parameterValue'],
             Type='String',
             Overwrite=True
           )
           
       responseString = 'Updated parameter %s with value %s.' % (event['parameterName'], event['parameterValue'])
           
       return responseString
   ```

1. 依次选择**文件、保存**。

1. 要测试 Lambda 函数，请从**测试**菜单中选择**配置测试事件**。

1. 对于**事件名称**，输入测试事件的名称，如 **MyTestEvent**。

1. 使用以下 JSON 替换现有文本。将 *AMI ID* 替换为您自己的信息来设置 `latestAmi` 参数值。

   ```
   {
      "parameterName":"latestAmi",
      "parameterValue":"AMI ID"
   }
   ```

1. 选择**保存**。

1. 选择**测试**以测试该函数。在**执行结果**选项卡上，应将状态报告为**已成功**，以及有关更新的其他详细信息。

## 任务 4：创建运行手册并修补 AMI


使用以下过程创建并运行运行手册，该文档修补您为 **latestAmi** 参数指定的 AMI。在自动化完成后，使用新修补的 AMI 的 ID 更新 **latestAmi** 的值。后续自动化使用先前执行创建的 AMI。

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

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

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

1. 对于**创建文档**，选择**自动化**。

1. 对于**名称**，请输入 **UpdateMyLatestWindowsAmi**。

1. 选择**编辑器**选项卡，然后选择**编辑**。

1. 当系统提示时，选择**确定**。

1. 在**文档编辑器**字段中，将默认内容替换为以下 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: The ID of the AMI you want to patch.
       default: '{{ ssm:latestAmi }}'
     SubnetId:
       type: String
       description: The ID of the subnet where the instance from the SourceAMI parameter is launched.
     SecurityGroupIds:
       type: StringList
       description: The IDs of the security groups to associate with the instance that's launched from the SourceAMI parameter.
     NewAMI:
       type: String
       description: The name of of newly patched AMI.
       default: 'patchedAMI-{{global:DATE_TIME}}'
     InstanceProfile:
       type: String
       description: 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: updateSsmParam
       action: aws:invokeLambdaFunction
       timeoutSeconds: 1200
       maxAttempts: 1
       onFailure: Abort
       inputs:
           FunctionName: Automation-UpdateSsmParam
           Payload: '{"parameterName":"latestAmi", "parameterValue":"{{createImage.ImageId}}"}'
   outputs:
   - createImage.ImageId
   ```

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

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

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

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

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

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

1. 指定输入参数的值。

1. 选择**执行**。

1. 自动化完成后，在导航窗格中选择 **Parameter Store**，并确认 `latestAmi` 的新值与自动化返回的值匹配。您还可以验证新 AMI ID 与 Amazon EC2 控制台的 **AMI** 部分中的自动化输出匹配。

# 使用 Automation 和 Jenkins 更新 AMIs


如果组织在 CI/CD 管道中使用 Jenkins 软件，则可以添加 Automation 作为构建后步骤，用于将应用程序发行版预安装到 Amazon Machine Images（AMIs）中。Automation 是 AWS Systems Manager 中的一项工具。您还可以使用 Jenkins 计划功能来调用 Automation 并创建自己的操作系统（OS）修补计划。

以下示例显示如何从运行在本地或 Amazon Elastic Compute Cloud（Amazon EC2）上的 Jenkins 服务器调用 Automation。对于身份验证，Jenkins 服务器使用 AWS 凭证，该凭证基于您在示例中创建并附加到实例配置文件的 IAM 策略。

**注意**  
配置实例时，请务必遵循 Jenkins 安全最佳实践。

**开始前的准备工作**  
在配置 Automation 用于 Jenkins 之前，请完成以下任务：
+ 完成 [使用 Automation、AWS Lambda 和 Parameter Store 来更新黄金 AMI](automation-tutorial-update-patch-golden-ami.md) 示例。以下示例使用在该示例中创建的 **UpdateMyLatestWindowsAmi** 运行手册。
+ 为自动化配置 IAM 角色。Systems Manager 需要实例配置文件角色和服务角色 ARN 来处理自动化。有关更多信息，请参阅 [设置自动化](automation-setup.md)。

**为 Jenkins 服务器创建 IAM 策略**

1. 登录 AWS 管理控制台，然后通过以下网址打开 IAM 控制台：[https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/)。

1. 在导航窗格中选择**策略**，然后选择**创建策略**。

1. 选择 **JSON** 选项卡。

1. 将每个*示例资源占位符*替换为您自己的信息。

------
#### [ JSON ]

****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": "ssm:StartAutomationExecution",
               "Resource": [
                   "arn:aws:ssm:us-east-1:111122223333:document/UpdateMyLatestWindowsAmi",
                   "arn:aws:ssm:us-east-1:111122223333:automation-execution/*"
               ]
           }
       ]
   }
   ```

------

1. 选择**查看策略**。

1. 在**查看策略**页面上，对于**名称**，输入内联策略的名称，例如 **JenkinsPolicy**。

1. 选择**创建策略**。

1. 在导航窗格中，选择**角色**。

1. 选择附加到 Jenkins 服务器的实例配置文件。

1. 在**权限**选项卡中，选择**添加权限**，然后选择**附加策略**。

1. 在**其他权限策略**部分中，输入您在之前步骤中创建的策略名称。例如，**JenkinsPolicy**。

1. 选中您的策略旁边的复选框，然后选择**附加策略**。

按照以下过程在 Jenkins 服务器上配置 AWS CLI。

**为 Automation 配置 Jenkins 服务器**

1. 使用首选浏览器连接到 8080 端口上的 Jenkins 服务器，以便访问管理界面。

1. 输入 `/var/lib/jenkins/secrets/initialAdminPassword` 在中找到的密码。要显示您的密码，请运行以下命令。

   ```
   sudo cat /var/lib/jenkins/secrets/initialAdminPassword
   ```

1. Jenkins 安装脚本会将您引导到**自定义 Jenkins** 页面。选择**安装建议的插件**。

1. 安装完成后，依次选择**管理员凭证**、**保存凭证**、**开始使用 Jenkins**。

1. 在左侧导航窗格中，选择**管理 Jenkins**，然后选择**管理插件**。

1. 选**可用**选项卡，然后输入 **Amazon EC2 plugin**。

1. 选中 **Amazon EC2 plugin** 的复选框，然后选择**安装但不重新启动**。

1. 安装完成后，选择**返回首页**。

1. 选择**管理 Jenkins**，然后选择**管理节点和云**。

1. 在**配置云**部分中，选择**添加新云**，然后选择 **Amazon EC2**。

1. 在其余字段中输入您的信息。确保选择**使用 EC2 实例配置文件获取凭证**选项。

按照以下过程配置 Jenkins 项目来调用 Automation。

**配置 Jenkins 服务器来调用 Automation**

1. 在 Web 浏览器中打开 Jenkins 控制台。

1. 选择要配置用于自动化的项目，然后选择**配置**。

1. 在**构建**选项卡上，选择**添加构建步骤**。

1. 选择**执行 shell** 或**执行 Windows 批命令**（具体取决于您的操作系统)。

1. 在 **Command**（命令）字段中，运行 AWS CLI 命令，如下所示。将每个*示例资源占位符*替换为您自己的信息。

   ```
   aws ssm start-automation-execution \
           --document-name runbook name \
           --region AWS 区域 of your source AMI \
           --parameters runbook parameters
   ```

   以下示例命令使用 **UpdateMyLatestWindowsAmi** 运行手册以及在 [使用 Automation、AWS Lambda 和 Parameter Store 来更新黄金 AMI](automation-tutorial-update-patch-golden-ami.md) 中创建的 Systems Manager 参数 `latestAmi`：

   ```
   aws ssm start-automation-execution \
           --document-name UpdateMyLatestWindowsAmi \
           --parameters \
               "sourceAMIid='{{ssm:latestAmi}}'"
           --region region
   ```

   在 Jenkins 中，命令类似于以下屏幕截图中的示例。  
![\[Jenkins 软件中的示例命令。\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/sysman-ami-jenkins2.png)

1. 在 Jenkins 项目中，选择**立即构建**。Jenkins 会返回类似于以下示例的输出。  
![\[Jenkins 软件中的示例命令输出。\]](http://docs.aws.amazon.com/zh_cn/systems-manager/latest/userguide/images/sysman-ami-jenkins.png)

# 更新自动扩缩组的 AMIs


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

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

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

## 创建 **PatchAMIAndUpdateASG** 运行手册


使用以下过程创建 **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 启动。

# 使用 AWS 支持 自助服务运行手册


本部分介绍如何使用由 AWS 支持 团队创建的自助自动化。这些自动化可帮助您管理 AWS 的资源。

**支持自动化工作流**  
Support Workflows (SAW) 是由 AWS 支持 团队撰写并维护的自动化运行手册。这些运行手册帮助您对有关 AWS 资源的常见问题进行故障排除，主动监控和识别网络问题，收集和分析日志，等等。

SAW 运行手册使用 **`AWSSupport`** 前缀 例如 [https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awssupport-activatewindowswithamazonlicense.html](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awssupport-activatewindowswithamazonlicense.html)。

此外,具有 Business Support\$1 及更高 AWS Support 计划的客户还可以访问使用 **`AWSPremiumSupport`** 前缀的运行手册。例如 [https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awspremiumsupport-troubleshootEC2diskusage.html](https://docs.aws.amazon.com/systems-manager-automation-runbooks/latest/userguide/automation-awspremiumsupport-troubleshootEC2diskusage.html)。

如需了解关于 AWS 支持 的更多信息，请参阅 [AWS 支持 入门](https://docs.aws.amazon.com/awssupport/latest/user/getting-started.html)。

**Topics**
+ [

# 在无法访问的实例上运行 EC2Rescue 工具
](automation-ec2rescue.md)
+ [

# 在 EC2 实例上重置密码和 SSH 密钥
](automation-ec2reset.md)

# 在无法访问的实例上运行 EC2Rescue 工具


EC2Rescue 可以帮助您诊断有关 Linux 和 Windows Server 的 Amazon Elastic Compute Cloud (Amazon EC2) 实例的问题并进行故障排除。您可以手动运行工具，如[使用适用于 Linux Server 的 EC2Rescue](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Linux-Server-EC2Rescue.html) 和[使用适用于 Windows Server 的 EC2Rescue](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/Windows-Server-EC2Rescue.html)。或者，您也可以使用 Systems Manager 自动化和 **`AWSSupport-ExecuteEC2Rescue`** 运行手册。Automation 是 AWS Systems Manager 中的一项工具。**`AWSSupport-ExecuteEC2Rescue`** 运行手册旨在全面执行 Systems Manager 的操作、CloudFormation 的操作和 Lambda 功能，从而将使用 EC2Rescue 通常所需的步骤自动化。

您可以使用 **`AWSSupport-ExecuteEC2Rescue`** 运行手册，对不同类型的操作系统 (OS) 问题进行故障排除和潜在修复。不支持带有加密根卷的实例。有关完整列表，请参阅以下主题：

**Windows**：请参阅*将适用于 Windows Server 的 EC2Rescue 与命令行配合使用*中的[抢救操作](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2rw-cli.html#ec2rw-rescue)。

**Linux** 和 **macOS**：一些适用于 Linux 的 EC2Rescue 模块会检测并尝试修复问题。有关更多信息，请参阅 GitHub 上各个模块的 [https://github.com/awslabs/aws-ec2rescue-linux/tree/master/docs](https://github.com/awslabs/aws-ec2rescue-linux/tree/master/docs) 文档。

## 工作原理


如下文所示，使用自动化和 **`AWSSupport-ExecuteEC2Rescue`** 运行手册对实例进行故障排除：
+ 您为无法访问的实例指定 ID 并启动运行手册。
+ 系统创建一个临时 VPC，然后运行一系列 Lambda 函数以配置该 VPC。
+ 系统在与您的原始实例相同的可用区内为您的临时 VPC 标识一个子网。
+ 系统启动一个临时的启用了 SSM 的 帮助程序实例。
+ 系统停止您的原始实例并创建备份。然后，它将原始根卷附加到帮助程序实例。
+ 系统使用 Run Command 在帮助程序实例上运行 EC2Rescue。EC2Rescue 识别并尝试修复有关已附加的原始根卷的问题。完成后，EC2Rescue 重新将根卷附加回原始实例。
+ 系统重启您的原始实例，并终止临时实例。系统也将终止临时 VPC 和在自动化开始时创建的 Lambda 函数。

## 开始前的准备工作


运行以下自动化之前，请执行以下操作：
+ 复制无法访问的实例的实例 ID。您将在过程中指定此 ID。
+ (可选) 收集无法访问实例所在可用区中子网的 ID。EC2Rescue 实例将在此子网中创建。如果不指定子网，自动化会在您的 AWS 账户中创建新建一个临时 VPC。验证您的 AWS 账户是否至少有一个可用 VPC。默认情况下，一个区域中可以创建 5 个 VPC。如果您已在该区域中创建 5 个 VPC，自动化将会失败，但不会对您的实例进行更改。有关 Amazon VPC 配额的更多信息，请参阅 *Amazon VPC 用户指南*中的 [VPC 和子网](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-vpcs-subnets)。
+ 或者，您可以为自动化创建并指定一个 AWS Identity and Access Management (IAM) 角色。如果您不指定此角色，自动化将在运行自动化的用户的环境中运行。

### 向 `AWSSupport-EC2Rescue` 授予在您的实例上执行操作的权限


在自动化执行期间，EC2Rescue 需要权限才能在您的实例上执行一系列操作。这些操作调用 AWS Lambda、IAM 和 Amazon EC2 服务，安全地尝试修复实例的问题。如果您在 AWS 账户 和/或 VPC 中具有管理员级权限，您可能能够在不按照本部分中所述配置权限的情况下运行自动化。如果您没有管理员级权限，则您或管理员必须使用以下选项之一配置权限。
+ [使用 IAM policy 授予权限](#automation-ec2rescue-access-iam)
+ [使用 CloudFormation 模板授予权限](#automation-ec2rescue-access-cfn)

#### 使用 IAM policy 授予权限


您可以将以下 IAM policy 作为内联策略附加到您的用户、组或角色；也可以创建新的 IAM 托管策略，并将其附加到您的用户、组或角色。有关将内联策略添加到您的用户、组或角色的更多信息，请参阅[使用内联策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_inline-using.html)。有关创建新的托管策略的更多信息，请参阅[使用托管策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-using.html)。

**注意**  
如果创建新的 IAM 托管式策略，则还必须将 **AmazonSSMAutomationRole** 托管式策略附加到该策略，以便实例与 Systems Manager API 通信。

**适用于 AWSSupport-EC2Rescue 的 IAM policy**

将 *account ID* 替换为您自己的信息。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "lambda:InvokeFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction"
            ],
            "Resource": "arn:aws:lambda:*:111122223333:function:AWSSupport-EC2Rescue-*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::awssupport-ssm.*/*.template",
                "arn:aws:s3:::awssupport-ssm.*/*.zip"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:CreateRole",
                "iam:CreateInstanceProfile",
                "iam:GetRole",
                "iam:GetInstanceProfile",
                "iam:PutRolePolicy",
                "iam:DetachRolePolicy",
                "iam:AttachRolePolicy",
                "iam:PassRole",
                "iam:AddRoleToInstanceProfile",
                "iam:RemoveRoleFromInstanceProfile",
                "iam:DeleteRole",
                "iam:DeleteRolePolicy",
                "iam:DeleteInstanceProfile"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/AWSSupport-EC2Rescue-*",
                "arn:aws:iam::111122223333:instance-profile/AWSSupport-EC2Rescue-*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:CreateFunction",
                "ec2:CreateVpc",
                "ec2:ModifyVpcAttribute",
                "ec2:DeleteVpc",
                "ec2:CreateInternetGateway",
                "ec2:AttachInternetGateway",
                "ec2:DetachInternetGateway",
                "ec2:DeleteInternetGateway",
                "ec2:CreateSubnet",
                "ec2:DeleteSubnet",
                "ec2:CreateRoute",
                "ec2:DeleteRoute",
                "ec2:CreateRouteTable",
                "ec2:AssociateRouteTable",
                "ec2:DisassociateRouteTable",
                "ec2:DeleteRouteTable",
                "ec2:CreateVpcEndpoint",
                "ec2:DeleteVpcEndpoints",
                "ec2:ModifyVpcEndpoint",
                "ec2:Describe*",
                "autoscaling:DescribeAutoScalingInstances"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}
```

------

#### 使用 CloudFormation 模板授予权限


CloudFormation 使用预配置模板自动化创建 IAM 角色和策略的过程。使用 CloudFormation，通过以下过程为 EC2Rescue 自动化创建所需的 IAM 角色和策略。

**为 EC2Rescue 创建所需的 IAM 角色和策略**

1. 下载 [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWSSupport-EC2RescueRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWSSupport-EC2RescueRole.zip) 文件并将 `AWSSupport-EC2RescueRole.json` 解压到本地计算机上的目录。

1. 如果您的 AWS 账户是一个特殊分区，请编辑模板以将 ARN 值更改为您的分区的值。

   例如，对于中国地区，将出现的所有 `arn:aws` 更改为 `arn:aws-cn`。

1. 登录到 AWS 管理控制台 并打开 CloudFormation 控制台 [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 依次选择**创建堆栈**和**使用新资源（标准）**。

1. 在**创建堆栈**页面上，对于**先决条件 - 准备模板**，选择**模板已就绪**。

1. 对于**指定模板**，选择**上传模板文件**。

1. 选择**选择文件**，然后进行浏览并从您解压缩 `AWSSupport-EC2RescueRole.json` 文件的目录中选择此文件。

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

1. 在**指定堆栈详细信息**页上，对于**堆栈名称**字段，输入用于标识此堆栈的名称，然后选择**下一步**。

1. （可选）在**标签** 区域，将一个或多个标签键名称/值对应用到堆栈。

   标签是您分配给资源的可选元数据。标签可让您按各种标准（如用途、所有者或环境）对资源进行分类。例如，您可能需要对堆栈进行标记，以确定其运行的任务类型、涉及的目标或其他资源的类型以及其运行的环境。

1. 选择 **Next**（下一步）

1. 在**审核**页面上，审核堆栈详细信息，然后向下滚动并选择**我确认 CloudFormation 可能创建 IAM 资源**选项。

1. 选择**创建堆栈**。

   CloudFormation 将持续几分钟显示 **CREATE\$1IN\$1PROGRESS** 状态。创建堆栈后，状态将变为 **CREATE\$1COMPLETE**。您还可以选择刷新图标来检查创建过程的状态。

1. 在**堆栈**列表中，选择您刚刚创建的堆栈的选项按钮，然后选择**输出**选项卡。

1. 记下**值**。这是 AssumeRole 的 ARN。在下一个过程 [运行自动化](#automation-ec2rescue-executing) 中运行自动化时指定此 ARN。

## 运行自动化


**重要**  
以下自动化将停止无法访问的实例。停止实例可能导致附加的实例存储卷（如果存在）上的数据丢失。如果未关联弹性 IP，停止实例也可能导致公有 IP 更改。

**运行 `AWSSupport-ExecuteEC2Rescue` 自动化**

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

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

1. 选择**执行自动化**。

1. 在**自动化文档**部分中，从列表中选择 **Amazon 所拥有**。

1. 在运行手册列表中，选择卡片中的 `AWSSupport-ExecuteEC2Rescue`，然后选择**下一步**。

1. 在**执行自动化文档**页面上，选择**简单执行**。

1. 在**文档详细信息**部分中，验证**文档版本** 是否设置为最高默认版本。例如，**\$1DEFAULT** 或 **3 (默认值))**。

1. 在**输入参数**部分中，指定以下参数：

   1. 对于 **UnreachableInstanceId**，指定无法访问实例的 ID。

   1. （可选）对于 **EC2RescueInstanceType**，为 EC2Rescue 实例指定实例类型。默认的实例类型为 `t2.medium`。

   1. 对于 **AutomationAssumeRole**，如果您通过使用本主题前面介绍的 CloudFormation 过程为此自动化创建了角色，则选择您在 CloudFormation 控制台中创建的 AssumeRole 的 ARN。

   1. （可选）如果在排查实例故障时需要收集操作系统级别的日志，请为 **LogDestination** 指定 S3 存储桶。日志会自动上传到此指定存储桶。

   1. 对于 **SubnetId**，指定无法访问实例所在可用区中某个现有 VPC 的子网。默认情况下，Systems Manager 会新建一个 VPC，但您可以根据需要指定现有 VPC 中的某个子网。
**注意**  
如果未看到指定存储桶或子网 ID 的选项，请确认使用的是不是运行手册的最新**默认**版本。

1. （可选）在**标签**区域，应用一个或多个标签键名称/值对以帮助识别自动化，例如 `Key=Purpose,Value=EC2Rescue`。

1. 选择**执行**。

运行手册创建一个备份 AMI，作为自动化的一部分。自动化创建的所有其他资源都会自动删除，但此 AMI 将保留在您的账户中。此 AMI 遵从以下命名约定：

备份 AMI：AWSSupport-EC2Rescue:*UnreachableInstanceId*

在 Amazon EC2 控制台中，可以通过搜索自动化执行 ID 查找此 AMI。

# 在 EC2 实例上重置密码和 SSH 密钥


您可以使用 `AWSSupport-ResetAccess` 运行手册在适用于 Windows Server 的 Amazon Elastic Compute Cloud（Amazon EC2）实例上自动重新启用本地管理员密码生成，以及在适用于 Linux 的 EC2 实例上生成新的 SSH 密钥。`AWSSupport-ResetAccess` 运行手册旨在执行 AWS Systems Manager 操作、AWS CloudFormation 操作和 AWS Lambda 函数的组合，从而将重置本地管理员密码通常所需的步骤自动化。

您可以使用 Automation（AWS Systems Manager 中的一项工具）搭配 `AWSSupport-ResetAccess` 运行手册来解决以下问题：

**Windows**

*您丢失了 EC2 密钥对*：要解决此问题，您可以使用 **AWSSupport-ResetAccess** 运行手册，从当前实例创建启用了密码的 AMI，从 AMI 启动新实例，然后选择您拥有的密钥对。

*您丢失了本地管理员密码*：要解决此问题，您可以使用 `AWSSupport-ResetAccess` 运行手册生成可以使用当前 EC2 密钥对解密的一个新密码。

**Linux**

*您丢失了 EC2 密钥对，或者配置了对实例的 SSH 访问但丢失*：要解决此问题，您可以使用 `AWSSupport-ResetAccess` 运行手册创建当前实例的新 SSH 密钥，这使您能够重新连接到该实例。

**注意**  
如果适用于 Windows Server 的 EC2 实例针对 Systems Manager 进行了配置，也可以使用 EC2Rescue 和 AWS Systems Manager Run Command 重置您的本地管理员密码。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[将 EC2Rescue for Windows Server 与 Systems Manager Run Command 结合使用](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2rw-ssm.html)。

**相关信息**  
《Amazon EC2 用户指南》**中的[使用 PuTTY 从 Windows 连接到 Linux 实例](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html)。

## 工作原理


使用自动化和 `AWSSupport-ResetAccess` 运行手册进行故障排除的工作原理如下：
+ 您指定实例的 ID 并运行运行手册。
+ 系统创建一个临时 VPC，然后运行一系列 Lambda 函数以配置该 VPC。
+ 系统在与您的原始实例相同的可用区内为您的临时 VPC 标识一个子网。
+ 系统启动一个临时的启用了 SSM 的 帮助程序实例。
+ 系统停止您的原始实例并创建备份。然后，它将原始根卷附加到帮助程序实例。
+ 系统使用 Run Command 在帮助程序实例上运行 EC2Rescue。在 Windows 上，EC2Rescue 通过在附加的原始根卷上使用 EC2Config 或 EC2Launch 为本地管理员启用密码生成。在 Linux 上，EC2Rescue 生成并注入新的 SSH 密钥并将私有密钥加密保存到 Parameter Store 中。完成后，EC2Rescue 重新将根卷附加回原始实例。
+ 系统根据您的实例创建新 Amazon Machine Image (AMI)，现在密码生成已启用。您可以使用此 AMI 创建新 EC2 实例，并根据需要关联新密钥对。
+ 系统重启您的原始实例，并终止临时实例。系统也将终止临时 VPC 和在自动化开始时创建的 Lambda 函数。
+ **Windows**：您的实例生成一个新密码，您可以使用分配给实例的当前密钥对从 Amazon EC2 控制台对该密码进行解码。

  **Linux**：您可以使用存储在 Systems Manager Parameter Store 中的 SSH 密钥（格式为 **/ec2rl/openssh/*instance ID*/key**）通过 SSH 连接到实例。

## 开始前的准备工作


运行以下自动化之前，请执行以下操作：
+ 复制要重置管理员密码的实例的实例 ID。您将在过程中指定此 ID。
+ (可选) 收集无法访问实例所在可用区中子网的 ID。EC2Rescue 实例将在此子网中创建。如果不指定子网，自动化会在您的 AWS 账户中创建新建一个临时 VPC。验证您的 AWS 账户是否至少有一个可用 VPC。默认情况下，一个区域中可以创建 5 个 VPC。如果您已在该区域中创建 5 个 VPC，自动化将会失败，但不会对您的实例进行更改。有关 Amazon VPC 配额的更多信息，请参阅 *Amazon VPC 用户指南*中的 [VPC 和子网](https://docs.aws.amazon.com/vpc/latest/userguide/amazon-vpc-limits.html#vpc-limits-vpcs-subnets)。
+ 或者，您可以为自动化创建并指定一个 AWS Identity and Access Management (IAM) 角色。如果您不指定此角色，自动化将在运行自动化的用户的环境中运行。

### 向 AWSSupport-EC2Rescue 授予在您的实例上执行操作的权限


在自动化期间，EC2Rescue 需要权限才能在您的实例上执行一系列操作。这些操作调用 AWS Lambda、IAM 和 Amazon EC2 服务，安全地尝试修复实例的问题。如果您在 AWS 账户 和/或 VPC 中具有管理员级权限，您可能能够在不按照本部分中所述配置权限的情况下运行自动化。如果您没有管理员级权限，则您或管理员必须使用以下选项之一配置权限。
+ [使用 IAM policy 授予权限](#automation-ec2reset-access-iam)
+ [使用 CloudFormation 模板授予权限](#automation-ec2reset-access-cfn)

#### 使用 IAM policy 授予权限


您可以将以下 IAM policy 作为内联策略附加到您的用户、组或角色；也可以创建新的 IAM 托管策略，并将其附加到您的用户、组或角色。有关将内联策略添加到您的用户、组或角色的更多信息，请参阅[使用内联策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_inline-using.html)。有关创建新的托管策略的更多信息，请参阅[使用托管策略](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_managed-using.html)。

**注意**  
如果创建新的 IAM 托管式策略，则还必须将 **AmazonSSMAutomationRole** 托管式策略附加到该策略，以便实例与 Systems Manager API 通信。

**`AWSSupport-ResetAccess` 的 IAM policy**

将 *account ID* 替换为您自己的信息。

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "lambda:InvokeFunction",
                "lambda:DeleteFunction",
                "lambda:GetFunction"
            ],
            "Resource": "arn:aws:lambda:*:111122223333:function:AWSSupport-EC2Rescue-*",
            "Effect": "Allow"
        },
        {
            "Action": [
                "s3:GetObject",
                "s3:GetObjectVersion"
            ],
            "Resource": [
                "arn:aws:s3:::awssupport-ssm.*/*.template",
                "arn:aws:s3:::awssupport-ssm.*/*.zip"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "iam:CreateRole",
                "iam:CreateInstanceProfile",
                "iam:GetRole",
                "iam:GetInstanceProfile",
                "iam:PutRolePolicy",
                "iam:DetachRolePolicy",
                "iam:AttachRolePolicy",
                "iam:PassRole",
                "iam:AddRoleToInstanceProfile",
                "iam:RemoveRoleFromInstanceProfile",
                "iam:DeleteRole",
                "iam:DeleteRolePolicy",
                "iam:DeleteInstanceProfile"
            ],
            "Resource": [
                "arn:aws:iam::111122223333:role/AWSSupport-EC2Rescue-*",
                "arn:aws:iam::111122223333:instance-profile/AWSSupport-EC2Rescue-*"
            ],
            "Effect": "Allow"
        },
        {
            "Action": [
                "lambda:CreateFunction",
                "ec2:CreateVpc",
                "ec2:ModifyVpcAttribute",
                "ec2:DeleteVpc",
                "ec2:CreateInternetGateway",
                "ec2:AttachInternetGateway",
                "ec2:DetachInternetGateway",
                "ec2:DeleteInternetGateway",
                "ec2:CreateSubnet",
                "ec2:DeleteSubnet",
                "ec2:CreateRoute",
                "ec2:DeleteRoute",
                "ec2:CreateRouteTable",
                "ec2:AssociateRouteTable",
                "ec2:DisassociateRouteTable",
                "ec2:DeleteRouteTable",
                "ec2:CreateVpcEndpoint",
                "ec2:DeleteVpcEndpoints",
                "ec2:ModifyVpcEndpoint",
                "ec2:Describe*"
            ],
            "Resource": "*",
            "Effect": "Allow"
        }
    ]
}
```

------

#### 使用 CloudFormation 模板授予权限


CloudFormation 使用预配置模板自动化创建 IAM 角色和策略的过程。使用 CloudFormation，通过以下过程为 EC2Rescue 自动化创建所需的 IAM 角色和策略。

**为 EC2Rescue 创建所需的 IAM 角色和策略**

1. 下载 [https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWSSupport-EC2RescueRole.zip](https://docs.aws.amazon.com/systems-manager/latest/userguide/samples/AWSSupport-EC2RescueRole.zip) 文件并将 `AWSSupport-EC2RescueRole.json` 解压到本地计算机上的目录。

1. 如果您的 AWS 账户是一个特殊分区，请编辑模板以将 ARN 值更改为您的分区的值。

   例如，对于中国地区，将出现的所有 `arn:aws` 更改为 `arn:aws-cn`。

1. 登录到 AWS 管理控制台 并打开 CloudFormation 控制台 [https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)。

1. 依次选择**创建堆栈**和**使用新资源（标准）**。

1. 在**创建堆栈**页面上，对于**先决条件 - 准备模板**，选择**模板已就绪**。

1. 对于**指定模板**，选择**上传模板文件**。

1. 选择**选择文件**，然后进行浏览并从您解压缩 `AWSSupport-EC2RescueRole.json` 文件的目录中选择此文件。

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

1. 在**指定堆栈详细信息**页上，对于**堆栈名称**字段，输入用于标识此堆栈的名称，然后选择**下一步**。

1. （可选）在**标签** 区域，将一个或多个标签键名称/值对应用到堆栈。

   标签是您分配给资源的可选元数据。标签可让您按各种标准（如用途、所有者或环境）对资源进行分类。例如，您可能需要对堆栈进行标记，以确定其运行的任务类型、涉及的目标或其他资源的类型以及其运行的环境。

1. 选择 **Next**（下一步）

1. 在**审核**页面上，审核堆栈详细信息，向下滚动并选择**我确认 CloudFormation 可能创建 IAM 资源**选项。

1. CloudFormation 将持续几分钟显示 **CREATE\$1IN\$1PROGRESS** 状态。创建堆栈后，状态将变为 **CREATE\$1COMPLETE**。您还可以选择刷新图标来检查创建过程的状态。

1. 在堆栈列表中，选择您刚刚创建的堆栈旁边的选项，然后选择**输出**选项卡。

1. 复制**值**。这是 AssumeRole 的 ARN。在运行自动化时，您将指定此 ARN。

## 运行自动化


以下过程介绍如何使用 AWS Systems Manager 控制台运行 `AWSSupport-ResetAccess` 运行手册。

**重要**  
以下自动化执行将停止实例。停止实例可能导致附加的实例存储卷（如果存在）上的数据丢失。如果未关联弹性 IP，停止实例也可能导致公有 IP 更改。要避免这些配置更改，请使用 Run Command 重置访问权限。有关更多信息，请参阅《Amazon EC2 用户指南》**中的[将 EC2Rescue for Windows Server 与 Systems Manager Run Command 结合使用](https://docs.aws.amazon.com/AWSEC2/latest/WindowsGuide/ec2rw-ssm.html)。

**要运行 AWSSupport-ResetAccess Automation，请执行以下操作：**

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

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

1. 选择**执行自动化**。

1. 在**自动化文档**部分中，从列表中选择 **Amazon 所拥有**。

1. 在运行手册列表中，选择 **AWSSupport-ResetAccess** 卡片中的按钮，然后选择**下一步**。

1. 在**执行运行手册**页面上，选择**简单执行**。

1. 在**文档详细信息**部分中，验证**文档版本** 是否设置为最高默认版本。例如，**\$1DEFAULT** 或 **3 (默认值))**。

1. 在**输入参数**部分中，指定以下参数：

   1. 对于 **InstanceID**，指定无法访问实例的 ID。

   1. 对于 **SubnetId**，指定您指定的实例所在可用区中某个现有 VPC 的子网。默认情况下，Systems Manager 会新建一个 VPC，但您可以根据需要指定现有 VPC 中的某个子网。
**注意**  
如果未看到指定子网 ID 的选项，请确认使用的是不是运行手册的最新**默认**版本。

   1. 对于 **EC2RescueInstanceType**，为 EC2Rescue 实例指定实例类型。默认的实例类型为 `t2.medium`。

   1. 对于 **AssumeRole**，如果是使用本主题前面介绍的 CloudFormation 过程为此自动化创建的角色，则指定您在 CloudFormation 控制台记下的 AssumeRole ARN。

1. （可选）在**标签**区域，应用一个或多个标签键名称/值对以帮助识别自动化，例如 `Key=Purpose,Value=ResetAccess`。

1. 选择**执行**。

1. 要监控自动化过程，请选择正在运行的自动化，然后选择**步骤**选项卡。完成自动化后，选择**描述**选项卡，然后选择**查看输出**以查看结果。要查看单个步骤的输出，请选择**步骤**选项卡，然后选择步骤旁的**查看输出**。

运行手册创建一个备份 AMI 和已启用密码的 AMI 作为自动化的一部分。自动化创建的所有其他资源都会自动删除，但这些 AMIs 将保留在您的账户中。这些 AMIs 遵从以下命名约定：
+ 备份 AMI：`AWSSupport-EC2Rescue:InstanceID`
+ 启用了密码的 AMI：AWSSupport-EC2Rescue: Password-enabled AMI from *Instance ID*

可以通过搜索自动化执行 ID 查找这些 AMIs。

对于 Linux，您的实例的新 SSH 私有密钥加密保存到 Parameter Store 中。参数名称为 **/ec2rl/openssh/*instance ID*/key**。

# 使用输入变压器将数据传递到 Automation


此 AWS Systems Manager Automation 教程展示了如何使用 Amazon EventBridge 的输入转换器功能，从实例状态更改事件中提取 Amazon Elastic Compute Cloud (Amazon EC2) 实例的 `instance-id`。Automation 是 AWS Systems Manager 中的一项工具。我们使用输入转换器将该数据作为 `InstanceId` 输入参数传递给 `AWS-CreateImage` 运行手册目标。当任何实例更改为 `stopped` 状态时，均将触发该规则。

有关使用输入转换器的更多信息，请参阅 *Amazon EventBridge 用户指南*中的[教程：使用输入转换器自定义要传递给事件目标的内容](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-input-transformer-tutorial.html)。

**开始前的准备工作**  
验证是否已向 Systems Manager 自动化服务角色添加了 EventBridge 所需的权限和信任策略。有关更多信息，请参阅 *Amazon EventBridge 用户指南*中的[管理 EventBridge 资源访问权限概述](https://docs.aws.amazon.com/eventbridge/latest/userguide/iam-access-control-identity-based-eventbridge.html)。

**将输入转换器与自动化结合使用**

1. 打开位于 [https://console.aws.amazon.com/events/](https://console.aws.amazon.com/events/) 的 Amazon EventBridge 控制台。

1. 在导航窗格中，选择**规则**。

1. 选择**创建规则**。

1. 为规则输入名称和描述。

   规则不能与同一区域中的另一个规则和同一事件总线上的名称相同。

1. 对于**事件总线**，请选择要与此规则关联的事件总线。如果您希望此规则响应来自您自己的 AWS 账户的匹配事件，请选择 **defaul**（默认）。当您账户中的某个 AWS 服务发出一个事件时，它始终会发送到您账户的默认事件总线。

1. 对于**规则类型**，选择**具有事件模式的规则**。

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

1. 对于**事件源**，选择**AWS 事件或 EventBridge 合作伙伴事件**。

1. 在**事件模式**部分，选择**使用模式表单**。

1. 对于 **Event source**（事件源），选择 **AWS services**（服务）。

1. 在 **AWS service**（服务）中，选择 **EC2**。

1. 对于**事件类型**，请选择 **EC2 实例状态更改通知**。

1. 对于**事件类型规范 1**，选择**特定状态**，然后选择**已停止**。

1. 对于**事件类型规范 2**，选择**任何实例**，或选择**特定实例 ID** 并输入要监控的实例的 ID。

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

1. 对于**目标类型**，选择**AWS 服务**。

1. 对于 **Target**（目标），选择 **Systems Manager Automation**。

1. 对于 **Document**（文档），选择 **AWS-CreateImage**。

1. 在 **Configure automation parameter(s)**（配置自动化参数）部分中，选择 **Input Transformer**（输入转换器）。

1. 对于 **Input path**（输入路径），输入 **\$1"instance":"\$1.detail.instance-id"\$1**。

1. 对于 **Template**（模板），输入 **\$1"InstanceId":[<instance>]\$1**。

1. 对于 **Execution role**（执行角色），选择 **Use existing role**（使用现有角色），然后选择您的自动化服务角色。

1. 选择 **Next（下一步）**。

1. （可选）为规则输入一个或多个标签。有关更多信息，请参阅 *Amazon EventBridge 用户指南*中的[标记 Amazon EventBridge 资源](https://docs.aws.amazon.com/eventbridge/latest/userguide/eventbridge-tagging.html)。

1. 选择 **Next（下一步）**。

1. 查看规则详细信息并选择**创建规则**。

# 了解 Systems Manager Automation 返回的状态


AWS Systems Manager自动化报告有关运行自动化时自动化操作或步骤所经历的各种状态的详细状态信息，以及整体自动化的同类信息。Automation 是 AWS Systems Manager 中的一项工具。您可以使用以下方法监视自动化状态。
+ 在 Systems Manager 自动化控制台中监控**执行状态**。
+ 使用您的首选命令行工具。对于 AWS Command Line Interface(AWS CLI），您可以使用 [describe-automation-step-executions](https://docs.aws.amazon.com/cli/latest/reference/ssm/describe-automation-step-executions.html) 或 [get-automation-execution](https://docs.aws.amazon.com/cli/latest/reference/ssm/get-automation-execution.html)。对于 AWS Tools for Windows PowerShell，您可以使用 [Get-SSMAutomationStepExecution](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-SSMAutomationStepExecution.html) 或 [Get-SSMAutomationExecution](https://docs.aws.amazon.com/powershell/latest/reference/items/Get-SSMAutomationExecution.html)。
+ 配置 Amazon EventBridge 以响应操作或自动化状态更改。

有关处理自动化中超时的更多信息，请参阅[处理运行手册中的超时](automation-handling-timeouts.md)。

## 关于自动化状态


除了整体自动化之外，自动化还会报告单个自动化操作的状态详细信息。

整体自动化状态可能不同于单个操作或步骤报告的状态，如下表所述。


**操作的详细状态**  

| Status | Details | 
| --- | --- | 
| 待处理 | 该步骤尚未开始运行。如果自动化使用条件操作，则在自动化完成后，如果运行步骤的条件未满足，步骤将保持此状态。如果在步骤运行之前取消了自动化，则步骤也会保持此状态。 | 
| InProgress | 步骤正在运行。 | 
| IN LIST | 步骤正在等待输入。 | 
| 成功 | 步骤成功完成。这是最终状态。 | 
| 超时 | 步骤或批准未在指定的超时期限之前完成。这是最终状态。 | 
| 正在取消 | 请求者取消步骤后，该步骤正在停止。 | 
| 已取消 | 该步骤在完成之前已由请求者停止。这是最终状态。 | 
| 已失败 |  该步骤未成功完成。这是最终状态。  | 
| Exited |  仅通过 `aws:loop` 操作返回。循环未完全完成。使用 `nextStep`、`onCancel` 或 `onFailure` 属性将循环内的步骤移至外部步骤。  | 


**自动化的详细状态**  

| Status | Details | 
| --- | --- | 
| 待处理 | 自动化尚未开始运行。 | 
| InProgress | 自动化正在运行。 | 
| IN LIST | 自动化正在等待输入。 | 
| 成功 | 已成功完成操作。这是最终状态。 | 
| 超时 | 步骤或批准未在指定的超时期限之前完成。这是最终状态。 | 
| 正在取消 | 请求者取消后，自动化正在停止。 | 
| 已取消 | 自动化在完成之前被请求者停止。这是最终状态。 | 
| 已失败 |  自动化未成功完成。这是最终状态。  | 

# Systems Manager 自动化故障排除


利用以下信息，帮助排查 AWS Systems Manager Automation（AWS Systems Manager 中的一项工具）出现的问题。本主题介绍了依据自动化错误消息解决问题的特定任务。

**Topics**
+ [

## 常见自动化错误
](#automation-trbl-common)
+ [

## 自动化执行无法启动
](#automation-trbl-access)
+ [

## 执行已启动，但是状态为“失败”
](#automation-trbl-exstrt)
+ [

## 执行已启动，但超时
](#automation-trbl-to)

## 常见自动化错误


此部分提供有关常见自动化错误的信息。

### VPC not defined 400


默认情况下，当自动化运行 `AWS-UpdateLinuxAmi` 运行手册或 `AWS-UpdateWindowsAmi` 运行手册时，系统会在默认 VPC (172.30.0.0/16) 中创建一个临时实例。如果您删除了默认 VPC，会收到以下错误：

`VPC not defined 400`

要解决此问题，您必须为 `SubnetId` 输入参数指定值。

## 自动化执行无法启动


如果您没有为自动化正确配置 AWS Identity and Access Management（IAM）角色和策略，自动化可能因拒绝访问错误或担任角色无效错误而失败。

### 拒绝访问


以下示例描述了自动化执行因拒绝访问错误无法启动的情况。

**对 Systems Manager API 的访问被拒绝**  
**错误消息**：`User: user arn isn't authorized to perform: ssm:StartAutomationExecution on resource: document arn (Service: AWSSimpleSystemsManagement; Status Code: 400; Error Code: AccessDeniedException; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)`
+ 可能的原因 1：尝试启动自动化的用户没有调用 `StartAutomationExecution` API 的权限。要解决此问题，请将所需的 IAM policy 附加到用于启动自动化的用户。
+ 可能的原因 2：尝试启动自动化的用户拥有调用 `StartAutomationExecution` API 的权限，但是无权使用特定运行手册来调用该 API。要解决此问题，请将所需的 IAM policy 附加到用于启动自动化的用户。

**由于缺少 PassRole 权限而导致访问被拒**  
**错误消息**：`User: user arn isn't authorized to perform: iam:PassRole on resource: automation assume role arn (Service: AWSSimpleSystemsManagement; Status Code: 400; Error Code: AccessDeniedException; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)`

尝试启动自动化的 IAM 用户没有担任角色所需的 PassRole 权限。要解决此问题，请将 iam:PassRole 策略附加到尝试启动自动化的用户的角色。有关更多信息，请参阅 [任务 2：将 iam:PassRole 策略附加到您的自动化角色](automation-setup-iam.md#attach-passrole-policy)。

### 担任角色无效


运行自动化时，要么在运行手册中提供担任角色，要么将担任角色作为运行手册的一个参数值传递。如果未指定或未正确配置担任角色，可出现不同类型的错误。

**担任角色格式错误**  
**错误消息**：`The format of the supplied assume role ARN isn't valid.`担任角色格式不正确。要解决该问题，请验证运行手册中是否指定了有效的担任角色，或者在启动自动化时指定为运行时的参数。

**无法担任担任角色**  
**错误消息**：`The defined assume role is unable to be assumed. (Service: AWSSimpleSystemsManagement; Status Code: 400; Error Code: InvalidAutomationExecutionParametersException; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)`
+ 可能的原因 1：担任角色不存在。要解决该问题，请创建角色。有关更多信息，请参阅 [设置自动化](automation-setup.md)。创建此角色的特定详细信息在以下主题中介绍 [任务 1：为自动化创建服务角色](automation-setup-iam.md#create-service-role)。
+ 可能的原因 2：担任角色没有与 Systems Manager 服务的信任关系。要解决该问题，请创建信任关系。有关更多信息，请参阅 *《IAM 用户指南》*中的[我无法担任角色](https://docs.aws.amazon.com/IAM/latest/UserGuide/troubleshoot_roles.html#troubleshoot_roles_cant-assume-role)。

## 执行已启动，但是状态为“失败”


### 操作特定的失败


运行手册包含步骤，并且步骤按顺序运行。每个步骤会调用一项或多项 AWS 服务 API。API 可确定本步的输入、行为和输出。在多个位置错误可能导致步骤失败。失败消息指示出现错误的时间和位置。

要查看 Amazon Elastic Compute Cloud (Amazon EC2) 控制台中的失败消息，请选择失败步骤的**查看输出**链接。要查看 AWS CLI 中的失败消息，请调用 `get-automation-execution` 并查找失败的 `StepExecution` 中的 `FailureMessage` 属性。

在以下示例中，与 `aws:runInstance` 操作相关联的步骤失败。每个示例探讨了不同类型的错误。

**缺少映像**  
**错误消息**：`Automation Step Execution fails when it's launching the instance(s). Get Exception from RunInstances API of ec2 Service. Exception Message from RunInstances API: [The image id '[ami id]' doesn't exist (Service: AmazonEC2; Status Code: 400; Error Code: InvalidAMIID.NotFound; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)]. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`

`aws:runInstances` 操作收到的 `ImageId` 输入不存在。要解决该问题，请用正确的 AMI ID 更新运行手册或参数值。

**担任角色策略缺少足够的权限**  
**错误消息**：`Automation Step Execution fails when it's launching the instance(s). Get Exception from RunInstances API of ec2 Service. Exception Message from RunInstances API: [You aren't authorized to perform this operation. Encoded authorization failure message: xxxxxxx (Service: AmazonEC2; Status Code: 403; Error Code: UnauthorizedOperation; Request ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)]. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`

担任角色的权限不足，无法在 EC2 实例上调用 `RunInstances` API。要解决此问题，请将 IAM policy 附加到有权调用 `RunInstances` API 的担任角色。有关更多信息，请参阅[使用控制台为 Automation 创建服务角色](automation-setup-iam.md)。

**意外状态**  
**错误消息**：`Step fails when it's verifying launched instance(s) are ready to be used. Instance i-xxxxxxxxx entered unexpected state: shutting-down. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`
+ 可能的原因 1：实例或 Amazon EC2 服务有问题。要解决此问题，请登录到实例或查阅实例系统日志以了解实例启动关闭的原因。
+ 可能的原因 2：为 `aws:runInstances` 操作指定的用户数据脚本有问题或语法错误。验证用户数据脚本的语法。另外，请验证用户数据脚本是否未关闭实例，或者调用了关闭该实例的其他脚本。

**操作特定失败参考**  
如果步骤失败，失败消息可能指示失败时正在调用哪个服务。下表列出每个操作调用的服务。该表还提供指向有关每个服务的信息的链接。


****  

| Action | 此操作调用的 AWS 服务 | 有关此服务的信息 | 排查内容问题 | 
| --- | --- | --- | --- | 
|  `aws:runInstances`  |  Amazon EC2  |  [Amazon EC2 用户指南](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/)  |  [EC2 实例故障排除](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-troubleshoot.html)  | 
|  `aws:changeInstanceState`  |  Amazon EC2  |  [Amazon EC2 用户指南](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/)  |  [EC2 实例故障排除](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-troubleshoot.html)  | 
|  `aws:runCommand`  |  Systems Manager  |   [AWS Systems Manager Run Command](run-command.md)  |   [对 Systems Manager Run Command 进行故障排除](troubleshooting-remote-commands.md)  | 
|  `aws:createImage`  |  Amazon EC2  |  [https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html)  |  | 
|  `aws:createStack`  |  CloudFormation  |  [《AWS CloudFormation 用户指南》](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)  |  [CloudFormation 问题排查](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html)  | 
|  `aws:deleteStack`  |  CloudFormation  |  [《AWS CloudFormation 用户指南》](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)  |  [CloudFormation 问题排查](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/troubleshooting.html)  | 
|  `aws:deleteImage`  |  Amazon EC2  |  [亚马逊机器映像](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html)  |  | 
|  `aws:copyImage`  |  Amazon EC2  |  [https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html)  |  | 
|  `aws:createTag`  |  Amazon EC2，Systems Manager  |  [EC2 资源和标签](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EC2_Resources.html)  |  | 
|  `aws:invokeLambdaFunction`  |  AWS Lambda  |  [AWS Lambda 开发人员指南](https://docs.aws.amazon.com/lambda/latest/dg/)  |  [Lambda 故障排除](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions.html)  | 

### 自动化服务内部错误


**错误消息**：`Internal Server Error. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`

自动化 服务中的一个问题导致指定运行手册无法正确运行。要解决此问题，请联系 AWS 支持。请提供执行 ID 和客户 ID (如果有)。

## 执行已启动，但超时


**错误消息**：`Step timed out while step is verifying launched instance(s) are ready to be used. Please refer to Automation Service Troubleshooting Guide for more diagnosis details.`

`aws:runInstances` 操作中的步骤超时。如果运行本步骤操作所花的时间超出此步骤中为 `timeoutSeconds` 指定的值，就会发生这种情况。要解决此问题，请为 `aws:runInstances` 操作中的 `timeoutSeconds` 参数指定更长的值。如果不能解决问题，请调查步骤运行时间超出预期的原因