

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 在 中使用迴圈建構 AWS TOE
<a name="toe-looping-constructs"></a>

本節提供的資訊可協助您在 中建立迴圈建構 AWS TOE。循環建構定義一系列重複的指示。您可以在 中使用下列類型的循環建構 AWS TOE：
+ `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>

會 AWS TOE 解析參考表達式，如下所示：
+ `{{ <loop_name>.* }}` –使用以下邏輯 AWS TOE 解決此表達式：
  + 如果目前執行步驟的迴圈符合 `<loop_name>`值，則參考表達式會解析為目前執行步驟的迴圈建構。
  + `<loop_name>` 如果在目前執行的步驟中出現， 會解析為具名迴圈建構。
+ `{{ loop.* }}` –使用目前執行步驟中定義的迴圈建構來 AWS TOE 解析表達式。

如果在不包含迴圈的步驟中使用參考表達式，則 AWS TOE 不會解析表達式，並且它們會出現在步驟中，而不會替換。

**注意**  
參考表達式必須以雙引號括住，以便 YAML 編譯器正確解譯。

## 迴圈建構的類型
<a name="toe-loop-types"></a>

本節提供有關迴圈可在 中使用的建構類型的資訊和範例 AWS TOE。

**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]`，並包含邊界值。

AWS TOE 驗證 `start`、 `end`和 `updateBy`值，以確保組合不會造成無限迴圈。

`for` 迴圈結構描述

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


**`for` 迴圈輸入**  

| 欄位 | 說明 | Type | 必要 | 預設 | 
| --- | --- | --- | --- | --- | 
|  `name`  | 迴圈的唯一名稱。與相同階段中的其他迴圈名稱相比，它必須是唯一的。 |  String  |  否  |  ""  | 
|  `start`  | 反覆運算的起始值。不接受鏈結表達式。 |  Integer  |  是  |  N/A  | 
| `end` | 反覆運算的結束值。不接受鏈結表達式。 | Integer | 是 | N/A | 
| `updateBy` | 透過新增更新反覆運算值的差異。它必須是負值或非零值。不接受鏈結表達式。 | Integer | 是 | N/A | 

`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`  | 迴圈的唯一名稱。與相同階段中的其他迴圈名稱相比，它必須是唯一的。 |  String  |  否  |  ""  | 
|  `forEach` 迴圈字串清單  |  反覆運算的字串清單。接受鏈結表達式做為清單中的字串。鏈結表達式必須以雙引號括住，YAML 編譯器才能正確解譯。  |  字串清單  |  是  |  N/A  | 

`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>

迴圈會反覆運算字串，其中包含以分隔符號分隔的值。若要反覆運算字串的元件， AWS TOE 請使用分隔符號將字串分割為適合反覆運算的陣列。

`forEach` 具有分隔清單結構描述的迴圈

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


**`forEach` 具有分隔清單輸入的迴圈**  

| 欄位 | 說明 | Type | 必要 | 預設 | 
| --- | --- | --- | --- | --- | 
|  `name`  | 提供給迴圈的唯一名稱。與相同階段中的其他迴圈名稱相比，它應該是唯一的。 |  String  |  否  |  ""  | 
|  `list`  | 由共同分隔符號字元聯結的組成字串組成的字串。也接受鏈結表達式。如果是鏈結表達式，請確保以雙引號括住這些表達式，以便 YAML 編譯器正確解譯。 | String |  是  |  N/A  | 
| `delimiter` | 用來分隔區塊中字串的字元。預設為逗號字元。指定清單中只允許一個分隔符號字元：[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_tw/imagebuilder/latest/userguide/toe-looping-constructs.html) 無法使用鏈結表達式。 | String | 否 | 逗號： "," | 

**注意**  
的值`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* – 迴圈的所有反覆運算必須在此欄位指定的期間內執行。如果迴圈執行逾時，則 會 AWS TOE 執行步驟的重試政策，並重設每次新嘗試的逾時參數。如果迴圈執行在達到重試次數上限後超過逾時值，步驟的失敗訊息會指出迴圈執行已逾時。
+ *onFailure* – 失敗處理會套用至步驟，如下所示：
  + 如果 *onFailure* 設定為 `Abort`，則會 AWS TOE 退出迴圈，並根據重試政策重試步驟。在重試嘗試次數上限之後， 會將目前步驟 AWS TOE 標記為失敗，並停止執行程序。

    AWS TOE 會將父階段的狀態碼和文件設定為 `Failed`。
**注意**  
在失敗的步驟之後，不會執行任何進一步的步驟。
  + 如果 *onFailure* 設定為 `Continue`， AWS TOE 會結束迴圈，並根據重試政策重試步驟。在重試嘗試次數上限之後， 會將目前步驟 AWS TOE 標記為失敗，並繼續執行下一個步驟。

    AWS TOE 會將父階段的狀態碼和文件設定為 `Failed`。
  + 如果 *onFailure* 設定為 `Ignore`， AWS TOE 會結束迴圈，並根據重試政策重試步驟。在重試嘗試次數上限之後， 會將目前步驟 AWS TOE 標記為 `IgnoredFailure`，並繼續執行下一個步驟。

    AWS TOE 會將父階段的狀態碼和文件設定為 `SuccessWithIgnoredFailure`。
**注意**  
這仍然被視為成功執行，但包含的資訊會讓您知道一或多個步驟失敗並被忽略。
+ *maxAttempts * – 每次重試時，整個步驟和所有反覆運算都會從頭開始執行。
+ *狀態* – 步驟執行的整體狀態。`status` 不代表個別反覆運算的狀態。具有迴圈之步驟的狀態決定如下：
  + 如果單一反覆運算無法執行，步驟的狀態會指向失敗。
  + 如果所有反覆運算都成功，步驟的狀態會指向成功。
+ *startTime * – 步驟執行的整體開始時間。不代表個別反覆運算的開始時間。
+ *endTime * – 步驟執行的整體結束時間。不代表個別反覆運算的結束時間。
+ *failureMessage * – 包含非逾時錯誤時失敗的反覆運算索引。如果發生逾時錯誤，訊息會指出迴圈執行失敗。不會針對每個反覆運算提供個別錯誤訊息，以將失敗訊息的大小降至最低。

## 步驟和反覆運算輸出
<a name="toe-loop-step-output"></a>

每次反覆運算都包含輸出。在迴圈執行結束時， 會 AWS TOE 整合 中所有成功的反覆運算輸出`detailedOutput.json`。合併輸出是屬於動作模組輸出結構描述中定義之對應輸出索引鍵的值定序。下列範例顯示輸出的合併方式：

**適用於反覆運算 1 `ExecuteBash`的 輸出**

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

**適用於反覆運算 2 `ExecuteBash`的 輸出**

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

**`ExecuteBash`適用於步驟的 輸出**

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

例如，`ExecuteBash`、 `ExecutePowerShell`和 `ExecuteBinary`是`STDOUT`作為動作模組輸出傳回的動作模組。`STDOUT`訊息會加入新的行字元，以在 中產生步驟的整體輸出`detailedOutput.json`。

AWS TOE 不會合併失敗反覆運算的輸出。