ノート:

Oracle Cloud Native Frameworkを使用したコスト分析レポートのイベント・ベースの自動電子メール通知の設定

イントロダクション

ワークロードをクラウドで実行するすべての組織は、クラウドのコスト支出を理解することに非常に熱心であり、有意義な方法でレポートしたいと考えています。このため、Oracle Cloud Infrastructure(OCI)には、コストに基づいて自動レポートを作成し、それらのレポートをOCI Object Storageで取得できる機能が用意されています。

これらのコスト・レポートでは、レポートが生成され次第、対応するチームが通知を受け取るように自動化を設定することもできます。これにより、通知の一部としてレポートへのリンクも必要になります。Oracle Cloud Native Frameworkを使用して、この自動化をすべて設定できます。

目的

前提条件

タスク1: 必要なOCI IAMポリシーおよび動的グループの設定

  1. OCIコンソールにログインし、「動的グループ」に移動して、新しい動的グループを作成します。

    動的グループの作成

  2. ルール1にコンパートメントOCIDを入力します。OCIファンクションは同じコンパートメントに存在する必要があります。

    動的グループの設定

  3. OCI IAMポリシーに移動し、次の文を使用してポリシーを作成します。

    allow dynamic-group dynamic_group_name to manage ons-family in compartment compartment_name
    
    allow dynamic-group dynamic_group_name to manage object-family in compartment compartment_name
    

    ノート:

    • ユース・ケースに適した、より具体的なIAMポリシーを使用してください。次の例を参照してください:

      • allow dynamic-group dynamic_group_name to use ons-topics in compartment compartment_name where request.operation = 'PublishMessage'
      • allow dynamic-group dynamic_group_name to manage buckets in compartment compartment_name where all {request.operation = 'CreatePreauthenticatedRequest', target.bucket.name = 'bucket_name'}

タスク2: OCIオブジェクト・ストレージ・バケットの設定およびスケジュール済レポートの作成

  1. OCIコンソールを使用してバケットを作成します。このバケットを使用してレポートをプッシュします。作成したバケットがプライベートであることを確認します。これにより、コンテンツがパブリック・アクセスから保護され、このバケットでオブジェクト・イベントの出力が有効になっていることが確認されます。これにより、新しいオブジェクトがプッシュされたときにイベントが発行されるためです。

    バケットの作成

  2. 「コスト管理」「スケジュール済レポート」に移動し、スケジュール済レポートを作成します。「名前」「説明」「開始日」および「繰返し」を入力します。

    スケジュールされたレポートの作成

    レポートを公開するバケットを選択します。ドロップダウン・メニューからバケットを選択するには、次のイメージに示すようにポリシーを追加して、測定サービスが作成したバケットにアクセスできるようにする必要があります。

    スケジュールされたレポートの作成

  3. バケットおよびスケジュール済レポートの作成後、実行されたレポートの履歴を確認でき、選択したOCIオブジェクト・ストレージ・バケットにレポートが公開されることも表示されます。

    履歴スケジュール済レポート

タスク3: OCI通知トピックの作成およびサブスクリプションの追加

  1. 電子メール通知の送信に必要なOCI通知トピックを作成します。「通知」「トピック」に移動して、トピックを作成します。

    トピックの作成

  2. 同じトピックにサブスクリプションを作成し、通知の送信先となる電子メールを追加します。

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

    これで、OCI通知トピックが構成されました。

タスク4: 関数コードの作成とデプロイ

functions/applicationsに移動して関数を作成します。このファンクションは、OCI IAM動的グループおよびポリシーを使用してOCIオブジェクト・ストレージ・バケットにアクセスし、ファンクションが発行されたイベントによってトリガーされたときに必要な操作(スケジュール済レポート・ファイルのPAR URLの作成および通知の送信)を実行します。

OCI Functionsの開発に使用できる様々なアプローチがあります。クイックスタート・ガイドでは、OCI Cloud Shell、OCI仮想マシン、またはローカルで実行する開発環境の設定について説明します。このガイドの残りのイメージにはOCI Cloud Shellが表示されますが、これらのアプローチのいずれかが有効です。Pythonを使用して必要なロジックをコーディングしましたが、別の言語を使用して、必要に応じてロジックを変更できます。

  1. コードを記述するには、OCI Cloud Shellでrequirement.txtおよびfunc.pyファイルを開きます。

    ファンクションのデプロイ

  2. OCI資格証明を保持する必要がないように、OCIリソース・プリンシパルを使用するファンクション・コードを次に示します。作成の変数(バケット名、トピックOCIDなど)を必ず置き換えてください。

    • requirements.txt.

      fdk>=0.1.71
      oci>=2.112.0
      
    • func.yaml.

      schema_version: 20180708
      name: reportsauto
      version: 0.0.6
      runtime: python
      build_image: fnproject/python:3.11-dev
      run_image: fnproject/python:3.11
      entrypoint: /python/bin/fdk /function/func.py handler
      memory: 256
      
    • func.py.

      import io
      import json
      import logging
      import oci
      from datetime import datetime
      
      from fdk import response
      
      
      def handler(ctx, data: io.BytesIO = None):
          try:
              body = json.loads(data.getvalue())
              logging.getLogger().info(body.get("eventType"))
              logging.getLogger().info(body.get("data").get("resourceName"))
          except (Exception, ValueError) as ex:
              logging.getLogger().info('error parsing json payload: ' + str(ex))
      
          logging.getLogger().info("Inside Python Hello World function")
          initiateFn(body.get("data").get("resourceName"))
          return response.Response(
              ctx, response_data=json.dumps(
                  {"message": "Function Executed!"}),
              headers={"Content-Type": "application/json"}
          )
      
      def initiateFn(uploaded_file):
          logging.getLogger().info("Reached initiate function...")
      
          signer = oci.auth.signers.get_resource_principals_signer()
          object_storage_client = oci.object_storage.ObjectStorageClient(config={}, signer=signer)
          namespace_name="orasenatdplt01"
          bucket_name="demobucket"
      
          now = datetime.now()
          par_name = "PAR_Request_" + str(now).split('.')[0].replace(" ", "_").replace(":", "_").replace("-", "_")
          create_preauthenticated_request_response = object_storage_client.create_preauthenticated_request(
              namespace_name=namespace_name,
              bucket_name=bucket_name,
              create_preauthenticated_request_details=oci.object_storage.models.CreatePreauthenticatedRequestDetails(
                  name=par_name,
                  access_type="ObjectRead",
                  time_expires=datetime.strptime(
                      "2037-06-05T04:25:22.344Z",
                      "%Y-%m-%dT%H:%M:%S.%fZ"),
                  object_name=uploaded_file))
      
          callNotificationAPI(create_preauthenticated_request_response.data)
      
      # Function to call Notification API as soon as an object push is detected
      def callNotificationAPI(parData):
          logging.getLogger().info("Trigger notification as object push is detected...")
          topicOcid = "ocid1.onstopic.oc1.iad.amaaaaxxxxxxxxxamn4"
          signer = oci.auth.signers.get_resource_principals_signer()
          ons_client = oci.ons.NotificationDataPlaneClient(config={}, signer=signer)
          publish_message_response = ons_client.publish_message(
              topic_id=topicOcid,
              message_details=oci.ons.models.MessageDetails(
                  body="OCI Notification Service - Cost Report File is created: " + str(parData.full_path),
                  title="OCI Notification Service - Cost Report File is created"),
              message_type="RAW_TEXT")
          logging.getLogger().info("Triggered notification as object push is detected...")
      
  3. OCI Cloud Shellで次のコマンドを使用し、レジストリ内のファンクションを更新し、最新のコードをデプロイします。

    fn -v deploy — app reportsauto
    
  4. デプロイすると、ファンクションを起動する準備が整います。ファンクションinvokeコマンドを使用してテストし、必要に応じてファンクションが機能していることを確認できます。

    DEBUG=1 fn invoke reportsauto your_app_name
    

    ノート:

    • OCIでは、リソース/インスタンス・プリンシパルがサポートされており、ファンクションの実行中にユーザー関連の情報が提供されないようにします。そのため、このタスクは、関数がAPIを呼び出すための正しい権限セットを持っていることを確認するために必要であり、どの関数が正しく機能しないかを失敗させます。

    • (オプション)トラブルシューティングのためにデバッグ・モードを確認することもできます。たとえば、OCI Cloud Shellから次のコマンドを実行して、関数が期待どおりに機能している場合は起動およびテストします。

      DEBUG=1 fn invoke e2e-function-demo e2e-fn-streaming
      

タスク5: OCIイベント・ルールの設定

  1. OCIコンソールに移動し、「アプリケーション統合」「イベント・サービス」「ルール」および「イベント・ルールの作成」をクリックします。ルール条件を入力し、タスク4で作成された関数をトリガー・アクションとして追加します。

  2. 「表示名」および「説明」を入力します。

    イベント・ルールの作成

  3. 「ルール条件」セクションで、最初の条件として「イベント・タイプ」「オブジェクト・ストレージ」「オブジェクト- 作成」を選択し、別の条件として「属性」bucketNamedemoBucketを選択します。

    イベント・ルールの定義

  4. 「アクション」セクションを使用して、イベントをファンクションに接続します。「ファンクション・コンパートメント」「ファンクション・アプリケーション」およびタスク4にデプロイされたファンクションを選択します。

    イベント・ルール・ターゲット

  5. 「変更の保存」をクリックし、イベント・ルールを保存します。これにより、OCIオブジェクト・ストレージ・バケットから発行されたイベントの条件が一致したときにファンクションが起動されます。

承認

その他の学習リソース

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

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