使用條件式分支建立動態自動化 - AWS Systems Manager

使用條件式分支建立動態自動化

根據預設,您在 Runbook 之 mainSteps 區段中定義的步驟會循序執行。一個動作完成後,mainSteps 區段中指定的下一個動作就會開始。此外,如果動作無法執行,整個自動化就會失敗 (根據預設)。您可以使用本節說明的 aws:branch 自動化動作和 Runbook 選項建立執行條件式分支的自動化。這表示您可以建立自動化以在評估不同選擇後跳至不同的步驟,或是在步驟完成時動態回應變更。以下是您可以用來建立動態自動化的選項清單:

  • aws:branch:動作可讓您建立動態自動化,以評估單一步驟中的多個選擇,接著根據該評估的結果跳至 Runbook 中的不同步驟。

  • nextStep:此選項會指定在成功完成步驟後要接著處理自動化中的哪個步驟。

  • isEnd:此選項會在特定步驟結束時停止自動化執行。此選項的預設值為 false。

  • isCritical:此選項會指定某個步驟是成功完成自動化的關鍵。如果此指定步驟失敗,則自動化會將自動化的最終狀態回報為 Failed。此選項的預設值為 true

  • onFailure:此選項指示自動化在失敗時應中止、繼續或前往不同的步驟。此選項的預設值為 abort。

以下部分說明 aws:branch 自動化動作。如需 nextStepisEndisCriticalonFailure 選項的詳細資訊,請參閱 使用動態選項的範例

使用 aws:branch 動作

aws:branch 動作為自動化提供了最動態的條件式分支選項。如前所述,此動作可讓您的自動化評估單一步驟中的多個條件,接著根據該評估的結果跳至新的步驟。aws:branch 動作的功能類似程式設計中的 IF-ELIF-ELSE 陳述式。

以下為 aws:branch 步驟的 YAML 範例。

- name: ChooseOSforCommands action: aws:branch inputs: Choices: - NextStep: runPowerShellCommand Variable: "{{GetInstance.platform}}" StringEquals: Windows - NextStep: runShellCommand Variable: "{{GetInstance.platform}}" StringEquals: Linux Default: PostProcessing

指定步驟的 aws:branch 動作時,您要指定自動化必須評估的 Choices。自動化可以根據您在 Runbook Parameters 區段中指定的參數值評估 Choices。自動化也可以根據前一個步驟的輸出評估 Choices

自動化會使用布林值表達式評估每個選擇。如果評估判斷第一個選擇為 true,則自動化會跳至為該選擇指定的步驟。如果第一個選擇的評估判斷是 false,則自動化會評估下一個選擇。如果您的步驟包括三個或更多 Choices,則工作流程會循序評估每個選擇,直到評估某個選擇是 true 為止。接著自動化會跳至選擇為 true 的指定步驟。

如果 Choices 均不為 true,則自動化會檢查步驟是否包含 Default 值。如果沒有選擇為 true,則 Default 值會定義自動化應跳至的步驟。如果未針對步驟指定 Default 值,則自動化會處理 Runbook 中的下一個步驟。

以下是 YAML 中的 aws:branch 步驟,名稱為 chooseOSfromParameter。步驟包含兩個 Choices:(NextStep: runWindowsCommand) 和 (NextStep: runLinuxCommand)。自動化會評估這些 Choices,決定要針對適當的作業系統執行什麼命令。每個選擇的 Variable 會使用 {{OSName}},此為 Runbook 撰寫者在 Runbook Parameters 區段中定義的參數。

mainSteps: - name: chooseOSfromParameter action: aws:branch inputs: Choices: - NextStep: runWindowsCommand Variable: "{{OSName}}" StringEquals: Windows - NextStep: runLinuxCommand Variable: "{{OSName}}" StringEquals: Linux

以下是 YAML 中的 aws:branch 步驟,名稱為 chooseOSfromOutput。步驟包含兩個 Choices:(NextStep: runPowerShellCommand) 和 (NextStep: runShellCommand)。自動化會評估這些 Choices,決定要針對適當的作業系統執行什麼命令。每個選擇的 Variable 會使用 {{GetInstance.platform}},也就是 Runbook 中先前步驟的輸出。此範例也包含一個名稱為 Default 的選項。如果工作流程評估了兩個 Choices,而兩個選擇都不是 true,則自動化工作流程會跳至名稱為 PostProcessing 的步驟。

mainSteps: - name: chooseOSfromOutput action: aws:branch inputs: Choices: - NextStep: runPowerShellCommand Variable: "{{GetInstance.platform}}" StringEquals: Windows - NextStep: runShellCommand Variable: "{{GetInstance.platform}}" StringEquals: Linux Default: PostProcessing

在 Runbook 中建立 aws:branch 步驟

當您在 Runbook 中建立 aws:branch 步驟,您要定義應由自動化評估的 Choices,以決定自動化接下來應跳至哪個步驟。如前所述,Choices 是使用布林值運算式評估。每個選擇都必須定義以下選項:

  • NextStep:如果指定選擇為 true,在 Runbook 中要處理的下一個步驟。

  • Variable:指定 Runbook Parameters 區段中定義的參數名稱,或指定 Runbook 中先前步驟的輸出物件。

    使用以下格式指定參數變數。

    Variable: "{{parameter name}}"

    使用以下格式指定輸出物件變數。

    Variable: "{{previousStepName.outputName}}"

    注意

    有關建立輸出變數的詳細資訊,請參閱下一節 關於建立輸出變數

  • Operation:用於評估選擇的條件,例如 StringEquals: Linuxaws:branch 動作支援以下運算:

    字串運算

    • StringEquals

    • EqualsIgnoreCase

    • StartsWith

    • EndsWith

    • Contains

    數值運算

    • NumericEquals

    • NumericGreater

    • NumericLesser

    • NumericGreaterOrEquals

    • NumericLesser

    • NumericLesserOrEquals

    布林運算

    • BooleanEquals

    重要

    當您建立 Runbook 時,系統會驗證 Runbook 中的每個操作。如果不支援操作,系統會在您嘗試建立 Runbook 時傳回錯誤。

  • Default:指定 Choices 均不為 true 時,自動化應跳至的遞補步驟。

    注意

    如果不想指定 Default 值,您可以指定 isEnd 選項。如果 Choices 均不為 true,而 Default 值也未指定,則自動化會在步驟結束時停止。

使用以下範本協助您在 Runbook 中建構 aws:branch 步驟:將每個範例資源預留位置取代為您自己的資訊。

YAML
mainSteps: - name: step name action: aws:branch inputs: Choices: - NextStep: step to jump to if evaluation for this choice is true Variable: "{{parameter name or output from previous step}}" Operation type: Operation value - NextStep: step to jump to if evaluation for this choice is true Variable: "{{parameter name or output from previous step}}" Operation type: Operation value Default: step to jump to if all choices are false
JSON
{ "mainSteps":[ { "name":"a name for the step", "action":"aws:branch", "inputs":{ "Choices":[ { "NextStep":"step to jump to if evaluation for this choice is true", "Variable":"{{parameter name or output from previous step}}", "Operation type":"Operation value" }, { "NextStep":"step to jump to if evaluation for this choice is true", "Variable":"{{parameter name or output from previous step}}", "Operation type":"Operation value" } ], "Default":"step to jump to if all choices are false" } } ] }

關於建立輸出變數

若要建立參考先前步驟之輸出的 aws:branch 選擇,您必須指定先前步驟的名稱和輸出欄位的名稱。接著,使用以下格式結合步驟和欄位的名稱。

Variable: "{{previousStepName.outputName}}"

例如,以下範例中的第一個步驟名稱為 GetInstance。而在 outputs 下,有一個欄位的名稱為 platform。在第二個步驟 (ChooseOSforCommands) 中,撰寫者想要參考 platform 欄位的輸出做為變數。若要建立變數,只需結合步驟名稱 (GetInstance) 和輸出欄位名稱 (platform) 以建立 Variable: "{{GetInstance.platform}}"

mainSteps: - Name: GetInstance action: aws:executeAwsApi inputs: Service: ssm Api: DescribeInstanceInformation Filters: - Key: InstanceIds Values: ["{{ InstanceId }}"] outputs: - Name: myInstance Selector: "$.InstanceInformationList[0].InstanceId" Type: String - Name: platform Selector: "$.InstanceInformationList[0].PlatformType" Type: String - name: ChooseOSforCommands action: aws:branch inputs: Choices: - NextStep: runPowerShellCommand Variable: "{{GetInstance.platform}}" StringEquals: Windows - NextStep: runShellCommand Variable: "{{GetInstance.platform}}" StringEquals: Linux Default: Sleep

以下範例,說明如何從先前的步驟及輸出建立 "Variable":"{{ describeInstance.Platform }}"

- name: describeInstance action: aws:executeAwsApi onFailure: Abort inputs: Service: ec2 Api: DescribeInstances InstanceIds: - "{{ InstanceId }}" outputs: - Name: Platform Selector: "$.Reservations[0].Instances[0].Platform" Type: String nextStep: branchOnInstancePlatform - name: branchOnInstancePlatform action: aws:branch inputs: Choices: - NextStep: runEC2RescueForWindows Variable: "{{ describeInstance.Platform }}" StringEquals: windows Default: runEC2RescueForLinux

範例 aws:branch Runbook

以下是一些使用 aws:branch 的範例 Runbook。

範例 1:使用 aws:branch 搭配輸出變數以根據作業系統類型執行命令

在此範例 (GetInstance) 的第一個步驟,Runbook 撰寫人使用 aws:executeAwsApi 動作來呼叫 ssm DescribeInstanceInformation API 操作。撰寫者透過此動作來判斷執行個體使用的作業系統類型。aws:executeAwsApi 動作會輸出執行個體 ID 和平台類型。

在第二個步驟中 (ChooseOSforCommands),撰寫者使用 aws:branch 動作搭配兩個 Choices (NextStep: runPowerShellCommand) 和 (NextStep: runShellCommand)。自動化會使用先前步驟的輸出評估執行個體的作業系統 (Variable: "{{GetInstance.platform}}")。自動化跳至指定作業系統的步驟。

--- schemaVersion: '0.3' assumeRole: "{{AutomationAssumeRole}}" parameters: AutomationAssumeRole: default: "" type: String mainSteps: - name: GetInstance action: aws:executeAwsApi inputs: Service: ssm Api: DescribeInstanceInformation outputs: - Name: myInstance Selector: "$.InstanceInformationList[0].InstanceId" Type: String - Name: platform Selector: "$.InstanceInformationList[0].PlatformType" Type: String - name: ChooseOSforCommands action: aws:branch inputs: Choices: - NextStep: runPowerShellCommand Variable: "{{GetInstance.platform}}" StringEquals: Windows - NextStep: runShellCommand Variable: "{{GetInstance.platform}}" StringEquals: Linux Default: Sleep - name: runShellCommand action: aws:runCommand inputs: DocumentName: AWS-RunShellScript InstanceIds: - "{{GetInstance.myInstance}}" Parameters: commands: - ls isEnd: true - name: runPowerShellCommand action: aws:runCommand inputs: DocumentName: AWS-RunPowerShellScript InstanceIds: - "{{GetInstance.myInstance}}" Parameters: commands: - ls isEnd: true - name: Sleep action: aws:sleep inputs: Duration: PT3S

範例 2:使用 aws:branch 搭配參數變數以根據作業系統類型執行命令

Runbook 撰寫者在 Runbook 開頭的 parameters 區段定義了數個參數選項。其中一個參數名稱為 OperatingSystemName。在第一個步驟中 (ChooseOS),撰寫者使用 aws:branch 動作搭配兩個 Choices (NextStep: runWindowsCommand) 和 (NextStep: runLinuxCommand)。這些 Choices 的變數會參考在參數區段中指定的參數選項 (Variable: "{{OperatingSystemName}}")。使用者執行此 Runbook 時,針對 OperatingSystemName 指定了在執行時間的值。自動化在 Choices 評估期間使用執行時間參數。自動化會根據針對 OperatingSystemName 指定的執行時間參數跳至指定作業系統的步驟。

--- schemaVersion: '0.3' assumeRole: "{{AutomationAssumeRole}}" parameters: AutomationAssumeRole: default: "" type: String OperatingSystemName: type: String LinuxInstanceId: type: String WindowsInstanceId: type: String mainSteps: - name: ChooseOS action: aws:branch inputs: Choices: - NextStep: runWindowsCommand Variable: "{{OperatingSystemName}}" StringEquals: windows - NextStep: runLinuxCommand Variable: "{{OperatingSystemName}}" StringEquals: linux Default: Sleep - name: runLinuxCommand action: aws:runCommand inputs: DocumentName: "AWS-RunShellScript" InstanceIds: - "{{LinuxInstanceId}}" Parameters: commands: - ls isEnd: true - name: runWindowsCommand action: aws:runCommand inputs: DocumentName: "AWS-RunPowerShellScript" InstanceIds: - "{{WindowsInstanceId}}" Parameters: commands: - date isEnd: true - name: Sleep action: aws:sleep inputs: Duration: PT3S

使用運算子建立複雜的分支自動化

您可以使用 aws:branch 步驟中的 AndOrNot 運算子建立複雜的分支自動化。

「And」運算子

當您希望一個選擇有多個為 true 的變數,請使用 And 運算子。在以下範例中,第一個選擇評估了執行個體是否 running 並使用 Windows 作業系統。如果兩個變數均為 true,則自動化會跳至 runPowerShellCommand 步驟。如果一個或多個變數為 false,則自動化會評估第二個選擇的變數。

mainSteps: - name: switch2 action: aws:branch inputs: Choices: - And: - Variable: "{{GetInstance.pingStatus}}" StringEquals: running - Variable: "{{GetInstance.platform}}" StringEquals: Windows NextStep: runPowerShellCommand - And: - Variable: "{{GetInstance.pingStatus}}" StringEquals: running - Variable: "{{GetInstance.platform}}" StringEquals: Linux NextStep: runShellCommand Default: sleep3

「Or」運算子

當您希望一個選擇有多個為 true 的變數,請使用 Or 運算子。在以下範例中,第一個選擇評估了參數字串是否為 Windows 且 AWS Lambda 步驟的輸出是否為 true。如果評估判斷這些變數其中之一為 true,則自動化會跳至 RunPowerShellCommand 步驟。如果兩個變數均為 false,則自動化會評估第二個選擇的變數。

- Or: - Variable: "{{parameter1}}" StringEquals: Windows - Variable: "{{BooleanParam1}}" BooleanEquals: true NextStep: RunPowershellCommand - Or: - Variable: "{{parameter2}}" StringEquals: Linux - Variable: "{{BooleanParam2}}" BooleanEquals: true NextStep: RunShellScript

「Not」運算子

當您想要跳至變數為 true 時定義的步驟時,使用 Not 運算子。在以下範例中,第一個選擇評估了參數字串是否為 Not Linux。如果評估判斷變數不是 Linux,則自動化會跳至 sleep2 步驟。如果第一個選擇的評估判斷 Linux,則自動化會評估下一個選擇。

mainSteps: - name: switch action: aws:branch inputs: Choices: - NextStep: sleep2 Not: Variable: "{{testParam}}" StringEquals: Linux - NextStep: sleep1 Variable: "{{testParam}}" StringEquals: Windows Default: sleep3

使用動態選項的範例

本節包括不同的範例,示範如何在 Runbook 中使用動態選項。本節中每個範例都會延伸以下的 Runbook。此 Runbook 有兩個動作。第一種動作名稱為 InstallMsiPackage。它會使用 aws:runCommand 動作在 Windows Server 執行個體上安裝應用程式。第二個動作名稱為 TestInstall。這會使用 aws:invokeLambdaFunction 動作對安裝的應用程式執行測試,確認應用程式是否安裝成功。步驟一指定 onFailure: Abort。這表示如果應用程式未安裝成功,自動化就在步驟二前停止。

範例 1:具有兩個線性動作的 Runbook

--- schemaVersion: '0.3' description: Install MSI package and run validation. assumeRole: "{{automationAssumeRole}}" parameters: automationAssumeRole: type: String description: "(Required) Assume role." packageName: type: String description: "(Required) MSI package to be installed." instanceIds: type: String description: "(Required) Comma separated list of instances." mainSteps: - name: InstallMsiPackage action: aws:runCommand maxAttempts: 2 onFailure: Abort inputs: InstanceIds: - "{{instanceIds}}" DocumentName: AWS-RunPowerShellScript Parameters: commands: - msiexec /i {{packageName}} - name: TestInstall action: aws:invokeLambdaFunction maxAttempts: 1 timeoutSeconds: 500 inputs: FunctionName: TestLambdaFunction ...

建立動態自動化以使用 onFailure 選項跳至不同步驟

以下範例使用 onFailure: step:step namenextStepisEnd 選項來建立動態自動化。在這個範例中,如果 InstallMsiPackage 動作失敗,則會跳至名為 PostFailure (onFailure: step:PostFailure) 的動作,在安裝失敗時執行 AWS Lambda 函數以執行某動作。如果安裝成功,則自動化會跳至 TestInstall 動作 (nextStep: TestInstall)。TestInstallPostFailure 步驟均使用 isEnd 選項 (isEnd: true),因此自動化會在其中一個步驟完成時結束執行。

注意

mainSteps 區段最後一個步驟使用 isEnd 選項是選用的。如果最後一個步驟未跳至其他步驟,則自動化會在最後一個步驟中執行動作之後停止。

範例 2:跳至不同步驟的動態自動化

mainSteps - name: InstallMsiPackage action: aws:runCommand onFailure: step:PostFailure maxAttempts: 2 inputs: InstanceIds: - "{{instanceIds}}" DocumentName: AWS-RunPowerShellScript Parameters: commands: - msiexec /i {{packageName}} nextStep: TestInstall - name: TestInstall action: aws:invokeLambdaFunction maxAttempts: 1 timeoutSeconds: 500 inputs: FunctionName: TestLambdaFunction isEnd: true - name: PostFailure action: aws:invokeLambdaFunction maxAttempts: 1 timeoutSeconds: 500 inputs: FunctionName: PostFailureRecoveryLambdaFunction isEnd: true ...
注意

在處理 Runbook 之前,系統會驗證 Runbook 是否不會建立無限迴圈。如果偵測到無限迴圈,自動化會傳回錯誤和圓形追蹤,顯示建立迴圈的步驟。

建立定義關鍵步驟的動態自動化

您可以將一個步驟指定為自動化整體成功的關鍵。如果關鍵步驟失敗,即使有一個或多個步驟已執行成功,Automation 仍會將自動化的狀態回報為 Failed。在下列範例中,使用者會在 InstallMsiPackage 步驟失敗 (onFailure: step:VerifyDependencies) 時識別 VerifyDependencies 步驟。使用者指定 InstallMsiPackage 步驟不是關鍵 (isCritical: false)。在此範例中,如果應用程式無法安裝,自動化會處理 VerifyDependencies 步驟以判斷是否有一個或多個相依性遺失,因此導致應用程式安裝失敗。

範例 3:定義自動化的關鍵步驟

--- name: InstallMsiPackage action: aws:runCommand onFailure: step:VerifyDependencies isCritical: false maxAttempts: 2 inputs: InstanceIds: - "{{instanceIds}}" DocumentName: AWS-RunPowerShellScript Parameters: commands: - msiexec /i {{packageName}} nextStep: TestPackage ...