從 Systems Manager Automation Runbook 叫用其他 AWS 服務 - AWS Systems Manager

從 Systems Manager Automation Runbook 叫用其他 AWS 服務

您可以使用 Runbook 中的以下自動化動作叫用其他 AWS 服務和其他 Systems Manager 功能:

  • aws:executeAwsApi:此自動化動作會呼叫並執行 AWS API 操作。大部分 API 操作均有支援,但並非所有 API 操作都經過測試。例如,以下 API 操作均有支援:CreateImageDelete bucketRebootDBInstanceCreateGroups。不支援串流 API 操作,例如 Get Object 動作。

  • aws:waitForAwsResourceProperty:此自動化動作可讓您的自動化在繼續自動化之前等待特定的資源狀態或事件狀態。例如,您可以使用此動作搭配 Amazon Relational Database Service (Amazon RDS) DescribeDBInstances API 動作來暫停自動化,使資料庫執行個體有時間啟動。

  • aws:assertAwsResourceProperty:此自動化動作可讓您針對特定資源狀態宣告特定的資源狀態或事件狀態。例如,您可以指定步驟必須等待 EC2 執行個體啟動。然後,它會使用 running DesiredValue 屬性呼叫 Amazon Elastic Compute Cloud (Amazon EC2) DescribeInstanceStatus API 操作。這可確保自動化等待執行中的執行個體,接著在執行個體實際執行時繼續。

以下是 YAML 格式的範例 Runbook,它使用 aws:executeAwsApi 動作關閉 S3 儲存貯體的讀取和寫入許可。

--- description: Disable S3-Bucket's public WriteRead access via private ACL schemaVersion: "0.3" assumeRole: "{{ AutomationAssumeRole }}" parameters: S3BucketName: type: String description: (Required) S3 Bucket subject to access restriction AutomationAssumeRole: type: String description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. default: "" mainSteps: - name: DisableS3BucketPublicReadWrite action: aws:executeAwsApi inputs: Service: s3 Api: PutBucketAcl Bucket: "{{S3BucketName}}" ACL: private isEnd: true ...

以下為 YAML 中使用這三個動作的 Runbook。自動化執行下列操作:

  • 使用 aws:executeAwsApi 動作呼叫 Amazon EC2 DescribeImages API 操作,以獲得特定 Windows Server 2016 AMI 的名稱。這會將映像 ID 輸出為 ImageId

  • 使用 aws:executeAwsApi 動作呼叫 Amazon EC2 RunInstances API 操作,以啟動使用先前步驟之 ImageId 的執行個體。這會將執行個體 ID 輸出為 InstanceId

  • 使用 aws:waitForAwsResourceProperty 動作輪詢 Amazon EC2 DescribeInstanceStatus API 操作,以等待執行個體達到 running 狀態。動作在 60 秒逾時。如果執行個體狀態無法在 60 秒的輪詢後達到 running,則步驟會逾時。

  • 使用 aws:assertAwsResourceProperty 動作來呼叫 Amazon EC2 DescribeInstanceStatus API 操作,以宣告執行個體位於 running 狀態。如果執行個體狀態不是 running,則步驟會失敗。

--- description: Sample runbook using AWS API operations schemaVersion: '0.3' assumeRole: "{{ AutomationAssumeRole }}" parameters: AutomationAssumeRole: type: String description: "(Optional) The ARN of the role that allows Automation to perform the actions on your behalf." default: '' ImageName: type: String description: "(Optional) Image Name to launch EC2 instance with." default: "Windows_Server-2016-English-Full-Base-2018.07.11" mainSteps: - name: getImageId action: aws:executeAwsApi inputs: Service: ec2 Api: DescribeImages Filters: - Name: "name" Values: - "{{ ImageName }}" outputs: - Name: ImageId Selector: "$.Images[0].ImageId" Type: "String" - name: launchOneInstance action: aws:executeAwsApi inputs: Service: ec2 Api: RunInstances ImageId: "{{ getImageId.ImageId }}" MaxCount: 1 MinCount: 1 outputs: - Name: InstanceId Selector: "$.Instances[0].InstanceId" Type: "String" - name: waitUntilInstanceStateRunning action: aws:waitForAwsResourceProperty # timeout is strongly encouraged for action - aws:waitForAwsResourceProperty timeoutSeconds: 60 inputs: Service: ec2 Api: DescribeInstanceStatus InstanceIds: - "{{ launchOneInstance.InstanceId }}" PropertySelector: "$.InstanceStatuses[0].InstanceState.Name" DesiredValues: - running - name: assertInstanceStateRunning action: aws:assertAwsResourceProperty inputs: Service: ec2 Api: DescribeInstanceStatus InstanceIds: - "{{ launchOneInstance.InstanceId }}" PropertySelector: "$.InstanceStatuses[0].InstanceState.Name" DesiredValues: - running outputs: - "launchOneInstance.InstanceId" ...

使用輸入和輸出

前述的每個自動化動作都可讓您藉由指定服務命名空間、API 操作名稱、輸入參數、輸出參數來呼叫特定 API 操作。輸入是由您選擇的 API 操作定義。您可以檢視 API 操作 (也稱為方法),方式是在以下服務參考頁面的左側導覽中選擇一項服務。在您想要呼叫之服務的 Client (用戶端) 部分選擇一個方法。例如,Amazon Relational Database Service (Amazon RDS) 的所有 API 操作 (方法) 均列於以下頁面:Amazon RDS 方法

您可以在以下位置檢視每個自動化動作的結構描述:

結構描述包括使用各動作之必要欄位的描述。

使用 Selector/PropertySelector 欄位

每個 Automation 動作都需要您指定輸出 Selector (用於 aws:executeAwsApi) 或 PropertySelector (用於 aws:assertAwsResourcePropertyaws:waitForAwsResourceProperty)。這些欄位用於處理來自 AWS API 操作的 JSON 回應。這些欄位使用 JSONPath 語法。

以下範例可協助說明 aws:executeAwsAPi 動作的概念。

--- mainSteps: - name: getImageId action: aws:executeAwsApi inputs: Service: ec2 Api: DescribeImages Filters: - Name: "name" Values: - "{{ ImageName }}" outputs: - Name: ImageId Selector: "$.Images[0].ImageId" Type: "String" ...

aws:executeAwsApi 步驟 getImageId 中,自動化會叫用 DescribeImages API 操作,並接收來自 ec2 的回應。接著自動化將 Selector - "$.Images[0].ImageId" 套用至 API 回應並將選取的值指派給輸出 ImageId 變數。在相同自動化中的其他步驟可藉由指定 "{{ getImageId.ImageId }}" 使用 ImageId 的值。

以下範例可協助說明 aws:waitForAwsResourceProperty 動作的概念。

--- - name: waitUntilInstanceStateRunning action: aws:waitForAwsResourceProperty # timeout is strongly encouraged for action - aws:waitForAwsResourceProperty timeoutSeconds: 60 inputs: Service: ec2 Api: DescribeInstanceStatus InstanceIds: - "{{ launchOneInstance.InstanceId }}" PropertySelector: "$.InstanceStatuses[0].InstanceState.Name" DesiredValues: - running ...

aws:waitForAwsResourceProperty 步驟 waitUntilInstanceStateRunning 中,自動化會叫用 DescribeInstanceStatus API 操作,並接收來自 ec2 的回應。自動化接著將 PropertySelector - "$.InstanceStatuses[0].InstanceState.Name" 套用至回應,並檢查指定傳回的值是否符合 DesiredValues 清單中的值 (在此例中為 running)。步驟會重複程序,直到回應傳回的執行個體狀態為 running

在 Runbook 中使用 JSONPath

JSONPath 表達式是以「$」開頭的字串。用於在 JSON 元素中選取一個或多個元件。以下清單包括由 Systems Manager 自動化支援的 JSONPath 運算子相關資訊:

  • 以點標記的子代 (.):與 JSON 物件搭配使用。此運算子會選取特定索引鍵的值。

  • Deep-scan (..):與 JSON 元素搭配使用。此運算子會在各層級掃描 JSON 元素並選取具有特定索引鍵之值的清單。此運算子的傳回類型一律為 JSON 陣列。在自動化動作輸出類型的內容中,運算子可以是 StringList 或 MapList。

  • Array-Index ([ ]):與 JSON 陣列搭配使用。此運算子會取得特定索引的值。

為了更全面了解 JSONPath 運算子,請檢閱以下 ec2 DescribeInstances API 操作的 JSON 回應。在此回應下有幾個範例,顯示套用不同的 JSONPath 運算式到 DescribeInstances API 操作之回應的不同結果。

{
    "NextToken": "abcdefg",
    "Reservations": [
        {
            "OwnerId": "123456789012",
            "ReservationId": "r-abcd12345678910",
            "Instances": [
                {
                    "ImageId": "ami-12345678",
                    "BlockDeviceMappings": [
                        {
                            "Ebs": {
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-000000000000"
                            },
                            "DeviceName": "/dev/xvda"
                        }
                    ],
                    "State": {
                        "Code": 16,
                        "Name": "running"
                    }
                }
            ],
            "Groups": []
        },
        {
            "OwnerId": "123456789012",
            "ReservationId": "r-12345678910abcd",
            "Instances": [
                {
                    "ImageId": "ami-12345678",
                    "BlockDeviceMappings": [
                        {
                            "Ebs": {
                                "DeleteOnTermination": true,
                                "Status": "attached",
                                "VolumeId": "vol-111111111111"
                            },
                            "DeviceName": "/dev/xvda"
                        }
                    ],
                    "State": {
                        "Code": 80,
                        "Name": "stopped"
                    }
                }
            ],
            "Groups": []
        }
    ]
}

JSONPath 範例 1:從 JSON 回應取得特定字串

JSONPath: $.Reservations[0].Instances[0].ImageId Returns: "ami-12345678" Type: String

JSONPath 範例 2:從 JSON 回應取得特定布林值

JSONPath: $.Reservations[0].Instances[0].BlockDeviceMappings[0].Ebs.DeleteOnTermination Returns: true Type: Boolean

JSONPath 範例 3:從 JSON 回應取得特定整數

JSONPath: $.Reservations[0].Instances[0].State.Code Returns: 16 Type: Integer

JSONPath Example 4:深度掃描 JSON 回應,接著取得做為 StringList 的 VolumeId 所有值

JSONPath: $.Reservations..BlockDeviceMappings..VolumeId Returns: [ "vol-000000000000", "vol-111111111111" ] Type: StringList

JSONPath 範例 5:取得做為 StringMap 的特定 BlockDeviceMappings 物件

JSONPath: $.Reservations[0].Instances[0].BlockDeviceMappings[0] Returns: { "Ebs" : { "DeleteOnTermination" : true, "Status" : "attached", "VolumeId" : "vol-000000000000" }, "DeviceName" : "/dev/xvda" } Type: StringMap

JSONPath Example 6:深度掃描 JSON 回應,接著取得做為 MapList 的所有 State 物件

JSONPath: $.Reservations..Instances..State Returns: [ { "Code" : 16, "Name" : "running" }, { "Code" : 80, "Name" : "stopped" } ] Type: MapList
重要

如果您執行可使用 AWS Identity and Access Management (IAM) 服務角色叫用其他服務的自動化工作流程,請注意您必須為該服務角色設定可叫用這些服務的許可。此要求適用於所有 AWS Automation Runbook (AWS-* Runbook),例如 AWS-ConfigureS3BucketLoggingAWS-CreateDynamoDBBackupAWS-RestartEC2Instance Runbook 等。此要求也適用於您所建立會透過呼叫其他服務的動作來叫用其他 AWS 服務的任何自訂自動化 Runbooks。例如,如果您使用 aws:executeAwsApiaws:createStackaws:copyImage 動作,為服務角色設定可叫用這些服務的許可。您可新增 IAM 內嵌政策到角色,以啟用其他 AWS 服務的許可。如需更多詳細資訊,請參閱 (選用) 新增 Automation 內嵌政策以叫用其他 AWS 服務

範例演練:從 Systems Manager Automation Runbook 啟動 Amazon RDS 執行個體

此範例演練示範如何以 YAML 格式建立並執行 Systems Manager Automation Runbook,以使用三個 API 操作確認 Amazon Relational Database Service (Amazon RDS) 資料庫執行個體是否正在執行。如果資料庫執行個體未執行,則自動化會將其啟動。

從 Runbook 叫用 Amazon RDS API 操作

  1. 開啟文字編輯器並將以下的 Runbook 內容貼入檔案。指定自動化角色和要檢查的執行個體 ID。您會在之後新增 mainSteps 動作。

    --- description: Start RDS instance schemaVersion: "0.3" assumeRole: "The_Automation_role_to_use_when_running_the_runbook" parameters: InstanceId: The_instance_ID_to_start type: String description: (Required) RDS instance ID to start AutomationAssumeRole: type: String description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. default: "" mainSteps:
  2. 在自動化的第一個步驟,您必須確定執行個體是否已在執行。您可以使用 aws:assertAwsResourceProperty 動作來判斷和宣告特定的執行個體狀態。在您可以將 aws:assertAwsResourceProperty 動作新增至 Runbook 之前,您必須判斷並指定所需的輸入。以下清單說明如何判斷並指定所需的輸入。您可以檢視將此資訊輸入清單後的 Runbook 之範例。

    1. 檢視結構描述以查看 aws:assertAwsResourceProperty – 宣告 AWS 資源狀態或事件狀態 動作所有可用的輸入。

    2. 決定要呼叫之服務的命名空間。您可以檢視《Amazon Web Services 一般參考》中 Amazon 資源名稱 (ARN) 和 AWS 服務命名空間的 AWS 服務命名空間。Amazon RDS 的命名空間為 rds

    3. 決定哪些 Amazon RDS API 操作可讓您檢視資料庫執行個體的狀態。您可以在 Amazon RDS 方法頁面檢視 API 操作 (也稱為方法)。

    4. 指定一個或多個 DescribeDBInstances API 操作的請求參數。例如,此動作使用 DBInstanceIdentifier 請求參數。

    5. 決定一個或多個 PropertySelector。PropertySelector 是一種回應物件,由此 API 操作的請求傳回。例如,關於 Amazon RDS 方法。選擇 describe_db_instances 方法並向下捲動至 Response Structure (回應結構) 區段。DBInstances (DBInstance) 列為回應物件。為了此演練的目的,請指定 DBInstancesDBInstanceStatus 做為 PropertySelector。請記住 PropertySelector 是使用 JSONPath 輸入。這表示您要格式化 Runbook 中的資訊,如下所示。

      PropertySelector: "$.DBInstances[0].DBInstanceStatus".

    6. 指定一個或多個 DesiredValue。如果您不知道您想要指定的值,請執行 DescribeDBInstances API 操作,以判斷可能的值。在此演練中,指定 availablestarting

    7. 輸入您收集到 Runbook 的資訊,如以下範例所示。

    --- description: Start RDS instance schemaVersion: "0.3" assumeRole: "The_Automation_role_to_use_when_running_the_runbook" parameters: InstanceId: The_instance_ID_to_start type: String description: (Required) RDS Instance Id to stop AutomationAssumeRole: type: String description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. default: "" mainSteps: - name: AssertNotStartingOrAvailable action: aws:assertAwsResourceProperty isCritical: false onFailure: step:StartInstance nextStep: CheckStart inputs: Service: rds Api: DescribeDBInstances DBInstanceIdentifier: "{{InstanceId}}" PropertySelector: "$.DBInstances[0].DBInstanceStatus" DesiredValues: ["available", "starting"]
  3. 若先前的動作判斷未啟動,則在 mainSteps 區段中指定 aws:executeAwsApi 動作以啟動執行個體。

    1. 檢視結構描述以查看 aws:executeAwsApi – 呼叫並執行 AWS API 操作 所有可用的輸入。

    2. 指定 Amazon RDS StartDBInstance API 操作來啟動執行個體。

    3. 輸入您收集到 Runbook 的資訊,如以下範例所示。

    --- description: Start RDS instance schemaVersion: "0.3" assumeRole: "{{ The_Automation_role_to_use_when_running_the_runbook }}" parameters: InstanceId: type: String description: (Required) RDS Instance Id to stop AutomationAssumeRole: type: String description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. default: "" mainSteps: - name: AssertNotStartingOrAvailable action: aws:assertAwsResourceProperty isCritical: false onFailure: step:StartInstance nextStep: CheckStart inputs: Service: rds Api: DescribeDBInstances DBInstanceIdentifier: "{{InstanceId}}" PropertySelector: "$.DBInstances[0].DBInstanceStatus" DesiredValues: ["available", "starting"] - name: StartInstance action: aws:executeAwsApi inputs: Service: rds Api: StartDBInstance DBInstanceIdentifier: "{{InstanceId}}"
  4. 在結束自動化之前,於 mainSteps 區段中指定 aws:waitForAwsResourceProperty 動作以等待執行個體啟動。

    1. 檢視結構描述以查看 aws:waitForAwsResourceProperty – 在 AWS 資源屬性上等待 所有可用的輸入。

    2. 指定 Amazon RDS DescribeDBInstances API 操作來判斷執行個體狀態。

    3. $.DBInstances[0].DBInstanceStatus 指定為 PropertySelector

    4. available 指定為 DesiredValue

    5. 輸入您收集到 Runbook 的資訊,如以下範例所示。

    --- description: Start RDS instance schemaVersion: "0.3" assumeRole: "{{ The_Automation_role_to_use_when_running_the_runbook }}" parameters: InstanceId: type: String description: (Required) RDS Instance Id to stop AutomationAssumeRole: type: String description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf. default: "" mainSteps: - name: AssertNotStartingOrAvailable action: aws:assertAwsResourceProperty isCritical: false onFailure: step:StartInstance nextStep: CheckStart inputs: Service: rds Api: DescribeDBInstances DBInstanceIdentifier: "{{InstanceId}}" PropertySelector: "$.DBInstances[0].DBInstanceStatus" DesiredValues: ["available", "starting"] - name: StartInstance action: aws:executeAwsApi inputs: Service: rds Api: StartDBInstance DBInstanceIdentifier: "{{InstanceId}}" - name: CheckStart action: aws:waitForAwsResourceProperty onFailure: Abort maxAttempts: 10 timeoutSeconds: 600 inputs: Service: rds Api: DescribeDBInstances DBInstanceIdentifier: "{{InstanceId}}" PropertySelector: "$.DBInstances[0].DBInstanceStatus" DesiredValues: ["available"] isEnd: true ...
  5. 將檔案儲存為 sample.yaml。

  6. 在 AWS CLI 中執行以下命令,將 Runbook 新增至您的 AWS 帳戶。

    aws ssm create-document --name sampleRunbook --document-type Automation --document-format YAML --content file://sample.yaml
  7. 執行以下命令,使用您剛建立的 Runbook 來開始自動化。啟動自動化後,請記下 Systems Manager 傳回的執行 ID。

    aws ssm start-automation-execution --document-name sampleRunbook
  8. 執行以下命令來檢視執行狀態。

    aws ssm get-automation-execution --automation-execution-id automation_execution_id

叫用 AWS API 的預先定義 Runbook

Systems Manager Automation 包括叫用 AWS API 的以下預先定義 Runbook。

Runbook 名稱 用途

AWS-StartRdsInstance

啟動 Amazon RDS 執行個體。

AWS-StopRdsInstance

停止 Amazon RDS 執行個體。

AWS-RebootRdsInstance

重新啟動 Amazon RDS 執行個體。

AWS-CreateSnapshot

建立 Amazon Elastic Block Store (Amazon EBS) 磁碟區快照。

AWS-DeleteSnapshot

刪除一個 Amazon EBS 磁碟區快照。

AWS-ConfigureS3BucketLogging

啟用 Amazon Simple Storage Service (Amazon S3) 儲存貯體上的記錄功能。

AWS-DisableS3BucketPublicReadWrite

使用私有 ACL 關閉 S3 儲存貯體的讀取和寫入許可。

AWS-ConfigureS3BucketVersioning

啟用或暫停 S3 儲存貯體的版本控制。

AWS-DeleteDynamoDbBackup

刪除 Amazon DynamoDB 資料表備份。

選擇前表中的連結,或使用下列處理程序在 Systems Manager 主控台中檢視這些 Runbook 的詳細資訊。

  1. 開啟位於 AWS Systems Managerhttps://console.aws.amazon.com/systems-manager/ 的 主控台。https://console.aws.amazon.com/systems-manager/

  2. 在導覽窗格中,選擇 Documents (文件)

    -或-

    如果 AWS Systems Manager 首頁先開啟,選擇選單圖示 ( ) 以開啟導覽窗格,然後在導覽窗格中,選擇 Documents (文件)。

  3. 選擇 Runbook,接著選擇 View details (檢視詳細資訊)

  4. 選擇 Content (內容) 索引標籤。