概要
前回ではAWS DataSync (以下DataSync
)のタスク実行を自動化させる方法を説明してきました。
タスク実行の自動化は便利ですが、データ転送の状況はAWSコンソールかAWS CLIまたはAWS SDKから確認することになります。どれも手動操作です。知りたいDataSync
タスク実行ステータスをSlackなどに通知を飛ばせたらすぐに気づけますし便利ですよね。実際に仕事でもこの仕組みを実装しましたのでその方法を記事にしたいと思います。
DataSync
の転送先Locationは前回と同じくAmazon EFS (以下EFS
)、通知先はSlackを例に挙げて解説していきます。
注意事項
- AWSサービスに知見のある方を対象にしていますが、初心者の方にもトライして頂けますと嬉しいです。
- 東京リージョン(ap-northeast-1)でリソースを構築します。
AWSサービス
-
AWS IAM (以下
IAM
) -
AWS Lambda (以下
Lambda
) -
Amazon EventBridge (以下
EventBridge
)
手順
■ 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
を作成していきます。Lambda
はEventBridge
からのイベントを処理し、Slackに通知させる役割を担います。
コードには次の考慮がされています。
1. SlackアイコンはDataSync
のタスク実行ステータスによって分けています。
ERRORの場合 : 雨マーク
ERROR以外 : 晴れマーク
2. どのファイルがどんなステータスなのかSlackのメッセージに記載します。実現方法はDataSync
のdescribe_task_executionメソッドを使います。
関数名 | ランタイム | 実行ロール |
---|---|---|
任意の名前 | Python 3.9 (記事執筆時) | 上記で作成したIAMロール |
- コード
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))
channelとwebhook_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-idとtask-idはご自身のAWSアカウントに置き換えて下さい。
動作確認
DataSync
タスク実行が行われた時に、そのステータスがSlackに通知されるか見ていきましょう。
※手順1,2,4のAWSリソースについては前回の記事に記載してあります。
1. 任意のファイルをS3
にアップロードします。
例ではcaminandes_llamigos_480p.mp4というMP4形式のファイルを使います。
2. DataSync
タスクが起動されたことを確認
3. Slackチャンネルに通知がされたことを確認
EventBridge
のイベントをLambda
が受け取って、その処理が正常に終われば、指定したSlackチャンネルに通知が届きます。
下記内容を例に挙げると、
LAUNCHING - 実行タスクが開始された
TRANSFERRING - データ転送が実行中
SUCCESS - データ転送が成功した
というDataSync
タスクの実行ステータスが通知されたことが分かりました。
ERRORステータスは中々出ないため、Lambda
のテストイベントを使って再現してみました。データ転送が失敗した場合のSlackへの通知は次の通りです。雨マークで一目瞭然ですよね。万が一ERRORステータスが出た場合、CloudWatch Logs
に詳細なエラー内容が記載されます。
Slackチャンネルの情報が正しいにも関わらず、Slackへの通知が届かない場合はLambda
のCloudWatch 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