LoginSignup
3
0

More than 1 year has passed since last update.

DataSyncの転送状況をSlackに通知させる方法

Last updated at Posted at 2023-03-10

概要

前回ではAWS DataSync (以下DataSync)のタスク実行を自動化させる方法を説明してきました。

タスク実行の自動化は便利ですが、データ転送の状況はAWSコンソールかAWS CLIまたはAWS SDKから確認することになります。どれも手動操作です。知りたいDataSyncタスク実行ステータスをSlackなどに通知を飛ばせたらすぐに気づけますし便利ですよね。実際に仕事でもこの仕組みを実装しましたのでその方法を記事にしたいと思います。

DataSyncの転送先Locationは前回と同じくAmazon EFS (以下EFS)、通知先はSlackを例に挙げて解説していきます。

注意事項

  • AWSサービスに知見のある方を対象にしていますが、初心者の方にもトライして頂けますと嬉しいです。
  • 東京リージョン(ap-northeast-1)でリソースを構築します。

AWSサービス

手順

■ IAM

Lambdaで利用するIAMロールを作成しておきます。

作成したら下記インラインポリシーを追加します。ポリシー名は任意のもので構いません。

  • AWSLambdaBasicExecutionRole-policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "logs:CreateLogGroup",
            "Resource": "arn:aws:logs:ap-northeast-1:account-id:*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": [
                "arn:aws:logs:ap-northeast-1:account-id:log-group:/aws/lambda/*:*"
            ]
        }
    ]
}
  • notify-datasync-status-policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "datasync:DescribeTaskExecution",
            "Resource": "arn:aws:datasync:ap-northeast-1:account-id:task/*/execution/*"
        }
    ]
}

account-idはご自身のAWSアカウントに置き換えて下さい。

■ Lambda

EventBridgeのトリガーとなるLambdaを作成していきます。LambdaEventBridgeからのイベントを処理し、Slackに通知させる役割を担います。

コードには次の考慮がされています。

1. SlackアイコンはDataSyncのタスク実行ステータスによって分けています。
ERRORの場合 : 雨マーク
ERROR以外 : 晴れマーク

2. どのファイルがどんなステータスなのかSlackのメッセージに記載します。実現方法はDataSyncdescribe_task_executionメソッドを使います。

関数名 ランタイム 実行ロール
任意の名前 Python 3.9 (記事執筆時) 上記で作成したIAMロール
  • コード
lambda_function.py
import urllib3
import json
import logging
import boto3

# Logging settings
log = logging.getLogger()
log.setLevel(logging.INFO)

# Boto3 settings
DataSync = boto3.client('datasync')

# Slack channel info
channel = "#your-slack-channel"
webhook_url = "https://hooks.slack.com/services/XXXX/YYYY/ZZZZ"

def lambda_handler(event, context):
    try:
        # Retrieve info that we need from EventBridge event
        log.info('Event:: ' + json.dumps(event))
        resource = event["resources"][0]
        state = event["detail"]['State']
        
        # Retrieve task execution info
        tasks = DataSync.describe_task_execution(TaskExecutionArn=resource)
        file_name = tasks['Includes'][0]['Value']
        
        if state in 'ERROR':
            slack_icon = ":umbrella:"

        else:
            slack_icon = ":sunny:"
        
        # Send notify to Slack channel
        text = slack_icon + " " + file_name +  '' + 'Task execution status: ' + '*' + state + '*'
        url = webhook_url
        msg = {
            "channel": channel,
            "text": text
        }
        encoded_msg = json.dumps(msg).encode('utf-8')
        http = urllib3.PoolManager()
        resp = http.request('POST',url, body=encoded_msg)
        log.info({
            'message:: ' + str(text),
            'status_code:: ' + str(resp.status),
            'response:: ' + str(resp.data)
        })

    except Exception as e:
      log.error('Error occurred:: ' + str(e))

channelwebhook_urlはご自身のSlack情報に置き換えて下さい。

■ EventBridge

ルール名 タイプ ターゲット
任意の名前 スタンダード 上記で作成したLambda関数

下記例では全てのリソースかつ全てのステータスを対象にします。

各タスク実行ステータスの説明についてはAWSのドキュメントをご参照下さい。

  • イベントパターン
{
  "source": ["aws.datasync"],
  "detail-type": ["DataSync Task Execution State Change"],
  "detail": {
    "State": ["QUEUED", "LAUNCHING", "PREPARING", "TRANSFERRING", "VERIFYING", "SUCCESS", "ERROR"]
  }
}

特定のリソースかつ特定のステータスのみフィルターして通知させたい場合は、下記イベントパターンで実現可能です。

{
  "source": ["aws.datasync"],
  "detail-type": ["DataSync Task Execution State Change"],
  "resources": [{
    "prefix": "arn:aws:datasync:ap-northeast-1:account-id:task/task-id/execution/exec-"
  }, {
    "prefix": "arn:aws:datasync:ap-northeast-1:account-id:task/task-id/execution/exec-"
  }],
  "detail": {
    "State": ["SUCCESS", "ERROR"]
  }
}

account-idtask-idはご自身のAWSアカウントに置き換えて下さい。

動作確認

DataSyncタスク実行が行われた時に、そのステータスがSlackに通知されるか見ていきましょう。

※手順1,2,4のAWSリソースについては前回の記事に記載してあります。

1. 任意のファイルをS3にアップロードします。

例ではcaminandes_llamigos_480p.mp4というMP4形式のファイルを使います。

スクリーンショット 2023-03-09 23.49.17.png

2. DataSyncタスクが起動されたことを確認

スクリーンショット 2023-03-09 22.28.08.png

3. Slackチャンネルに通知がされたことを確認

EventBridgeのイベントをLambdaが受け取って、その処理が正常に終われば、指定したSlackチャンネルに通知が届きます。

下記内容を例に挙げると、
LAUNCHING - 実行タスクが開始された
TRANSFERRING - データ転送が実行中
SUCCESS - データ転送が成功した
というDataSyncタスクの実行ステータスが通知されたことが分かりました。

スクリーンショット 2023-03-10 1.20.38.png

ERRORステータスは中々出ないため、Lambdaのテストイベントを使って再現してみました。データ転送が失敗した場合のSlackへの通知は次の通りです。雨マークで一目瞭然ですよね。万が一ERRORステータスが出た場合、CloudWatch Logsに詳細なエラー内容が記載されます。

スクリーンショット 2023-03-10 0.16.21.png

Slackチャンネルの情報が正しいにも関わらず、Slackへの通知が届かない場合はLambdaCloudWatch Logsから手掛かりや原因が見つかるかもしれません。

4. EFS上にデータを確認

念の為、実際のデータはどうなっているのかを見るために、EC2インスタンスにマウントされた対象のEFSの中身を確認します。ファイルが作成された日時とSUCCESSが通知された日時が同じであることから、データ転送が正常に行われたことが見て取れます。

$ ls -la /mnt/efs/
合計 47332
drwxr-xr-x 3 nfsnobody nfsnobody     6144  3月  9 22:47 .
drwxr-xr-x 4 root      root            31  1月 19 18:33 ..
drwx------ 2 root      root          6144  3月  9 22:47 .aws-datasync
-rwxr-xr-x 1 nfsnobody nfsnobody 48458210  3月  9 22:47 caminandes_llamigos_480p.mp4

まとめ

DataSyncの転送状況はコンソールからでも見ることができますが、転送が失敗した時にいち早く気づいて対応したい場面もあるかと思います。今回は通知先はSlackチャンネルにしましたが、Amazon SNSと連携すれば、EメールやSMSへの送信も可能です。そしてDataSyncだけではなく、AWSサービスの多くはEventBridgeが受け取るイベントを生成しますので、他のサービスでも微修正を施すだけで上記Lambdaの流用をすることができます。使い方次第で業務の効率が上がるかもしれません。興味があれば是非活用してみて下さい。少し短いですが最後までお読みいただき、ありがとうございました!

参考

https://aws.amazon.com/jp/datasync/
https://aws.amazon.com/jp/lambda/
https://aws.amazon.com/jp/eventbridge/
https://docs.aws.amazon.com/ja_jp/datasync/latest/userguide/understand-task-statuses.html

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0