はじめに
OCIでは イベントサービス と 通知サービス を用いることで、使用しているインスタンスでイベントが発生した場合等に簡単に通知を行うことができます。
例えば、イベントサービスでComputeインスタンスのイベントに対する通知メールを設定した場合には、以下のようになります。
※上記はイベントのルール条件に以下を設定して、Computeインスタンスを停止した場合の通知メールとなります。
- 条件:イベント・タイプ
- サービス名:Compute
- イベント・タイプ:Instance – Action Begin
メールを見ても、JSON形式であることかつ必要としない情報も含まれる為、すぐにどのインスタンスで何が起こったのかを読み取るには煩わしく思います。
そこで、今回は、電子メール配信サービス(Email Delivery)とOracle Functionsを使用して、件名だけでどのインスタンスで何のイベントが発生したか分かるようなシンプルなメールを送信してみたいと思います。
前提条件
-
Email Deliveryを利用する為の設定は事前に行っているものとします。
始めて使用される方は、以下のチュートリアルを参照してください。
・OCIチュートリアル/Email Deliveryを利用した外部へのメール送信(基礎編) -
Oracle Functionsではアプリケーションの作成までを行っているものとします。
始めて使用される方は、こちらも以下のチュートリアルに詳細な手順が記載されていますので、参照してください。
・OCIチュートリアル/Oracle Functions ハンズオン
手順
ファンクションの作成
事前準備に記載しております通り、Email Deliveryの設定を完了し、Oracle Functionsのアプリケーション作成を行ったあと、ファンクションを作成します。
言語は python
でファンクション名を sendmail-compute-event
としています。
1 |
$ fn init --runtime python sendmail-compute-event |
3つのファイルが作成されていることを確認します。
1 2 3 |
$ cd sendmail-compute-event $ ls func.py func.yaml requirements.txt |
func.yamlの定義
func.yamlに config
以下の設定を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
schema_version: 20180708 name: sendmail-compute-event version: 0.0.1 runtime: python build_image: fnproject/python:3.9-dev run_image: fnproject/python:3.9 entrypoint: /python/bin/fdk /function/func.py handler memory: 256 config: recipient_address: <送信先のメールアドレス> sender_address: <Email Deliveryの「承認済み送信者」に設定したメールアドレス> sender_name: <送信者名> smtp_host: <Email Deliveryのパブリック・エンドポイント> smtp_port: "587" smtp_user: <Email Deliveryの設定時に作成したSMTP資格証明のユーザ名> smtp_password: <Email Deliveryの設定時に作成したSMTP資格証明のパスワード> |
今回、メール送信に伴う情報を func.yaml に定義しましたが、カスタム構成パラメータをコンソール画面もしくは、Fn ProjectのCLIコマンドで設定することも可能となっております。
詳しくは以下のリファレンスをご参照ください。
func.pyの実装
func.pyを以下のように実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
import io import json import smtplib import email.utils from email.message import EmailMessage import ssl from fdk import response def send_mail(subject, body, config): msg = EmailMessage() msg['Subject'] = subject msg['From'] = email.utils.formataddr((config["sender_name"], config["sender_address"])) msg['To'] = config["recipient_address"] msg.set_content(body) server = smtplib.SMTP(config["smtp_host"], config["smtp_port"]) server.ehlo() server.starttls(context=ssl.create_default_context(purpose=ssl.Purpose.SERVER_AUTH, cafile=None, capath=None)) server.ehlo() server.login(config["smtp_user"], config["smtp_password"]) server.send_message(msg) server.close() def handler(ctx, data: io.BytesIO=None): try: body = json.loads(data.getvalue()) compartment_name = body["data"]["compartmentName"] instance_name = body["data"]["resourceName"] action_type = body["data"]["additionalDetails"]["instanceActionType"] subject = "[OCI-Compute] {0}/{1} is {2}.".format(compartment_name, instance_name, action_type) body_text = ("Compartment:{0}\r\n" "Compute Instance: {1}\r\n" "Action: {2}" ).format(compartment_name, instance_name, action_type) except (Exception) as ex: print('ERROR: Missing key in payload', ex, flush=True) raise try: send_mail(subject, body_text, dict(ctx.Config())) except Exception as ex: print("ERROR: ", ex, flush=True) raise else: print ("INFO: Email successfully sent!", flush=True) return response.Response( ctx, response_data="Email successfully sent!", headers={"Content-Type": "application/json"} ) |
Email Deliveryを使用したメール送信方法については、以下を参考にさせて頂きました。
また、Computeインスタンスの「com.oraclecloud.computeapi.instanceaction.begin」イベント(インスタンスの起動、停止処理の開始時に発生するイベント)で、受け取ったデータから、以下の情報をメールの件名と本文に設定するようにしています。
- コンパートメント名
- インスタンス名
- アクション
その他のComputeインスタンスのイベントについては、以下のリファレンスを参照してください。
ファンクションのデプロイ
実装が完了すれば、ファンクションをデプロイします。
(今回はアプリケーション名を notify-compute-event
で作成していますが、異なるアプリケーション名で作成された場合は、適宜変更してください。)
1 |
$ fn -v deploy --app notify-compute-event |
デプロイが完了すれば、ファンクションの作成は完了となります。
イベントルールの作成
次は、イベントルールの作成を行います。
コンソール画面のグローバルメニューから「監視および管理」を押下し、「イベント・サービス」下の「ルール」を押下します。
表示された画面からルールの作成を行います。
「ルール条件」「アクション」を以下のように設定します。
項目 | 設定値 |
---|---|
条件 | 「イベント・タイプ」を選択 |
サービス名 | 「Compute」を選択 |
イベント・タイプ | 「Instance – Action Begin」を選択 |
アクション・タイプ | 「ファンクション」を選択 |
ファンクション・コンパートメント | ファンクションを作成したコンパートメントを選択 |
ファンクション・アプリケーション | ファンクションを作成したアプリケーション名を選択 |
ファンクション・アプリケーション | 作成したファンクションを選択 |
以上で準備は完了となります。
メール通知
それでは、起動しているComputeインスタンスを停止して、送信される通知メールを確認してみましょう。
かなりシンプルになったのではないでしょうか。
件名が、<コンパートメント名>/<インスタンス名> is <アクション>
となっている為、ss_blog
コンパートメントの web01
インスタンスの停止処理イベントである事がメールの件名を見るだけで分かります。
アクションが何のイベントに相当するのかは、以下のCLIコマンドリファレンスが分かりやすいかと思います。
次は、停止しているComputeインスタンスを起動して、送信される通知メールを確認してみます。
今度は起動処理である為、アクションが start
となっています。
それでは、起動しているComputeインスタンスを再起動してみます。
アクションが softreset
となってることから再起動である事が分かります。
まとめ
今回はメール通知を行う為に、Email Delivery を活用しましたので、Oracle Functions の実装次第では、HTMLメールを送信したりすることも可能です。
しかし、件名とメール本文だけをテキストで設定できれば、送信者情報の設定は何でも構わない、本文に不要な情報が設定されても問題ないという場合には、Email Delivery でなく、Oracle Functions から通知サービスを呼び出す方が設定と実装が楽になるかと思います。
そういった場合には、以下に通知サービスを呼び出すサンプルがあるので活用してみて下さい。