1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Automation PilotでSAP HANA Cloudの稼働状態を確認し、再起動するコマンドを作成

Last updated at Posted at 2024-10-25

やりたいこと

トライアル環境のSAP HANA Cloudのインスタンスは毎日自動的に停止するので、使いたいときにすぐに使えるよう、停止状態を確認したら再起動したいです。

これまでにやったことと、課題

以前の記事で、毎日決まった時刻にインスタンスの起動をスケジュールすることはできました。

HANA Cloudの稼働状況を確認すると、日本時間の15時頃に停止していることがわかりますが、停止時刻には若干の変動があるようです。

image.png

停止から起動までの時間を最小にできないだろうか、と思ったことが今回の検証のきっかけです。

※単純に起動を5分おきにスケジュールするでもいいのですが、Automation Pilotで色々やってみたいために検証しました

参考にしたもの

Automation PilotのサンプルリポジトリにあるCheck HANA Cloud Availabilityというコマンドを参考に作成しました。

以下で参考にしたコマンドについて解説します。

インプット、アウトプット

インプットはHANA Cloudに関する情報、BTPのログイン情報など多数、アウトプットは3つです。
image.png

コマンド

このコマンドは4つのステップから構成されています。

image.png

  1. HANA CloudのAPIアクセス用のトークンを取得
  2. APIを使ってHANA Cloudの状態を確認
  3. (HANA Cloudが停止している場合)Alert Notificationに通知
  4. (HANA Cloudが停止している場合)HANA Cloudを起動

次に、今回作成しようとしているコマンドに関連するポイントについて説明します。

APIを使ってHANA Cloudの状態を確認

SAP HANA CloudのMetrics ServiceのAPIを使ってHANA Cloudの状態を取得しています。
https://api.sap.com/api/MetricsAPI/path/get_metrics_v1_serviceInstances__serviceInstanceID__values

names=HDBAccessibleというパラメータをつけて呼び出すと、直近1時間の30秒ごとの状態を返してくれます。valueに"1"が設定されている場合はアクセス可能な状態です。
image.png

HANA Cloudを起動

dblm-sapcp:StartHanaCloudInstance:1というコマンドを使っています。これはCloud Foundryに作成されたインスタンスを起動するコマンドです。

image.png

今回は"Other Environments"で作成したHANA Cloudインスタンスを起動するので、sm-sapcp:UpdateServiceInstance:1というコマンドを使用します。

image.png

作成したもの

インプット、アウトプット

コマンドで必要なパラメータはHANA Cloudのサービスキーと、Service Managerのサービスキーにすべて入っているので、この2つをインプットとします。アウトプットは参考にしたコマンドと同様です。

image.png

HANA Cloudのサービスキーは、Service Bindingで作成します。
image.png

コマンド

ステップは以下の2つです。pingHanaCloudのステップで使っているhttp-sapcp:HttpRequest:1というコマンドがOAuth 2.0 Client Credentials Flowに対応しているので、事前にトークンを取得するステップは不要になりました。

image.png

HANA Cloudの状態を確認

http-sapcp:HttpRequest:1コマンドのパラメータを以下のように設定しています。
image.png

URLはサービスキーのhostの値をもとに、式を使って設定しています。

https://api.gateway.orchestration.$(.execution.input.hanaCloudServiceKey.host | split(".") | .[2:] | join("."))/metrics/v1/serviceInstances/$(.execution.input.hanaCloudServiceKey.host | split(".")[0])/values?names=HDBAccessible

式の作成では全体的にChatGPTを活用しました。利用可能なjqの式には制限があるので、以下のヘルプを参照します。
https://help.sap.com/docs/automation-pilot/automation-pilot/dynamic-expression

サンプルのコマンドではインプットパラメータが多数ありましたが、jqを駆使することでサービスキーのみにできたのがよかったです。

hostの値
37b4cc7b-2eb5-4e06-912d-511d1a50135e.hana.trial-us10.hanacloud.ondemand.com

設定されたURL(網掛けがhostから設定された部分)
https
://api.gateway.orchestration.trial-us10.hanacloud.ondemand.com/metrics/v1/serviceInstances/37b4cc7b-2eb5-4e06-912d-511d1a50135e/values?names=HDBAccessible

レスポンスボディにはHANA Cloudの状態が時系列(古いものが上)で並んでいるので、直前の状態を確認するためにAdvancedタブのResponse Body Transformerで逆順に並べ替えています。これは、参考にしたコマンドの設定と同じです。

image.png

HANA Cloudを起動

HANA Cloudが停止している場合、sm-sapcp:UpdateServiceInstance:1というコマンドを使い、HANA Cloudを起動します。

「停止している場合」という条件は、コマンドのConditionで以下のように設定します。直近の3つ(90秒間)のHANA Cloudの状態で1つも稼働状態がない場合、ということです。
image.png

コマンドのインプットにはHANA CloudのサービスインスタンスIDとService Managerのキーを渡します。
image.png

また、parametersに以下を設定することで、インスタンスが起動されます。

{
    "data": {
        "serviceStopped": false
    }
}

実行結果

HANA Cloudが稼働している場合、アウトプットは以下のようになります。HANA Cloudの起動がスキップされています。実行時間は約2秒です。
image.png

HANA Cloudが停止している場合、アウトプットは以下のようになります。実行時間は3分半でした。
image.png

スケジュール

14:50~15:15の間、5分おきに起動するようにしたいので、以下のようにスケジュールします。(実際には14:00, 14:05, 14:10, 14:15, 15:50, 15:55にも動きます)

最終的には、15:10, 15:15, 15:20の3回で十分でした

image.png

初日の実行結果は以下のようになっていました(初日は20~40分台にもスケジュール)。6:10 UTCに開始したものが時間がかかっており、ここでHANA Cloudが起動したのがわかります。
image.png

Appendix: 使い方

1. カタログのインポート

以下のカタログをインポートします。
image.png

{
  "id": "HANACloud-<<<TENANT_ID>>>",
  "technicalName": "HANACloud",
  "name": "Manage HANA Cloud",
  "description": "",
  "owner": "<<<TENANT_ID>>>",
  "inputs": [
    {
      "id": "HANACloud-<<<TENANT_ID>>>:HanaCloudCredentials:1",
      "name": "HanaCloudCredentials",
      "description": null,
      "catalog": "HANACloud-<<<TENANT_ID>>>",
      "owner": null,
      "version": 1,
      "keys": {
        "serviceManagerKey": {
          "type": "object",
          "sensitive": true,
          "description": "Service Manager key"
        },
        "hanaCloudServiceKey": {
          "type": "object",
          "sensitive": true,
          "description": "HANA Cloud service key"
        }
      },
      "values": {
        "serviceManagerKey": "",
        "hanaCloudServiceKey": ""
      },
      "tags": {}
    }
  ],
  "commands": [
    {
      "configuration": {
        "values": [],
        "output": {
          "isHanaCloudAvailable": "$(.pingHanaCloud.output.body | toArray | [.[0] ,.[1] ,.[2]] | any(.value == 1) )",
          "resultHanaStart": "$(.startHanaCloud.executed)",
          "checkPing": "$(.pingHanaCloud.output.body)"
        },
        "executors": [
          {
            "execute": "http-sapcp:HttpRequest:1",
            "input": {
              "responseBodyTransformer": "toObject.data[0].values | reverse",
              "clientId": "$(.execution.input.hanaCloudServiceKey.uaa.clientid)",
              "tokenUrl": "$(.execution.input.hanaCloudServiceKey.uaa.url)/oauth/token?grant_type=client_credentials",
              "method": "GET",
              "clientSecret": "$(.execution.input.hanaCloudServiceKey.uaa.clientsecret)",
              "url": "https://api.gateway.orchestration.$(.execution.input.hanaCloudServiceKey.host | split(\".\") | .[2:] | join(\".\"))/metrics/v1/serviceInstances/$(.execution.input.hanaCloudServiceKey.host | split(\".\")[0])/values?names=HDBAccessible"
            },
            "alias": "pingHanaCloud",
            "description": null,
            "progressMessage": null,
            "initialDelay": null,
            "pause": null,
            "when": null,
            "validate": null,
            "autoRetry": null,
            "repeat": null,
            "errorMessages": [],
            "dryRun": null
          },
          {
            "execute": "sm-sapcp:UpdateServiceInstance:1",
            "input": {
              "instanceId": "$(.execution.input.hanaCloudServiceKey.host | split(\".\")[0])",
              "serviceKey": "$(.execution.input.serviceManagerKey)",
              "parameters": "{     \"data\": {         \"serviceStopped\": false     } }"
            },
            "alias": "startHanaCloud",
            "description": null,
            "progressMessage": null,
            "initialDelay": null,
            "pause": null,
            "when": {
              "semantic": "OR",
              "conditions": [
                {
                  "semantic": "OR",
                  "cases": [
                    {
                      "expression": "$(.pingHanaCloud.output.body | toArray | [.[0] ,.[1] ,.[2]] | any(.value == 1) )",
                      "operator": "EQUALS",
                      "semantic": "OR",
                      "values": [
                        "false"
                      ]
                    }
                  ]
                }
              ]
            },
            "validate": null,
            "autoRetry": null,
            "repeat": null,
            "errorMessages": [],
            "dryRun": null
          }
        ],
        "listeners": []
      },
      "id": "HANACloud-<<<TENANT_ID>>>:CheckHanaCloudAvailability:1",
      "name": "CheckHanaCloudAvailability",
      "description": "Check availability for HANA Cloud",
      "catalog": "HANACloud-<<<TENANT_ID>>>",
      "version": 1,
      "inputKeys": {
        "serviceManagerKey": {
          "type": "object",
          "sensitive": true,
          "required": false,
          "minSize": null,
          "maxSize": null,
          "minValue": null,
          "maxValue": null,
          "allowedValues": null,
          "allowedValuesFromInputKeys": null,
          "suggestedValues": null,
          "suggestedValuesFromInputKeys": null,
          "defaultValue": null,
          "defaultValueFromInput": {
            "inputReference": "HANACloud-<<<TENANT_ID>>>:HanaCloudCredentials:1",
            "inputKey": "serviceManagerKey"
          },
          "description": null
        },
        "hanaCloudServiceKey": {
          "type": "object",
          "sensitive": true,
          "required": false,
          "minSize": null,
          "maxSize": null,
          "minValue": null,
          "maxValue": null,
          "allowedValues": null,
          "allowedValuesFromInputKeys": null,
          "suggestedValues": null,
          "suggestedValuesFromInputKeys": null,
          "defaultValue": null,
          "defaultValueFromInput": {
            "inputReference": "HANACloud-<<<TENANT_ID>>>:HanaCloudCredentials:1",
            "inputKey": "hanaCloudServiceKey"
          },
          "description": null
        }
      },
      "outputKeys": {
        "isHanaCloudAvailable": {
          "type": "string",
          "sensitive": false,
          "description": "Check on whether or not the HANA Cloud instance is available, where: \"true\" = HANA Cloud is available; \"false\" = HANA Cloud is not available."
        },
        "resultHanaStart": {
          "type": "string",
          "sensitive": false,
          "description": null
        },
        "checkPing": {
          "type": "string",
          "sensitive": false,
          "description": "The entire response for the metric \"HDBAccessible\" returned by HANA Cloud Metrics Service REST API."
        }
      },
      "tags": {}
    }
  ]
}

2. インプットの設定

HanaCloudCredentialsというインプットにHANA CloudとService Managerのサービスキーを設定してください。
image.png

3. 実行

CheckHanaCloudAvailabilityというコマンドを実行します。

image.png

パラメータはインプットから入ってくるので、何も設定せずに"Trigger"を実行します。
image.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?