ノート:

Eメールを使用してコスト使用状況レポートを送信するためのOracle Cloud Infrastructure Functionsの設定

イントロダクション

コスト使用状況レポートは、要件に応じてカスタマイズでき、スケジュールされたコスト使用状況レポートを作成できます。スケジュールに従って、レポートは、選択したOracle Cloud Infrastructure (OCI) Object Storageバケットにプルおよび保存されます。

このレポートを電子メールで送信するには、OCI Functionsをデプロイする必要があります。OCI関数は、OCIで作成されたイベント・ルールに基づいてトリガーされます。ファイルがバケットに格納されるたびに、オブジェクト・アップロード・イベントによって関数がトリガーされ、OCI Functionsには、オブジェクトに対する事前認証済リクエストURLを作成する自動化があります。このURLはEメールで送信されます。

電子メールは、OCI電子メール配信サービスまたはOCI通知サービスのいずれかで受信できます。このチュートリアルでは、両方の構成について説明します。

目的

前提条件

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

  1. OCIコンソールにログインします。詳細は、Oracle Cloudへのログインを参照してください。

  2. OCI IAM動的グループに移動し、次のルールを使用して新しい動的グループを作成します。

    動的グループの作成

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

    allow dynamic-group dynamicgroup_name to manage buckets in compartment CompartmentName where all {target.bucket.name='bucket_name'}
    
    allow dynamic-group dynamicgroup_name to manage objects in compartment CompartmentName where all {target.bucket.name='bucket_name'}
    
    Allow service metering_overlay to manage objects in compartment CompartmentName where all {target.bucket.name='bucket_name', any {request.permission='OBJECT_CREATE', request.permission='OBJECT_DELETE', request.permission='OBJECT_READ'}}
    

    OCI通知サービスを使用して電子メールを送信するには、OCI通知トピックにアクセスするには、OCI IAMポリシーに次の文を追加する必要があります

    allow dynamic-group dynamicgroup_name to use ons-topics in compartment CompartmentName
    

タスク2: スケジュール済原価使用レポートの作成

  1. 「請求およびコストの管理」に移動して、「コストの管理」を選択します。「コスト分析」の下に独自のカスタマイズ済コスト使用レポートを作成し、「適用」をクリックしてレポートを保存します。

    原価レポートの作成

  2. 「スケジュール済レポート」をクリックし、バケット情報を含む新しいスケジュール済レポートを作成します。要件に従って、これをスケジュールできます。

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

    スケジュールに従って、レポートは指定されたOCI Object Storageバケットに自動的に保存されます。

タスク3: ファンクション・コードの作成およびデプロイ

  1. アプリケーションを作成するには、「開発者サービス」に移動し、「アプリケーション」をクリックして、使用可能なネットワークにアプリケーションを作成します。

  2. functions/applicationsに移動して関数を作成します。このファンクションは、OCI IAM動的グループおよびポリシーを使用してイベントにアクセスします。画面のステップに従ってファンクションを作成します。Pythonを使用して必要なロジックをコーディングしましたが、独自の言語を使用して、必要に応じてロジックを変更できます。コードを記述するには、OCI Cloud Shellでファンクションrequirement.txtファイルおよびfunc.pyファイルを開き、コードを記述します。

    クラウド・シェルおよびコード・エディタでのファンクションの作成

  3. func.pyに次のPythonコードをコピーし、requirement.txtファイルにテキスト・ファイルをコピーします。

    • func.py:

      • OCI Email Deliveryの使用:

        ノート:それぞれの電子メールIDおよびSimple Mail Transfer Protocol (SMTP)の詳細を追加します。

        import oci
        import json
        import io
        import logging
        import smtplib
        from os.path import basename
        from email.mime.application import MIMEApplication
        from email.mime.multipart import MIMEMultipart
        from email.mime.text import MIMEText
        from email.utils import COMMASPACE, formatdate
        from datetime import datetime
        import ssl
        import email.utils
        from email.message import EmailMessage
        
        def handler(ctx, data: io.BytesIO = None):
           funDataStr = data.read().decode('utf-8')
        
        #Convert the log data to json
           funData =  json.loads(funDataStr)
        
        #Set up OCI configuration using resource principal
           signer = oci.auth.signers.get_resource_principals_signer()
        #Create Object Storage client
           object_storage_client = oci.object_storage.ObjectStorageClient({},signer=signer)
        
        # Extract object details from the event
           object_name = funData['data']['resourceName']
           namespace = funData['data']['additionalDetails']['namespace']
           bucket_name = funData['data']['additionalDetails']['bucketName']
        # Download the object
        #get_object_response = object_storage_client.get_object(namespace, bucket_name, object_name)
        #object_content = str(get_object_response.data.text)
           create_preauthenticated_request_response = object_storage_client.create_preauthenticated_request(
              namespace_name = namespace,
              bucket_name = bucket_name,
              create_preauthenticated_request_details=oci.object_storage.models.CreatePreauthenticatedRequestDetails(
                 name = "prestorage",
                 access_type = "ObjectRead",
                 time_expires = datetime.strptime(
                    "2024-06-05T04:25:22.344Z",
                    "%Y-%m-%dT%H:%M:%S.%fZ"),
                 object_name = object_name))
           #logging.getLogger().info(create_preauthenticated_request_response.data)
           logging.getLogger().info("created pre authenticated url")
           string = str(create_preauthenticated_request_response.data)
           #response = create_preauthenticated_request_response.data().decode('utf-8')
           url = json.loads(string)
           logging.getLogger().info(url)
           temporary_url = f"{url['full_path']}"
           logging.getLogger().info(temporary_url)
        
        #Set your email credentials
           sender_email = "test@domain"
           sender_name = "Tester"
        
        #Set the recipient email address
           recipient_email = "xyz@oracle.com"
           USERNAME_SMTP = "SMTPOCID"
           password_smtp = "************"
           HOST = "smtp_email"
           PORT = 587
        
        #Create the email content
           subject = "Cost Usage Report"
           body = temporary_url
           message = EmailMessage()
           message['From'] = email.utils.formataddr((sender_name, sender_email))
           message['To'] = recipient_email
           message['Subject'] = subject
           message.set_content(body)
           try:
              server = smtplib.SMTP(HOST, PORT)
              server.ehlo()
              server.starttls(context=ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, cafile=None, capath=None))
              server.ehlo()
              server.login(USERNAME_SMTP, password_smtp)
              logging.getLogger().info("SMTP server logged in")
              server.sendmail(sender_email, recipient_email, message.as_string())
              #server.send_message(message)
              server.close()
           except Exception as e:
              logging.getLogger().info(f"Error: {e}")
           else:
              logging.getLogger().info('Email sent successfully!')
        
      • OCI通知の使用:

        ノート:トピックOCIDを更新します(通知を作成するステップについては、タスク5で説明します)。

        import oci
        import json
        import io
        import logging
        import smtplib
        from os.path import basename
        from email.mime.application import MIMEApplication
        from email.mime.multipart import MIMEMultipart
        from email.mime.text import MIMEText
        from email.utils import COMMASPACE, formatdate
        from datetime import datetime
        import ssl
        import email.utils
        from email.message import EmailMessage
        
        def handler(ctx, data: io.BytesIO = None):
           funDataStr = data.read().decode('utf-8')
        
        # Convert the log data to json
           funData =  json.loads(funDataStr)
        
        # Set up OCI configuration using resource principal
           signer = oci.auth.signers.get_resource_principals_signer()
        # Create Object Storage client
           object_storage_client = oci.object_storage.ObjectStorageClient({},signer=signer)
           ons_client = oci.ons.NotificationDataPlaneClient({},signer=signer)
        # Extract object details from the event
        
        
           object_name = funData['data']['resourceName']
           namespace = funData['data']['additionalDetails']['namespace']
           bucket_name = funData['data']['additionalDetails']['bucketName']
        
        # Download the object
           create_preauthenticated_request_response = object_storage_client.create_preauthenticated_request(
              namespace_name = namespace,
              bucket_name = bucket_name,
              create_preauthenticated_request_details=oci.object_storage.models.CreatePreauthenticatedRequestDetails(
                 name = "prestorage",
                 access_type = "ObjectRead",
                 time_expires = datetime.strptime(
                    "2024-06-05T04:25:22.344Z",
                    "%Y-%m-%dT%H:%M:%S.%fZ"),
                 object_name = object_name))
        #logging.getLogger().info(create_preauthenticated_request_response.data)
           logging.getLogger().info("created pre authenticated url")
           string = str(create_preauthenticated_request_response.data)
        #response = create_preauthenticated_request_response.data().decode('utf-8')
           url = json.loads(string)
        
           logging.getLogger().info(url)
           temporary_url = f"{url['full_path']}"
           logging.getLogger().info(temporary_url)
        #to send mail using notification
           publish_message_response = ons_client.publish_message(
              topic_id="ocid1.onstopic.oc1.iad.************",
              message_details=oci.ons.models.MessageDetails(
                 body=temporary_url,
                 title="Cost-usage report"),
           message_type="RAW_TEXT")
           logging.getLogger().info(publish_message_response)
           logging.getLogger().info('Email sent successfully!')
        
    • requirement.txt:

      fdk>=0.1.68
      oci
      
  4. OCI Cloud Shellで次のコマンドを使用し、レジストリ内のファンクションを更新し、最新のコードをデプロイします。

    fn -v deploy — app App_name
    

デプロイすると、ファンクションを起動する準備が整います。ファンクションをトリガーするには、イベント・ルールを作成する必要があります。

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

  1. OCIでイベント・ルールを作成します。「監視および管理」で、「イベント・サービス」「ルール」および「ルールの作成」をクリックします。次のイメージに示すように、バケットIDとして属性を持つ照合ルールを入力します。

    ノート:作成されたOCIオブジェクト・ストレージ・バケットは、emitオブジェクト・イベントで有効にする必要があります。

    イベント・ルールの作成

  2. 次の図に示すように、タスク2で作成された関数を使用して「アクション」を追加します。

    アクション

    これで、関数のトリガーが作成されます。

タスク5: OCI Email DeliveryまたはOCI Notificationsを使用した電子メール構成の設定

テスト

オブジェクトまたはファイルをバケットにアップロードすると、イベント・ルールを使用して自動的に機能がトリガーされます。

承認

その他の学習リソース

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

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