ノート:

OCIモニタリングでのOracle Cloud Infrastructure Eventsの電子メール通知の設定

イントロダクション

Oracle Cloud Infrastructure (OCI)サービスは、リソースの変更を示す構造化メッセージであるイベントを生成します。イベントを処理するルールを作成し、一致するイベントが見つかった場合にトリガーするアクションも指定する必要があります。

電子メール通知アクションは、イベントの照合用に定義する応答です。OCI電子メール配信サービスは、セキュアで大量のトランザクション電子メール通知を送信するための、迅速で信頼性の高い管理ソリューションを提供します。

目的

前提条件

Oracle Cloud Infrastructure Identity and Access Management (OCI IAM)管理者は、次のものを作成する必要があります。

サブスクライブ済および優先電子メール配信リージョンの詳細は、SMTP接続エンドポイントの構成を参照してください。

タスク1: 承認済送信者をEメール配信で構成

OCIを介してメールを送信するすべての「送信元: 」アドレスに、承認済送信者を設定する必要があります。これはコンパートメントに関連付けられ、承認済送信者が構成されたリージョンにのみ存在します。

次に示すように、承認送信者に対してドメイン名またはデフォルトのoracle通知を使用できます。

  1. OCIコンソールのナビゲーション・メニューを開き、「開発者サービス」をクリックします。

  2. 「アプリケーション統合」で、「電子メール配信」をクリックします。

  3. 「Email Delivery」で、承認済送信者をクリックします。

  4. 「承認済送信者の作成」をクリックし、承認済送信者としてリストする電子メール・アドレスを入力します。

    ノート: OCI電子メール配信のSMTP接続エンドポイントがSMTP.email.ap-mumbai-1.OCI.oraclecloud.comの場合は、リージョンにnoreply@notificationを追加し、承認送信者の電子メール・アドレスを入力します。たとえば、noreply@notification.ap-mumbai-1.oci.oraclecloud.comです。

  5. 「追加」をクリックして、「承認済送信者」リストにEメール・アドレスを追加します。

タスク2: タグ・ネームスペースおよびキー定義の作成

  1. ナビゲーション・メニューを開き、「ガバナンスと管理」をクリックします。

  2. 「テナンシ管理」で、「タグ・ネームスペース」をクリックします。

  3. 「タグ・ネームスペース」ページで、「タグ・ネームスペースの作成」をクリックします。

  4. 「タグ・ネームスペースの作成」パネルで、適切なコンパートメントを選択し、ネームスペース名にcustomと入力して、説明を指定します。

  5. customネームスペースで、「タグ・キー定義の作成」をクリックし、タグ・キーにrecipientと入力して作成します。

    ノート: 通知が必要な場合、各OCIリソースの定義済タグに受信者の電子メール・アドレスを追加できます。解決策では、recipient addressesを使用して、クラウド・イベントで使用可能な場合は通知し、それ以外の場合はdefaultrecepientアドレスがファンクション構成で指定されます。たとえば、demouser1@abc.com、demouser2@abc.com

タスク3: OCIボールトでのシークレットの作成

  1. ナビゲーション・メニューを開き、「アイデンティティとセキュリティ」「Vault」の順にクリックします。

  2. 「リスト」スコープで、ボールトを含むコンパートメントを選択します。

    ノート: 新しいボールトおよびマスター暗号化キーを作成する必要がある場合は、Vaultの作成およびマスター暗号化キーの手順に従います。

  3. 「リソース」で、「シークレットの作成」をクリックし、適切なマスター暗号化キーを選択します。

    • 名前フィールドにsmptppassと入力し、OCI電子メール配信認証用のSMTPパスワードの説明を入力します。

    • シークレット・タイプ・テンプレートの書式「プレーン・テキスト」を選択し、シークレットのコンテンツにsmtp passwordと入力します。

      ノート: OCI IAM管理者が共有するSMTPパスワードを使用します。

タスク4: OCIファンクションの作成およびデプロイ

  1. OCIコンソールで、上部のナビゲーションの「クラウド・シェル」をクリックします。

  2. クラウド・シェルからFn project CLIを使用してファンクションを作成します。

    fn init --runtime python <function-name>
    
    Example: fn init --runtime python emaildelivery-func
    
  3. ディレクトリを新しく作成されたディレクトリに変更します。

  4. ファンクションをデプロイするアプリケーションを作成します。

    # Specify the OCID of subnet
    fn create app emaildeliveryapp --annotation oracle.com/oci/subnetIds='["<subnet OCID>"]'
    
    Example:  fn create app emaildeliveryapp --annotation oracle.com/oci/subnetIds='["ocid1.subnet.oc1.ap-mumbai-1.aaaaaaaabitp32dkyox37qa3tk3evl2nxivwb....."]'
    
  5. 既存のコンテンツを上書きして、次のスクリプトをfunc.pyファイルにコピー・アンド・ペーストします。

    # python script for sending SMTP configuration with Oracle Cloud Infrastructure Email Delivery
    import io
    import json
    import logging
    import oci
    from fdk import response
    import smtplib
    import email.utils
    import ssl
    import base64
    from email.mime.text import MIMEText
    from email.mime.multipart import MIMEMultipart
    from email.mime.base import MIMEBase
    
    # Get Resource Principal Credentials
    signer = oci.auth.signers.get_resource_principals_signer()
    
    # Get instance principal context
    secret_client = oci.secrets.SecretsClient(config={}, signer=signer)
    identity_client = oci.identity.IdentityClient(config={}, signer=signer)
    tenancy_data = identity_client.get_tenancy(tenancy_id=signer.tenancy_id).data
    t_name = str(tenancy_data.name)
    t_id = signer.tenancy_id
    
    # Retrieve secret
    def read_secret_value(secret_client, secret_id):
       response = secret_client.get_secret_bundle(secret_id)
       base64_Secret_content = response.data.secret_bundle_content.content
       base64_secret_bytes = base64_Secret_content.encode('ascii')
       base64_message_bytes = base64.b64decode(base64_secret_bytes)
       secret_content = base64_message_bytes.decode('ascii')
       return secret_content
    
    # Sender name
    sendername = 'noreply'
    
    # If you're using Email Delivery in a different region, replace the HOST value with an appropriate SMTP endpoint.
    # Use port 25 or 587 to connect to the SMTP endpoint.
    port = 587
    
    # Reading company logo information in base64 encoded
    with open("companylogo.png", "rb") as image_file:
       image_data = base64.b64encode(image_file.read())
    image_data = '<img src="data:image/png;base64,'+str(image_data)[2:]+'" alt="company logo" />'
    
    def handler(ctx, data: io.BytesIO=None):
       try:
          # Extracting function config values
          cfg = ctx.Config()
          smtp_user = cfg["smtpuser"]
          host = cfg["host"]
          sender = cfg["sender"]
          smtp_defrec = cfg["defaultrecipient"]
          smtp_pass = cfg["smtppass"]
    
          # Secrets from vault
          smtp_pass = read_secret_value(secret_client, secret_id=smtp_pass )
    
          # Extracting values from triggered OCI event
          body = json.loads(data.getvalue())
          e_Type = body.get("eventType")
          e_time = body.get("eventTime")
          r_name = body["data"]["resourceName"]
          c_id = body["data"]["compartmentId"]
          c_name = body["data"]["compartmentName"]
          r_id = body["data"]["resourceId"]
          add_detail = ""
    
          try:
                # Extracting additional details from OCI event
                details = body["data"]["additionalDetails"]
                for key, value in details.items():
                   add_detail = add_detail+str(key)+' : '+str(value)+'<br>'
          except (Exception, ValueError) as ex:
                add_detail = "Additional details not available for this OCI event"
    
          try:
                # Extracting recepient details if available in OCI event
                recipient = body["data"]["definedTags"]["custom"]["recipient"]
          except Exception as e:
                recipient = smtp_defrec
    
          # Extract event type
          e_Type = e_Type.split('com.oraclecloud.')[1]
    
          # Extract region name
          r_id = r_id.split('.')[3]
    
          # The subject line of the email.
          SUBJECT = 'Event | '+ r_name + ' | ' + e_Type + ' | ' + e_time
    
          BODY_HTML = """\
          <html>
             <head></head>
             <body>
             """ +str(image_data)+ """
             <h2>Oracle Cloud Notification</h2>
             <hr>
             <b>Event Time : </b>""" +str(e_time)+ """
             <br>
             <b>Event Type : </b>""" +str(e_Type)+ """
             <br>
             <b>Tenancy Name : </b>""" +str(t_name)+ """
             <br>
             <b>Tenancy ID : </b>""" +str(t_id)+ """
             <hr>
             <b>Resource Name : </b>""" +str(r_name)+ """
             <br>
             <b>Region Name : </b>""" +str(r_id)+ """
             <br>
             <b>Compartment ID : </b>""" +str(c_id)+ """
             <br>
             <b>Compartment Name : </b>""" +str(c_name)+ """
             <hr>
             <b>Details : </b><br>""" +str(add_detail)+ """
             <hr>
          <br>
          <p>
          Thank you, <br>
          The OCI team <br><br><br>
          Please do not reply directly to this email. This mailbox is not monitored. If you have any questions regarding this notification, contact your account administrator. <br>
          </p>
          </body>
          </html>
          """
    
          # create message container
          msg = MIMEMultipart()
          msg['Subject'] = SUBJECT
          msg['From'] = email.utils.formataddr((sendername, sender))
          msg['To'] = recipient
    
          # Attach HTML body for email
          msg.attach(MIMEText(BODY_HTML, 'html'))
    
          # Attach JSON payload as attachement
          attach_file = json.dumps(body,indent=2)
          payload = MIMEBase('application', 'octate-stream')
          payload.set_payload(attach_file)
          payload.add_header('Content-Disposition', 'attachment', filename='event_output.json')
          msg.attach(payload)
    
          # Try to send the message.
          server = smtplib.SMTP(host, port)
          server.ehlo()
          # most python runtimes default to a set of trusted public CAs that will include the CA used by OCI Email Delivery.
          # However, on platforms lacking that default (or with an outdated set of CAs), customers may need to provide a capath that includes our public CA.
          server.starttls(context=ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, cafile=None, capath=None))
          # smtplib docs recommend calling ehlo() before & after starttls()
          server.ehlo()
          server.login(smtp_user, smtp_pass)
    
          # our requirement is that SENDER is the same as From address set previously
          server.sendmail(sender, recipient, msg.as_string())
          server.close()
          # Display an error message if something goes wrong.
       except (Exception, ValueError) as ex:
          logging.getLogger().info('error parsing json payload: ' + str(ex))
    
       return response.Response(ctx, response_data=json.dumps({"message": "success"}),headers={"Content-Type": "application/json"})
    
  6. companylogo.pngを会社のロゴに置き換え、HTMLテキストをスクリプトの電子メール本文として更新できます。デフォルトはOracleロゴです。

  7. ファンクションをデプロイするには、次のコマンドを実行します。

    fn -v deploy --app <app-name>
    
    Example: fn -v deploy --app emaildeliveryapp
    
  8. 次を実行して、各構成キーおよび値のファンクション構成を追加します。

    • sender: タスク1で構成された承認済送信者を使用します。

    • smtpuser: OCI IAM管理者が共有するSMTPユーザー。

    • smtppass: SMTPパスワード・ボールト・シークレットのOCIDを使用し、smtppass構成値で更新します。

    • host: 前提条件に従ってSMTP接続エンドポイントを使用します。

    • defaultrecipient: デフォルトの受信者として電子メール・アドレスを指定します。解決策では、_recipient addresses_を使用して、クラウド・イベントで使用可能な場合は通知し、それ以外の場合は_defaultrecepient_アドレスがファンクション構成で使用されます。

    fn config function <app-name> <function-name> <config-key> <config-value>
    
    Example: fn config function emaildeliveryapp emaildelivery-func sender noreply@notification.ap-mumbai-1.oci.oraclecloud.com
    

タスク5: イベント・ルールの作成

  1. ナビゲーション・メニューを開き、「監視および管理」をクリックします。

  2. 「イベント・サービス」で、「ルール」をクリックします。

  3. 「ルールの作成」をクリックし、「ルールの作成」パネルで、ルールのわかりやすい名前およびルールの説明を指定します。

  4. 「ルール条件」領域で、関数をトリガーするイベント・タイプおよびアクションを指定します。イベント・タイプ、属性およびタグに基づいてフィルタを定義して、アクションをトリガーするイベントを制限できます。次に、コンピュート・インスタンスの開始または停止イベントをトリガーする例を示します。

    コンピュート・インスタンス・イベント・ルール

タスク6: Eメール通知の検証

  1. OCIイベントをトリガーするためにイベント・ルールが作成されたコンパートメントでコンピュート・インスタンスを起動または停止します。

  2. 電子メールのわかりやすい通知と、RAW JSONがアタッチされます。

    電子メール通知

謝辞

著者 - Dipesh Kumar Rathod (インフラストラクチャ、マスター・プリンシパル・クラウド・アーキテクト)

その他の学習リソース

docs.oracle.com/learnで他のラボをご覧いただくか、Oracle Learning YouTubeチャネルでより無料のラーニング・コンテンツにアクセスしてください。また、education.oracle.com/learning-explorerにアクセスして、Oracle Learning Explorerになります。

製品ドキュメントについては、Oracle Help Centerを参照してください。