

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# Image Builder 如何使用 AWS Task Orchestrator and Executor 应用程序管理组件
<a name="toe-component-manager"></a>

EC2 Image Builder 使用 AWS Task Orchestrator and Executor (AWSTOE) 应用程序来编排复杂的工作流程、修改系统配置和测试映像，而无需额外的 devops 脚本或代码。此应用程序管理和运行使用其声明性文档架构的组件。

AWSTOE 是一个独立的应用程序，当您创建映像时，Image Builder 会将其安装在其构建和测试实例上。您也可以将其手动安装在 EC2 实例上，以创建自己的自定义组件。它不需要任何其他设置，也可以在本地运行。

**Topics**
+ [AWSTOE 下载](#toe-downloads)
+ [支持的区域](#toe-supported-regions)
+ [AWSTOE 命令参考](#toe-commands)
+ [手动设置以开发自定义组件 AWSTOE](toe-get-started.md)
+ [使用 AWSTOE 组件文档框架创建自定义组件](toe-use-documents.md)
+ [AWSTOE 组件管理器支持的操作模块](toe-action-modules.md)
+ [配置 AWSTOE 运行命令的输入](toe-run-config-input.md)

## AWSTOE 下载
<a name="toe-downloads"></a>

要安装 AWSTOE，请选择适用于您的架构和平台的下载链接。如果您连接到服务的 VPC 终端节点（例如 Image Builder），则该终端节点必须附加自定义终端节点策略，其中包括访问 S3 存储桶进行 AWSTOE 下载的权限。否则，您的构建和测试实例将无法下载引导脚本 (`bootstrap.sh`) 并安装 AWSTOE 应用程序。有关更多信息，请参阅 [为 Image Builder 创建 VPC 端点策略](vpc-interface-endpoints.md#vpc-endpoint-policy)。

**重要**  
AWS 正在逐步取消对 TLS 版本 1.0 和 1.1 的支持。要访问 S3 存储桶进行 AWSTOE 下载，您的客户端软件必须使用 TLS 版本 1.2 或更高版本。有关更多信息，请参阅[AWS 此博客文章](https://aws.amazon.com/blogs/security/tls-1-2-required-for-aws-endpoints/)。


| 架构 | 平台 | 下载链接 | 示例 | 
| --- | --- | --- | --- | 
| 386 |  AL 2 和 2023 RHEL 7、8 和 9 Ubuntu 16.04、18.04、20.04、22.04 和 24.04 CentOS 7 和 8 SUSE 12 和 15  | `https://awstoe-<region>.s3.<region>.amazonaws.com/latest/linux/386/awstoe`  | [https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/linux/386/awstoe](https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/linux/386/awstoe) | 
| AMD64 |  AL 2 和 2023 RHEL 7、8 和 9 Ubuntu 16.04、18.04、20.04、22.04 和 24.04 CentOS 7 和 8 CentOS Stream 8 SUSE 12 和 15  | https://awstoe-<region>.s3.<region>.amazonaws.com/latest/linux/amd64/awstoe | [https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/linux/amd64/awstoe](https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/linux/amd64/awstoe) | 
| AMD64 |  macOS 10.14.x (Mojave)、10.15.x (Catalina)、11.x (Big Sur)、12.x (Monterey)  | https://awstoe-region.s3.region.amazonaws.com/latest/darwin/amd64/awstoe | [https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/darwin/amd64/awstoe](https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/darwin/amd64/awstoe) | 
|  AMD64  |  Windows Server 2012 R2、2016、2019 和 2022  |   `https://awstoe-<region>.s3.<region>.amazonaws.com/latest/windows/amd64/awstoe.exe`  | [https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/windows/amd64/awstoe.exe](https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/windows/amd64/awstoe.exe) | 
| ARM64 |  AL 2 和 2023 RHEL 7、8 和 9 Ubuntu 16.04、18.04、20.04、22.04 和 24.04 CentOS 7 和 8 CentOS Stream 8 SUSE 12 和 15  | https://awstoe-<region>.s3.<region>.amazonaws.com/latest/linux/arm64/awstoe | [https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/linux/arm64/awstoe](https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/linux/arm64/awstoe) | 

## 支持的区域
<a name="toe-supported-regions"></a>

AWSTOE 在以下区域支持作为独立应用程序。


| AWS 区域 名字 | AWS 区域 | 
| --- | --- | 
|  美国东部（俄亥俄州）  |  us-east-2  | 
|  美国东部（弗吉尼亚州北部）  |  us-east-1  | 
|  AWS GovCloud （美国东部）  |  us-gov-east-1  | 
|  AWS GovCloud （美国西部）  |  us-gov-west-1  | 
|  美国西部（加利福尼亚北部）  | us-west-1 | 
|  美国西部（俄勒冈州）  | us-west-2 | 
|  非洲（开普敦）  | af-south-1 | 
|  亚太地区（香港）  | ap-east-1 | 
|  亚太地区（大阪）  | ap-northeast-3 | 
|  亚太地区（首尔）  | ap-northeast-2 | 
|  亚太地区 (孟买)  | ap-south-1 | 
|  亚太地区（海得拉巴）  | ap-south-2 | 
|  亚太地区（新加坡）  | ap-southeast-1 | 
|  亚太地区（悉尼）  | ap-southeast-2 | 
|  亚太地区（雅加达）  | ap-southeast-3 | 
|  亚太地区（东京）  | ap-northeast-1 | 
|  加拿大（中部）  | ca-central-1 | 
|  欧洲地区（法兰克福）  | eu-central-1 | 
|  欧洲（苏黎世）  | eu-central-2 | 
|  欧洲地区（斯德哥尔摩）  | eu-north-1 | 
|  欧洲（米兰）  | eu-south-1 | 
|  欧洲（西班牙）  | eu-south-2 | 
|  欧洲地区（爱尔兰）  | eu-west-1 | 
|  欧洲地区（伦敦）  | eu-west-2 | 
|  欧洲地区（巴黎）  | eu-west-3 | 
|  以色列（特拉维夫）  | il-central-1 | 
|  中东（阿联酋）  | me-central-1 | 
|  中东（巴林）  | me-south-1 | 
|  南美洲（圣保罗）  | sa-east-1 | 
|  中国（北京）  | cn-north-1 | 
|  中国（宁夏）  | cn-northwest-1 | 

## AWSTOE 命令参考
<a name="toe-commands"></a>

AWSTOE 是一款在 Amazon EC2 实例上运行的命令行组件管理应用程序。当 Image Builder 启动 EC2 构建或测试实例时，它会安装在该实例 AWSTOE 上。然后，它会在中运行 AWSTOE 命令 AWS CLI 来安装或验证镜像或容器配方中指定的组件。

**注意**  
某些 AWSTOE 操作模块需要更高的权限才能在 Linux 服务器上运行。要使用提升的权限，请在命令语法前加上前缀 **sudo**，或者在登录时运行 **sudo su** 命令，然后再运行下面链接的命令。有关 AWSTOE 操作模块的更多信息，请参见[AWSTOE 组件管理器支持的操作模块](toe-action-modules.md)。

***[运行](#cmd-run)***  
使用 **run** 命令为一个或多个组件文档运行 YAML 文档脚本。

***[验证](#cmd-validate)***  
使用 **validate** 命令为一个或多个组件文档验证 YAML 文档语法。

### awstoe run command
<a name="cmd-run"></a>

该命令按 `--config` 参数指定的配置文件或 `--documents` 参数指定的组件文档列表中 YAML 组件文档脚本的内置顺序运行 YAML 组件文档脚本。

**注意**  
您必须准确指定下列参数之一，切勿同时指定两个参数：  
--config  
--documents

#### 语法
<a name="run-syntax"></a>

```
awstoe run [--config <file path>] [--cw-ignore-failures <?>] 
      [--cw-log-group <?>] [--cw-log-region us-west-2] [--cw-log-stream <?>] 
      [--document-s3-bucket-owner <owner>] [--documents <file path,file path,...>] 
      [--execution-id <?>] [--log-directory <file path>] 
      [--log-s3-bucket-name <name>] [--log-s3-bucket-owner <owner>] 
      [--log-s3-key-prefix <?>] [--parameters name1=value1,name2=value2...] 
      [--phases <phase name>] [--state-directory <directory path>] [--version <?>] 
      [--help] [--trace]
```

#### 参数和选项
<a name="run-parameters"></a>参数

**config*`./config-example.json`***  
简写形式：-c *`./config-example.json`*  
配置文件*（条件性）*。此参数包含 JSON 文件的文件位置，该文件包含此命令正在运行的组件的配置设置。如果在配置文件中指定 **run** 命令设置，则不得指定 `--documents` 参数。有关输入配置的更多信息，请参阅 [配置 AWSTOE 运行命令的输入](toe-run-config-input.md)。  
有效位置包括：  
+ 本地文件路径 (*`./config-example.json`*)
+ 一个 S3; URI。(`s3://bucket/key`)

**--cw-ignore-failures**  
简写形式：不适用  
忽略日志中的 CloudWatch 日志失败。

**--cw-log-group**  
简写形式：不适用  
 CloudWatch 日志的`LogGroup`名称。

**--cw-log-region**  
简写形式：不适用  
适用于 CloudWatch 日志的 AWS 区域。

**--cw-log-stream**  
简写形式：不适用  
 CloudWatch 日志的`LogStream`名称，用于指示将`console.log`文件传输到 AWSTOE 何处。

**--document-s3-bucket-owner**  
简写形式：不适用  
基于 S3 URI 的文档的存储桶拥有者账户 ID。

**--文档 *`./doc-1.yaml`,`./doc-n.yaml`***  
简写形式：-d *`./doc-1.yaml`*,*`./doc-n`*  
组件文档*（条件性）*。此参数包含以逗号分隔的文件位置列表，以供运行 YAML 组件文档。如果您使用 `--documents` 参数为 **run** 命令指定 YAML 文档，则不得指定 `--config` 参数。  
有效位置包括：  
+ 本地文件路径 (*./component-doc-example.yaml*)。
+ S3 URIs (`s3://bucket/key`)。
+ Image Builder 组件构建版本 ARNs （arn: aws: imagebuilder: us-west--: component/ /2021.12.02/1）。*2:123456789012* *my-example-component*
列表中的项目之间没有空格，只有逗号。

**--execution-id**  
简写形式：-i  
这是适用于执行当前 **run** 命令的唯一 ID。此 ID 包含在输出和日志文件名中，用于唯一标识这些文件，并将它们链接到当前的命令执行。如果省略此设置，则 AWSTOE 生成 GUID。

**--log-directory**  
简写形式：-l  
 AWSTOE 存储此命令执行的所有日志文件的目标目录。默认情况下，该目录位于以下父目录中：`TOE_<DATETIME>_<EXECUTIONID>`。如果未指定日志目录，则 AWSTOE 使用当前工作目录 (`.`)。

**--log-s3-bucket-name**  
简写形式：-b  
如果组件日志存储在 Amazon S3 中（推荐），则将组件应用程序日志 AWSTOE 上传到此参数中命名的 S3 存储桶。

**--log-s3-bucket-owner**  
简写形式：不适用  
如果组件日志存储在 Amazon S3 中（推荐），则这是 AWSTOE 写入日志文件的存储桶的所有者账户 ID。

**--log-s3-key-prefix**  
简写形式：-k  
如果组件日志存储在 Amazon S3 中（推荐），则这是存储桶中日志位置的 S3 对象键前缀。

**--参数 *name1* =*value1*，*name2*=*value2*...**  
简写形式：不适用  
参数是在组建文档中定义的可变变量，其设置由调用应用程序在运行时提供。

**--phases**  
简写形式：-p  
以逗号分隔的列表，它指定要从 YAML 组件文档中运行哪些阶段。如果组件文档包含其他阶段，则这些阶段将无法运行。

**--state-directory**  
简写形式：-s  
存储状态跟踪文件的文件路径。

**--version**  
简写形式：-v  
指定组件应用程序版本。选项

**--help**  
简写形式：-h  
显示使用组件管理应用程序选项的帮助手册。

**--trace**  
简写形式：-t  
启用对控制台的详细日志记录。

### awstoe validate command
<a name="cmd-validate"></a>

运行此命令时，它会验证 `--documents` 参数指定的每个组件文档的 YAML 文档语法。

#### 语法
<a name="validate-syntax"></a>

```
awstoe validate [--document-s3-bucket-owner <owner>] 
      --documents <file path,file path,...> [--help] [--trace]
```

#### 参数和选项
<a name="validate-parameters"></a>参数

**--document-s3-bucket-owner**  
简写形式：不适用  
提供的基于 S3 URI 的文档源账户 ID。

**--文档 *`./doc-1.yaml`,`./doc-n.yaml`***  
简写形式：-d *`./doc-1.yaml`*,*`./doc-n`*  
组件文档*（必填）*。此参数包含以逗号分隔的文件位置列表，以供运行 YAML 组件文档。有效位置包括：  
+ 本地文件路径 (*./component-doc-example.yaml*)
+ S3 URIs (`s3://bucket/key`)
+ Image Builder 组件构建版本 ARNs （arn: aws: imagebuilder: us-west--: component/ /2021.12.02/1）*2:123456789012**my-example-component*
列表中的项目之间没有空格，只有逗号。选项

**--help**  
简写形式：-h  
显示使用组件管理应用程序选项的帮助手册。

**--trace**  
简写形式：-t  
启用对控制台的详细日志记录。

# 手动设置以开发自定义组件 AWSTOE
<a name="toe-get-started"></a>

 AWS Task Orchestrator and Executor (AWSTOE) 应用程序是一个独立的应用程序，用于在组件定义框架内创建、验证和运行命令。 AWS 服务可用于 AWSTOE 协调工作流程、安装软件、修改系统配置和测试映像构建。

按照以下步骤手动安装 AWSTOE 应用程序，并将其用作独立应用程序来开发自定义组件。如果您使用 Image Builder 控制台或 AWS CLI 命令创建自定义组件，Image Builder 会为您完成这些步骤。有关更多信息，请参阅 [使用 Image Builder 创建自定义组件](create-component.md)。

# 验证 AWSTOE 安装下载的签名
<a name="awstoe-verify-sig"></a>

本节介绍在基于 Linux、macOS 和 Windows 的操作系统 AWSTOE 上验证安装下载的有效性的推荐流程。

**Topics**
+ [在 Linux 或 macOS 上验证 AWSTOE 安装下载的签名](#awstoe-verify-sig-linux)
+ [在 Windows 上验证 AWSTOE 安装下载的签名](#awstoe-verify-sig-win)

## 在 Linux 或 macOS 上验证 AWSTOE 安装下载的签名
<a name="awstoe-verify-sig-linux"></a>

本主题介绍验证基于 Linux 或 macOS 操作系统的安装下载有效性的推荐流程。 AWSTOE 

无论何时从 Internet 下载应用程序，我们都建议您验证软件发布者的身份。另外，请检查应用程序自发布以来是否未被更改或损坏。这会保护您免于安装含有病毒或其他恶意代码的应用程序版本。

如果您在执行本主题中的步骤后确定适用于 AWSTOE 应用程序的软件已遭更改或损坏，请不要运行安装文件。相反，请联系 支持 。有关您的支持选项的更多信息，请参阅[支持](https://aws.amazon.com/premiumsupport/)。

AWSTOE 基于 Linux 和 macOS 操作系统的文件是使用`GnuPG`安全数字签名的 Pretty Good Privacy (OpenPGP) 标准的开源实现进行签名的。 `GnuPG`（也称为`GPG`）通过数字签名提供身份验证和完整性检查。Amazon EC2 发布了您可用于验证下载的 Amazon EC2 CLI 工具的公钥和签名。有关 `PGP` 和 `GnuPG` (`GPG`) 的更多信息，请参阅 [http://www.gnupg.org](https://www.gnupg.org/)。

第一步是与软件发行商建立信任。下载软件发布者的公有密钥，检查公有密钥的所有人是否真为其人，然后将该公有密钥添加到您的*密钥环*。密钥环是已知公有密钥的集合。验证公有密钥的真实性后，您可以使用它来验证应用程序的签名。

**Topics**
+ [安装 GPG 工具](#awstoe-verify-signature-of-binary-download-install-tools)
+ [验证并导入公有密钥](#awstoe-verify-signature-of-binary-download-authenticate-import-public-key)
+ [验证软件包的签名](#awstoe-verify-signature-of-binary-package)

### 安装 GPG 工具
<a name="awstoe-verify-signature-of-binary-download-install-tools"></a>

如果您的操作系统是 Linux、Unix 或 macOS，GPG 工具很可能已经安装。要测试系统上是否已安装这些工具，请在命令提示符处键入 **gpg**。如果已安装 GPG 工具，您会看到 GPG 命令提示。如果没有安装 GPG 工具，您会看到错误消息，告诉您无法找到命令。您可以从存储库安装 GnuPG 包。

要安装 GPG 工具，请选择与您的实例匹配的操作系统。

------
#### [ Debian-based Linux ]

从终端设备运行以下命令：

```
apt-get install gnupg
```

------
#### [ Red Hat–based Linux ]

从终端设备运行以下命令：

```
yum install gnupg
```

------
#### [ macOS ]

从终端设备运行以下命令：

```
brew install gnupg
```

------

### 验证并导入公有密钥
<a name="awstoe-verify-signature-of-binary-download-authenticate-import-public-key"></a>

该过程的下一步是对 AWSTOE 公钥进行身份验证，并将其作为可信密钥添加到您的密`GPG`钥环中。

**验证和导入 AWSTOE 公钥**

1. 通过执行下列操作之一获取公共 `GPG` 生成密钥的副本：
   + 从以下地址下载密钥：

      https://awstoe-**<region>** .s3。 **<region>**.amazonaws。 com/assets/awstoe.gpg。例如 [https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/assets/awstoe.gpg](https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/assets/awstoe.gpg)。
   + 将以下文本中的密钥复制并粘贴到名为 `awstoe.gpg` 的文件中。确保包含下列所有项：

     ```
     -----BEGIN PGP PUBLIC KEY BLOCK-----
     Version: GnuPG v2
     
     mQENBF8UqwsBCACdiRF2bkZYaFSDPFC+LIkWLwFvtUCRwAHtD8KIwTJ6LVn3fHAU
     GhuK0ZH9mRrqRT2bq/xJjGsnF9VqTj2AJqndGJdDjz75YCZYM+ocZ+r5HSJaeW9i
     S5dykHj7Txti2zHe0G5+W0v7v5bPi2sPHsN7XWQ7+G2AMEPTz8PjxY//I0DvMQns
     Sle3l9hz6wCClz1l9LbBzTyHfSm5ucTXvNe88XX5Gmt37OCDM7vfli0Ctv8WFoLN
     6jbxuA/sV71yIkPm9IYp3+GvaKeT870+sn8/JOOKE/U4sJV1ppbqmuUzDfhrZUaw
     8eW8IN9A1FTIuWiZED/5L83UZuQs1S7s2PjlABEBAAG0GkFXU1RPRSA8YXdzdG9l
     QGFtYXpvbi5jb20+iQE5BBMBCAAjBQJfFKsLAhsDBwsJCAcDAgEGFQgCCQoLBBYC
     AwECHgECF4AACgkQ3r3BVvWuvFJGiwf9EVmrBR77+Qe/DUeXZJYoaFr7If/fVDZl
     6V3TC6p0J0Veme7uXleRUTFOjzbh+7e5sDX19HrnPquzCnzfMiqbp4lSoeUuNdOf
     FcpuTCQH+M+sIEIgPno4PLl0Uj2uE1o++mxmonBl/Krk+hly8hB2L/9n/vW3L7BN
     OMb1Ll9PmgGPbWipcT8KRdz4SUex9TXGYzjlWb3jU3uXetdaQY1M3kVKE1siRsRN
     YYDtpcjmwbhjpu4xm19aFqNoAHCDctEsXJA/mkU3erwIRocPyjAZE2dnlkL9ZkFZ
     z9DQkcIarbCnybDM5lemBbdhXJ6hezJE/b17VA0t1fY04MoEkn6oJg==
     =oyze
     -----END PGP PUBLIC KEY BLOCK-----
     ```

1. 在您保存 **awstoe.gpg** 的目录中的命令提示符处，使用以下命令将 AWSTOE 公钥导入密钥环。

   ```
   gpg --import awstoe.gpg
   ```

   该命令返回的结果类似于下方内容：

   ```
   gpg: key F5AEBC52: public key "AWSTOE <awstoe@amazon.com>" imported
   gpg: Total number processed: 1
   gpg:               imported: 1  (RSA: 1)
   ```

   请记下该键值，因为下一步需要用到。在上一示例中，键值为 `F5AEBC52`。

1. 通过运行以下命令，将 *key-value* 替换为上一步中的值来验证指纹：

   ```
   gpg --fingerprint key-value
   ```

   该命令返回的结果类似于下方内容：

   ```
   pub   2048R/F5AEBC52 2020-07-19
         Key fingerprint = F6DD E01C 869F D639 15E5  5742 DEBD C156 F5AE BC52
   uid       [ unknown] AWSTOE <awstoe@amazon.com>
   ```

   此外，指纹字符串应与上述示例中所示的 `F6DD E01C 869F D639 15E5 5742 DEBD C156 F5AE BC52` 相同。将返回的密钥指纹与此页上发布的指纹进行比较。它们应该相互匹配。如果它们不匹配，请不要安装 AWSTOE 安装脚本，然后与联系 支持。

### 验证软件包的签名
<a name="awstoe-verify-signature-of-binary-package"></a>

在安装 `GPG` 工具、验证并导入 AWSTOE 公有密钥以及确认公有密钥可信后，便可以验证安装脚本的签名。

**验证安装脚本签名**

1. 在命令提示符处，运行以下命令以下载应用程序的二进制文件：

   ```
   curl -O https://awstoe-<region>.s3.<region>.amazonaws.com/latest/linux/<architecture>/awstoe
   ```

   例如：

   ```
   curl -O https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/linux/amd64/awstoe
   ```

   支持的 **architecture** 值可以是 `amd64`、`386` 和 `arm64`。

1. 在命令提示符处，运行以下命令以下载相同的 S3 key prefix 路径中对应的应用程序二进制文件的签名文件：

   ```
   curl -O https://awstoe-<region>.s3.<region>.amazonaws.com/latest/linux/<architecture>/awstoe.sig
   ```

   例如：

   ```
   curl -O https://awstoe-us-east-1.s3.us-east-1.amazonaws.com/latest/linux/amd64/awstoe.sig
   ```

   支持的 **architecture** 值可以是 `amd64`、`386` 和 `arm64`。

1. 通过在您保存的目录`awstoe.sig`和 AWSTOE 安装文件中的命令提示符处运行以下命令来验证签名。这两个文件都必须存在。

   ```
   gpg --verify ./awstoe.sig ~/awstoe
   ```

   输出应与以下内容类似：

   ```
   gpg: Signature made Mon 20 Jul 2020 08:54:55 AM IST using RSA key ID F5AEBC52
   gpg: Good signature from "AWSTOE awstoe@amazon.com" [unknown]
   gpg: WARNING: This key is not certified with a trusted signature!
   gpg:          There is no indication that the signature belongs to the owner.
   Primary key fingerprint: F6DD E01C 869F D639 15E5 5742 DEBD C156 F5AE BC52
   ```

   如果输出包含短语 `Good signature from "AWSTOE <awstoe@amazon.com>"`，则意味着已成功验证签名，您可以继续运行 AWSTOE 安装脚本。

   如果输出包含短语 `BAD signature`，则检查是否正确执行了此过程。如果您持续获得此响应，不要运行之前下载的安装文件，并且请联系 支持。

下面是有关您可能看到的警告的详细信息：
+ **警告：此密钥未使用可信签名进行认证！没有迹象表明签名属于所有者。**理想情况下，您可以亲自前往 AWS 办公室领取钥匙。但最可能的情况是，从网站下载此密钥。在这种情况下，该网站就是一个 AWS 网站。
+ **gpg: no ultimately trusted keys found.** 这意味着您 (或您信任的其他人) 对特定密钥不是“绝对信任”。

有关更多信息，请参阅 [http://www.gnupg.org](http://www.gnupg.org)。

## 在 Windows 上验证 AWSTOE 安装下载的签名
<a name="awstoe-verify-sig-win"></a>

本主题介绍在基于 Windows 的操作系统上验证 AWS Task Orchestrator and Executor 应用程序安装文件有效性的推荐流程。

无论何时从 Internet 下载应用程序，我们都建议您验证软件发布者的身份，并检查应用程序从发行以来是否已遭更改或损坏。这会保护您免于安装含有病毒或其他恶意代码的应用程序版本。

如果您在执行本主题中的步骤后确定适用于 AWSTOE 应用程序的软件已遭更改或损坏，请不要运行安装文件。相反，请联系 支持。

要验证基于 Windows 的操作系统上的已下载 awstoe 二进制文件是否有效，必须确保其 Amazon Services LLC 签署人证书的指纹等于此值：

**9D CA 72 17 DA FF B8 2F E4 C4 67 77 36 2F A4 AA C9 08 82 15**

**注意**  
在新二进制文件的推出窗口期间，您的签署人证书可能与新的指纹不匹配。如果您的签署人证书不匹配，请验证指纹值是否为：  
**BA 81 25 EE AC 64 2E A9 F3 C5 93 CA 6D 3E B7 93 7D 68 75 74**

要验证此值，请执行以下过程：

1. 右键单击下载的 `awstoe.exe`，然后打开 **Properties (属性)** 窗口。

1. 选择**数字签名**选项卡。

1. 在**签名列表 **中，选择 **Amazon Services LLC**，然后选择**详细信息**。

1. 选择**常规**选项卡 (如果尚未选择)，然后选择**查看证书**。

1. 选择**详细信息**选项卡，然后选择**显示**下拉列表中的**全部** (如果尚未选择)。

1. 向下滚动直至您看到**指纹**字段，然后选择**指纹**。这将在下部窗口中显示整个指纹值。
   + 如果下部窗口中的指纹值等于以下值：

     **9D CA 72 17 DA FF B8 2F E4 C4 67 77 36 2F A4 AA C9 08 82 15**

     那么你下载的 AWSTOE 二进制文件是真实的，可以安全地安装。
   + 如果下部详细信息窗口中的指纹值不等于前述值，请不要运行 `awstoe.exe`。

**Topics**
+ [验证 AWSTOE 安装下载的签名](awstoe-verify-sig.md)
+ [步骤 1：安装 AWSTOE](#toe-start-install)
+ [步骤 2：设置 AWS 凭证](#toe-start-credentials)
+ [第 3 步：在本地开发组件文档](#toe-start-develop)
+ [步骤 4：验证 AWSTOE 组件](#toe-start-validate)
+ [步骤 5：运行 AWSTOE 组件](#toe-start-run)

## 步骤 1：安装 AWSTOE
<a name="toe-start-install"></a>

要在本地开发组件，请下载并安装该 AWSTOE 应用程序。

1. 

**下载 AWSTOE 应用程序**

   要进行安装 AWSTOE，请选择适合您的架构和平台的下载链接。有关应用程序下载链接的完整列表，请参阅 [AWSTOE 下载](toe-component-manager.md#toe-downloads)
**重要**  
AWS 正在逐步取消对 TLS 版本 1.0 和 1.1 的支持。要访问 S3 存储桶进行 AWSTOE 下载，您的客户端软件必须使用 TLS 版本 1.2 或更高版本。有关更多信息，请参阅此 [AWS 安全博客文章](https://aws.amazon.com/blogs/security/tls-1-2-required-for-aws-endpoints/)。

1. 

**验证签名**

   验证下载的步骤取决于安装 AWSTOE 应用程序后在其中运行应用程序的服务器平台。要在 Linux 服务器上验证您的下载，请参阅 [在 Linux 或 macOS 上验证签名](awstoe-verify-sig.md#awstoe-verify-sig-linux)。要在 Windows 服务器上验证您的下载，请参阅 [在 Windows 上验证签名](awstoe-verify-sig.md#awstoe-verify-sig-win)。

**注意**  
AWSTOE 直接从其下载位置调用。无需单独执行安装步骤。这也意味着 AWSTOE 可以对本地环境进行更改。  
为确保在组件开发过程中隔离更改，我们建议您使用 EC2 实例来开发和测试 AWSTOE 组件。

## 步骤 2：设置 AWS 凭证
<a name="toe-start-credentials"></a>

 AWSTOE 运行任务时需要 AWS 凭证才能连接到其他任务 AWS 服务，例如 Amazon S3 和 Amazon CloudWatch，例如：
+ 从用户提供的 Amazon S3 路径下载 AWSTOE 文档。
+ 运行 `S3Download` 或 `S3Upload` 操作模块。
+ 启用后 CloudWatch，将日志流式传输到。

如果您 AWSTOE 在 EC2 实例上运行，则运行 AWSTOE 使用的权限与附加到该 EC2 实例的 IAM 角色相同。

有关的 IAM 角色的更多信息 EC2，请参阅适用于 A [mazon 的 IAM 角色EC2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/iam-roles-for-amazon-ec2.html)。

以下示例说明如何使用`AWS_ACCESS_KEY_ID`和`AWS_SECRET_ACCESS_KEY`环境变量设置 AWS 凭证。

要在 Linux、macOS 或 Unix 上设置这些变量，请使用 `export`。

```
export AWS_ACCESS_KEY_ID=your_access_key_id
```

```
export AWS_SECRET_ACCESS_KEY=your_secret_access_key
```

要在 Windows 上使用设置这些变量 PowerShell，请使用`$env`。

```
$env:AWS_ACCESS_KEY_ID=your_access_key_id
```

```
$env:AWS_SECRET_ACCESS_KEY=your_secret_access_key
```

要在 Windows 上使用命令提示设置这些变量，请使用 `set`。

```
set AWS_ACCESS_KEY_ID=your_access_key_id
```

```
set AWS_SECRET_ACCESS_KEY=your_secret_access_key
```

## 第 3 步：在本地开发组件文档
<a name="toe-start-develop"></a>

组件是用纯文本 YAML 文档编写的。有关文档语法的更多信息，请参阅 [使用 AWSTOE 组件文档框架创建自定义组件](toe-use-documents.md)。

以下是 *Hello World* 组件文档示例，可帮助您快速入门。

------
#### [ Linux ]

本指南中的某些 Linux 组件示例引用名为 `hello-world-linux.yml` 的组件文档文件。您可以使用下面的文档来着手这些示例。

```
name: Hello World
description: This is hello world testing document for Linux.
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: HelloWorldStep
        action: ExecuteBash
        inputs:
          commands:
            - echo 'Hello World from the build phase.'
  - name: validate
    steps:
      - name: HelloWorldStep
        action: ExecuteBash
        inputs:
          commands:
            - echo 'Hello World from the validate phase.'
  - name: test
    steps:
      - name: HelloWorldStep
        action: ExecuteBash
        inputs:
          commands:
            - echo 'Hello World from the test phase.'
```

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

本指南中的某些 Windows 组件示例引用名为 `hello-world-windows.yml` 的组件文档文件。您可以使用下面的文档来着手这些示例。

```
name: Hello World
description: This is Hello World testing document for Windows.
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: HelloWorldStep
        action: ExecutePowerShell
        inputs:
          commands:
            - Write-Host 'Hello World from the build phase.'
  - name: validate
    steps:
      - name: HelloWorldStep
        action: ExecutePowerShell
        inputs:
          commands:
            - Write-Host 'Hello World from the validate phase.'
  - name: test
    steps:
      - name: HelloWorldStep
        action: ExecutePowerShell
        inputs:
          commands:
            - Write-Host 'Hello World from the test phase.'
```

------
#### [ macOS ]

本指南中的某些 macOS 组件示例引用名为 `hello-world-macos.yml` 的组件文档文件。您可以使用下面的文档来着手这些示例。

```
name: Hello World
description: This is hello world testing document for macOS.
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: HelloWorldStep
        action: ExecuteBash
        inputs:
          commands:
            - echo 'Hello World from the build phase.'
  - name: validate
    steps:
      - name: HelloWorldStep
        action: ExecuteBash
        inputs:
          commands:
            - echo 'Hello World from the validate phase.'
  - name: test
    steps:
      - name: HelloWorldStep
        action: ExecuteBash
        inputs:
          commands:
            - echo 'Hello World from the test phase.'
```

------

## 步骤 4：验证 AWSTOE 组件
<a name="toe-start-validate"></a>

您可以使用 AWSTOE 应用程序在本地验证 AWSTOE 组件的语法。以下示例显示了无需运行组件即可验证其语法的 AWSTOE 应用程序`validate`命令。

**注意**  
 AWSTOE 应用程序只能验证当前操作系统的组件语法。例如，在 Windows 上运行 `awstoe.exe` 时，您无法验证使用 `ExecuteBash` 操作模块的 Linux 文档的语法。

Linux 或 macOS

```
awstoe validate --documents /home/user/hello-world.yml
```

Windows

```
awstoe.exe validate --documents C:\Users\user\Documents\hello-world.yml
```

## 步骤 5：运行 AWSTOE 组件
<a name="toe-start-run"></a>

 AWSTOE 应用程序可以使用`--phases`命令行参数运行指定文档的一个或多个阶段。`--phases` 支持的值有 `build`、`validate` 和 `test`。可以用逗号分隔的值形式输入多个阶段值。

当您提供阶段列表时， AWSTOE 应用程序会按顺序运行每个文档的指定阶段。例如， AWSTOE 运行的`build`和`validate`阶段`document1.yaml`，然后运行的`build`和`validate`阶段`document2.yaml`。

为了确保您的日志安全存储并保留以供故障排除，我们建议您在 Amazon S3 中配置日志存储。在 Image Builder 中，用于发布日志的 Amazon S3 位置是在基础设施配置中指定的。有关基础设施配置的更多信息，请参阅 [管理 Image Builder 基础设施配置](manage-infra-config.md)

如果未提供阶段列表，则 AWSTOE 应用程序将按照 YAML 文档中列出的顺序运行所有阶段。

要在单个或多个文档中运行特定阶段，请使用以下命令。

单个阶段

```
awstoe run --documents hello-world.yml --phases build
```

多个阶段

```
awstoe run --documents hello-world.yml --phases build,test
```

**文档运行**  
在单个文档中运行所有阶段

```
awstoe run --documents documentName.yaml
```

在多个文档中运行所有阶段

```
awstoe run --documents documentName1.yaml,documentName2.yaml
```

输入 Amazon S3 信息以从用户定义的本地路径上传 AWSTOE 日志（推荐）

```
awstoe run --documents documentName.yaml --log-s3-bucket-name amzn-s3-demo-destination-bucket --log-s3-key-prefix S3KeyPrefix --log-s3-bucket-owner S3BucketOwner --log-directory local_path
```

在单个文档中运行所有阶段，并在控制台上显示所有日志

```
awstoe run --documents documentName.yaml --trace
```

示例命令

```
awstoe run --documents s3://bucket/key/doc.yaml --phases build,validate
```

运行具有唯一 ID 的文档

```
awstoe run --documents documentName.yaml --execution-id user-provided-id --phases build,test
```

获取以下方面的帮助 AWSTOE

```
awstoe --help
```

# 使用 AWSTOE 组件文档框架创建自定义组件
<a name="toe-use-documents"></a>

要使用 AWS Task Orchestrator and Executor (AWSTOE) 组件框架构建组件，必须提供一个基于 YAML 的文档，该文档表示适用于您创建的组件的阶段和步骤。 AWS 服务 当他们创建新的 Amazon 系统映像 (AMI) 或容器映像时，请使用您的组件。

**Topics**
+ [组件文档工作流程](#component-doc-workflow)
+ [组件日志](#component-logging)
+ [输入和输出链](#document-chaining)
+ [文档架构和定义](#document-schema)
+ [文档示例](#document-example)
+ [在自定义组件文档中使用变量](toe-user-defined-variables.md)
+ [在中使用条件构造 AWSTOE](toe-conditional-constructs.md)
+ [在 AWSTOE 组件文档中使用比较运算符](toe-comparison-operators.md)
+ [在 AWSTOE 组件文档中使用逻辑运算符](toe-logical-operators.md)
+ [在中使用循环结构 AWSTOE](toe-looping-constructs.md)

## 组件文档工作流程
<a name="component-doc-workflow"></a>

 AWSTOE 组件文档使用阶段和步骤对相关任务进行分组，并将这些任务组织成组件的逻辑工作流程。

**提示**  
使用您的组件构建映像的服务可能会实施有关构建过程使用哪些阶段，以及何时允许这些阶段运行的规则。您在设计组件时，请务必考虑这一点。

**阶段**  
阶段表示您的工作流程在映像构建过程中的进展。例如，Image Builder 服务在其*构建阶段*对其生成的映像使用 `build` 和 `validate` 阶段。它在*测试阶段*使用 `test` 和 `container-host-test` 阶段来确保在创建最终 AMI 或分发容器映像之前，映像快照或容器映像产生预期的结果。

当组件运行时，每个阶段的关联命令将按照它们在组件文档中出现的顺序进行应用。

**阶段规则**
+ 每个阶段名称在文档中必须是唯一的。
+ 您可以在文档中定义多个阶段。
+ 您必须在文档中至少包含以下至少一个阶段：
  + **构建** — 对于 Image Builder，此阶段通常在*构建阶段*使用。
  + **验证** — 对于 Image Builder，此阶段通常在*构建阶段*使用。
  + **测试** — 对于 Image Builder，此阶段通常在*测试阶段*使用。
+ 阶段始终按照文档中定义的顺序运行。中为 AWSTOE 命令指定它们的顺序 AWS CLI 无效。

**Steps**  
步骤是定义每个阶段中的工作流程的各个工作单元。步骤按先后顺序运行。但是，一个步骤的输入或输出也可以作为输入馈送到后续步骤中。这就是所谓的“链”。

**步骤规则**
+ 步骤名称对于阶段来说必须是唯一的。
+ 步骤必须使用可返回退出代码的支持的操作（操作模块）。

  有关支持的操作模块、其工作原理、 input/output 值和示例的完整列表，请参阅[AWSTOE 组件管理器支持的操作模块](toe-action-modules.md)。

## 组件日志
<a name="component-logging"></a>

AWSTOE 每次运行组件时，都会在 EC2 实例上创建一个新的日志文件夹，用于构建和测试新映像。对于容器映像，日志文件夹存储在容器中。

为了帮助在图像创建过程中出现问题时进行故障排除，在运行组件时 AWSTOE 创建的输入文档和所有输出文件都存储在日志文件夹中。

日志文件夹名称由以下部分组成：

1. **日志目录** — 当服务运行 AWSTOE 组件时，它会与该命令的其他设置一起传入日志目录。在以下示例中，我们展示了 Image Builder 使用的日志文件格式。
   + **Linux 和 macOS**：`/var/lib/amazon/toe/`
   + **Windows**：`$env:ProgramFiles\Amazon\TaskOrchestratorAndExecutor\`

1. **文件前缀** — 这是用于所有组件的标准前缀：“`TOE_`”。

1. **运行时间** — 这是一个 YYYY-MM-DD \$1HH-MM-SS\$1UTC-0 格式的时间戳。

1. **执行 ID**-这是 AWSTOE 运行一个或多个组件时分配的 GUID。

示例：`/var/lib/amazon/toe/TOE_2021-07-01_12-34-56_UTC-0_a1bcd2e3-45f6-789a-bcde-0fa1b2c3def4`

AWSTOE 将以下核心文件存储在日志文件夹中：

**输入文件**
+ **document.yaml** — 用作命令输入的文档。组件运行后，该文件将作为构件存储。

**输出文件**
+ **application.log** — 应用程序日志包含来自 AWSTOE 、带有时间戳的调试级别信息，这些信息有关组件运行时发生的情况。
+ **detailedoutput.json** — 此 JSON 文件包含有关组件运行时适用于组件的所有文档、阶段和步骤的运行状态、输入、输出和失败的详细信息。
+ **console.log** — 控制台日志包含组件运行时 AWSTOE 写入控制台的所有标准输出 (stdout) 和标准错误 (stderr) 信息。
+ **chaining.json** — 此 JSON 文件表示 AWSTOE 应用于解析链接表达式的优化。

**注意**  
日志文件夹还可能包含此处未涵盖的其他临时文件。

## 输入和输出链
<a name="document-chaining"></a>

 AWSTOE 配置管理应用程序提供了一种通过编写以下格式的参考文献来链接输入和输出的功能：

`{{ phase_name.step_name.inputs/outputs.variable }}`

或者

`{{ phase_name.step_name.inputs/outputs[index].variable }}`

通过使用链功能，您可以回收代码并提高文档的可维护性。

**链式规则**
+ 只能在每个步骤的输入部分中使用链表达式。
+ 具有链表达式的语句必须用引号引起来。例如：
  + **无效的表达式**：`echo {{ phase.step.inputs.variable }}`
  + **有效的表达式**：`"echo {{ phase.step.inputs.variable }}"`
  + **有效的表达式**：`'echo {{ phase.step.inputs.variable }}'`
+ 链表达式可以引用同一文档中的其他步骤和阶段的变量。但是，调用服务可能有一些规则，要求链表达式只能在单个阶段的上下文中运行。例如，Image Builder 不支持从*构建阶段*到*测试阶段*的链接，因为它独立运行每个阶段。
+ 链表达式中的索引从零开始。索引以零 (0) 开头，以引用第一个元素。

**示例**

要在以下示例步骤的第二个条目中引用源变量，链模式为 `{{ build.SampleS3Download.inputs[1].source }}`。

```
phases:
  - name: 'build'
    steps:
      - name: SampleS3Download
        action: S3Download
        timeoutSeconds: 60
        onFailure: Abort
        maxAttempts: 3
        inputs:
          - source: 's3://sample-bucket/sample1.ps1'
            destination: 'C:\sample1.ps1'
          - source: 's3://sample-bucket/sample2.ps1'
            destination: 'C:\sample2.ps1'
```

要引用以下示例步骤的输出变量（等于“Hello”），链模式为 `{{ build.SamplePowerShellStep.outputs.stdout }}`。

```
phases:
  - name: 'build'
    steps:
      - name: SamplePowerShellStep
        action: ExecutePowerShell
        timeoutSeconds: 120
        onFailure: Abort
        maxAttempts: 3
        inputs:
          commands:
            - 'Write-Host "Hello"'
```

## 文档架构和定义
<a name="document-schema"></a>

以下是文档的 YAML 架构。

```
name: (optional)
description: (optional)
schemaVersion: "string"

phases:
  - name: "string"
    steps:
      - name: "string"
        action: "string"
        timeoutSeconds: integer
        onFailure: "Abort|Continue|Ignore"
        maxAttempts: integer
        inputs:
```

文档的架构定义如下所示。


| 字段 | 描述 | Type | 必需 | 
| --- | --- | --- | --- | 
| name | 文档的名称。 | 字符串 | 否 | 
| 描述 | 文档的描述。 | 字符串 |  否  | 
| schemaVersion | 文档的架构版本，当前为 1.0。 | 字符串 |  是  | 
| phases | 阶段及其步骤的列表。 |  列表  |  是  | 

阶段的架构定义如下所示。


| 字段 | 描述 | Type | 必需 | 
| --- | --- | --- | --- | 
| name | 阶段的名称。 | 字符串 | 是 | 
| 步骤 | 阶段中的步骤列表。 | 列表  |  是  | 

步骤的架构定义如下所示。


| 字段 | 描述 | Type | 必需 | 默认 值 | 
| --- | --- | --- | --- | --- | 
| name | 用户定义的步骤名称。 | 字符串 |  |  | 
| action | 与运行步骤的模块相关的关键字。 | 字符串 |  |  | 
| timeoutSeconds |  在失败或重试之前，步骤运行的秒数。 此外，支持 -1 值，表示无限超时。不允许 0 和其他负值。  | 整数 |  否  | 7,200 秒（120 分钟） | 
| onFailure |  指定该步骤在失败时应执行的操作。有效值如下所示： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-use-documents.html)  |  字符串  |  否  |  中止 | 
| maxAttempts | 在步骤失败之前允许的最大尝试次数。 | 整数 |  否  | 1 | 
| inputs | 包含操作模块运行步骤所需的参数。 | 字典 |  是  |  | 

## 文档示例
<a name="document-example"></a>

以下示例显示了为目标操作系统执行任务的 AWSTOE 组件文档。

------
#### [ Linux ]

**示例 1：运行自定义二进制文件**  
以下是在 Linux 实例上下载和运行自定义二进制文件的示例文档。

```
name: LinuxBin
description: Download and run a custom Linux binary file.
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: Download
        action: S3Download
        inputs:
          - source: s3://<replaceable>amzn-s3-demo-source-bucket</replaceable>/<replaceable>myapplication</replaceable>
            destination: /tmp/<replaceable>myapplication</replaceable>
      - name: Enable
        action: ExecuteBash
        onFailure: Continue
        inputs:
          commands:
            - 'chmod u+x {{ build.Download.inputs[0].destination }}'
      - name: Install
        action: ExecuteBinary
        onFailure: Continue
        inputs:
          path: '{{ build.Download.inputs[0].destination }}'
          arguments:
            - '--install'
      - name: Delete
        action: DeleteFile
        inputs:
          - path: '{{ build.Download.inputs[0].destination }}'
```

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

**示例 1：安装 Windows 更新**  
以下是一个示例文档，用于安装所有可用的 Windows 更新，运行配置脚本，在创建 AMI 之前验证更改以及在创建 AMI 后测试更改。

```
name: RunConfig_UpdateWindows
description: 'This document will install all available Windows updates and run a config script. It will then validate the changes before an AMI is created. Then after AMI creation, it will test all the changes.'
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: DownloadConfigScript
        action: S3Download
        timeoutSeconds: 60
        onFailure: Abort
        maxAttempts: 3
        inputs:
          - source: 's3://customer-bucket/config.ps1'
            destination: 'C:\config.ps1'

      - name: RunConfigScript
        action: ExecutePowerShell
        timeoutSeconds: 120
        onFailure: Abort
        maxAttempts: 3
        inputs:
          file: '{{build.DownloadConfigScript.inputs[0].destination}}'

      - name: Cleanup
        action: DeleteFile
        onFailure: Abort
        maxAttempts: 3
        inputs:
          - path: '{{build.DownloadConfigScript.inputs[0].destination}}'

      - name: RebootAfterConfigApplied
        action: Reboot
        inputs:
          delaySeconds: 60

      - name: InstallWindowsUpdates
        action: UpdateOS

  - name: validate
    steps:
      - name: DownloadTestConfigScript
        action: S3Download
        timeoutSeconds: 60
        onFailure: Abort
        maxAttempts: 3
        inputs:
          - source: 's3://customer-bucket/testConfig.ps1'
            destination: 'C:\testConfig.ps1'

      - name: ValidateConfigScript
        action: ExecutePowerShell
        timeoutSeconds: 120
        onFailure: Abort
        maxAttempts: 3
        inputs:
          file: '{{validate.DownloadTestConfigScript.inputs[0].destination}}'

      - name: Cleanup
        action: DeleteFile
        onFailure: Abort
        maxAttempts: 3
        inputs:
          - path: '{{validate.DownloadTestConfigScript.inputs[0].destination}}'

  - name: test
    steps:
      - name: DownloadTestConfigScript
        action: S3Download
        timeoutSeconds: 60
        onFailure: Abort
        maxAttempts: 3
        inputs:
          - source: 's3://customer-bucket/testConfig.ps1'
            destination: 'C:\testConfig.ps1'

      - name: ValidateConfigScript
        action: ExecutePowerShell
        timeoutSeconds: 120
        onFailure: Abort
        maxAttempts: 3
        inputs:
          file: '{{test.DownloadTestConfigScript.inputs[0].destination}}'
```

**示例 2：在 Windows 实例 AWS CLI 上安装**  
以下是使用安装文件在 Windows 实例 AWS CLI 上安装的示例文档。

```
name: InstallCLISetUp
description: Install &CLI; using the setup file
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: Download
        action: S3Download
        inputs:
          - source: s3://aws-cli/AWSCLISetup.exe
            destination: C:\Windows\temp\AWSCLISetup.exe
      - name: Install
        action: ExecuteBinary
        onFailure: Continue
        inputs:
          path: '{{ build.Download.inputs[0].destination }}'
          arguments:
            - '/install'
            - '/quiet'
            - '/norestart'
      - name: Delete
        action: DeleteFile
        inputs:
          - path: '{{ build.Download.inputs[0].destination }}'
```

**示例 3：使用 MSI 安装程序安装 AWS CLI**  
以下是使用 MSI 安装程序安装 AWS CLI 的示例文档。

```
name: InstallCLIMSI
description: Install &CLI; using the MSI installer
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: Download
        action: S3Download
        inputs:
          - source: s3://aws-cli/AWSCLI64PY3.msi
            destination: C:\Windows\temp\AWSCLI64PY3.msi
      - name: Install
        action: ExecuteBinary
        onFailure: Continue
        inputs:
          path: 'C:\Windows\System32\msiexec.exe'
          arguments:
            - '/i'
            - '{{ build.Download.inputs[0].destination }}'
            - '/quiet'
            - '/norestart'
      - name: Delete
        action: DeleteFile
        inputs:
          - path: '{{ build.Download.inputs[0].destination }}'
```

------
#### [ macOS ]

**示例 1：运行自定义 macOS 二进制文件**  
以下是在 macOS 实例上下载和运行自定义二进制文件的示例文档。

```
name: macOSBin
description: Download and run a binary file on macOS.
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: Download
        action: S3Download
        inputs:
          - source: s3://<replaceable>amzn-s3-demo-source-bucket</replaceable>/<replaceable>myapplication</replaceable>
            destination: /tmp/<replaceable>myapplication</replaceable>
      - name: Enable
        action: ExecuteBash
        onFailure: Continue
        inputs:
          commands:
            - 'chmod u+x {{ build.Download.inputs[0].destination }}'
      - name: Install
        action: ExecuteBinary
        onFailure: Continue
        inputs:
          path: '{{ build.Download.inputs[0].destination }}'
          arguments:
            - '--install'
      - name: Delete
        action: DeleteFile
        inputs:
          - path: '{{ build.Download.inputs[0].destination }}'
```

------

# 在自定义组件文档中使用变量
<a name="toe-user-defined-variables"></a>

变量提供了一种以在整个应用程序中可使用的有意义的名称来标记数据的方法。您可以为复杂的工作流程定义格式简单易读的自定义变量，并在组件的 YAML 应用程序组件文档中引用它们。 AWSTOE 

本节提供的信息可帮助您在 YAML 应用程序 AWSTOE 组件文档中为组件定义变量，包括语法、名称约束和示例。

## 常量
<a name="user-defined-vars-constants"></a>

常量是不可变的变量，一旦定义就无法修改或覆盖。常量可以使用 AWSTOE 文档`constants`部分中的值来定义。

**常量名称规则**
+ 名称长度必须介于 3 到 128 个字符之间。
+ 该名称只能包含字母/数字字符（a-z、A-Z、0-9）、短划线 (-) 或下划线 (\$1)。
+ 在文档内，此名称必须是唯一的。
+ 必须将名称指定为 YAML 字符串。

**语法**

```
constants:
  - <name>:
      type: <constant type>
      value: <constant value>
```


| 键名称 | 必需 | 描述 | 
| --- | --- | --- | 
|  `name`  |  是  | 常量的名称。文档必须是唯一的（不得与任何其他参数名称或常量相同）。 | 
| `value` | 是 | 常量的值。 | 
| `type` | 是 | 常量的类型。支持的类型为 string。 | 

**在文档中引用常量值**  
您可以在 YAML 文档内的步骤或循环输入中引用常量，如下所示：
+ 常量引用区分大小写，并且名称必须完全匹配。
+ 名称必须用双大括号括`{{`*MyConstant*`}}`起来。
+ 允许在花括号内留出空格，并且会自动修剪空格。例如，以下所有引用均有效：

  `{{ MyConstant }}`, `{{ MyConstant}}`, `{{MyConstant }}`, `{{MyConstant}}`
+ YAML 文档中的引用必须指定为字符串（用单引号或双引号括起来）。

  例如：`- {{ MyConstant }}` 无效，因为它未被标识为字符串。

  但是，以下引用均有效：`- '{{ MyConstant }}'` 和 `- "{{ MyConstant }}"`。

**示例**  
步骤输入中引用的常量

```
name: Download AWS CLI version 2
schemaVersion: 1.0
constants:
  - Source:
      type: string
      value: https://awscli.amazonaws.com/AWSCLIV2.msi
phases:
  - name: build
    steps:
      - name: Download
        action: WebDownload
        inputs:
          - source: '{{ Source }}'
            destination: 'C:\Windows\Temp\AWSCLIV2.msi'
```

循环输入中引用的常量

```
name: PingHosts
schemaVersion: 1.0
constants:
  - Hosts:
      type: string
      value: 127.0.0.1,amazon.com
phases:
  - name: build
    steps:
      - name: Ping
        action: ExecuteBash
        loop:
          forEach:
            list: '{{ Hosts }}'
            delimiter: ','
        inputs:
          commands:
            - ping -c 4 {{ loop.value }}
```

## 参数
<a name="user-defined-vars-parameters"></a>

参数是可变变量，其设置由调用应用程序在运行时提供。您可以在 YAML 文档的 `Parameters` 部分中定义参数。

**参数名称规则**
+ 名称长度必须介于 3 到 128 个字符之间。
+ 该名称只能包含字母/数字字符（a-z、A-Z、0-9）、短划线 (-) 或下划线 (\$1)。
+ 在文档内，此名称必须是唯一的。
+ 必须将名称指定为 YAML 字符串。

### 语法
<a name="vars-parameters-syntax"></a>

```
parameters:
  - <name>:
      type: <parameter type>
      default: <parameter value>
      description: <parameter description>
```


| 键名称 | 必需 | 描述 | 
| --- | --- | --- | 
| `name` | 是 | 参数的名称。文档必须是唯一的（不得与任何其他参数名称或常量相同）。 | 
| `type` | 是 | 参数的数据类型。支持的类型包括：`string`。 | 
| `default` | 否 | 参数的默认值。 | 
| `description` | 否 | 描述参数。 | 

### 在文档中引用参数值
<a name="vars-parameters-referencing"></a>

您可以在 YAML 文档里的步骤或循环输入中引用参数，如下所示：
+ 参数引用区分大小写，并且名称必须完全匹配。
+ 名称必须用双大括号括`{{`*MyParameter*`}}`起来。
+ 允许在花括号内留出空格，并且会自动修剪空格。例如，以下所有引用均有效：

  `{{ MyParameter }}`, `{{ MyParameter}}`, `{{MyParameter }}`, `{{MyParameter}}`
+ YAML 文档中的引用必须指定为字符串（用单引号或双引号括起来）。

  例如：`- {{ MyParameter }}` 无效，因为它未被标识为字符串。

  但是，以下引用均有效：`- '{{ MyParameter }}'` 和 `- "{{ MyParameter }}"`。

**示例**  
以下示例显示如何在 YAML 文档中使用参数：
+ 参考步骤输入中的参数：

  ```
  name: Download AWS CLI version 2
  schemaVersion: 1.0
  parameters:
    - Source:
        type: string
        default: 'https://awscli.amazonaws.com/AWSCLIV2.msi'
        description: The AWS CLI installer source URL.
  phases:
    - name: build
      steps:
        - name: Download
          action: WebDownload
          inputs:
            - source: '{{ Source }}'
              destination: 'C:\Windows\Temp\AWSCLIV2.msi'
  ```
+ 参考循环输入中的参数：

  ```
  name: PingHosts
  schemaVersion: 1.0
  parameters:
    - Hosts:
        type: string
        default: 127.0.0.1,amazon.com
        description: A comma separated list of hosts to ping.
  phases:
    - name: build
      steps:
        - name: Ping
          action: ExecuteBash
          loop:
            forEach:
              list: '{{ Hosts }}'
              delimiter: ','
          inputs:
            commands:
              - ping -c 4 {{ loop.value }}
  ```

### 在运行时覆盖参数
<a name="vars-parameters-set-at-runtime"></a>

您可以将中的`--parameters`选项与键值对 AWS CLI 一起使用，在运行时设置参数值。
+ 将参数键值对指定为名称和值，用等号 (=) 分隔 (<name>=<value>)。
+ 多个参数必须用逗号分隔。
+ 在 YAML 组件文档中找不到的参数名称将被忽略。
+ 参数名称和值都是必需的。

**重要**  
组件参数是纯文本值，并且已记录在 AWS CloudTrail中。我们建议您使用 AWS Secrets Manager 或 P AWS Systems Manager arameter Store 来存储您的密钥。有关 Secrets Manager 的更多信息，请参阅*AWS Secrets Manager 用户指南*中的[什么是 Secrets Manager?](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)。有关 AWS Systems Manager Parameter Store 的更多信息，请参阅 *AWS Systems Manager 用户指南*中的 [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)。

#### 语法
<a name="vars-runtime-parameters-syntax"></a>

```
--parameters name1=value1,name2=value2...
```


| CLI 选项 | 必需 | 说明 | 
| --- | --- | --- | 
| --参数 *name* =*value*，... | 否 | 此选项采用键/值对列表，以参数名称为键。 | 

**示例**  
以下示例显示如何在 YAML 文档中使用参数：
+ 此 `--parameter` 选项中指定的参数键值对无效：

  ```
  --parameters ntp-server=
  ```
+ 使用 AWS CLI中的 `--parameter` 选项设置一个参数键值对：

  ```
  --parameters ntp-server=ntp-server-windows-qe.us-east1.amazon.com
  ```
+ 使用 AWS CLI中的 `--parameter` 选项设置多个参数键值对：

  ```
  --parameters ntp-server=ntp-server.amazon.com,http-url=https://internal-us-east1.amazon.com
  ```

## 使用 Systems Manager 参数存储参数
<a name="toe-ssm-parameters"></a>

您可以通过在变量前面加上前缀来引用组件文档中的 AWS Systems Manager 参数存储参数（SSM 参数）。`aws:ssm`例如，

`{{ aws:ssm:/my/param }}`解析为 SSM 参数的值。`/my/param`

此功能支持以下 SSM 参数类型：
+ 字符串-映射到 AWSTOE 字符串类型。
+ StringList — 映射到 AWSTOE `stringList`类型。
+ SecureString — 映射到 AWSTOE 字符串类型。

有关参数存储的更多信息，请参阅*AWS Systems Manager 用户指南*中的[AWS Systems Manager 参数存储](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html)。

您也可以使用 SSM 参数`SecureString`引用 AWS Secrets Manager 密钥。例如：`{{ aws:ssm:/aws/reference/secretsmanager/test/test-secret }}`。有关更多信息，请参阅[从参数存储参数中引用 AWS Secrets Manager 密钥](https://docs.aws.amazon.com/systems-manager/latest/userguide/integration-ps-secretsmanager.html)。

**重要**  
Image Builder 从其日志中排除`SecureString`参数解析。但是，您也有责任确保敏感信息不会通过组件文档中发出的命令进行记录。例如，如果您使用带有安全字符串的`echo`命令，则该命令会将纯文本值写入日志。

### 所需的 IAM 权限
<a name="toe-ssm-parameters-permissions"></a>

要在组件中使用 Systems Manager 参数，您的实例角色必须拥有参数资源 ARN 的`ssm:GetParameter`权限。例如：

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

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Statement": [
		{
			"Effect": "Allow",
			"Action": "ssm:GetParameter",
			"Resource": "arn:aws:ssm:*:111122223333:parameter/ImageBuilder-*"
		}
	]
}
```

------

要访问加密值，您还需要以下权限：
+ `kms:Decrypt`对于使用客户管理的`SecureString`参数或 AWS Secrets Manager 值进行加密，请添加 AWS KMS key。
+ `secretsmanager:GetSecretValue`如果您引用 Secrets Manager 密钥，请添加。

### 在组件文档中引用 SSM 参数
<a name="toe-ssm-parameters-example"></a>

以下示例说明如何引用组件中 Systems Manager 参数的 Systems Manager 参数存储参数：

```
name: UseSSMParameterVariable
description: This is a sample component document that prints out the value of an SSM Parameter. Never do this for a SecureString parameter.
schemaVersion: 1.0

phases:
  - name: verify
    steps:
      - name: EchoParameterValue
        action: ExecuteBash
        inputs:
          commands:
            - echo "Log SSM parameter name: /my/test/param, value {{ aws:ssm:/my/test/param }}."
```

### SSM 参数的动态运行时变量分辨率
<a name="toe-dynamic-vars"></a>

AWSTOE 提供了以下内置函数，您可以在变量引用中使用该函数在运行时操作或转换值。

#### 解析函数
<a name="toe-function-resolve"></a>

该`resolve`函数解析另一个变量引用内部的变量引用，从而允许动态变量名引用。这在使用 SSM 参数时很有用，因为其中部分参数路径可能是可变的，并作为文档参数传入。

该`resolve`函数仅支持 SSM 参数名称部分的动态解析。

##### 语法
<a name="toe-function-resolve-syntax"></a>

以下示例`dynamic_variable`中的表示 SSM 参数的名称，并且必须是以下参数之一：
+ SSM 参数参考（例如，`aws:ssm:/my/param`）
+ 组件文档参数引用（例如，`parameter-name`）

```
{{ aws:ssm:resolve(dynamic_variable) }}
```

##### 示例：在运行时解析 SSM 参数
<a name="toe-function-resolve-examples"></a>

以下示例说明如何在 YAML 组件文档中使用该`resolve`函数：

```
name: SsmParameterTest
description: This component verifies an SSM parameter variable reference with the echo command.
schemaVersion: 1.0

parameters:
  - parameter-name:
      type: string
      description: "test"

phases:
  - name: validate
    steps:
      - name: PrintDynamicVariable
        action: ExecuteBash
        inputs:
          commands:
            - echo "{{ aws:ssm:resolve(parameter-name) }}"
```

# 在中使用条件构造 AWSTOE
<a name="toe-conditional-constructs"></a>

根据指定的条件表达式的计算结果是 `true` 还是 `false`，条件构造会在组件文档中执行不同的操作。您可以使用 `if` 构造来控制组件文档中的执行流程。

## if 构造
<a name="toe-conditional-if"></a>

您可以使用 `if` 构造来评估是否应该运行某步骤。默认情况下，当 `if` 条件表达式的计算结果为 `true` 时， AWSTOE 运行该步骤，当条件表达式计算结果为 `false` 时， AWSTOE 跳过该步骤。如果跳过某个步骤，则在 AWSTOE 评估阶段和文档是否成功运行时，该步骤将被视为成功步骤。

**注意**  
即使该步骤触发了重启，也只对一个 `if` 语句进行一次计算。如果某个步骤重启，它就会识别出 `if` 语句已经进行计算，并从中断的地方继续进行。

### 语法
<a name="toe-conditional-if-syntax"></a>

```
if:
  - <conditional expression>:
      [then: <step action>]
      [else: <step action>]
```


| 键名称 | 必需 | 说明 | 
| --- | --- | --- | 
| 条件表达式 | 是 |  条件表达式可以在顶层包含以下类型的运算符之一。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-conditional-constructs.html) 如果您的表达式必须满足多个条件，请使用逻辑运算符来指定您的条件。  | 
| then | 否 |  定义条件表达式的计算结果为 `true` 时要采取的操作。  | 
| else | 否 |  定义条件表达式的计算结果为 `false` 时要采取的操作。  | 
| 步骤操作 | 有条件 |  使用 `then` 或 `else` 时，必须指定以下步骤操作之一： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-conditional-constructs.html)  | 

**示例 1：安装软件包**  
 AWSTOE 组件文档中的以下示例步骤使用逻辑运算符来测试参数值，并在软件包解压缩后运行相应的软件包管理器命令来安装应用程序。

```
    - name: InstallUnzipAptGet
      action: ExecuteBash
      if:
        and:
            - binaryExists: 'apt-get'
            - not:
                binaryExists: 'unzip'
      inputs:
        commands:
            - sudo apt-get update
            - sudo apt-get install -y unzip

    - name: InstallUnzipYum
      action: ExecuteBash
      if:
        and:
            - binaryExists: 'yum'
            - not:
                binaryExists: 'unzip'
      inputs:
        commands:
            - sudo yum install -y unzip

    - name: InstallUnzipZypper
      action: ExecuteBash
      if:
        and:
            - binaryExists: 'zypper'
            - not:
                binaryExists: 'unzip'
      inputs:
        commands:
            - sudo zypper refresh
            - sudo zypper install -y unzip
```

**示例 2：跳过步骤**  
以下示例显示了跳过步骤的两种方法。一种是使用逻辑运算符，另一种是结合使用比较运算符与 `Skip` 步骤操作。

```
# Creates a file if it does not exist using not
- name: CreateMyConfigFile-1
  action: ExecuteBash
  if:
    not:
      fileExists: '/etc/my_config'
  inputs:
    commands:
      - echo "Hello world" > '/etc/my_config'

# Creates a file if it does not exist using then and else
- name: CreateMyConfigFile-2
  action: ExecuteBash
  if:
    fileExists: '/etc/my_config'
    then: Skip
    else: Execute
  inputs:
    commands:
      - echo "Hello world" > '/etc/my_config'
```

# 在 AWSTOE 组件文档中使用比较运算符
<a name="toe-comparison-operators"></a>

您可以结合使用以下比较运算符与 **[Assert](toe-action-modules.md#action-modules-assertion)** 操作模块以及使用 [if 构造语法](toe-conditional-constructs.md#toe-conditional-if)的条件表达式。比较运算符可以对单个值进行比较，例如 `stringIsEmpty`，也可以将基准值与第二个值（变量值）进行比较，以确定条件表达式的计算结果是 `true` 还是 `false`。

如果对两个值进行比较，则第二个值可以是链式变量。

比较不同类型的值时，在比较之前可能会进行以下值转换：
+ 对于数值比较，如果变量值是字符串，则在计算之前将字符串 AWSTOE 转换为数字。如果无法进行转换，则比较返回 `false`。例如，如果变量值为 `"1.0"`，则可以进行转换，但如果变量值为 `"a10"`，则转换将会失败。
+ 对于字符串比较，如果变量值是一个数字，则在求值之前将其 AWSTOE 转换为字符串。

## 比较字符串
<a name="toe-compare-strings"></a>

以下比较运算符结合字符串来比较值、测试空格或空字符串，或者将输入值与正则表达式模式进行比较。字符串比较不区分大小写，也不会从字符串输入的开头或结尾去掉空格。

**字符串比较运算符**
+ [stringIsEmpty](#stringIsEmpty)
+ [stringIsWhitespace](#stringIsWhitespace)
+ [stringEquals](#stringEquals)
+ [stringLessThan](#stringLessThan)
+ [stringLessThanEquals](#stringLessThanEquals)
+ [stringGreaterThan](#stringGreaterThan)
+ [stringGreaterThanEquals](#stringGreaterThanEquals)
+ [patternMatches](#patternMatches)

**stringIsEmpty**  
如果指定的字符串不包含任何字符，则 `stringIsEmpty` 运算符将返回 `true`。例如：  

```
# Evaluates to true
stringIsEmpty: ""

# Evaluates to false
stringIsEmpty: " "
				
# Evaluates to false
stringIsEmpty: "Hello."
```

**stringIsWhitespace**  
测试为 `stringIsWhitespace` 指定的字符串是否仅包含空格。例如：  

```
# Evaluates to true
stringIsWhitespace: "   "

# Evaluates to false
stringIsWhitespace: ""
				
# Evaluates to false
stringIsWhitespace: " Hello?"
```

**stringEquals**  
测试为 `stringEquals` 指定的字符串是否与 `value` 参数中指定的字符串完全匹配。例如：  

```
# Evaluates to true
stringEquals: 'Testing, testing...'
value: 'Testing, testing...'

# Evaluates to false
stringEquals: 'Testing, testing...'
value: 'Hello again.'

# Evaluates to false
stringEquals: 'Testing, testing...'
value: 'TESTING, TESTING....'

# Evaluates to false
stringEquals: 'Testing, testing...'
value: '   Testing, testing...'
				
# Evaluates to false
stringEquals: 'Testing, testing...'
value: 'Testing, testing...   '
```

**stringLessThan**  
测试为 `stringLessThan` 指定的字符串是否小于 `value` 参数中指定的字符串。例如：  

```
# Evaluates to true
# This comparison operator isn't case sensitive
stringlessThan: 'A'
value: 'a'

# Evaluates to true - 'a' is less than 'b'
stringlessThan: 'b'
value: 'a'

# Evaluates to true
# Numeric strings compare as less than alphabetic strings
stringlessThan: 'a'
value: '0'

# Evaluates to false
stringlessThan: '0'
value: 'a'
```

**stringLessThan等于**  
测试为 `stringLessThanEquals` 指定的字符串是否小于或等于 `value` 参数中指定的字符串。例如：  

```
# Evaluates to true - 'a' is equal to 'a'
stringLessThanEquals: 'a'
value: 'a'

# Evaluates to true - since the comparison isn't case sensitive, 'a' is equal to 'A'
stringLessThanEquals: 'A'
value: 'a'

# Evaluates to true - 'a' is less than 'b'
stringLessThanEquals: 'b'
value: 'a'

# Evaluates to true - '0' is less than 'a'
stringLessThanEquals: 'a'
value: '0'

# Evaluates to false - 'a' is greater than '0'
stringLessThanEquals: '0'
value: 'a'
```

**stringGreaterThan**  
测试为 `stringGreaterThan` 指定的字符串是否大于 `value` 参数中指定的字符串。例如：  

```
# Evaluates to false - since the comparison isn't case sensitive, 'A' is equal to 'a'
stringGreaterThan: 'a'
value: 'A'

# Evaluates to true - 'b' is greater than 'a'
stringGreaterThan: 'a'
value: 'b'

# Evaluates to true - 'a' is greater than '0'
stringGreaterThan: '0'
value: 'a'

# Evaluates to false - '0' is less than 'a'
stringGreaterThan: 'a'
value: '0'
```

**stringGreaterThan等于**  
测试为 `stringGreaterThanEquals` 指定的字符串是否大于或等于 `value` 参数中指定的字符串。例如：  

```
# Evaluates to true - 'a' is equal to 'A'
stringGreaterThanEquals: 'A'
value: 'a'

# Evaluates to true - 'b' is greater than 'a'
stringGreaterThanEquals: 'a'
value: 'b'

# Evaluates to true - 'a' is greater than '0'
stringGreaterThanEquals: '0'
value: 'a'

# Evaluates to false - '0' is less than 'a'
stringGreaterThanEquals: 'a'
value: '0'
```

**patternMatches**  
测试 `value` 参数中指定的字符串是否与为 `patternMatches` 指定的正则表达式模式匹配。比较使用符合语法的 [Golang regexp 包](https://pkg.go.dev/regexp)。 RE2 有关 RE2 规则的更多信息，请参阅中的 [google/re2](https://github.com/google/re2/wiki/Syntax) 存储库。*GitHub*  
以下示例显示了返回 `true` 的模式匹配：  

```
patternMatches: '^[a-z]+$'
value: 'ThisIsValue'
```

## 比较数字
<a name="toe-compare-numbers"></a>

以下比较运算符适用于数字。根据 YAML 规范，为这些运算符提供的值必须是以下类型之一。对数字比较的支持使用 golang big 包比较运算符，例如：[func (\$1Float) Cmp](https://pkg.go.dev/math/big#Float.Cmp)。
+ 整数
+ Float（基于 float64，支持从 -1.7e\$1308 到 \$11.7e\$1308 之间的数字）
+ 与以下正则表达式模式相匹配的字符串：`^[-+]?([0-9]+[.])?[0-9]+$`

**数字比较运算符**
+ [numberEquals](#numberEquals)
+ [numberLessThan](#numberLessThan)
+ [numberLessThanEquals](#numberLessThanEquals)
+ [numberGreaterThan](#numberGreaterThan)
+ [numberGreaterThanEquals](#numberGreaterThanEquals)

**numberEquals**  
测试为 `numberEquals` 指定的数字是否等于 `value` 参数中指定的数字。以下所有示例的比较均返回 `true`：  

```
# Values provided as a positive number
numberEquals: 1
value: 1

# Comparison value provided as a string
numberEquals: '1'
value: 1

# Value provided as a string
numberEquals: 1
value: '1'

# Values provided as floats
numberEquals: 5.0
value: 5.0

# Values provided as a negative number
numberEquals: -1
value: -1
```

**numberLessThan**  
测试为 `numberLessThan` 指定的数字是否小于 `value` 参数中指定的数字。例如：  

```
# Evaluates to true
numberLessThan: 2
value: 1

# Evaluates to true
numberLessThan: 2
value: 1.9

# Evaluates to false
numberLessThan: 2
value: '2'
```

**numberLessThan等于**  
测试为 `numberLessThanEquals` 指定的数字是否小于或等于 `value` 参数中指定的数字。例如：  

```
# Evaluates to true
numberLessThanEquals: 2
value: 1

# Evaluates to true
numberLessThanEquals: 2
value: 1.9

# Evaluates to true
numberLessThanEquals: 2
value: '2'

# Evaluates to false
numberLessThanEquals: 2
value: 2.1
```

**numberGreaterThan**  
测试为 `numberGreaterThan` 指定的数字是否大于 `value` 参数中指定的数字。例如：  

```
# Evaluates to true
numberGreaterThan: 1
value: 2

# Evaluates to true
numberGreaterThan: 1
value: 1.1

# Evaluates to false
numberGreaterThan: 1
value: '1'
```

**numberGreaterThan等于**  
测试为 `numberGreaterThanEquals` 指定的数字是否大于或等于 `value` 参数中指定的数字。例如：  

```
# Evaluates to true
numberGreaterThanEquals: 1
value: 2

# Evaluates to true
numberGreaterThanEquals: 1
value: 1.1

# Evaluates to true
numberGreaterThanEquals: 1
value: '1'

# Evaluates to false
numberGreaterThanEquals: 1
value: 0.8
```

## 检查文件
<a name="toe-check-files"></a>

以下比较运算符检查文件哈希值或检查文件或文件夹是否存在。

**文件和文件夹运算符**
+ [binaryExists](#binaryExists)
+ [fileExists](#fileExists)
+ [folderExists](#folderExists)
+ [fileMD5Equals](#fileMD5Equals)
+ [fileSHA1Equals](#fileSHA1Equals)
+ [fileSHA256Equals](#fileSHA256Equals)
+ [fileSHA512Equals](#fileSHA512Equals)

**binaryExists**  
测试应用程序在当前路径中是否可用。例如：  

```
binaryExists: 'foo'
```
在 Linux 和 macOS 系统上，对于名为的应用程序*foo*，其工作原理与以下 bash 命令相同：**type *foo* >/dev/null 2>&1**，其中**\$1? == 0**表示比较成功。  
在 Windows 系统上，对于名为的应用程序*foo*，其工作原理与**\$1LASTEXITCODE = 0**表示成功比较**& C:\$1Windows\$1System32\$1where.exe /Q *foo***的 PowerShell 命令相同。

**fileExists**  
测试指定路径上是否存在文件。您可以提供绝对路径或相对路径。如果您指定的位置存在并且是一个文件，则比较的计算结果为 `true`。例如：  

```
fileExists: '/path/to/file'
```
在 Linux 和 macOS 系统上，其工作原理与以下 bash 命令相同：**-d */path/to/file***，其中 **\$1? == 0** 表示比较成功。  
在 Windows 系统上，这与 PowerShell 命令的工作原理相同**Test-Path -Path '*C:\$1path\$1to\$1file*' -PathType 'Leaf'**。

**folderExists**  
测试指定路径上是否存在文件夹。您可以提供绝对路径或相对路径。如果您指定的位置存在并且是一个文件夹，则比较的计算结果为 `true`。例如：  

```
folderExists: '/path/to/folder'
```
在 Linux 和 macOS 系统上，其工作原理与以下 bash 命令相同：**-d */path/to/folder***，其中 **\$1? == 0** 表示比较成功。  
在 Windows 系统上，这与 PowerShell 命令的工作原理相同**Test-Path -Path '*C:\$1path\$1to\$1folder*' -PathType 'Container'**。

**文件MD5等于**  
测试文件的 MD5 哈希值是否等于指定值。例如：  

```
fileMD5Equals: '<MD5Hash>'
path: '/path/to/file'
```

**文件SHA1等于**  
测试文件的 SHA1 哈希值是否等于指定值。例如：  

```
fileSHA1Equals: '<SHA1Hash>'
path: '/path/to/file'
```

**文件SHA256等于**  
测试文件的 SHA256 哈希值是否等于指定值。例如：  

```
fileSHA256Equals: '<SHA256Hash>'
path: '/path/to/file'
```

**文件SHA512等于**  
测试文件的 SHA512 哈希值是否等于指定值。例如：  

```
fileSHA512Equals: '<SHA512Hash>'
path: '/path/to/file'
```

# 在 AWSTOE 组件文档中使用逻辑运算符
<a name="toe-logical-operators"></a>

您可以使用以下逻辑运算符在组件文档中添加或修改条件表达式。 AWSTOE 按条件的指定顺序计算条件表达式。有关组件文档比较运算符的更多信息，请参阅[在 AWSTOE 组件文档中使用比较运算符](toe-comparison-operators.md)。

** 和 **  
使用 `and` 运算符，您可以将两个或多个比较作为单个表达式进行计算。当列表中的所有条件都为 true 时，表达式的计算结果为 `true`。否则，表达式的计算结果为 `false`。  
**示例：**  
下面的示例执行了两个比较：字符串和数字。两个比较的结果均为 true，因此表达式的计算结果为 true。

```
and:
  - stringEquals: 'test_string'
    value: 'test_string'
  - numberEquals: 1
    value: 1
```
以下示例还执行了两个比较。第一个比较的结果为 false，此时计算停止，第二个比较被跳过。表达式的计算结果为 `false`。  

```
and:
  - stringEquals: 'test_string'
    value: 'Hello world!'
  - numberEquals: 1
    value: 1
```

**或者**  
使用 `or` 运算符，您可以将两个或多个比较作为单个表达式进行计算。当其中一个指定的比较结果为 true 时，表达式的计算结果为 `true`。如果指定比较的计算结果均不为 `true`，则表达式的计算结果为 `false`。  
**示例：**  
下面的示例执行了两个比较：字符串和数字。第一个比较的结果为 true，因此表达式的计算结果为 `true`，第二个比较被跳过。

```
or:
  - stringEquals: 'test_string'
    value: 'test_string'
  - numberEquals: 1
    value: 3
```
以下示例还执行了两个比较。第一个比较的结果为 false，计算继续进行。第二个比较的结果为 true，因此表达式的计算结果为 `true`。  

```
or:
  - stringEquals: 'test_string'
    value: 'Hello world!'
  - numberEquals: 1
    value: 1
```
在最后一个示例中，两个比较的结果均为 false，因此表达式的计算结果为 `false`。  

```
or:
  - stringEquals: 'test_string'
    value: 'Hello world!'
  - numberEquals: 1
    value: 3
```

**not**  
使用 `not` 运算符，您可以否定单个比较。如果比较的结果为 false，则表达式的计算结果为 `true`。如果比较的结果为 true，则表达式的计算结果为 `false`。  
**示例：**  
以下示例执行了字符串比较。比较的结果为 false，因此表达式的计算结果为 `true`。

```
not:
  - stringEquals: 'test_string'
    value: 'Hello world!'
```
以下示例还执行了字符串比较。比较的结果为 true，因此表达式的计算结果为 `false`。  

```
not:
  - stringEquals: 'test_string'
    value: 'test_string'
```

# 在中使用循环结构 AWSTOE
<a name="toe-looping-constructs"></a>

本部分提供了有助于您在 AWSTOE中创建循环结构的信息。循环结构定义了重复的指令序列。您可以在 AWSTOE中使用以下类型的循环结构：
+ `for` 结构 – 在有界的整数序列上迭代。
+ `forEach` 结构
  + `forEach` 使用输入列表循环 – 迭代有限的字符串集合。
  + `forEach` 带分隔列表的循环 – 迭代由分隔符连接的有限字符串集合。

**注意**  
循环结构仅支持字符串数据类型。

**Topics**
+ [引用迭代变量](#toe-loop-iteration-variables)
+ [循环结构的类型](#toe-loop-types)
+ [步骤字段](#toe-loop-step-fields)
+ [步骤和迭代输出](#toe-loop-step-output)

## 引用迭代变量
<a name="toe-loop-iteration-variables"></a>

要引用当前迭代变量的索引和值，必须在包含循环结构的步骤的输入主体中使用引用表达式 `{{ loop.* }}`。此表达式不能用于引用另一个步骤的循环结构的迭代变量。

引用表达式由以下成员组成：
+ `{{ loop.index }}` – 当前迭代的序数位置，索引为 `0`。
+ `{{ loop.value }}` – 与当前迭代变量关联的值。

### 循环名称
<a name="toe-loop-iteration-variables-names"></a>

 所有循环结构都有一个用于标识的可选名称字段。如果提供了循环名称，则可以使用它来引用步骤输入主体中的迭代变量。要引用命名循环的迭代索引和值，请在步骤的输入主体中使用带 `{{ loop.* }}` 的 `{{ <loop_name>.* }}`。此表达式不能用于引用另一个步骤的命名循环结构。

引用表达式由以下成员组成：
+ `{{ <loop_name>.index }}` – 命名循环当前迭代的序数位置，其索引位于 `0`。
+ `{{ <loop_name>.value }}` – 与命名循环的当前迭代变量关联的值。

### 解析引用表达式
<a name="toe-loop-iteration-variables-expressions"></a>

解 AWSTOE 析引用表达式如下：
+ `{{ <loop_name>.* }}`— 使用以下逻辑 AWSTOE 解析此表达式：
  + 如果当前正在运行的步骤的循环与 `<loop_name>` 值匹配，则引用表达式将解析为当前正在运行的步骤的循环结构。
  + 如果命名的循环结构出现在当前运行的步骤内，则 `<loop_name>` 解析为该结构。
+ `{{ loop.* }}`— 使用在当前运行的步骤中定义的循环结构 AWSTOE 解析表达式。

如果在不包含循环的步骤中使用引用表达式，则 AWSTOE 不会解析这些表达式，并且它们出现在步骤中而不进行替换。

**注意**  
引用表达式必须用双引号括起来，YAML 编译器才能正确解释。

## 循环结构的类型
<a name="toe-loop-types"></a>

本节提供有关可在 AWSTOE中使用的循环结构类型的信息和示例。

**Topics**
+ [`for` 循环](#toe-loop-types-for)
+ [`forEach` 使用输入列表循环](#toe-loop-types-foreach)
+ [`forEach` 使用带分隔列表的循环](#toe-loop-types-foreach-delimited)

### `for` 循环
<a name="toe-loop-types-for"></a>

该 `for` 循环迭代处于由变量开头和结尾勾勒的边界内指定的整数范围。迭代值在集合 `[start, end]` 中，包括边界值。

AWSTOE 验证`start``end`、和`updateBy`值，以确保组合不会导致无限循环。

`for` 循环架构

```
  - name: "StepName"
    action: "ActionModule"
    loop:
      name: "string"
      for:
        start: int
        end: int
        updateBy: int
inputs:
  ...
```


**`for` 循环输入**  

| 字段 | 描述 | Type | 必需 | 默认 | 
| --- | --- | --- | --- | --- | 
|  `name`  | 循环的唯一名称。与同一阶段的其他循环名称相比，它必须是唯一的。 |  字符串  |  否  |  ""  | 
|  `start`  | 迭代的起始值。不接受链接表达式。 |  整数  |  是  |  不适用  | 
| `end` | 迭代的结束值。不接受链接表达式。 | 整数 | 是 | 不适用 | 
| `updateBy` | 通过加法更新迭代值的差异。它必须是非零负值或正值。不接受链接表达式。 | 整数 | 是 | 不适用 | 

`for` 循环输入示例

```
  - name: "CalculateFileUploadLatencies"
    action: "ExecutePowerShell"
    loop:
      for:
        start: 100000
        end: 1000000
        updateBy: 100000
    inputs:
      commands:
        - |
          $f = new-object System.IO.FileStream c:\temp\test{{ loop.index }}.txt, Create, ReadWrite
          $f.SetLength({{ loop.value }}MB)
          $f.Close()
        - c:\users\administrator\downloads\latencyTest.exe --file c:\temp\test{{ loop.index }}.txt
        - AWS s3 cp c:\users\administrator\downloads\latencyMetrics.json s3://bucket/latencyMetrics.json
        - |
          Remove-Item -Path c:\temp\test{{ loop.index }}.txt
          Remove-Item -Path c:\users\administrator\downloads\latencyMetrics.json
```

### `forEach` 使用输入列表循环
<a name="toe-loop-types-foreach"></a>

该 `forEach` 循环迭代一个显式的值列表，该列表可以是字符串和链式表达式。

`forEach` 使用输入列表架构进行循环

```
  - name: "StepName"
    action: "ActionModule"
    loop:
      name: "string"
      forEach:
        - "string"
    inputs:
  ...
```


**`forEach` 使用输入列表输入进行循环**  

| 字段 | 描述 | Type | 必需 | 默认 | 
| --- | --- | --- | --- | --- | 
|  `name`  | 循环的唯一名称。与同一阶段的其他循环名称相比，它必须是唯一的。 |  字符串  |  否  |  ""  | 
|  `forEach` 循环字符串列表  |  用于迭代的字符串列表。接受链式表达式作为列表中的字符串。链式表达式必须用双引号括起来，YAML 编译器才能正确解释它们。  |  字符串列表  |  是  |  不适用  | 

`forEach` 使用输入列表循环示例 1

```
  - name: "ExecuteCustomScripts"
    action: "ExecuteBash"
    loop:
      name: BatchExecLoop
      forEach:
        - /tmp/script1.sh
        - /tmp/script2.sh
        - /tmp/script3.sh
    inputs:
      commands:
        - echo "Count {{ BatchExecLoop.index }}"
        - sh "{{ loop.value }}"
        - |
          retVal=$?
          if [ $retVal -ne 0 ]; then
            echo "Failed"
          else
            echo "Passed"
         fi
```

`forEach` 使用输入列表循环示例 2

```
  - name: "RunMSIWithDifferentArgs"
    action: "ExecuteBinary"
    loop:
      name: MultiArgLoop
      forEach:
        - "ARG1=C:\Users ARG2=1"
        - "ARG1=C:\Users"
        - "ARG1=C:\Users ARG3=C:\Users\Administrator\Documents\f1.txt"
    inputs:
      commands:
        path: "c:\users\administrator\downloads\runner.exe"
        args:
          - "{{ MultiArgLoop.value }}"
```

`forEach` 使用输入列表循环示例 3

```
  - name: "DownloadAllBinaries"
    action: "S3Download"
    loop:
      name: MultiArgLoop
      forEach:
        - "bin1.exe"
        - "bin10.exe"
        - "bin5.exe"
    inputs:
      - source: "s3://bucket/{{ loop.value }}"
        destination: "c:\temp\{{ loop.value }}"
```

### `forEach` 使用带分隔列表的循环
<a name="toe-loop-types-foreach-delimited"></a>

该循环遍历包含由分隔符分隔的值的字符串。要遍历字符串的组成部分，请 AWSTOE 使用分隔符将字符串拆分为适合迭代的数组。

`forEach` 使用分隔列表架构的循环

```
  - name: "StepName"
    action: "ActionModule"
    loop:
      name: "string"
      forEach:
        list: "string"
        delimiter: ".,;:\n\t -_"
    inputs:
  ...
```


**`forEach` 使用分隔列表输入的循环**  

| 字段 | 描述 | Type | 必需 | 默认 | 
| --- | --- | --- | --- | --- | 
|  `name`  | 赋予循环的唯一名称。与同一阶段的其他循环名称相比，它应该是唯一的。 |  字符串  |  否  |  ""  | 
|  `list`  | 由组成字符串组成的字符串，这些字符串由一个通用分隔符连接在一起。也接受链式表达式。如果是链式表达式，请确保用双引号将它们括起来，以便 YAML 编译器正确解释。 | 字符串 |  是  |  不适用  | 
| `delimiter` | 用于在区块中分隔字符串的字符。默认为逗号字符。在给定的列表中只允许使用一个分隔符：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-looping-constructs.html) 不能使用链接表达式。 | 字符串 | 否 | 逗号："," | 

**注意**  
`list` 的值被视为不可变的字符串。如果在运行时更改了 `list` 的源，则它在运行期间不会反映出来。

`forEach` 使用分隔列表循环示例 1

此示例使用以下链接表达式模式来引用另一个步骤的输出：`<phase_name>.<step_name>.[inputs | outputs].<var_name>`。

```
  - name: "RunMSIs"
    action: "ExecuteBinary"
    loop:
      forEach:
        list: "{{ build.GetAllMSIPathsForInstallation.outputs.stdout }}"
        delimiter: "\n"
    inputs:
      commands:
        path: "{{ loop.value }}"
```

`forEach` 使用分隔列表循环示例 2

```
  - name: "UploadMetricFiles"
    action: "S3Upload"
    loop:
      forEach:
        list: "/tmp/m1.txt,/tmp/m2.txt,/tmp/m3.txt,..."
    inputs:
      commands:
        - source: "{{ loop.value }}"
          destination: "s3://bucket/key/{{ loop.value }}"
```

## 步骤字段
<a name="toe-loop-step-fields"></a>

循环是步骤的一部分。任何与步骤运行相关的字段都不会应用于单个迭代。步骤字段仅应用于步骤级别，如下所示：
+ *timeoutSeconds* – 循环的所有迭代都必须在此字段指定的时间段内运行。如果循环运行超时，则 AWSTOE 运行该步骤的重试策略，并为每次新的尝试重置超时参数。如果循环运行在达到最大重试次数后超过超时值，则该步骤的失败消息将表明循环运行已超时。
+ *onFailure* – 对步骤应用失败处理，如下所示：
  + 如果 *onFa* ilure 设置为`Abort`，则 AWSTOE 退出循环并根据重试策略重试该步骤。在达到最大重试次数后，将当前步骤 AWSTOE 标记为失败，并停止运行该进程。

    AWSTOE 将父阶段和文档的状态码设置为`Failed`。
**注意**  
在失败的步骤之后，不再运行任何其他步骤。
  + 如果 *onFailure* 设置为 `Continue`，则 AWSTOE 退出循环并根据重试策略重试该步骤。在达到最大重试次数后，将当前步骤 AWSTOE 标记为失败，然后继续运行下一个步骤。

    AWSTOE 将父阶段和文档的状态码设置为`Failed`。
  + 如果 *onFailure* 设置为 `Ignore`，则 AWSTOE 退出循环并根据重试策略重试该步骤。在达到最大重试次数后，将当前步骤 AWSTOE 标记为`IgnoredFailure`，然后继续运行下一步。

    AWSTOE 将父阶段和文档的状态码设置为`SuccessWithIgnoredFailure`。
**注意**  
这仍被视为成功运行，但包含一些信息，可让您知道一个或多个步骤失败并被忽略。
+ *maxAttempts * – 每次重试，整个步骤和所有迭代都是从头开始运行的。
+ *状态* – 步骤运行的总体状态。`status` 不代表各个迭代的状态。包含循环的步骤状态确定如下：
  + 如果单个迭代运行失败，则步骤的状态指向失败。
  + 如果所有迭代都成功，则步骤的状态指向成功。
+ *startTime * – 步骤运行的总开始时间。不代表各个迭代的开始时间。
+ *endTime * – 步骤运行的总结束时间。不代表单个迭代的结束时间。
+ *failureMessage * – 包括在出现非超时错误时失败的迭代索引。如果出现超时错误，消息指出该循环运行失败。为了最大限度地减少失败消息的大小，不为每次迭代提供单独的错误消息。

## 步骤和迭代输出
<a name="toe-loop-step-output"></a>

每次迭代都包含一个输出。在循环运行结束时， AWSTOE 将所有成功的迭代输出合并到中。`detailedOutput.json`合并输出是属于相应输出键的值的排序规则，这些值在操作模块的输出架构中定义。下面的示例说明如何合并输出：

**迭代 1 的 `ExecuteBash` 的输出**

```
{
	"stdout":"Hello"
}
```

**迭代 2 的 `ExecuteBash` 的输出**

```
{
	"stdout":"World"
}
```

**步骤的 `ExecuteBash` 的输出**

```
{
	"stdout":"Hello\nWorld"
}
```

例如，`ExecuteBash`、`ExecutePowerShell` 和 `ExecuteBinary` 是操作模块，其返回 `STDOUT` 作为操作模块输出。`STDOUT` 消息与换行符连接以在 `detailedOutput.json` 中生成步骤的总体输出。

AWSTOE 不会合并失败迭代的输出。

# AWSTOE 组件管理器支持的操作模块
<a name="toe-action-modules"></a>

映像构建服务（例如 EC2 Image Builder）使用 AWSTOE 操作模块来帮助配置用于构建和测试自定义机器映像的 EC2 实例。本节介绍常用 AWSTOE 操作模块的功能以及如何配置它们，包括示例。

组件是用纯文本 YAML 文档编写的。有关文档语法的更多信息，请参阅 [使用 AWSTOE 组件文档框架创建自定义组件](toe-use-documents.md)。

**注意**  
所有操作模块在运行时都使用与 Systems Manager 代理相同的帐户，即 Linux 上的 `root` 和 Windows 上的 `NT Authority\SYSTEM`。

以下交叉引用按操作模块执行的操作类型对其进行了分类。

 

**一般执行**
+ [Assert（Linux、Windows、macOS）](#action-modules-assertion)
+ [ExecuteBash （Linux、macOS）](#action-modules-executebash)
+ [ExecuteBinary （Linux、Windows、macOS）](#action-modules-executebinary)
+ [ExecuteDocument （Linux、Windows、macOS）](#action-modules-executedocument)
+ [ExecutePowerShell （视窗）](#action-modules-executepowershell)

 

**文件下载与上传**
+ [S3Download（Linux、Windows、macOS）](#action-modules-s3download)
+ [S3Upload（Linux、Windows、macOS）](#action-modules-s3upload)
+ [WebDownload （Linux、Windows、macOS）](#action-modules-webdownload)

 

**文件系统操作**
+ [AppendFile （Linux、Windows、macOS）](#action-modules-appendfile)
+ [CopyFile （Linux、Windows、macOS）](#action-modules-copyfile)
+ [CopyFolder （Linux、Windows、macOS）](#action-modules-copyfolder)
+ [CreateFile （Linux、Windows、macOS）](#action-modules-createfile)
+ [CreateFolder （Linux、Windows、macOS）](#action-modules-createfolder)
+ [CreateSymlink （Linux、Windows、macOS）](#action-modules-createsymlink)
+ [DeleteFile （Linux、Windows、macOS）](#action-modules-deletefile)
+ [DeleteFolder （Linux、Windows、macOS）](#action-modules-deletefolder)
+ [ListFiles （Linux、Windows、macOS）](#action-modules-listfiles)
+ [MoveFile （Linux、Windows、macOS）](#action-modules-movefile)
+ [MoveFolder （Linux、Windows、macOS）](#action-modules-movefolder)
+ [ReadFile （Linux、Windows、macOS）](#action-modules-readfile)
+ [SetFileEncoding （Linux、Windows、macOS）](#action-modules-setfileencoding)
+ [SetFileOwner （Linux、Windows、macOS）](#action-modules-setfileowner)
+ [SetFolderOwner （Linux、Windows、macOS）](#action-modules-setfolderowner)
+ [SetFilePermissions （Linux、Windows、macOS）](#action-modules-setfilepermissions)
+ [SetFolderPermissions （Linux、Windows、macOS）](#action-modules-setfolderpermissions)

 

**软件安装操作**
+ [InstallMSI (Windows)](#action-modules-install-msi)
+ [UninstallMSI (Windows)](#action-modules-uninstall-msi)

 

**系统操作**
+ [Reboot（Linux、Windows）](#action-modules-reboot)
+ [SetRegistry （视窗）](#action-modules-setregistry)
+ [UpdateOS（Linux、Windows）](#action-modules-updateos)

## 通用执行模块
<a name="action-modules-general-execution"></a>

下一部分详细介绍了运行命令和控制执行工作流的操作模块。

**Topics**
+ [Assert（Linux、Windows、macOS）](#action-modules-assertion)
+ [ExecuteBash （Linux、macOS）](#action-modules-executebash)
+ [ExecuteBinary （Linux、Windows、macOS）](#action-modules-executebinary)
+ [ExecuteDocument （Linux、Windows、macOS）](#action-modules-executedocument)
+ [ExecutePowerShell （视窗）](#action-modules-executepowershell)

### Assert（Linux、Windows、macOS）
<a name="action-modules-assertion"></a>

**Assert** 操作模块使用[比较运算符](toe-comparison-operators.md)或[逻辑运算符](toe-logical-operators.md)作为输入进行值比较。运算符表达式的结果（true 或 false）表示步骤的总体成功或失败状态。

如果比较或逻辑运算符表达式的计算结果为 `true`，则该步骤将标记为 `Success`。否则，该步骤将标记为 `Failed`。如果步骤失败，则 `onFailure` 参数决定步骤的结果。


**Input**  

| 键名称 | 说明 | Type | 必需 | 
| --- | --- | --- | --- | 
| input | 包含单个比较运算符或逻辑运算符。注意，逻辑运算符可以包含多个比较运算符。 | 这不是固定不变的，具体取决于操作人员 | 是 | 

**输入示例：使用 `stringEquals` 比较运算符进行简单比较**

此示例的计算结果为 `true`。

```
- name: StringComparison
  action: Assert
  inputs:
    stringEquals: '2.1.1'
    value: '{{ validate.ApplicationVersion.outputs.stdout }}'
```

**输入示例：使用 `patternMatches` 比较运算符的正则表达式比较**

这些示例的计算结果均为 `true`。

```
- name: Letters only
  action: Assert
  inputs:
    patternMatches: '^[a-zA-Z]+$'
    value: 'ThisIsOnlyLetters'

- name: Letters and spaces only
  action: Assert
  inputs:
    patternMatches: '^[a-zA-Z\s]+$'
    value: 'This text contains spaces'
  
- name: Numbers only
  action: Assert
  inputs:
    patternMatches: '^[0-9]+$'
    value: '1234567890'
```

**输入示例：使用逻辑运算符和链式变量的嵌套比较**

以下示例演示了使用逻辑运算符和链式变量执行嵌套比较。如果以下任一条件为 true，则 `Assert` 的计算结果为 `true`：
+ `ApplicationVersion` 大于 `2.0` 并且 `CPUArchitecture` 等于 `arm64`。
+ `CPUArchitecture` 等于 `x86_64`。

```
- name: NestedComparisons
  action: Assert
  inputs:
    or: # <- first level deep
      - and: # <- second level deep
          - numberGreaterThan: 2.0 # <- third level deep
            value: '{{ validate.ApplicationVersion.outputs.stdout }}'
          - stringEquals: 'arm64'
            value: '{{ validate.CPUArchitecture.outputs.stdout }}'
      - stringEquals: 'x86_64'
        value: '{{ validate.CPUArchitecture.outputs.stdout }}'
```

**输出**：

`Assert` 的输出表示步骤的成功或失败。

### ExecuteBash （Linux、macOS）
<a name="action-modules-executebash"></a>

**ExecuteBash**操作模块允许您使用内联 shell 代码/命令运行 bash 脚本。该模块支持 Linux。

您在命令块中指定的所有命令和指令都将转换为文件（例如 `input.sh`）并使用 bash Shell 执行。Shell 文件的执行结果是退出代码步骤。

如果脚本退出时退出代码为，则该**ExecuteBash**模块会处理系统重新启动。`194`在启动后，该应用程序执行以下操作之一：
+ 如果是由 Systems Manager 代理执行的，该应用程序将向调用方返回退出代码。Systems Manager 代理处理系统重启并运行启动重启的步骤，如[从脚本重启托管实例](https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-reboot.html)中所述。
+ 该应用程序保存当前 `executionstate`，配置重新启动触发器以重新执行该应用程序，然后重新启动系统。

在系统重新启动后，该应用程序执行触发重新启动的相同步骤。如果需要使用该功能，您必须编写幂等脚本以处理多次调用同一 Shell 命令的操作。


**Input**  

| 键名称 | 说明 | Type | 必需 | 
| --- | --- | --- | --- | 
| commands | 包含根据 bash 语法执行的指令或命令列表。允许使用多行 YAML。 | 列表 | 是 | 

**输入示例：重启前后**

```
name: ExitCode194Example
description: This shows how the exit code can be used to restart a system with ExecuteBash
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: RestartTrigger
        action: ExecuteBash
        inputs:
          commands:
            - |
              REBOOT_INDICATOR=/var/tmp/reboot-indicator
              if [ -f "${REBOOT_INDICATOR}" ]; then
                echo 'The reboot file exists. Deleting it and exiting with success.'
                rm "${REBOOT_INDICATOR}"
                exit 0
              fi
              echo 'The reboot file does not exist. Creating it and triggering a restart.'
              touch "${REBOOT_INDICATOR}"
              exit 194
```


**Output**  

| 字段 | 描述 | Type | 
| --- | --- | --- | 
| stdout | 命令执行的标准输出。 | 字符串 | 

如果您执行重新引导，并返回退出代码 `194` 以作为操作模块的一部分，构建将在启动重新引导的同一操作模块步骤处继续执行。如果执行重新引导而没有退出代码，构建过程可能会失败。

**输出示例：重启前（首次按照文档）**

```
{
	“stdout”: “The reboot file does not exist. Creating it and triggering a restart."
}
```

**输出示例：重启后（第二次按照文档）**

```
{
	“stdout”: “The reboot file exists. Deleting it and exiting with success."
}
```

### ExecuteBinary （Linux、Windows、macOS）
<a name="action-modules-executebinary"></a>

**ExecuteBinary**操作模块允许您使用命令行参数列表运行二进制文件。

如果二进制文件退出时退出代码为 `194` (Linux) 或 `3010` (Windows)，则该**ExecuteBinary**模块会处理系统的重新启动。在触发后，该应用程序执行以下操作之一：
+ 如果是由 Systems Manager 代理执行的，该应用程序将向调用方返回退出代码。Systems Manager 代理负责系统重启并运行启动重启的步骤，如[从脚本重启托管实例](https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-reboot.html)中所述。
+ 该应用程序保存当前 `executionstate`，配置重新启动触发器以重新执行该应用程序，然后重新启动系统。

在系统重新启动后，该应用程序执行触发重新启动的相同步骤。如果需要使用该功能，您必须编写幂等脚本以处理多次调用同一 Shell 命令的操作。


**Input**  

| 键名称 | 说明 | Type | 必需 | 
| --- | --- | --- | --- | 
| path | 要执行的二进制文件的路径。 | 字符串 | 是 | 
| arguments | 包含在运行二进制文件时使用的命令行参数列表。 | 字符串列表 | 否 | 

**输入示例：安装 .NET**

```
  - name: "InstallDotnet"
    action: ExecuteBinary
    inputs:
      path: C:\PathTo\dotnet_installer.exe
      arguments:
        - /qb
        - /norestart
```


**Output**  

| 字段 | 描述 | Type | 
| --- | --- | --- | 
| stdout | 命令执行的标准输出。 | 字符串 | 

**输出示例**

```
{
	"stdout": "success"
}
```

### ExecuteDocument （Linux、Windows、macOS）
<a name="action-modules-executedocument"></a>

**ExecuteDocument**操作模块增加了对嵌套组件文档的支持，从一个文档中运行多个组件文档。 AWSTOE 验证运行时在输入参数中传递的文档。

**限制**
+ 此操作模块运行一次，不允许重试，也没有设置超时限制的选项。 **ExecuteDocument**设置以下默认值，如果您尝试更改这些值，则会返回错误。
  + `timeoutSeconds`: -1
  + `maxAttempts`：1
**注意**  
您可以将这些值留空，并 AWSTOE 使用默认值。
+ 文档可以嵌套，最多可嵌套三层，不得超过此限制。三个嵌套级别转换为四个文档级别，因为顶层不是嵌套的。在这种情况下，最低级别的文档不得调用任何其他文档。
+ 不允许循环执行组件文档。任何在循环结构之外调用自身文档，或者调用当前执行链中调用更高层的文档，都会引发循环，从而引发无限循环。当检测到循环执行时， AWSTOE 会停止执行并记录失败。

![\[ExecuteDocument 操作模块的嵌套级别限制。\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/images/toe-component-document-nesting.png)


如果组件文档尝试自行运行，或者尝试运行当前执行链中更高层的任何组件文档，执行将会失败。

**输入**


| 键名称 | 说明 | Type | 必需 | 
| --- | --- | --- | --- | 
| document |  组件文档的路径。有效选项包括： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | 字符串 | 是 | 
| document-s3-bucket-owner |  S3 存储桶所有者的账户 ID，用于存储组件文档的 S3 存储桶。*（如果您在组件文档 URIs 中使用 S3，则建议使用。）*  | 字符串 | 否 | 
| phases |  组件文件中要运行的阶段已用逗号分隔的列表来表示。如果未指定任何阶段，将运行所有阶段。  | 字符串 | 否 | 
| parameters |  在运行时作为键值对传递到组件文档的输入参数。  | 参数映射列表 | 否 | 

**参数映射输入**


| 键名称 | 说明 | Type | 必需 | 
| --- | --- | --- | --- | 
| name |  要传递给**ExecuteDocument**操作模块正在运行的组件文档的输入参数的名称。  | 字符串 | 是 | 
| value |  输入参数的值。  | 字符串 | 是 | 

**输入示例**  
以下示例显示了组件文档的输入变体，具体取决于您的安装路径。

**输入示例：本地文档路径**

```
# main.yaml
schemaVersion: 1.0

phases:
  - name: build
    steps:
      - name: ExecuteNestedDocument
        action: ExecuteDocument
        inputs:
          document: Sample-1.yaml
          phases: build
          parameters:
            - name: parameter-1
              value: value-1
            - name: parameter-2
              value: value-2
```

**输入示例：S3 URI 为文档路径**

```
# main.yaml
schemaVersion: 1.0

phases:
  - name: build
    steps:
      - name: ExecuteNestedDocument
        action: ExecuteDocument
        inputs:
          document: s3://my-bucket/Sample-1.yaml
          document-s3-bucket-owner: 123456789012
          phases: build,validate
          parameters:
            - name: parameter-1
              value: value-1
            - name: parameter-2
              value: value-2
```

**输入示例：EC2 Image Builder 组件 ARN 为文档路径**

```
# main.yaml
schemaVersion: 1.0

phases:
  - name: build
    steps:
      - name: ExecuteNestedDocument
        action: ExecuteDocument
        inputs:
          document: arn:aws:imagebuilder:us-west-2:aws:component/Sample-Test/1.0.0
          phases: test
          parameters:
            - name: parameter-1
              value: value-1
            - name: parameter-2
              value: value-2
```

**使用 ForEach 循环运行文档**

```
# main.yaml
schemaVersion: 1.0

phases:
  - name: build
    steps:
      - name: ExecuteNestedDocument
        action: ExecuteDocument
        loop:
          name: 'myForEachLoop'
          forEach:
            - Sample-1.yaml
            - Sample-2.yaml
        inputs:
          document: "{{myForEachLoop.value}}"
          phases: test
          parameters:
            - name: parameter-1
              value: value-1
            - name: parameter-2
              value: value-2
```

**使用 For 循环运行文档**

```
# main.yaml
schemaVersion: 1.0

phases:
  - name: build
    steps:
      - name: ExecuteNestedDocument
        action: ExecuteDocument
        loop:
          name: 'myForLoop'
          for:
            start: 1
            end: 2
            updateBy: 1
        inputs:
          document: "Sample-{{myForLoop.value}}.yaml"
          phases: test
          parameters:
            - name: parameter-1
              value: value-1
            - name: parameter-2
              value: value-2
```

**Output**  
AWSTOE 创建`detailedoutput.json`每次运行时都调用的输出文件。该文件包含运行时调用的每个组件文档的每个阶段和步骤的详细信息。对于**ExecuteDocument**操作模块，您可以在`outputs`字段中找到简短的运行时摘要，以及有关该模块在其中运行的阶段、步骤和文档的详细信息`detailedOutput`。

```
{
	\"executedStepCount\":1,\"executionId\":\"97054e22-06cc-11ec-9b14-acde48001122\",\"failedStepCount\":0,\"failureMessage\":\"\",\"ignoredFailedStepCount\":0,\"logUrl\":\"\",\"status\":\"success\"
}",
```

每个组件文档的输出摘要对象都包含以下详细信息以及示例值，如下所示：
+ executedStepCount“:1
+ "executionId": "12345a67-89bc-01de-2f34-abcd56789012"
+ failedStepCount“: 0
+ "failureMessage": ""
+ “ignoredFailedStep计数”: 0
+ "logUrl": ""
+ "status": "success"

**输出示例**  
以下示例显示了发生嵌套执行时**ExecuteDocument**操作模块的输出。在此示例中，`main.yaml` 组件文档成功运行了 `Sample-1.yaml` 组件文档。

```
{
    "executionId": "12345a67-89bc-01de-2f34-abcd56789012",
    "status": "success",
    "startTime": "2021-08-26T17:20:31-07:00",
    "endTime": "2021-08-26T17:20:31-07:00",
    "failureMessage": "",
    "documents": [
        {
            "name": "",
            "filePath": "main.yaml",
            "status": "success",
            "description": "",
            "startTime": "2021-08-26T17:20:31-07:00",
            "endTime": "2021-08-26T17:20:31-07:00",
            "failureMessage": "",
            "phases": [
                {
                    "name": "build",
                    "status": "success",
                    "startTime": "2021-08-26T17:20:31-07:00",
                    "endTime": "2021-08-26T17:20:31-07:00",
                    "failureMessage": "",
                    "steps": [
                        {
                            "name": "ExecuteNestedDocument",
                            "status": "success",
                            "failureMessage": "",
                            "timeoutSeconds": -1,
                            "onFailure": "Abort",
                            "maxAttempts": 1,
                            "action": "ExecuteDocument",
                            "startTime": "2021-08-26T17:20:31-07:00",
                            "endTime": "2021-08-26T17:20:31-07:00",
                            "inputs": "[{\"document\":\"Sample-1.yaml\",\"document-s3-bucket-owner\":\"\",\"phases\":\"\",\"parameters\":null}]",
                            "outputs": "[{\"executedStepCount\":1,\"executionId\":\"98765f43-21ed-09cb-8a76-fedc54321098\",\"failedStepCount\":0,\"failureMessage\":\"\",\"ignoredFailedStepCount\":0,\"logUrl\":\"\",\"status\":\"success\"}]",
                            "loop": null,
                            "detailedOutput": [
                                {
                                    "executionId": "98765f43-21ed-09cb-8a76-fedc54321098",
                                    "status": "success",
                                    "startTime": "2021-08-26T17:20:31-07:00",
                                    "endTime": "2021-08-26T17:20:31-07:00",
                                    "failureMessage": "",
                                    "documents": [
                                        {
                                            "name": "",
                                            "filePath": "Sample-1.yaml",
                                            "status": "success",
                                            "description": "",
                                            "startTime": "2021-08-26T17:20:31-07:00",
                                            "endTime": "2021-08-26T17:20:31-07:00",
                                            "failureMessage": "",
                                            "phases": [
                                                {
                                                    "name": "build",
                                                    "status": "success",
                                                    "startTime": "2021-08-26T17:20:31-07:00",
                                                    "endTime": "2021-08-26T17:20:31-07:00",
                                                    "failureMessage": "",
                                                    "steps": [
                                                        {
                                                            "name": "ExecuteBashStep",
                                                            "status": "success",
                                                            "failureMessage": "",
                                                            "timeoutSeconds": 7200,
                                                            "onFailure": "Abort",
                                                            "maxAttempts": 1,
                                                            "action": "ExecuteBash",
                                                            "startTime": "2021-08-26T17:20:31-07:00",
                                                            "endTime": "2021-08-26T17:20:31-07:00",
                                                            "inputs": "[{\"commands\":[\"echo \\\"Hello World!\\\"\"]}]",
                                                            "outputs": "[{\"stdout\":\"Hello World!\"}]",
                                                            "loop": null,
                                                            "detailedOutput": null
                                                        }]
                                                }]
                                        }]
                                }]
                        }]
                
                }]
        }]
}
```

### ExecutePowerShell （视窗）
<a name="action-modules-executepowershell"></a>

**ExecutePowerShell**操作模块允许您使用内联 shell 代码/命令运行 PowerShell 脚本。该模块支持 Windows 平台和 Windows PowerShell。

命令块中 commands/instructions 指定的所有内容都将转换为脚本文件（例如`input.ps1`），并使用 Windows 运行PowerShell。Shell 文件的执行结果是退出代码。

如果 shell 命令退出时退出代码为，则该**ExecutePowerShell**模块将处理系统重新启动。`3010`在启动后，该应用程序执行以下操作之一：
+ 如果由 Systems Manager 代理运行，则将退出代码交给调用者。Systems Manager 代理处理系统重启并运行启动重启的步骤，如[从脚本重启托管实例](https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-reboot.html)中所述。
+ 保存当前 `executionstate`，配置重新启动触发器以重新运行该应用程序，然后重新引导系统。

在系统重新启动后，该应用程序执行触发重新启动的相同步骤。如果需要使用该功能，您必须编写幂等脚本以处理多次调用同一 Shell 命令的操作。


**Input**  

| 键名称 | 说明 | Type | 必需 | 
| --- | --- | --- | --- | 
| commands | 包含要按照PowerShell 语法运行的指令或命令的列表。允许使用多行 YAML。 | 字符串列表 | 可以。必须指定 `commands` 或 `file`，但不能同时指定。  | 
| file | 包含 PowerShell 脚本文件的路径。 PowerShell 将使用-file命令行参数对这个文件运行。路径必须指向 .ps1 文件。 | 字符串 | 可以。必须指定 `commands` 或 `file`，但不能同时指定。  | 

**输入示例：重启前后**

```
name: ExitCode3010Example
description: This shows how the exit code can be used to restart a system with ExecutePowerShell
schemaVersion: 1.0
phases:
  - name: build
    steps:
      - name: RestartTrigger
        action: ExecutePowerShell
        inputs:
          commands:
            - |
              $rebootIndicator = Join-Path -Path $env:SystemDrive -ChildPath 'reboot-indicator'
              if (Test-Path -Path $rebootIndicator) {
                Write-Host 'The reboot file exists. Deleting it and exiting with success.'
                Remove-Item -Path $rebootIndicator -Force | Out-Null
                [System.Environment]::Exit(0)
              }
              Write-Host 'The reboot file does not exist. Creating it and triggering a restart.'
              New-Item -Path $rebootIndicator -ItemType File | Out-Null
              [System.Environment]::Exit(3010)
```


**Output**  

| 字段 | 描述 | Type | 
| --- | --- | --- | 
| stdout | 命令执行的标准输出。 | 字符串 | 

如果您执行重新引导，并返回退出代码 `3010` 以作为操作模块的一部分，构建将在启动重新引导的同一操作模块步骤处继续执行。如果执行重新引导而没有退出代码，构建过程可能会失败。

**输出示例：重启前（首次按照文档）**

```
{
	“stdout”: “The reboot file does not exist. Creating it and triggering a restart."
}
```

**输出示例：重启后（第二次按照文档）**

```
{
	“stdout”: “The reboot file exists. Deleting it and exiting with success."
}
```

## 文件下载与上传模块
<a name="action-modules-download-upload"></a>

下一节详细介绍了上传或下载文件的操作模块。

**Topics**
+ [S3Download（Linux、Windows、macOS）](#action-modules-s3download)
+ [S3Upload（Linux、Windows、macOS）](#action-modules-s3upload)
+ [WebDownload （Linux、Windows、macOS）](#action-modules-webdownload)

### S3Download（Linux、Windows、macOS）
<a name="action-modules-s3download"></a>

使用 `S3Download` 操作模块，您可以将 Amazon S3 对象或一组对象下载到您使用 `destination` 路径指定的本地文件或文件夹。如果指定位置已存在任何文件，且 `overwrite` 标志设置为正确，则 `S3Download` 会覆盖该文件。

`source` 位置可以指向 Amazon S3 中的特定对象，也可以使用带有星号通配符 (`*`) 的键前缀，以下载一组与键前缀路径匹配的对象。当您在 `source` 位置指定键前缀时，`S3Download` 操作模块会下载与该前缀匹配的所有内容（包括文件和文件夹）。确保键前缀以正斜杠结尾，后跟星号 (`/*`)，以下载与该前缀匹配的所有内容。例如：`s3://my-bucket/my-folder/*`。

如果在下载过程中对指定键前缀的 `S3Download` 操作失败，文件夹内容不会回滚到失败之前的状态。目标文件夹将保持失败时的状态。

**支持的使用案例**  
`S3Download` 操作模块支持以下案例：
+ Amazon S3 对象将下载到下载路径中指定的本地文件夹。
+ Amazon S3 对象（在 Amazon S3 文件路径中带有键前缀）将下载到指定的本地文件夹，该文件夹以递归方式将所有与键前缀匹配的 Amazon S3 对象复制到本地文件夹。

**IAM 要求**  
与实例配置文件关联的 IAM 角色必须具有运行 `S3Download` 操作模块的权限。必须将以下 IAM 角色策略附加到与实例配置文件关联的 IAM 角色：
+ **单个文件**：`s3:GetObject`反对 bucket/object （例如，`arn:aws:s3:::BucketName/*`）。
+ **多个文件**：`s3:ListBucket`针对 bucket/object （例如，`arn:aws:s3:::BucketName`）和`s3:GetObject`反对 bucket/object （例如`arn:aws:s3:::BucketName/*`）。


**Input**  

|  Key  |  说明  |  Type  |  必需  |  默认  | 
| --- | --- | --- | --- | --- | 
|  `source`  |  Amazon S3 存储桶为下载源。您可以指定特定对象的路径，也可以使用键前缀（以正斜杠结尾，后跟星号通配符 (`/*`) 来下载一组与键前缀匹配的对象。  |  字符串  |  是  |  不适用  | 
|  `destination`  |  下载 Amazon S3 对象的本地路径。要下载单个文件，您必须将文件名指定为路径的一部分。例如 `/myfolder/package.zip`。  |  字符串  |  是  |  不适用  | 
|  `expectedBucketOwner`  |  `source` 路径中提供的存储桶的预期拥有者账户 ID。我们建议您验证源中指定的 Amazon S3 存储桶的所有权。  |  字符串  |  否  |  不适用  | 
|  `overwrite`  |  设置为正确时，如果指定本地路径的目标文件夹中已存在同名文件，下载文件将覆盖本地文件。如果设置为错误，可避免本地系统上的现有文件被覆盖，并且操作模块会因下载错误而失败。 例如，`Error: S3Download: File already exists and "overwrite" property for "destination" file is set to false. Cannot download.`  |  布尔值  |  否  |  true  | 

**注意**  
对于以下示例，可以将 Windows 文件夹路径替换为 Linux 路径。例如，可以将 `C:\myfolder\package.zip` 替换为 `/myfolder/package.zip`。

**输入示例：将 Amazon S3 对象复制到本地文件**  
以下示例说明了如何将 Amazon S3 对象复制到本地文件。

```
  - name: DownloadMyFile
    action: S3Download
    inputs:
      - source: s3://amzn-s3-demo-source-bucket/path/to/package.zip
        destination: C:\myfolder\package.zip
        expectedBucketOwner: 123456789022
        overwrite: false
      - source: s3://amzn-s3-demo-source-bucket/path/to/package.zip
        destination: C:\myfolder\package.zip
        expectedBucketOwner: 123456789022
        overwrite: true
      - source: s3://amzn-s3-demo-source-bucket/path/to/package.zip
        destination: C:\myfolder\package.zip
        expectedBucketOwner: 123456789022
```

**输入示例：将具有键前缀的 Amazon S3 存储桶中的所有 Amazon S3 对象复制到本地文件夹**  
下面的示例展示了如何将 Amazon S3 存储桶中带有键前缀的所有 Amazon S3 对象复制到本地文件夹。Amazon S3 没有文件夹概念，因此，将复制与键前缀匹配的所有对象。最大可下载数量为 1000。

```
  - name: MyS3DownloadKeyprefix
    action: S3Download
    maxAttempts: 3
    inputs:
      - source: s3://amzn-s3-demo-source-bucket/path/to/*
        destination: C:\myfolder\
        expectedBucketOwner: 123456789022
        overwrite: false
      - source: s3://amzn-s3-demo-source-bucket/path/to/*
        destination: C:\myfolder\
        expectedBucketOwner: 123456789022
        overwrite: true
      - source: s3://amzn-s3-demo-source-bucket/path/to/*
        destination: C:\myfolder\
        expectedBucketOwner: 123456789022
```

**Output**  
无。

### S3Upload（Linux、Windows、macOS）
<a name="action-modules-s3upload"></a>

使用 **S3Upload** 操作模块可以将文件从源文件/文件夹上传到某个 Amazon S3 位置。您可以在源位置指定的路径中使用通配符 (`*`)，以上传路径与通配符模式匹配的所有文件。

如果递归 **S3Upload** 操作失败，已上传的任何文件都将保留在目标 Amazon S3 存储桶中。

**支持的使用案例**
+ 将本地文件上传到 S3 对象。
+ 将文件夹中的本地文件（使用通配符）上传到 Amazon S3 键前缀。
+ 将本地文件夹（必须将 `recurse` 设置为 `true`）复制到 Amazon S3 键前缀。

**IAM 要求**  
与实例配置文件关联的 IAM 角色必须具有运行 `S3Upload` 操作模块的权限。必须将以下 IAM 策略附加到与实例配置文件关联的 IAM 角色。该策略必须向目标 Amazon S3 存储桶授予 `s3:PutObject` 权限。例如，`arn:aws:s3:::BucketName/*`）。


**Input**  

|  Key  |  说明  |  Type  |  必需  |  默认  | 
| --- | --- | --- | --- | --- | 
|  `source`  |   files/folders 源所在的本地路径。`source` 支持星号通配符 (`*`)。  |  字符串  |  是  |  不适用  | 
|  `destination`  |  上传源文件/文件夹的目标 Amazon S3 存储桶的路径。  |  字符串  |  是  |  不适用  | 
|  `recurse`  |  如果设置为 `true`，则递归执行 **S3Upload**。  |  字符串  |  否  |  `false`  | 
|  `expectedBucketOwner`  |  目标路径中指定的 Amazon S3 存储桶的预期所有者账户 ID。我们建议您验证目标中指定的 Amazon S3 存储桶的所有权。  |  字符串  |  否  |  不适用  | 

**输入示例：将本地文件复制到 Amazon S3 对象**  
以下示例说明了如何将本地文件复制到 Amazon S3 对象。

```
  - name: MyS3UploadFile
    action: S3Upload
    onFailure: Abort
    maxAttempts: 3
    inputs:
      - source: C:\myfolder\package.zip
        destination: s3://amzn-s3-demo-destination-bucket/path/to/package.zip
        expectedBucketOwner: 123456789022
```

**输入示例：将具有键前缀的 Amazon S3 存储桶中的所有文件复制到本地文件夹**  
以下示例展示了如何将本地文件夹中的所有文件复制到带有键前缀的 Amazon S3 存储桶中。该示例不会复制子文件夹或其内容，因为未指定 `recurse`，并且它默认为 `false`。

```
  - name: MyS3UploadMultipleFiles
    action: S3Upload
    onFailure: Abort
    maxAttempts: 3
    inputs:
      - source: C:\myfolder\*
        destination: s3://amzn-s3-demo-destination-bucket/path/to/
        expectedBucketOwner: 123456789022
```

**输入示例：将所有文件和文件夹从本地文件夹递归复制到 Amazon S3 存储桶**  
以下示例展示了如何将所有文件和文件夹从本地文件夹递归复制到带有键前缀的 Amazon S3 存储桶中。

```
  - name: MyS3UploadFolder
    action: S3Upload
    onFailure: Abort
    maxAttempts: 3
    inputs:
      - source: C:\myfolder\*
        destination: s3://amzn-s3-demo-destination-bucket/path/to/
        recurse: true
        expectedBucketOwner: 123456789022
```

**Output**  
无。

### WebDownload （Linux、Windows、macOS）
<a name="action-modules-webdownload"></a>

**WebDownload**操作模块允许您通过 HTTP/HTTPS 协议从远程位置下载文件和资源（*建议使用 HTTPS*）。对下载数量或大小没有限制。该模块处理重试和指数回退逻辑。

根据用户输入，每次下载操作最多可尝试 5 次。这些尝试与 `steps` 文档的 `maxAttempts` 字段中指定的尝试不同，而是与操作模块失败有关。

此操作模块隐式处理重定向。除 `200` 外，所有 HTTP 状态代码都会引发错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 | 
| --- | --- | --- | --- | --- | 
| source | 有效的 HTTP/HTTPS 网址（建议使用 HTTPS），它符合 RFC 3986 标准。允许使用链式表达式。 | 字符串 |  是  | 不适用 | 
| destination | 本地系统上的绝对或相对文件或文件夹路径。文件夹路径必须以 / 结尾。如果文件夹路径不以 / 结尾，将被视为文件路径。该模块会创建成功下载所需的任何文件或文件夹。允许使用链式表达式。 | 字符串 | 是 | 不适用 | 
| overwrite | 启用后，下载的文件或资源将覆盖本地系统上的任何现有文件。如果未启用，则不会覆盖本地系统上的任何现有文件，并且操作模块会因错误而失败。启用覆盖并指定了校验和及算法后，只有在任何先前存在的文件的校验和与哈希值不匹配时，操作模块才会下载文件。 | 布尔值 | 否 | true | 
| checksum | 当您指定校验和时，校验和会与使用提供的算法生成的已下载文件的哈希值进行比对。要启用文件验证，必须同时提供校验和与算法。允许使用链式表达式。 | 字符串 | 否 | 不适用 | 
| algorithm | 用于计算校验和的算法。选项包括MD5、 SHA1 SHA256、和 SHA512。要启用文件验证，必须同时提供校验和与算法。允许使用链式表达式。 | 字符串 | 否 | 不适用 | 
| ignoreCertificateErrors | 启用后，SSL 证书验证会被忽略。 | 布尔值 | 否 | false | 


**Output**  

| 键名称 | 说明 | Type | 
| --- | --- | --- | 
| destination | 以换行符分隔的字符串，指定了存储已下载文件或资源的目标路径。 | 字符串 | 

**输入示例：将远程文件下载到本地目标**

```
  - name: DownloadRemoteFile
    action: WebDownload
    maxAttempts: 3
    inputs:
      - source: https://testdomain/path/to/java14.zip
        destination: C:\testfolder\package.zip
```

**输出**：

```
{
	"destination": "C:\\testfolder\\package.zip"
}
```

**输入示例：将多个远程文件下载到多个本地目标**

```
  - name: DownloadRemoteFiles
    action: WebDownload
    maxAttempts: 3
    inputs:
      - source: https://testdomain/path/to/java14.zip
        destination: /tmp/java14_renamed.zip
      - source: https://testdomain/path/to/java14.zip
        destination: /tmp/create_new_folder_and_add_java14_as_zip/
```

**输出**：

```
{
	"destination": "/tmp/create_new_folder/java14_renamed.zip\n/tmp/create_new_folder_and_add_java14_as_zip/java14.zip"
}
```

**输入示例：下载一个远程文件而不覆盖本地目标，然后下载另一个带有文件验证功能的远程文件**

```
  - name: DownloadRemoteMultipleProperties
    action: WebDownload
    maxAttempts: 3
    inputs:
      - source: https://testdomain/path/to/java14.zip
        destination: C:\create_new_folder\java14_renamed.zip
        overwrite: false
      - source: https://testdomain/path/to/java14.zip
        destination: C:\create_new_folder_and_add_java14_as_zip\
        checksum: ac68bbf921d953d1cfab916cb6120864
        algorithm: MD5
        overwrite: true
```

**输出**：

```
{
	"destination": "C:\\create_new_folder\\java14_renamed.zip\nC:\\create_new_folder_and_add_java14_as_zip\\java14.zip"
}
```

**输入示例：下载远程文件并忽略 SSL 认证验证**

```
  - name: DownloadRemoteIgnoreValidation
    action: WebDownload
    maxAttempts: 3
    inputs:
      - source: https://www.bad-ssl.com/resource
        destination: /tmp/downloads/
        ignoreCertificateErrors: true
```

**输出**：

```
{
	"destination": "/tmp/downloads/resource"
}
```

## 文件系统操作模块
<a name="action-modules-file-system-operations"></a>

下一节详细介绍了执行文件系统操作的操作模块。

**Topics**
+ [AppendFile （Linux、Windows、macOS）](#action-modules-appendfile)
+ [CopyFile （Linux、Windows、macOS）](#action-modules-copyfile)
+ [CopyFolder （Linux、Windows、macOS）](#action-modules-copyfolder)
+ [CreateFile （Linux、Windows、macOS）](#action-modules-createfile)
+ [CreateFolder （Linux、Windows、macOS）](#action-modules-createfolder)
+ [CreateSymlink （Linux、Windows、macOS）](#action-modules-createsymlink)
+ [DeleteFile （Linux、Windows、macOS）](#action-modules-deletefile)
+ [DeleteFolder （Linux、Windows、macOS）](#action-modules-deletefolder)
+ [ListFiles （Linux、Windows、macOS）](#action-modules-listfiles)
+ [MoveFile （Linux、Windows、macOS）](#action-modules-movefile)
+ [MoveFolder （Linux、Windows、macOS）](#action-modules-movefolder)
+ [ReadFile （Linux、Windows、macOS）](#action-modules-readfile)
+ [SetFileEncoding （Linux、Windows、macOS）](#action-modules-setfileencoding)
+ [SetFileOwner （Linux、Windows、macOS）](#action-modules-setfileowner)
+ [SetFolderOwner （Linux、Windows、macOS）](#action-modules-setfolderowner)
+ [SetFilePermissions （Linux、Windows、macOS）](#action-modules-setfilepermissions)
+ [SetFolderPermissions （Linux、Windows、macOS）](#action-modules-setfolderpermissions)

### AppendFile （Linux、Windows、macOS）
<a name="action-modules-appendfile"></a>

**AppendFile**操作模块将指定内容添加到文件中先前存在的内容中。

如果文件编码值与默认编码 (`utf-8`) 值不同，可以使用 `encoding` 选项指定文件编码值。默认情况下，`utf-16` 和 `utf-32` 使用小端字节序编码。

发生以下情况时，操作模块会返回错误：
+ 指定的文件在运行时不存在。
+ 您没有修改文件内容的写入权限。
+ 该模块在文件操作期间遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| content | 要附加到文件的内容。 | 字符串 | 否 | 空字符串 | 不适用 | 是 | 
| encoding | 编码标准。 | 字符串 | 否 | utf8 | utf8、utf-8、utf16、utf-16、utf16-LE、utf-16-LE、utf16-BE、utf-16-BE、utf32、utf-32、utf32-LE、utf-32-LE、utf32-BE 和  utf-32-BE。编码选项的值不区分大小写。 | 是 | 

**输入示例：附加文件而不编码（Linux）**

```
  - name: AppendingFileWithOutEncodingLinux
    action: AppendFile
    inputs:
      - path: ./Sample.txt
        content: "The string to be appended to the file"
```

**输入示例：附加文件而不编码（Windows）**

```
  - name: AppendingFileWithOutEncodingWindows
    action: AppendFile
    inputs:
      - path: C:\MyFolder\MyFile.txt
        content: "The string to be appended to the file"
```

**输入示例：附加文件并编码（Linux）**

```
  - name: AppendingFileWithEncodingLinux
    action: AppendFile
    inputs:
      - path: /FolderName/SampleFile.txt
        content: "The string to be appended to the file"
        encoding: UTF-32
```

**输入示例：附加文件并编码（Windows）**

```
  - name: AppendingFileWithEncodingWindows
    action: AppendFile
    inputs:
      - path: C:\MyFolderName\SampleFile.txt
        content: "The string to be appended to the file"
        encoding: UTF-32
```

**输入示例：以空字符串附加文件（Linux）**

```
  - name: AppendingEmptyStringLinux
    action: AppendFile
    inputs:
      - path: /FolderName/SampleFile.txt
```

**输入示例：以空字符串附加文件（Windows）**

```
  - name: AppendingEmptyStringWindows
    action: AppendFile
    inputs:
      - path: C:\MyFolderName\SampleFile.txt
```

**Output**  
无。

### CopyFile （Linux、Windows、macOS）
<a name="action-modules-copyfile"></a>

**CopyFile**操作模块将文件从指定源复制到指定目标。默认情况下，如果目标文件夹在运行时不存在，该模块将会以递归方式创建该文件夹。

如果指定文件夹中已存在具有指定名称的文件，则默认情况下，操作模块将覆盖现有文件。您可以将覆盖选项设置为 `false`，覆盖这一默认行为。当覆盖选项设置为 `false`，并且在指定位置已经存在具有指定名称的文件时，操作模块将返回错误。此选项的工作原理与 Linux 中的 `cp` 命令相同，默认情况下会覆盖。

源文件名可以包含通配符 (`*`)。只有在最后一个文件路径分隔符（`/` 或 `\`）之后才可使用通配符。如果源文件名中包含通配符，则所有与通配符匹配的文件都将复制到目标文件夹。如果要使用通配符移动多个文件，则 `destination` 选项的输入必须以文件路径分隔符（`/` 或 `\`）结尾，这表示目标输入是一个文件夹。

如果目标文件名与源文件名不同，则可以使用 `destination` 选项指定目标文件名。如果未指定目标文件名，则使用源文件的名称来创建目标文件。最后一个文件路径分隔符（`/` 或 `\`）之后的任何文本都将视为文件名。如果要使用与源文件相同的文件名，则 `destination` 选项的输入必须以文件路径分隔符（`/` 或 `\`）结尾。

发生以下情况时，操作模块会返回错误：
+ 您无权在指定文件夹中创建文件。
+ 源文件在运行时不存在。
+ 已存在具有指定文件名的文件夹，且 `overwrite` 选项设置为 `false`。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| source | 源文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| destination | 目标文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| overwrite | 如果设置为错误，当指定位置已经存在具有指定名称的文件时，目标文件将不会被替换。 | 布尔值 | 否 | true | 不适用 | 是 | 

**输入示例：复制文件（Linux）**

```
  - name: CopyingAFileLinux
    action: CopyFile
    inputs:
      - source: /Sample/MyFolder/Sample.txt
        destination: /MyFolder/destinationFile.txt
```

**输入示例：复制文件（Windows）**

```
  - name: CopyingAFileWindows
    action: CopyFile
    inputs:
      - source: C:\MyFolder\Sample.txt
        destination: C:\MyFolder\destinationFile.txt
```

**输入示例：使用源文件名复制文件（Linux）**

```
  - name: CopyingFileWithSourceFileNameLinux
    action: CopyFile
    inputs:
      - source: /Sample/MyFolder/Sample.txt
        destination: /MyFolder/
```

**输入示例：使用源文件名复制文件（Windows）**

```
  - name: CopyingFileWithSourceFileNameWindows
    action: CopyFile
    inputs:
      - source: C:\Sample\MyFolder\Sample.txt
        destination: C:\MyFolder\
```

**输入示例：使用通配符复制文件（Linux）**

```
  - name: CopyingFilesWithWildCardLinux
    action: CopyFile
    inputs:
      - source: /Sample/MyFolder/Sample*
        destination: /MyFolder/
```

**输入示例：使用通配符复制文件（Windows）**

```
  - name: CopyingFilesWithWildCardWindows
    action: CopyFile
    inputs:
      - source: C:\Sample\MyFolder\Sample*
        destination: C:\MyFolder\
```

**输入示例：复制文件而不覆盖（Linux）**

```
  - name: CopyingFilesWithoutOverwriteLinux
    action: CopyFile
    inputs:
      - source: /Sample/MyFolder/Sample.txt
        destination: /MyFolder/destinationFile.txt
        overwrite: false
```

**输入示例：复制文件而不覆盖（Windows）**

```
  - name: CopyingFilesWithoutOverwriteWindows
    action: CopyFile
    inputs:
      - source: C:\Sample\MyFolder\Sample.txt
        destination: C:\MyFolder\destinationFile.txt
        overwrite: false
```

**Output**  
无。

### CopyFolder （Linux、Windows、macOS）
<a name="action-modules-copyfolder"></a>

**CopyFolder**操作模块将文件夹从指定源复制到指定目标。`source` 选项的输入为要复制的文件夹，`destination` 选项的输入为源文件夹内容被复制的文件夹。默认情况下，如果目标文件夹在运行时不存在，该模块将会以递归方式创建该文件夹。

如果指定文件夹中已经存在具有指定名称的文件夹，则默认情况下，操作模块会覆盖现有文件夹。您可以将覆盖选项设置为 `false`，覆盖这一默认行为。如果将覆盖选项设置为 `false`，并且在指定位置已经存在具有指定名称的文件夹，操作模块将返回错误。

源文件夹名称可以包含通配符 (`*`)。只有在最后一个文件路径分隔符（`/` 或 `\`）之后才可使用通配符。如果源文件夹名称中包含通配符，则所有与通配符匹配的文件夹都将复制到目标文件夹。如果要使用通配符复制多个文件夹，则 `destination` 选项的输入必须以文件路径分隔符（`/` 或 `\`）结尾，这表示目标输入是一个文件夹。

如果目标文件夹名称与源文件夹名称不同，则可以使用 `destination` 选项指定目标文件夹名称。如果未指定目标文件夹名称，则使用源文件夹的名称来创建目标文件夹。最后一个文件路径分隔符（`/` 或 `\`）之后的任何文本都将视为文件夹名称。如果要使用与源文件夹相同的文件夹名称，则 `destination` 选项的输入必须以文件路径分隔符（`/` 或 `\`）结尾。

发生以下情况时，操作模块会返回错误：
+ 您无权在指定文件夹中创建文件夹。
+ 源文件夹在运行时不存在。
+ 已存在具有指定文件夹名称的文件夹，且 `overwrite` 选项设置为 `false`。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| source | 源文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| destination | 目标文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| overwrite | 如果设置为错误，当指定位置中已经存在具有指定名称的文件夹时，目标文件夹将不会被替换。 | 布尔值 | 否 | true | 不适用 | 是 | 

**输入示例：复制文件夹（Linux）**

```
  - name: CopyingAFolderLinux
    action: CopyFolder
    inputs:
      - source: /Sample/MyFolder/SampleFolder
        destination: /MyFolder/destinationFolder
```

**输入示例：复制文件夹（Windows）**

```
  - name: CopyingAFolderWindows
    action: CopyFolder
    inputs:
      - source: C:\Sample\MyFolder\SampleFolder
        destination: C:\MyFolder\destinationFolder
```

**输入示例：使用源文件夹名称复制文件夹（Linux）**

```
  - name: CopyingFolderSourceFolderNameLinux
    action: CopyFolder
    inputs:
      - source: /Sample/MyFolder/SourceFolder
        destination: /MyFolder/
```

**输入示例：使用源文件夹名称复制文件夹（Windows）**

```
  - name: CopyingFolderSourceFolderNameWindows
    action: CopyFolder
    inputs:
      - source: C:\Sample\MyFolder\SampleFolder
        destination: C:\MyFolder\
```

**输入示例：使用通配符复制文件夹（Linux）**

```
  - name: CopyingFoldersWithWildCardLinux
    action: CopyFolder
    inputs:
      - source: /Sample/MyFolder/Sample*
        destination: /MyFolder/
```

**输入示例：使用通配符复制文件夹（Windows）**

```
  - name: CopyingFoldersWithWildCardWindows
    action: CopyFolder
    inputs:
      - source: C:\Sample\MyFolder\Sample*
        destination: C:\MyFolder\
```

**输入示例：在不覆盖的情况下复制文件夹（Linux）**

```
  - name: CopyingFoldersWithoutOverwriteLinux
    action: CopyFolder
    inputs:
      - source: /Sample/MyFolder/SourceFolder
        destination: /MyFolder/destinationFolder
        overwrite: false
```

**输入示例：在不覆盖的情况下复制文件夹（Windows）**

```
  - name: CopyingFoldersWithoutOverwrite
    action: CopyFolder
    inputs:
      - source: C:\Sample\MyFolder\SourceFolder
        destination: C:\MyFolder\destinationFolder
        overwrite: false
```

**Output**  
无。

### CreateFile （Linux、Windows、macOS）
<a name="action-modules-createfile"></a>

**CreateFile**操作模块在指定位置创建文件。默认情况下，如有需要，该模块还会以递归方式创建父文件夹。

如果指定文件夹中已存在该文件，则默认情况下，操作模块会截断或覆盖现有文件。您可以将覆盖选项设置为 `false`，覆盖这一默认行为。当覆盖选项设置为 `false`，并且在指定位置已经存在具有指定名称的文件时，操作模块将返回错误。

如果文件编码值与默认编码 (`utf-8`) 值不同，可以使用 `encoding` 选项指定文件编码值。默认情况下，`utf-16` 和 `utf-32` 使用小端字节序编码。

`owner`、`group`、和 `permissions` 是可选输入。`permissions` 的输入必须是字符串值。如果未提供默认值，将使用默认值创建文件。Windows 平台不支持这些选项。如果在 Windows 平台上使用选项 `owner`、`group` 和 `permissions`，则此操作模块将验证并返回错误。

此操作模块可以创建一个文件，其权限由操作系统的默认 `umask` 值定义。如果想覆盖默认值，则必须设置 `umask` 值。

发生以下情况时，操作模块会返回错误：
+ 您无权在指定的父文件夹中创建文件或文件夹。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| content | 文件的文本内容。 | 字符串 | 否 | 不适用 | 不适用 | 是 | 
| encoding | 编码标准。 | 字符串 | 否 | utf8 | utf8、utf-8、utf16、utf-16、utf16-LE、utf-16-LE、utf16-BE、utf-16-BE、utf32、utf-32、utf32-LE、utf-32-LE、utf32-BE 和  utf-32-BE。编码选项的值不区分大小写。 | 是 | 
| owner | 用户名或 ID。 | 字符串 | 否 | 不适用 | 不适用 | Windows 中不支持。 | 
| group | 组名称或 ID。 | 字符串 | 否 | 当前用户。 | 不适用 | Windows 中不支持。 | 
| permissions | 文件权限。 | 字符串 | 否 | 0666 | 不适用 | Windows 中不支持。 | 
| overwrite | 如果指定文件的名称已经存在，则默认情况下，将此值设置为 false 可防止文件被截断或覆盖。 | 布尔值 | 否 | true | 不适用 | 是 | 

**输入示例：创建文件而不覆盖（Linux）**

```
  - name: CreatingFileWithoutOverwriteLinux
    action: CreateFile
    inputs:
      - path: /home/UserName/Sample.txt
        content: The text content of the sample file.
        overwrite: false
```

**输入示例：创建文件而不覆盖（Windows）**

```
  - name: CreatingFileWithoutOverwriteWindows
    action: CreateFile
    inputs:
      - path: C:\Temp\Sample.txt
        content: The text content of the sample file.
        overwrite: false
```

**输入示例：创建带文件属性的文件**

```
  - name: CreatingFileWithFileProperties
    action: CreateFile
    inputs:
      - path: SampleFolder/Sample.txt
        content: The text content of the sample file.
        encoding: UTF-16
        owner: Ubuntu
        group: UbuntuGroup
        permissions: 0777
     - path: SampleFolder/SampleFile.txt
        permissions: 755
      - path: SampleFolder/TextFile.txt
        encoding: UTF-16
        owner: root
        group: rootUserGroup
```

**输入示例：创建不带文件属性的文件**

```
  - name: CreatingFileWithoutFileProperties
    action: CreateFile
    inputs:
      - path: ./Sample.txt
      - path: Sample1.txt
```

**输入示例：创建一个空文件以跳过 Linux 清理脚本中的某一部分**

```
  - name: CreateSkipCleanupfile
    action: CreateFile
    inputs:
      - path: <skip section file name>
```

有关更多信息，请参阅 [覆盖 Linux 清理脚本](security-best-practices.md#override-linux-cleanup-script)

**Output**  
无。

### CreateFolder （Linux、Windows、macOS）
<a name="action-modules-createfolder"></a>

**CreateFolder**操作模块在指定位置创建一个文件夹。默认情况下，如有需要，该模块还会以递归方式创建父文件夹。

如果指定文件夹中已存在该文件夹，则默认情况下，操作模块会截断或覆盖现有文件夹。您可以将覆盖选项设置为 `false`，覆盖这一默认行为。如果将覆盖选项设置为 `false`，并且在指定位置已经存在具有指定名称的文件夹，操作模块将返回错误。

`owner`、`group`、和 `permissions` 是可选输入。`permissions` 的输入必须是字符串值。Windows 平台不支持这些选项。如果在 Windows 平台上使用选项 `owner`、`group` 和 `permissions`，则此操作模块将验证并返回错误。

此操作模块可以创建一个文件夹，其权限由操作系统的默认 `umask` 值定义。如果想覆盖默认值，则必须设置 `umask` 值。

发生以下情况时，操作模块会返回错误：
+ 您无权在指定位置创建文件夹。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| owner | 用户名或 ID。 | 字符串 | 否 | 当前用户。 | 不适用 | Windows 中不支持。 | 
| group | 组名称或 ID。 | 字符串 | 否 | 当前用户的组。 | 不适用 | Windows 中不支持。 | 
| permissions | 文件夹权限。 | 字符串 | 否 | 0777 | 不适用 | Windows 中不支持。 | 
| overwrite | 如果指定文件的名称已经存在，则默认情况下，将此值设置为 false 可防止文件被截断或覆盖。 | 布尔值 | 否 | true | 不适用 | 是 | 

**输入示例：创建文件夹（Linux）**

```
  - name: CreatingFolderLinux
    action: CreateFolder
    inputs:
      - path: /Sample/MyFolder/
```

**输入示例：创建文件夹（Windows）**

```
  - name: CreatingFolderWindows
    action: CreateFolder
    inputs:
      - path: C:\MyFolder
```

**输入示例：创建指定文件夹属性的文件夹**

```
  - name: CreatingFolderWithFolderProperties
    action: CreateFolder
    inputs:
      - path: /Sample/MyFolder/Sample/
        owner: SampleOwnerName
        group: SampleGroupName
        permissions: 0777
      - path: /Sample/MyFolder/SampleFoler/
        permissions: 777
```

**输入示例：创建一个覆盖现有文件夹的文件夹（如有）。**

```
  - name: CreatingFolderWithOverwrite
    action: CreateFolder
    inputs:
      - path: /Sample/MyFolder/Sample/
        overwrite: true
```

**Output**  
无。

### CreateSymlink （Linux、Windows、macOS）
<a name="action-modules-createsymlink"></a>

**CreateSymlink**操作模块创建符号链接或包含对另一个文件的引用的文件。Windows 平台不支持此模块。

`path` 和 `target` 选项的输入可以是绝对路径，也可以是相对路径。如果 `path` 选项的输入是相对路径，则在创建链接时它将替换为绝对路径。

默认情况下，当指定文件夹中已存在具有指定名称的链接时，操作模块会返回错误。您可以将 `force` 选项设置为 `true`，覆盖这一默认行为。当 `force` 选项设置为 `true` 时，模块将覆盖现有链接。

如果父文件夹不存在，则默认情况下，操作模块会以递归方式创建该文件夹。

发生以下情况时，操作模块会返回错误：
+ 目标文件在运行时不存在。
+ 已存在具有指定名称的非符号链接文件。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件路径。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| target | 符号链接指向的目标文件路径。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| force | 当名称相同的链接存在时，将强制创建链接。 | 布尔值 | 否 | false | 不适用 | Windows 中不支持。 | 

**输入示例：创建强制创建链接的符号链接**

```
  - name: CreatingSymbolicLinkWithForce
    action: CreateSymlink
    inputs:
      - path: /Folder2/Symboliclink.txt
        target: /Folder/Sample.txt
        force: true
```

**输入示例：创建不强制创建链接的符号链接**

```
  - name: CreatingSymbolicLinkWithOutForce
    action: CreateSymlink
    inputs:
      - path: Symboliclink.txt
        target: /Folder/Sample.txt
```

**Output**  
无。

### DeleteFile （Linux、Windows、macOS）
<a name="action-modules-deletefile"></a>

**DeleteFile**操作模块删除指定位置的一个或多个文件。

`path` 的输入应该是有效的文件路径或文件名中带有通配符 (`*`) 的文件路径。如果在文件名中已指定通配符，则同一文件夹中与通配符匹配的所有文件都将被删除。

发生以下情况时，操作模块会返回错误：
+ 您无权执行删除的操作。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 

**输入示例：删除单个文件（Linux）**

```
  - name: DeletingSingleFileLinux
    action: DeleteFile
    inputs:
      - path: /SampleFolder/MyFolder/Sample.txt
```

**输入示例：删除单个文件（Windows）**

```
  - name: DeletingSingleFileWindows
    action: DeleteFile
    inputs:
      - path: C:\SampleFolder\MyFolder\Sample.txt
```

**输入示例：删除以“日志”结尾的文件（Linux）**

```
  - name: DeletingFileEndingWithLogLinux
    action: DeleteFile
    inputs:
      - path: /SampleFolder/MyFolder/*log
```

**输入示例：删除以“日志”结尾的文件（Windows）**

```
  - name: DeletingFileEndingWithLogWindows
    action: DeleteFile
    inputs:
      - path: C:\SampleFolder\MyFolder\*log
```

**输入示例：删除指定文件夹中的所有文件（Linux）**

```
  - name: DeletingAllFilesInAFolderLinux
    action: DeleteFile
    inputs:
      - path: /SampleFolder/MyFolder/*
```

**输入示例：删除指定文件夹中的所有文件（Windows）**

```
  - name: DeletingAllFilesInAFolderWindows
    action: DeleteFile
    inputs:
      - path: C:\SampleFolder\MyFolder\*
```

**Output**  
无。

### DeleteFolder （Linux、Windows、macOS）
<a name="action-modules-deletefolder"></a>

**DeleteFolder**操作模块删除文件夹。

如果该文件夹不为空，则必须将 `force` 选项设置为 `true` 才能删除该文件夹及其内容。如果您未将 `force` 选项设置为 `true`，并且您要删除的文件夹不为空，则操作模块会返回错误。`force` 选项的默认值为 `false`。

发生以下情况时，操作模块会返回错误：
+ 您无权执行删除的操作。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| force | 无论文件夹是否为空，都将删除该文件夹。 | 布尔值 | 否 | false | 不适用 | 是 | 

**输入示例：使用 `force` 选项删除非空文件夹（Linux）** 

```
  - name: DeletingFolderWithForceOptionLinux
    action: DeleteFolder
    inputs:
      - path: /Sample/MyFolder/Sample/
        force: true
```

**输入示例：使用 `force` 选项删除非空文件夹（Windows）** 

```
  - name: DeletingFolderWithForceOptionWindows
    action: DeleteFolder
    inputs:
      - path: C:\Sample\MyFolder\Sample\
        force: true
```

**输入示例：删除文件夹（Linux）** 

```
  - name: DeletingFolderWithOutForceLinux
    action: DeleteFolder
    inputs:
      - path: /Sample/MyFolder/Sample/
```

**输入示例：删除文件夹（Windows）** 

```
  - name: DeletingFolderWithOutForce
    action: DeleteFolder
    inputs:
      - path: C:\Sample\MyFolder\Sample\
```

**Output**  
无。

### ListFiles （Linux、Windows、macOS）
<a name="action-modules-listfiles"></a>

**ListFiles**操作模块列出了指定文件夹中的文件。当递归选项设置为 `true` 时，将列出子文件夹中的文件。默认情况下，此模块不列出子文件夹中的文件。

要列出名称与指定模式匹配的所有文件，请使用 `fileNamePattern` 选项提供该模式。`fileNamePattern` 选项接受通配符 (`*`) 值。提供 `fileNamePattern` 时，将返回与指定文件名格式匹配的所有文件。

发生以下情况时，操作模块会返回错误：
+ 指定的文件夹在运行时不存在。
+ 您无权在指定的父文件夹中创建文件或文件夹。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| fileNamePattern | 要匹配以列出名称与该模式匹配的所有文件的模式。 | 字符串 | 否 | 不适用 | 不适用 | 是 | 
| recursive | 递归列出文件夹中的文件。 | 布尔值 | 否 | false | 不适用 | 是 | 

**输入示例：列出指定文件夹中的文件（Linux）**

```
  - name: ListingFilesInSampleFolderLinux
    action: ListFiles
    inputs:
      - path: /Sample/MyFolder/Sample
```

**输入示例：列出指定文件夹中的文件（Windows）**

```
  - name: ListingFilesInSampleFolderWindows
    action: ListFiles
    inputs:
      - path: C:\Sample\MyFolder\Sample
```

**输入示例：列出以“日志”结尾的文件（Linux）**

```
  - name: ListingFilesWithEndingWithLogLinux
    action: ListFiles
    inputs:
      - path: /Sample/MyFolder/
        fileNamePattern: *log
```

**输入示例：列出以“日志”结尾的文件（Windows）**

```
  - name: ListingFilesWithEndingWithLogWindows
    action: ListFiles
    inputs:
      - path: C:\Sample\MyFolder\
        fileNamePattern: *log
```

**输入示例：递归列出文件**

```
  - name: ListingFilesRecursively
    action: ListFiles
    inputs:
      - path: /Sample/MyFolder/
        recursive: true
```


**Output**  

| 键名称 | 说明 | Type | 
| --- | --- | --- | 
| files | 文件列表。 | 字符串 | 

**输出示例**

```
{
	"files": "/sample1.txt,/sample2.txt,/sample3.txt"
}
```

### MoveFile （Linux、Windows、macOS）
<a name="action-modules-movefile"></a>

**MoveFile**操作模块将文件从指定源移动到指定目标。

如果指定文件夹中已存在该文件，则默认情况下，操作模块会覆盖现有文件。您可以将覆盖选项设置为 `false`，覆盖这一默认行为。当覆盖选项设置为 `false`，并且在指定位置已经存在具有指定名称的文件时，操作模块将返回错误。此选项的工作原理与 Linux 中的 `mv` 命令相同，默认情况下会覆盖。

源文件名可以包含通配符 (`*`)。只有在最后一个文件路径分隔符（`/` 或 `\`）之后才可使用通配符。如果源文件名中包含通配符，则所有与通配符匹配的文件都将复制到目标文件夹。如果要使用通配符移动多个文件，则 `destination` 选项的输入必须以文件路径分隔符（`/` 或 `\`）结尾，这表示目标输入是一个文件夹。

如果目标文件名与源文件名不同，则可以使用 `destination` 选项指定目标文件名。如果未指定目标文件名，则使用源文件的名称来创建目标文件。最后一个文件路径分隔符（`/` 或 `\`）之后的任何文本都将视为文件名。如果要使用与源文件相同的文件名，则 `destination` 选项的输入必须以文件路径分隔符（`/` 或 `\`）结尾。

发生以下情况时，操作模块会返回错误：
+ 您无权在指定文件夹中创建文件。
+ 源文件在运行时不存在。
+ 已存在具有指定文件名的文件夹，且 `overwrite` 选项设置为 `false`。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| source | 源文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| destination | 目标文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| overwrite | 如果设置为错误，当指定位置已经存在具有指定名称的文件时，目标文件将不会被替换。 | 布尔值 | 否 | true | 不适用 | 是 | 

**输入示例：移动文件（Linux）**

```
  - name: MovingAFileLinux
    action: MoveFile
    inputs:
      - source: /Sample/MyFolder/Sample.txt
        destination: /MyFolder/destinationFile.txt
```

**输入示例：移动文件（Windows）**

```
  - name: MovingAFileWindows
    action: MoveFile
    inputs:
      - source: C:\Sample\MyFolder\Sample.txt
        destination: C:\MyFolder\destinationFile.txt
```

**输入示例：使用源文件名移动文件（Linux）**

```
  - name: MovingFileWithSourceFileNameLinux
    action: MoveFile
    inputs:
      - source: /Sample/MyFolder/Sample.txt
        destination: /MyFolder/
```

**输入示例：使用源文件名移动文件（Windows）**

```
  - name: MovingFileWithSourceFileNameWindows
    action: MoveFile
    inputs:
      - source: C:\Sample\MyFolder\Sample.txt
        destination: C:\MyFolder
```

**输入示例：使用通配符移动文件（Linux）**

```
  - name: MovingFilesWithWildCardLinux
    action: MoveFile
    inputs:
      - source: /Sample/MyFolder/Sample*
        destination: /MyFolder/
```

**输入示例：使用通配符移动文件（Windows）**

```
  - name: MovingFilesWithWildCardWindows
    action: MoveFile
    inputs:
      - source: C:\Sample\MyFolder\Sample*
        destination: C:\MyFolder
```

**输入示例：移动文件而不覆盖（Linux）**

```
  - name: MovingFilesWithoutOverwriteLinux
    action: MoveFile
    inputs:
      - source: /Sample/MyFolder/Sample.txt
        destination: /MyFolder/destinationFile.txt
        overwrite: false
```

**输入示例：移动文件而不覆盖（Windows）**

```
  - name: MovingFilesWithoutOverwrite
    action: MoveFile
    inputs:
      - source: C:\Sample\MyFolder\Sample.txt
        destination: C:\MyFolder\destinationFile.txt
        overwrite: false
```

**Output**  
无。

### MoveFolder （Linux、Windows、macOS）
<a name="action-modules-movefolder"></a>

**MoveFolder**操作模块将文件夹从指定源移动到指定目标。`source` 选项的输入是要移动的文件夹，而 `destination` 选项的输入是源文件夹内容被移动的文件夹。

如果目标父文件夹或 `destination` 选项的输入在运行时不存在，则默认情况下，模块会在指定的目标上递归创建文件夹。

如果目标文件夹中已存在与源文件夹相同的文件夹，则默认情况下，操作模块会覆盖现有文件夹。您可以将覆盖选项设置为 `false`，覆盖这一默认行为。如果将覆盖选项设置为 `false`，并且在指定位置已经存在具有指定名称的文件夹，操作模块将返回错误。

源文件夹名称可以包含通配符 (`*`)。只有在最后一个文件路径分隔符（`/` 或 `\`）之后才可使用通配符。如果源文件夹名称中包含通配符，则所有与通配符匹配的文件夹都将复制到目标文件夹。如果要使用通配符移动多个文件夹，则 `destination` 选项的输入必须以文件路径分隔符（`/` 或 `\`）结尾，这表示目标输入是一个文件夹。

如果目标文件夹名称与源文件夹名称不同，则可以使用 `destination` 选项指定目标文件夹名称。如果未指定目标文件夹名称，则使用源文件夹的名称来创建目标文件夹。最后一个文件路径分隔符（`/` 或 `\`）之后的任何文本都将视为文件夹名称。如果要使用与源文件夹相同的文件夹名称，则 `destination` 选项的输入必须以文件路径分隔符（`/` 或 `\`）结尾。

发生以下情况时，操作模块会返回错误：
+ 您无权在目标文件夹中创建文件夹。
+ 源文件夹在运行时不存在。
+ 已存在具有指定名称的文件夹，且 `overwrite` 选项设置为 `false`。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| source | 源文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| destination | 目标文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| overwrite | 如果设置为错误，当指定位置中已经存在具有指定名称的文件夹时，目标文件夹将不会被替换。 | 布尔值 | 否 | true | 不适用 | 是 | 

**输入示例：移动文件夹（Linux）**

```
  - name: MovingAFolderLinux
    action: MoveFolder
    inputs:
      - source: /Sample/MyFolder/SourceFolder
        destination: /MyFolder/destinationFolder
```

**输入示例：移动文件夹（Windows）**

```
  - name: MovingAFolderWindows
    action: MoveFolder
    inputs:
      - source: C:\Sample\MyFolder\SourceFolder
        destination: C:\MyFolder\destinationFolder
```

**输入示例：使用源文件夹名称移动文件夹（Linux）**

```
  - name: MovingFolderWithSourceFolderNameLinux
    action: MoveFolder
    inputs:
      - source: /Sample/MyFolder/SampleFolder
        destination: /MyFolder/
```

**输入示例：使用源文件夹名称移动文件夹（Windows）**

```
  - name: MovingFolderWithSourceFolderNameWindows
    action: MoveFolder
    inputs:
      - source: C:\Sample\MyFolder\SampleFolder
        destination: C:\MyFolder\
```

**输入示例：使用通配符移动文件夹（Linux）**

```
  - name: MovingFoldersWithWildCardLinux
    action: MoveFolder
    inputs:
      - source: /Sample/MyFolder/Sample*
        destination: /MyFolder/
```

**输入示例：使用通配符移动文件夹（Windows）**

```
  - name: MovingFoldersWithWildCardWindows
    action: MoveFolder
    inputs:
      - source: C:\Sample\MyFolder\Sample*
        destination: C:\MyFolder\
```

**输入示例：在不覆盖的情况下移动文件夹（Linux）**

```
  - name: MovingFoldersWithoutOverwriteLinux
    action: MoveFolder
    inputs:
      - source: /Sample/MyFolder/SampleFolder
    destination: /MyFolder/destinationFolder
    overwrite: false
```

**输入示例：在不覆盖的情况下移动文件夹（Windows）**

```
  - name: MovingFoldersWithoutOverwriteWindows
    action: MoveFolder
    inputs:
      - source: C:\Sample\MyFolder\SampleFolder
        destination: C:\MyFolder\destinationFolder
        overwrite: false
```

**Output**  
无。

### ReadFile （Linux、Windows、macOS）
<a name="action-modules-readfile"></a>

**ReadFile**操作模块读取字符串类型的文本文件的内容。该模块可用于读取文件内容，以便通过链接在后续步骤中使用，或者用于读取数据到 `console.log` 文件。如果指定的路径是符号链接，则此模块将返回目标文件的内容。该模块仅支持文本文件。

如果文件编码值与默认编码 (`utf-8`) 值不同，可以使用 `encoding` 选项指定文件编码值。默认情况下，`utf-16` 和 `utf-32` 使用小端字节序编码。

默认情况下，此模块无法将文件内容打印到 `console.log` 文件中。您可以通过将 `printFileContent` 属性设置为 `true` 来覆盖此设置。

该模块只能返回文件的内容。该模块无法解析文件（例如 Excel 或 JSON 文件）。

发生以下情况时，操作模块会返回错误：
+ 该文件在运行时不存在。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| encoding | 编码标准。 | 字符串 | 否 | utf8 | utf8、utf-8、utf16、utf-16、utf16-LE、utf-16-LE、utf16-BE、utf-16-BE、utf32、utf-32、utf32-LE、utf-32-LE、utf32-BE 和  utf-32-BE。编码选项的值不区分大小写。 | 是 | 
| printFileContent | 将文件内容打印到 console.log 文件中。 | 布尔值 | 否 | false | 不适用 | 可以。 | 

**输入示例：读取文件（Linux）**

```
  - name: ReadingFileLinux
    action: ReadFile
    inputs:
      - path: /home/UserName/SampleFile.txt
```

**输入示例：读取文件（Windows）**

```
  - name: ReadingFileWindows
    action: ReadFile
    inputs:
      - path: C:\Windows\WindowsUpdate.log
```

**输入示例：读取文件并指定编码标准**

```
  - name: ReadingFileWithFileEncoding
    action: ReadFile
    inputs:
      - path: /FolderName/SampleFile.txt
        encoding: UTF-32
```

**输入示例：读取文件并将其打印到 `console.log` 文件**

```
  - name: ReadingFileToConsole
    action: ReadFile
    inputs:
      - path: /home/UserName/SampleFile.txt
        printFileContent: true
```


**Output**  

| 字段 | 描述 | Type | 
| --- | --- | --- | 
| content | 文件内容。 | 字符串 | 

**输出示例**

```
{
	"content" : "The file content"
}
```

### SetFileEncoding （Linux、Windows、macOS）
<a name="action-modules-setfileencoding"></a>

**SetFileEncoding**操作模块修改现有文件的编码属性。该模块可以将文件编码从 `utf-8` 转换为指定的编码标准。默认情况下，`utf-16` 和 `utf-32` 为小端字节序编码。

发生以下情况时，操作模块会返回错误：
+ 您无权执行指定修改。
+ 该文件在运行时不存在。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件路径。 | 字符串 | 是 | 不适用 | 不适用 | 是 | 
| encoding | 编码标准。 | 字符串 | 否 | utf8 | utf8、utf-8、utf16、utf-16、utf16-LE、utf-16-LE、utf16-BE、utf-16-BE、utf32、utf-32、utf32-LE、utf-32-LE、utf32-BE 和  utf-32-BE。编码选项的值不区分大小写。 | 是 | 

**输入示例：设置文件编码属性**

```
  - name: SettingFileEncodingProperty
    action: SetFileEncoding
    inputs:
      - path: /home/UserName/SampleFile.txt
        encoding: UTF-16
```

**Output**  
无。

### SetFileOwner （Linux、Windows、macOS）
<a name="action-modules-setfileowner"></a>

**SetFileOwner**操作模块修改现有文件的`owner`和`group`所有者属性。如果指定文件是符号链接，则模块将修改源文件的 `owner` 属性。Windows 平台不支持此模块。

该模块接受用户名和组名作为输入。如果未提供组名，则该模块会将文件的组所有者分配给该用户所属的组。

发生以下情况时，操作模块会返回错误：
+ 您无权执行指定修改。
+ 指定的用户名或组名在运行时不存在。
+ 该文件在运行时不存在。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件路径。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| owner | 用户名。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| group | 用户组的名称。 | 字符串 | 否 | 用户属于的组的名称。 | 不适用 | Windows 中不支持。 | 

**输入示例：设置文件所有者属性而不指定用户组名称**

```
  - name: SettingFileOwnerPropertyNoGroup
    action: SetFileOwner
    inputs:
      - path: /home/UserName/SampleText.txt
        owner: LinuxUser
```

**输入示例：通过指定所有者和用户组来设置文件所有者属性**

```
  - name: SettingFileOwnerProperty
    action: SetFileOwner
    inputs:
      - path: /home/UserName/SampleText.txt
        owner: LinuxUser
        group: LinuxUserGroup
```

**Output**  
无。

### SetFolderOwner （Linux、Windows、macOS）
<a name="action-modules-setfolderowner"></a>

**SetFolderOwner**操作模块以递归方式修改现有文件夹的`owner`和`group`所有者属性。默认情况下，该模块可以修改文件夹中所有内容的所有权。您可以将 `recursive` 选项设置为 `false` 以覆盖此行为。Windows 平台不支持此模块。

该模块接受用户名和组名作为输入。如果未提供组名，则该模块会将文件的组所有者分配给该用户所属的组。

发生以下情况时，操作模块会返回错误：
+ 您无权执行指定修改。
+ 指定的用户名或组名在运行时不存在。
+ 该文件夹在运行时不存在。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| owner | 用户名。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| group | 用户组的名称。 | 字符串 | 否 | 用户属于的组的名称。 | 不适用 | Windows 中不支持。 | 
| recursive | 如果设置为 false，将覆盖修改文件夹所有内容所有权的默认行为。 | 布尔值 | 否 | true | 不适用 | Windows 中不支持。 | 

**输入示例：设置文件夹所有者属性而不指定用户组名称**

```
  - name: SettingFolderPropertyWithOutGroup
    action: SetFolderOwner
    inputs:
      - path: /SampleFolder/
        owner: LinuxUser
```

**输入示例：设置文件夹所有者属性而不覆盖文件夹中所有内容的所有权**

```
  - name: SettingFolderPropertyWithOutRecursively
    action: SetFolderOwner
    inputs:
      - path: /SampleFolder/
        owner: LinuxUser
        recursive: false
```

**输入示例：通过指定用户组名称来设置文件所有权属性**

```
  - name: SettingFolderPropertyWithGroup
    action: SetFolderOwner
    inputs:
      - path: /SampleFolder/
        owner: LinuxUser
        group: LinuxUserGroup
```

**Output**  
无。

### SetFilePermissions （Linux、Windows、macOS）
<a name="action-modules-setfilepermissions"></a>

**SetFilePermissions**操作模块修改现有文件的。`permissions`Windows 平台不支持此模块。

`permissions` 的输入必须是字符串值。

此操作模块将创建一个文件，其权限由操作系统默认的 umask 值定义。如果想覆盖默认值，则必须设置 `umask` 值。

发生以下情况时，操作模块会返回错误：
+ 您无权执行指定修改。
+ 该文件在运行时不存在。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件路径。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| permissions | 文件权限。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 

**输入示例：修改文件权限**

```
  - name: ModifyingFilePermissions
    action: SetFilePermissions
    inputs:
      - path: /home/UserName/SampleFile.txt
        permissions: 766
```

**Output**  
无。

### SetFolderPermissions （Linux、Windows、macOS）
<a name="action-modules-setfolderpermissions"></a>

**SetFolderPermissions**操作模块以递归方式修改现有文件夹及其所有子文件和子文件夹。`permissions`默认情况下，此模块可以修改指定文件夹中所有内容的权限。您可以将 `recursive` 选项设置为 `false` 以覆盖此行为。Windows 平台不支持此模块。

`permissions` 的输入必须是字符串值。

此操作模块可以根据操作系统的默认 umask 值修改权限。如果想覆盖默认值，则必须设置 `umask` 值。

发生以下情况时，操作模块会返回错误：
+ 您无权执行指定修改。
+ 该文件夹在运行时不存在。
+ 操作模块在执行操作时遇到错误。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 支持全平台 | 
| --- | --- | --- | --- | --- | --- | --- | 
| path | 文件夹路径。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| permissions | 文件夹权限。 | 字符串 | 是 | 不适用 | 不适用 | Windows 中不支持。 | 
| recursive | 如果设置为 false，将覆盖修改文件夹所有内容权限的默认行为。 | 布尔值 | 否 | true | 不适用 | Windows 中不支持。 | 

**输入示例：设置文件夹权限**

```
  - name: SettingFolderPermissions
    action: SetFolderPermissions
    inputs:
      - path: SampleFolder/
        permissions: 0777
```

**输入示例：设置文件夹权限而不修改文件夹所有内容的权限**

```
  - name: SettingFolderPermissionsNoRecursive
    action: SetFolderPermissions
    inputs:
      - path: /home/UserName/SampleFolder/
        permissions: 777
        recursive: false
```

**Output**  
无。

## 软件安装操作
<a name="action-modules-software-install-actions"></a>

下一部分介绍了安装或卸载软件的操作模块。

**IAM 要求**  
如果您的安装下载路径是 S3 URI，则与您的实例配置文件关联的 IAM 角色必须具有运行 `S3Download` 操作模块的权限。要授予所需权限，请将 `S3:GetObject` IAM 策略附加到与实例配置文件关联的 IAM 角色，并指定存储桶的路径。例如，`arn:aws:s3:::BucketName/*`）。

**复杂 MSI 输入**  
如果您的输入字符串包含双引号字符 (`"`)，则必须使用以下方法之一来确保其得到正确解释：
+ 您可以在字符串的外部使用单引号（'）来包含它，并在字符串内部使用双引号（"），如下面的示例所示。

  ```
  properties:
    COMPANYNAME: '"Acme ""Widgets"" and ""Gizmos."""'
  ```

  在这种情况下，如果您需要在字符串中使用撇号，则必须对其进行转义。这意味着需要在撇号前使用另一个单引号（'）。
+ 你可以在字符串的外面使用双引号（"）来包含它。您可以使用反斜杠字符 (`\`) 对字符串中的任何双引号进行转义，如以下示例所示。

  ```
  properties:
    COMPANYNAME: "\"Acme \"\"Widgets\"\" and \"\"Gizmos.\"\"\""
  ```

这两种方法都将值 `COMPANYNAME="Acme ""Widgets"" and ""Gizmos."""` 传递给 **msiexec** 命令。

**Topics**
+ [InstallMSI (Windows)](#action-modules-install-msi)
+ [UninstallMSI (Windows)](#action-modules-uninstall-msi)

### InstallMSI (Windows)
<a name="action-modules-install-msi"></a>

`InstallMSI` 操作模块使用 MSI 文件安装 Windows 应用程序。您可以使用本地路径、S3 对象 URI 或 Web URL 来指定 MSI 文件。重新启动选项可配置系统的重新启动行为。

AWSTOE 根据操作模块的输入参数生成**msiexec**命令。`path`（MSI 文件位置）和 `logFile`（日志文件位置）输入参数的值必须用引号（"）括起来。

以下 MSI 退出代码视为成功：
+ 0（成功）
+ 1614（ERROR\$1PRODUCT\$1UNINSTALLED）
+ 1641（已启动重启）
+ 3010（需要重启）


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 
| --- | --- | --- | --- | --- | --- | 
| path |  使用以下之一指定 MSI 文件位置： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html) 允许使用链接表达式。  | 字符串 | 是 | 不适用 | 不适用 | 
| reboot |  配置成功运行操作模块后的系统重启行为。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | 字符串 | 否 | Allow | Allow, Force, Skip | 
| logOptions |  指定用于 MSI 安装日志的选项。指定的标志与 `/L` 命令行参数一起传递给 MSI 安装程序，以启用日志记录。如果未指定任何标志，则 AWSTOE 使用默认值。 有关 MSI 日志选项的更多信息，请参阅 Microsoft *Windows Installer* 产品文档中的 [命令行选项](https://learn.microsoft.com/en-us/windows/win32/msi/command-line-options)。  | 字符串 | 否 | \$1VX | i,w,e,a,r,u,c,m,o,p,v,x,\$1,\$1,\$1 | 
| logFile |  日志文件位置的绝对路径或相对路径。如果该日志文件路径不存在，请创建它。如果未提供日志文件路径，则 AWSTOE 不存储 MSI 安装日志。  | 字符串 | 否 | 不适用 | 不适用 | 
| properties |  MSI 日志属性键值对，例如：`TARGETDIR: "C:\target\location"`   注意：不允许修改以下属性： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | Map[String]String | 否 | 不适用 | 不适用 | 
| ignoreAuthenticodeSignatureErrors |  忽略路径中指定的安装程序的 authenticode 签名验证错误的标志。**Get-AuthenticodeSignature** 命令用于验证安装程序。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | 布尔值 | 否 | false | true, false | 
| allowUnsignedInstaller |  允许运行路径中指定的未签名安装程序的标志。**Get-AuthenticodeSignature** 命令用于验证安装程序。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | 布尔值 | 否 | false | true, false | 

**示例**  
以下示例显示了组件文档输入部分的变体，具体取决于您的安装路径。

**输入示例：本地文档路径安装**

```
- name: local-path-install
  steps:
    - name: LocalPathInstaller
      action: InstallMSI
      inputs:
        path: C:\sample.msi
        logFile: C:\msilogs\local-path-install.log
        logOptions: '*VX'
        reboot: Allow
        properties:
          COMPANYNAME: '"Amazon Web Services"'
        ignoreAuthenticodeSignatureErrors: true
        allowUnsignedInstaller: true
```

**输入示例：Amazon S3 路径安装**

```
- name: s3-path-install
  steps:
    - name: S3PathInstaller
      action: InstallMSI
      inputs:
        path: s3://<bucket-name>/sample.msi
        logFile: s3-path-install.log
        reboot: Force
        ignoreAuthenticodeSignatureErrors: false
        allowUnsignedInstaller: true
```

**输入示例：Web 路径安装**

```
- name: web-path-install
  steps:
    - name: WebPathInstaller
      action: InstallMSI
      inputs:
        path: https://<some-path>/sample.msi
        logFile: web-path-install.log
        reboot: Skip
        ignoreAuthenticodeSignatureErrors: true
        allowUnsignedInstaller: false
```

**Output**  
以下是 `InstallMSI` 操作模块的输出示例。

```
{
	"logFile": "web-path-install.log",
	"msiExitCode": 0,
	"stdout": ""
}
```

### UninstallMSI (Windows)
<a name="action-modules-uninstall-msi"></a>

`UninstallMSI` 操作模块允许您使用 MSI 文件删除 Windows 应用程序。您可以使用本地文件路径、S3 对象 URI 或 Web URL 指定 MSI 文件位置。重新启动选项可配置系统的重新启动行为。

AWSTOE 根据操作模块的输入参数生成**msiexec**命令。生成 **msiexec** 命令时，MSI 文件位置 (`path`) 和日志文件位置 (`logFile`) 将明确用双引号（"）括起来。

以下 MSI 退出代码视为成功：
+ 0（成功）
+ 1605（ERROR\$1UNKNOWN\$1PRODUCT）
+ 1614（ERROR\$1PRODUCT\$1UNINSTALLED）
+ 1641（已启动重启）
+ 3010（需要重启）


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 值 | 可接受值 | 
| --- | --- | --- | --- | --- | --- | 
| path |  使用以下之一指定 MSI 文件位置： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html) 允许使用链接表达式。  | 字符串 | 是 | 不适用 | 不适用 | 
| reboot |  配置成功运行操作模块后的系统重启行为。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | 字符串 | 否 | Allow | Allow, Force, Skip | 
| logOptions |  指定用于 MSI 安装日志的选项。指定的标志与 `/L` 命令行参数一起传递给 MSI 安装程序，以启用日志记录。如果未指定任何标志，则 AWSTOE 使用默认值。 有关 MSI 日志选项的更多信息，请参阅 Microsoft *Windows Installer* 产品文档中的 [命令行选项](https://docs.microsoft.com/en-us/windows/win32/msi/command-line-options)。  | 字符串 | 否 | \$1VX | i,w,e,a,r,u,c,m,o,p,v,x,\$1,\$1,\$1 | 
| logFile |  日志文件位置的绝对路径或相对路径。如果该日志文件路径不存在，请创建它。如果未提供日志文件路径，则 AWSTOE 不存储 MSI 安装日志。  | 字符串 | 否 | 不适用 | 不适用 | 
| properties |  MSI 日志属性键值对，例如：`TARGETDIR: "C:\target\location"`   注意：不允许修改以下属性： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | Map[String]String | 否 | 不适用 | 不适用 | 
| ignoreAuthenticodeSignatureErrors |  忽略路径中指定的安装程序的 authenticode 签名验证错误的标志。**Get-AuthenticodeSignature** 命令用于验证安装程序。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | 布尔值 | 否 | false | true, false | 
| allowUnsignedInstaller |  允许运行路径中指定的未签名安装程序的标志。**Get-AuthenticodeSignature** 命令用于验证安装程序。 [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html)  | 布尔值 | 否 | false | true, false | 

**示例**  
以下示例显示了组件文档输入部分的变体，具体取决于您的安装路径。

**输入示例：移除本地文档路径安装**

```
- name: local-path-uninstall
  steps:
    - name: LocalPathUninstaller
      action: UninstallMSI
      inputs:
        path: C:\sample.msi
        logFile: C:\msilogs\local-path-uninstall.log
        logOptions: '*VX'
        reboot: Allow
        properties:
          COMPANYNAME: '"Amazon Web Services"'
        ignoreAuthenticodeSignatureErrors: true
        allowUnsignedInstaller: true
```

**输入示例：移除 Amazon S3 路径安装**

```
- name: s3-path-uninstall
  steps:
    - name: S3PathUninstaller
      action: UninstallMSI
      inputs:
        path: s3://<bucket-name>/sample.msi
        logFile: s3-path-uninstall.log
        reboot: Force
        ignoreAuthenticodeSignatureErrors: false
        allowUnsignedInstaller: true
```

**输入示例：移除 Web 路径安装**

```
- name: web-path-uninstall
  steps:
    - name: WebPathUninstaller
      action: UninstallMSI
      inputs:
        path: https://<some-path>/sample.msi
        logFile: web-path-uninstall.log
        reboot: Skip
        ignoreAuthenticodeSignatureErrors: true
        allowUnsignedInstaller: false
```

**Output**  
以下是 `UninstallMSI` 操作模块的输出示例。

```
{
	"logFile": "web-path-uninstall.log",
	"msiExitCode": 0,
	"stdout": ""
}
```

## 系统操作模块
<a name="action-modules-system-actions"></a>

下一部分介绍了执行系统操作或更新系统设置的操作模块。

**Topics**
+ [Reboot（Linux、Windows）](#action-modules-reboot)
+ [SetRegistry （视窗）](#action-modules-setregistry)
+ [UpdateOS（Linux、Windows）](#action-modules-updateos)

### Reboot（Linux、Windows）
<a name="action-modules-reboot"></a>

**重启** 操作模块重新引导实例。它具有一个可配置的选项以延迟启动重新引导。默认情况下，`delaySeconds` 设置为 `0`，表示没有延迟。由于在实例重启时步骤超时不适用，因此重启操作模块不支持步骤超时。

如果该应用程序是由 Systems Manager 代理调用的，则向 Systems Manager 代理返回退出代码（Windows 为 `3010`，Linux 为 `194`）。Systems Manager 代理处理系统重新引导，如[从脚本中重新引导托管实例](https://docs.aws.amazon.com/systems-manager/latest/userguide/send-commands-reboot.html)中所述。

如果该应用程序是在主机上作为单独进程调用的，它将保存当前执行状态，配置重新引导后自动运行触发器以重新执行该应用程序，然后重新引导系统。

**重新引导后自动运行触发器：**
+ **Windows**： AWSTOE 创建了一个 Windows 任务调度器条目，其触发器在 `SystemStartup` 自动运行
+ **Linux**： AWSTOE 在 crontab 中添加了一个在系统重启后自动运行的作业。

```
@reboot /download/path/awstoe run --document s3://bucket/key/doc.yaml
```

在该应用程序启动时，将清除该触发器。

**重试**  
默认情况下，最大重试次数设置为 Systems Manager `CommandRetryLimit`。如果重启次数超过重试限制，自动化将失败。您可以通过编辑 Systems Manager 代理配置文件（`Mds.CommandRetryLimit`）来更改限制。请参阅 Systems Manager 代理开源中的 [Runtime Configuration](https://github.com/aws/amazon-ssm-agent/blob/mainline/README.md#runtime-configuration)。

要使用 **Reboot** 操作模块，对于包含重新引导 `exitcode` 的步骤（例如，`3010`），您必须以 `sudo user` 形式运行应用程序二进制文件。


**Input**  

| 键名称 | 说明 | Type | 必需 | 默认 | 
| --- | --- | --- | --- | --- | 
| delaySeconds | 在启动重新引导之前延迟特定的时间。 | 整数 |  否  |  `0`  | 

**输入示例：重启步骤**

```
  - name: RebootStep
    action: Reboot
    onFailure: Abort
    maxAttempts: 2
    inputs:
      delaySeconds: 60
```

**输出**

无。

在 **重新引导** 模块完成后，Image Builder 继续执行构建中的下一步。

### SetRegistry （视窗）
<a name="action-modules-setregistry"></a>

**SetRegistry**操作模块接受输入列表，并允许您设置指定注册表项的值。如果注册表项不存在，则会在定义的路径中创建该注册表项。该功能仅适用于 Windows。


**Input**  

| 键名称 | 说明 | Type | 必需 | 
| --- | --- | --- | --- | 
| path | 注册表项的路径。 | 字符串 | 是 | 
| name | 注册表项的名称。 | 字符串 | 是 | 
| value | 注册表项的值。 | String/Number/Array | 是 | 
| type | 注册表项的值类型。 | 字符串 | 是 | 

**支持的路径前缀**
+ `HKEY_CLASSES_ROOT / HKCR:`
+ `HKEY_USERS / HKU:`
+ `HKEY_LOCAL_MACHINE / HKLM:`
+ `HKEY_CURRENT_CONFIG / HKCC:`
+ `HKEY_CURRENT_USER / HKCU:`

**支持的类型**
+ `BINARY`
+ `DWORD`
+ `QWORD`
+ `SZ`
+ `EXPAND_SZ`
+ `MULTI_SZ`

**输入示例：设置注册表键值**

```
  - name: SetRegistryKeyValues
    action: SetRegistry
    maxAttempts: 3
    inputs:
      - path: HKLM:\SOFTWARE\MySoftWare
        name: MyName
        value: FirstVersionSoftware
        type: SZ
      - path: HKEY_CURRENT_USER\Software\Test
        name: Version
        value: 1.1
        type: DWORD
```

**输出**

无。

### UpdateOS（Linux、Windows）
<a name="action-modules-updateos"></a>

**UpdateOS** 操作模块增加了对安装 Windows 和 Linux 更新的支持。默认情况下会安装所有可用更新。或者，您可以为待安装的操作模块配置一个或多个特定更新的列表。您也可以指定要从安装中排除的更新。

如果同时提供了“包括”和“排除”列表，则更新的结果列表只能包含在“包括”列表中列出并且在“排除”列表中未列出的那些更新。

**注意**  
**UpdateOS** 不支持亚马逊 Linux 2023 () AL2023。我们建议您将基本 AMI 更新到每个发布版本附带的新版本。有关其他替代方案，请参阅 *Amazon Linux 2023 用户指南*中的[控制从主要版本和次要版本收到的更新](https://docs.aws.amazon.com/linux/al2023/ug/deterministic-upgrades.html#controlling-release-updates)。
+ **Windows**。更新是从目标计算机上配置的更新源中安装的。
+ **Linux**。该应用程序检查 Linux 平台中支持的软件包管理器，并使用 `yum` 或 `apt-get` 软件包管理器。如果不支持这两个软件包管理器，则会返回错误。你应当拥有运行 **UpdateOS** 操作模块的 `sudo` 权限。如果您没有 `sudo` 权限，则会返回 `error.Input`。


**Input**  

| 键名称 | 说明 | Type | 必需 | 
| --- | --- | --- | --- | 
| include |  对于 Windows，可以指定以下值： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html) 对于 Linux，您可以指定一个或多个要包括在安装的更新列表中的软件包。  | 字符串列表 | 否 | 
| exclude |  对于 Windows，可以指定以下值： [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/imagebuilder/latest/userguide/toe-action-modules.html) 对于 Linux，您可以指定一个或多个要从安装的更新列表中排除的软件包。  | 字符串列表 | 否 | 

**输入示例：添加对安装 Linux 更新的支持**

```
  - name: UpdateMyLinux
    action: UpdateOS
    onFailure: Abort
    maxAttempts: 3
    inputs:
      exclude:
        - ec2-hibinit-agent
```

**输入示例：添加对安装 Windows 更新的支持**

```
  - name: UpdateWindowsOperatingSystem
    action: UpdateOS
    onFailure: Abort
    maxAttempts: 3
    inputs:
      include:
        - KB1234567
        - '*Security*'
```

**输出**

无。

# 配置 AWSTOE 运行命令的输入
<a name="toe-run-config-input"></a>

要简化命令的命令行输入，可以在文件 AWSTOE **run**扩展名为 JSON 格式的输入配置文件中包含命令参数和选项的`.json`设置。 AWSTOE 可以从以下位置之一读取您的文件：
+ 本地文件路径 (*./config.json*)。
+ 一个 S3 存储桶 (*s3://<bucket-path>/<bucket-name>/config.json*)。

输入 **run** 命令时，您可以使用 **--config** 参数指定输入配置文件。例如：

```
awstoe run --config <file-path>/config.json
```

**输入配置文件**  
输入配置 JSON 文件中包含所有设置的键值对，您可以通过 **run** 命令参数和选项直接提供这些设置。如果您在输入配置文件和 **run** 命令中都指定了一个设置作为参数或选项，则以下优先规则适用：

**优先规则**

1. 通过参数或选项直接提供给**run**命令的 AWS CLI设置会覆盖在输入配置文件中为相同设置定义的任何值。

1. 输入配置文件中的设置会覆盖组件的默认值。

1. 如果没有将其他设置传递到组件文档，则它可以应用默认值（如果存在）。

此规则有两个例外：文档和参数。这些设置在输入配置中和作为命令参数时的工作方式有所不同。如果使用输入配置文件，则不得直接向 **run** 命令指定这些参数。这样做会产生错误。

**组件设置**  
输入配置文件包含以下设置。要简化文件，可以省略任何不需要的可选设置。除非另有说明，否则所有设置均为可选设置。
+ **cwIgnoreFailures**（布尔值）-忽略日志中的 CloudWatch 日志失败。
+ **cwLogGroup**（字符串）- CloudWatch 日志的`LogGroup`名称。
+ **cwLogRegion**（字符串）-适用于 CloudWatch 日志的 AWS 区域。
+ **cwLogStream**（字符串）- CloudWatch 日志的`LogStream`名称，用于指示将`console.log`文件流式传输到 AWSTOE 何处。
+ d@@ **ocumentS3 BucketOwner**（字符串）— 基于 URI 的 S3 文档的存储桶所有者的账户 ID。
+ **文档**（对象数组，必填）— 一个 JSON 对象数组，代表 AWSTOE **run**命令正在运行的 YAML 组件文档。必须指定至少一个组件文档。

  对象由以下字段组成：
  + **路径**（字符串，必填）-YAML 组件文档的文件位置。其必须是以下内容之一：
    + 本地文件路径 (*./component-doc-example.yaml*)。
    + 一个 S3; URI (`s3://bucket/key`)。
    + Image Builder 组件构建版本 ARN（arn: aws: imagebuilder: us-west--: component/ /2021.12.02/1）。*2:123456789012* *my-example-component*
  + **parameters**（对象数组）-键值对对象的数组，每个代表 **run** 命令在运行组件文档时传入的特定于组件的参数。组件的参数是可选的。组件文档可能定义参数，也可能没有定义参数。

    对象由以下字段组成：
    + **name**（字符串，必填）-组件参数的名称。
    + **value**（字符串，必填）-要传递到组件文档的命名参数的值。

    要了解有关组件参数的更多信息，请参阅 [在自定义组件文档中使用变量](toe-user-defined-variables.md) 页面的**参数**一节。
+ **executonId**（字符串）-这是适用于执行当前 **run** 命令的唯一 ID。此 ID 包含在输出和日志文件名中，用于唯一标识这些文件，并将它们链接到当前的命令执行。如果省略此设置，则 AWSTOE 生成 GUID。
+ **LogDire** ctory（字符串）- AWSTOE 存储此命令执行的所有日志文件的目标目录。默认情况下，该目录位于以下父目录中：`TOE_<DATETIME>_<EXECUTIONID>`。如果未指定日志目录，则 AWSTOE 使用当前工作目录 (`.`)。
+ **LogS3 BucketName**（字符串）-如果组件日志存储在 Amazon S3 中（推荐），则将组件应用程序日志 AWSTOE 上传到此参数中命名的 S3 存储桶。
+ **LogS3 BucketOwner**（字符串）-如果组件日志存储在 Amazon S3 中（推荐），则这是 AWSTOE 写入日志文件的存储桶的所有者账户 ID。
+ **LogS3 KeyPrefix**（字符串）— 如果组件日志存储在 Amazon S3 中（推荐），则这是存储桶中日志位置的 S3 对象密钥前缀。
+ **parameters**（对象数组）-键值对对象的数组，表示全局应用于当前 **run** 命令执行中包含的所有组件的参数。
  + **name**（字符串，必填）-全局参数的名称。
  + **值**（字符串，必填）-要传递到所有组件文档的命名参数的值。
+ **phases**（字符串）-以逗号分隔的列表，它指定要从 YAML 组件文档中运行哪些阶段。如果组件文档包含其他阶段，则这些阶段将无法运行。
+ **stateDirectory**（字符串）-存储状态跟踪文件的文件路径。
+ **trace**(布尔值)-启用对控制台的详细日志记录。

**示例**  
以下示例显示了一个输入配置文件，该文件为两个组件文档 `sampledoc.yaml` 和 `conversation-intro.yaml` 运行 `build` 和 `test` 阶段。每个组件文档都有一个仅适用于其自身的参数，并且两者都使用一个共享参数。`project` 参数对两个组件文档均适用。

```
{
   "documents": [
     {
       "path": "<file path>/awstoe/sampledoc.yaml>",
       "parameters": [
         {
           "name": "dayofweek",
           "value": "Monday"
         }
       ]
     },
     {
       "path": "<file path>/awstoe/conversation-intro.yaml>",
       "parameters": [
         {
           "name": "greeting",
           "value": "Hello, HAL."
         }
       ]
     }
   ],
   "phases": "build,test",
   "parameters": [
     {
       "name": "project",
       "value": "examples"
     }
   ],
   "cwLogGroup": "<log_group_name>",
   "cwLogStream": "<log_stream_name>",
   "documentS3BucketOwner": "<owner_aws_account_number>",
   "executionId": "<id_number>",
   "logDirectory": "<local_directory_path>",
   "logS3BucketName": "<bucket_name_for_log_files>",
   "logS3KeyPrefix": "<key_prefix_for_log_files>",
   "logS3BucketOwner": "<owner_aws_account_number>"
 }
```