AWS

AWS LambdaとS3、SNSでファイルのアップロードを自動通知


press
AWS LambdaとS3、SNSでファイルのアップロードを自動通知

AWS LambdaとS3、SNSでファイルのアップロードを自動通知

AWS Lambdaは特定の条件を満たすときにサーバーレスでPython(他のプログラミング言語も)を実行できるサービスです。トリガーを検知したときや指定したタイミングでのみ起動するので、常時起動しているEC2などと比べてコスト面でも優れています。さらに、バッチ処理や特定のスクリプトはcronで実行することも多かったですが、AWS Lambdaに移行することで本番環境のリソースを使わずに処理を実行できることも魅力的です。

本記事ではAWS LambdaとストレージサービスのS3、メッセージ通知サービスのSNSを組み合わせて、S3でファイルのアップロードを検知したらAWS Lambdaでファイル名を取得して、取得したファイル名をSNSでメールに通知する機能を構築します。

構築の流れ

  1. S3でファイルをアップロードするバケットを作成
  2. IAMでSNS用のポリシーを作成
  3. SNSのトピック、サブスクリプションを作成
  4. Lambda関数の作成とIAMロールを設定
  5. Lambda関数のトリガーを設定
  6. Lambda関数にプログラムを記述

S3でファイルをアップロードするバケットを作成

S3でバケットを作成
S3でバケットを作成

ストレージサービスのS3で新しいをバケットを作成します。「バケットを作成」を押します。

S3でバケットを作成
S3でバケットを作成

バケット名とリージョンを指定します。

バケット名: lambda-triggered-file-upload-bucket-dev
リージョン: 東京

IAMでSNS用のポリシーを作成

ポリシーを作成
ポリシーを作成

IAMでSNS用のポリシーを作成します。「ポリシーの作成」を押します。

ポリシーを作成
ポリシーを作成
書き込み権限を付与
書き込み権限を付与
ポリシーの作成
ポリシーの作成

SNSを選択して、書き込み権限の「Publish」を選択します。リソースは「すべて」を選択して「次へ」を押します。

SNS用のポリシーを作成
SNS用のポリシーを作成
SNS用のポリシーを作成
SNS用のポリシーを作成

ポリシー名を入力して「ポリシーの作成」を押します。

ポリシー名: SNSPublishS3ToLambdaDev

SNSのトピック、サブスクリプションを作成

SNSでトピックを作成
SNSでトピックを作成

メッセージ通知サービスのSNSでトピックを作成します。トピック名を入力して「次のステップ」を押します。

SNSでトピックを作成
SNSでトピックを作成
トピックの作成
トピックの作成

スタンダードを選択して「トピックの作成」を押します。

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

サブスクリプションを作成します。「サブスクリプションの作成」を押します。ARNの値は後ほどLambda関数の設定で必要になるのでコピーしておきます。

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

トピックARNは先程作成したトピック名を選択、プロトコルはEメールを選択、エンドポイントには通知するメールアドレスを入力して「サブスクリプションの作成」を押します。

トピックARN: LambdaTriggeredEmailsDev
プロトコル: Eメール
エンドポイント: 通知するメールアドレス

サブスクリプションの確認メール
サブスクリプションの確認メール

サブスクリプションが作成されるとエンドポイントに入力したメールアドレス宛に確認メールが届くのでURLをクリックします。

サブスクリプションの確認
サブスクリプションの確認

この画面が表示されればサブスクリプションの作成が完了です。

サブスクリプションのステータスを確認
サブスクリプションのステータスを確認

URLをクリック後、SNSのサブスクリプションを確認するとステータスが「確認済み」に変わります。

Lambda関数の作成とIAMロールを設定

Lambda関数を作成
Lambda関数を作成

Lambdaで関数を作成します。「関数の作成」を押します。

Lambda関数の作成
Lambda関数の作成
Lambda関数の作成
Lambda関数の作成

関数名を入力します。ランタイムはPythonを選択、アーキテクチャはx86_64を選択、実行ロールは新しいをロールを作成を選択して「関数の作成」を押します。

Lambda関数名: sendEmailOnS3UploadDev
ランタイム: Python
アーキテクチャ: x86_64
実行ロール: 新しいをロールを作成

IAMの設定
IAMの設定

Lambda関数が作成できたら実行ロールの設定を行います。ロール名のURLを押します。

ポリシーをアタッチ
ポリシーをアタッチ

「許可を追加」を押してから「ポリシーをアタッチ」を押します。

SNS用のポリシーをアタッチ
SNS用のポリシーをアタッチ

IAMで作成したポリシーを検索すると候補に表示されるので選択して「許可を追加」を押します。

Lambda関数のトリガーを設定

Lambda関数のトリガーを設定
Lambda関数のトリガーを設定

Lambda関数を実行させるトリガーを設定します。「トリガーを追加」を押します。

トリガーのS3の設定
トリガーのS3の設定
トリガーにS3を追加
トリガーにS3を追加

S3を選択、バケット作成したバケット名を選択、イベントタイプは「PUT」と「POST」を選択して「追加」を押します。(コピーや削除をトリガーに追加することも可能)通知対象を特定のフォルダにする場合はPrefixにフォルダ名などを入力し、特定の拡張子を対象にする場合はSuffixに入力します。

Lambda関数に設定されたトリガー
Lambda関数に設定されたトリガー

トリガーにS3が追加されました。

Lambda関数にプログラムを記述

Lambda関数にコードを記述
Lambda関数にコードを記述

Lambda関数に以下のコードを記述します。記述が終わったら「Deploy」を押して保存します。

import boto3

def lambda_handler(event, context):

    sns = boto3.resource('sns')
    arn = 'SNSトピックARN'  # SNSトピックARN
    
    file_name = event['Records'][0]['s3']['object']['key']  # S3にアップロードされたファイル名を取得
    
    platform_endpoint = sns.PlatformEndpoint(arn)

    subject = 'Lambdaから送られたメール'
    msg = f'S3のバケットにファイルがアップロードされました。\nファイル名: {file_name}'

    response = platform_endpoint.publish(
        Message = msg,
        Subject = subject
    )

    return response
    

SNSトピックARNの値はSNSでトピックを作成したときに生成された「arn:aws:sns:」から始まるARNの値を指定します。

arn = 'SNSトピックARN'

S3にファイルをアップロードして確認

S3にアップロードするファイルを追加
S3にアップロードするファイルを追加

S3にファイルをアップロードしてメールが通知されるか確認します。「ファイルを追加」を押します。

S3にファイルをアップロード
S3にファイルをアップロード

選択したファイルをアップロードします。

ファイルアップロードを通知するメールを確認
ファイルアップロードを通知するメールを確認

アップロード完了後、メールを確認するとこのようにアップロードしたファイル名が通知されました。

CloudWatchでログを確認

Amazon CloudWatchでログの確認
Amazon CloudWatchでログの確認

CloudWatchでログを確認します。「CloudWatch ログを表示」を押します。

Amazon CloudWatchでログの確認
Amazon CloudWatchでログの確認

ログストリームに実行されたログが表示されます。詳しく見る場合はログのURLをクリックします。


株式会社ファントムへのお問い合わせ

群馬県でPythonを使ったAIやソフトウェアを開発している株式会社ファントムが運営しています。




    Related Articles

    Python

    Pythonのargparseでコマンドライン引数をパース

    Pythonのargparseでコマンドライン引数をパース argparseモジュールを使って、Pythonを実行する際にコマンドライン引数を指定してプログラム内に情報を渡す方法です。 引数によって処理を変えたり、別々の […]

    Posted on by press
    Python

    Pythonのenumerate関数でfor文のインデックスを取得

    Pythonのenumerate関数でfor文のインデックスを取得 enumerate関数を使うとPythonでforを書くときに処理毎にカウントアップしたり、値を代入したりといった処理が簡単にできるので便利です。 実際 […]

    Posted on by press

    最新情報をお届けします!

    メーリングリストに登録するとファントムの最新情報をお届けします

    お客様のメールアドレスを共有することはありません