ServiceNowを使用したアラームの管理

このトピックでは、アラームが発生するたびに自動ServiceNowチケットを登録する方法について説明します。

このシナリオでは、CPU使用率がアラームで指定されたしきい値を超えると、オンコール・エンジニアに対してServiceNowチケットが作成されます。

Oracle Cloud Infrastructure Console、APIまたはCLIを使用してクラウド・リソースに説明、タグまたはフレンドリ名を割り当てる場合、機密情報を入力しないでください。

このシナリオでは、ServiceNowチケットをファイルするためのファンクションの書込み(およびServiceNow資格証明を格納するシークレットの作成)、そのファンクションおよびオプションの電子メールをサブスクリプションとしてトピックに追加し、アラームしきい値を超えた場合にそのトピックにメッセージを送信するアラームを作成します。メッセージはトピックのサブスクリプションにファン・アウトされ、機能に加えてグループEメール・アドレスも含まれます。メッセージの受信時にファンクションが呼び出されます。

ファンクション以外はすべてコンソールで設定できます。または、Oracle Cloud Infrastructure CLIまたはAPIを使用して、各操作を自分で実行できます。

次の表に、一般的なプロセス フローを示します。



servicenow-notifications-oracle.zip

ServiceNow資格証明のシークレットへの格納

後でファンクションを作成するときに参照するシークレットを作成します。

コンソールを使用してシークレットを作成します(コマンドライン・インタフェース(CLI)またはアプリケーション・プログラミング・インタフェース(API)を使用してシークレットを作成することもできます)。

  1. ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」「ボールト」の順にクリックします。
  2. 「リスト範囲」の「コンパートメント」リストで、シークレットを作成するコンパートメントの名前をクリックします。
  3. コンパートメント内のボールトのリストから、次のいずれかを実行します。
    • シークレットを作成するボールトの名前をクリックします。
    • シークレットに新しいボールトを作成し、ボールトの名前をクリックします。
  4. usernameシークレットを作成します:
    1. 「シークレット」「シークレットの作成」の順にクリックします。
    2. 「シークレットの作成」ダイアログ・ボックスで、「コンパートメントに作成」リストからコンパートメントを選択します。シークレットは、ボールトが含まれるコンパートメントの外部に存在できます。)
    3. 「名前」をクリックし、シークレットを識別する名前を入力します。このフィールドには、機密情報を入力しないでください。
      nameの例: servicenow_username_plain_text
    4. 「説明」をクリックし、シークレットの識別に役立つ簡単な説明を入力します。このフィールドには、機密情報を入力しないでください。
      説明の例: servicenow_username_plain_text
    5. ボールトへのインポート中にシークレット・コンテンツの暗号化に使用するマスター暗号化キーを選択します(キーは同じボールトに属している必要があります)。
    6. 「シークレット・タイプ・テンプレート」で、「プレーン・テキスト」を選択します。
    7. 「シークレット・コンテンツ」をクリックし、ServiceNowユーザー名を入力します:
      <your-servicenow-username>
    8. 「Create Secret」をクリックします。
    9. シークレットOCIDを書き留めます。

関数の作成

次のサンプル・コードで開始して、ServiceNowチケットをファイルするファンクションを作成し、Oracle Cloud Infrastructure Vaultサービスを使用して作成されたシークレットのServiceNow資格証明へのアクセスをファンクションに認可します。

コード・サンプルには、仮想関数で使用される変数SNOW_URL、SNOW_USER_ID_SECおよびSNOW_USER_PWD_SECが含まれています。これらの値を関数から直接読み取るか、かわりに値をカスタム構成パラメータとして渡すかを選択できます。

#####################################################
# THIS SAMPLE CODE IS FOR DEMO PURPOSES ONLY
#*************************************************
# ******** DO NOT USE IN PRODUCTION *************
# ************************************************
#####################################################
import io
import sys
import oci
import json
import base64
import requests
from fdk import response
SNOW_URL = '<Provide Service Now URL here>'
SNOW_USER_ID_SEC = '<Provide the OCID of OCI Secret for Service Now User ID>'
SNOW_USER_PWD_SEC = '<Provide the OCID of OCI Secret for Service Now User Password>'
OCI_TO_SNOW_SEV_MAP =
{    'CRITICAL'  : '1',    'WARNING'   : '2',    'ERROR'     : '3',    'INFO'      : '4' }
def handler(ctx, data: io.BytesIO = None):
    try:
        funDataStr = data.read().decode('utf-8')
        funDataJSON =  json.loads(funDataStr)
        alarmData = {}
        alarmData['type'] = funDataJSON['type']
        alarmData['metaDataList'] = funDataJSON['alarmMetaData']
        alarmData['title'] = funDataJSON['title']
        alarmData['body'] = funDataJSON['body']
        alarmData['sev'] = OCI_TO_SNOW_SEV_MAP[funDataJSON['severity'].upper()]
        if alarmData['type'].upper() == 'OK_TO_FIRING':
            snowURL = SNOW_URL
            snowUsrIDSec = SNOW_USER_ID_SEC
            snowUsrPwdSec = SNOW_USER_PWD_SEC
            ociResPrncplSigner = oci.auth.signers.get_resource_principals_signer()
            ociSecSvc = oci.secrets.SecretsClient(config={}, signer=ociResPrncplSigner)
            snowUserID = readSecValueFromSecSvc(ociSecSvc, snowUsrIDSec)
            snowPswd = readSecValueFromSecSvc(ociSecSvc, snowUsrPwdSec)
            snowData = getSNOWData(alarmData)
            sendDataToSnow(snowURL, snowUserID, snowPswd, snowData)
    except Exception as e:
        sys.stderr.write("Exception : " + str(e))
        sys.stderr.write("Exception Class : " + str(e._class_))
    return response.Response(ctx, response_data="", headers={"Content-Type": "application/json"})
def sendDataToSnow(snowURL, uid, pwd, snowData):
    try:
{ 
snowHdrs =
      "Content-Type" : "application/json",
counter = 0
for sd in snowData:
"Accept" : "application/json"         }
        snowResp = requests.post(snowURL, auth=(uid, pwd), headers=snowHdrs, data=json.dumps(sd))
except Exception as e:
    sys.stderr.write("Exception : " + str(e))
    sys.stderr.write("Exception Class : " + str(e._class_))
   def getSNOWData(alarmData):
       snowData = []
       if alarmData['type'].upper() == 'OK_TO_FIRING':
           alrmMD = alarmData['metaDataList'][0]
           for d in alrmMD['dimensions']:
               snowDataElem = {}
               snowDataElem['node'] = d['resourceDisplayName']
               snowDataElem['source'] = 'OCI'
               snowDataElem['severity'] = alarmData['sev']
               snowDataElem['description'] = alarmData['body']
               snowDataElem['type'] = alarmData['title']
               snowData.append(snowDataElem)
       return snowData
   def readSecValueFromSecSvc(ociSecSvc, secID):
       secResp = ociSecSvc.get_secret_bundle(secID)
       secContent = secResp.data.secret_bundle_content.content
       secret_content = base64.b64decode(secContent).decode('utf-8')
       return secret_content

動的グループを使用して、ファンクションにシークレットの読取り権限を付与します。前に作成したシークレットに格納されているServiceNow資格証明にアクセスするには、ファンクションにこの認可が必要です。

  1. 次の形式のファンクションOCIDを見つけてノートにとります:
    ocid1.fnfunc.oc1.iad.<exampleuniqueID>

    次のルールを指定して、関連する動的グループに関数を含めます。

    resource.id = '<function-ocid>'

    または、すべての機能を含む動的グループを作成できます。

    ALL{resource.type=’fnfunc’, resource.compartment.id=’<compartment_OCID>’}
  2. 次のポリシーを追加して、動的グループにシークレットへのアクセス権を付与します。
    allow dynamic-group <dynamic-group-name> to read secret-family in tenancy

    コンピュート・インスタンスなどの他のOracle Cloud Infrastructureリソースへのアクセスをファンクションに認可するには、動的グループにファンクションを含め、それらのリソースへのアクセス権を動的グループに付与するポリシーを作成します。

トピックの作成

サブスクリプションおよびアラームに使用するトピックを作成します。

トピックは、サブスクリプションにメッセージを送信するための通信チャネルです。各トピック名はテナンシ間で一意です。トピックを作成するには、コンソール、コマンドライン・インタフェース(CLI)またはアプリケーション・プログラミング・インタフェース(API)を使用します。

トピックで使用する前に、ファンクションをデプロイする必要があります。

  1. コンソールを使用してトピックを作成するには:
    1. ナビゲーション・メニューを開き、「開発者サービス」をクリックします。「アプリケーション統合」で、「通知」をクリックします。
    2. トピック・リストの上部にある「トピックの作成」をクリックします。
    3. 「トピックの作成」ダイアログ・ボックスで、トピックを構成します。
      • 名前: トピックのフレンドリ名を指定します。テナンシ内で一意である必要があります。検証では大文字と小文字が区別されます。機密情報を入力しないでください。
      • 説明: オプションでトピックの説明を入力します。機密情報を入力しないでください。
    4. 「作成」をクリックします。
  2. CLIを使用してトピックを作成するには、コマンド・プロンプトを開き、次のようなコマンドを入力します:
    oci ons topic create
    --name "My Topic"
    --compartment-id "<compartment-ocid>"
  3. APIを使用してトピックを作成するには、次のような操作を使用します:
    POST /20181201/topics
    Host: notification.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "name": "My Topic",
      "compartmentId": "<compartment_OCID>"
    }
    

サブスクリプションの作成

トピックのサブスクリプションを作成します。

サブスクリプションは、トピックのエンドポイントです。パブリッシュされたメッセージは、トピックの各サブスクリプションに送信されます。

サブスクリプションで使用する前にファンクションをデプロイする必要があり、そのファンクションをトピックのサブスクリプションとして追加するには、そのファンクションに対してFN_INVOCATION権限を持っている必要があります。

  1. コンソールを使用してファンクション・サブスクリプションを作成するには:
    1. ナビゲーション・メニューを開き、「開発者サービス」をクリックします。「アプリケーション統合」で、「通知」をクリックします。サブスクリプションを追加するトピックの名前をクリックします。
    2. トピックの詳細ページで、「サブスクリプションの作成」をクリックします。
    3. 「サブスクリプションの作成」ダイアログ・ボックスで、ファンクション・サブスクリプションを構成します。ファンクション・サブスクリプションの確認は必要ありません。
      • サブスクリプション・プロトコルの場合は、「ファンクション」をクリックします。
      • 「ファンクション・コンパートメント」で、ファンクションを含むコンパートメントをクリックします。
      • 「ファンクション・アプリケーション」で、ファンクションを含むアプリケーションをクリックします。
      • 「Function」で、自分の機能をクリックします。
    4. 「作成」をクリックします。
  2. コンソールを使用してオプションの電子メール・サブスクリプションを作成するには:
    1. ナビゲーション・メニューを開き、「開発者サービス」をクリックします。「アプリケーション統合」で、「通知」をクリックします。サブスクリプションを追加するトピックの名前をクリックします。
    2. トピックの詳細ページで、「サブスクリプションの作成」をクリックします。
    3. 「サブスクリプションの作成」ダイアログ・ボックスで、電子メール・サブスクリプションを構成します。
      • サブスクリプション・プロトコルの場合は、「電子メール」をクリックします。
      • 「Email」に、電子メール・アドレスを指定します。
    4. 「作成」をクリックします。
      電子メール・サブスクリプションが作成され、指定された電子メール・アドレスにサブスクリプション確認URLが送信されます。サブスクリプションは、確認されるまで「保留」ステータスのままです。新しいEメール・サブスクリプションを確認するには、Eメールを開き、確認URLをクリックします。
  3. CLIを使用してサブスクリプションを作成するには:
    1. ファンクション・サブスクリプションを作成するには、コマンド・プロンプトを開き、次のようなコマンドを入力します。
      oci ons subscription create
      --compartment-id "<compartment-ocid>"
      --topic-id "<topic-ocid>" 
      --protocol "ORACLE_FUNCTIONS"
      --subscription-endpoint "<function-ocid>"
    2. 電子メール・サブスクリプションを作成するには、コマンド・プロンプトを開き、次のようなコマンドを入力します。
      oci ons subscription create
      --compartment-id "<compartment-ocid>"
      --topic-id "<topic-ocid>" 
      --protocol "EMAIL"
      --subscription-endpoint "team@example.com"
  4. APIを使用してサブスクリプションを作成するには:
    1. APIを使用してファンクション・サブスクリプションを作成するには、次のような操作を使用します:
      POST /20181201/subscriptions
      Host: notification.us-phoenix-1.oraclecloud.com
      <authorization and other headers>
      {
        "topicId": "<topic_OCID>",
        "compartmentId": "<compartment_OCID>",
        "protocol": "ORACLE_FUNCTIONS",
        "endpoint": "<function_OCID>"
      } 
    2. APIを使用して電子メール・サブスクリプションを作成するには、次のような操作を使用します:
      POST /20181201/subscriptions
      Host: notification.us-phoenix-1.oraclecloud.com
      <authorization and other headers>
      {
        "topicId": "<topic_OCID>",
        "compartmentId": "<compartment_OCID>",  
        "protocol": "EMAIL",
        "endpoint": "team@example.com"
      
      } 

警告の作成

アラームしきい値を超えるたびにトピックにメッセージを送信するアラームを作成します。Notificationsでは、そのトピック内のアクティブなサブスクリプションにメッセージが配信されます。

  1. コンソールを使用してアラームを作成するには:
    1. ナビゲーション・メニューを開き、「監視および管理」をクリックします。「モニタリング」で、「アラーム定義」をクリックします。
    2. 「アラームの作成」をクリックします。
    3. 「アラートの作成」ページの「アラームの定義」の下で、しきい値を設定します:
      「メトリックの説明」の下:
      • Compartment: 対象のコンピュート・インスタンスを含むコンパートメントを選択します。
      • メトリック・ネームスペース: oci_computeagent
      • メトリック名: CpuUtilization
      • 間隔: 1m
      • 統計:
      「トリガー・ルール」で、次のようにします。
      • 演算子: 次より大きい
      • 値: 90
      • トリガー遅延分数: 1
    4. アラーム通知を定義するには、前に作成したトピックを宛先として追加します。
      「Destination」の下:
      • 宛先サービス: 通知
      • コンパートメント: (トピックを含むコンパートメントを選択します)
      • トピック: (トピックを選択)
    5. 「アラームの保存」をクリックします。
  2. CLIを使用してアラームを作成するには、コマンド・プロンプトを開き、次のようなコマンドを入力します:
    oci monitoring alarm create
    --display-name "My Alarm"
    --compartment-id "<compartment-ocid>" 
    --metric-compartment-id "<compartment-ocid>" 
    --namespace "oci_computeagent" 
    --query-text "CPUUtilization[1m].count() > 90"
    --severity "CRITICAL"
    --destinations "<topic-ocid>"
    --is-enabled true
  3. APIを使用してアラームを作成するには、次のような操作を使用します:
    POST /20180401/alarms
    Host: telemetry.us-phoenix-1.oraclecloud.com
    <authorization and other headers>
    {
      "displayName": "My Alarm",
      "compartmentId": "<compartment_OCID>",
      "metricCompartmentId": "<compartment_OCID>",
      "namespace": "oci_computeagent",
      "query": "MemoryUtilization[1m].max() > 90",
      "severity": "CRITICAL",
      "destinations":
        [
          "<topic_OCID>"
        ],
      "isEnabled": true
    }