こんにちは。ITエンジニアのきゅうです。
今回作成するアプリのシステム構成図です。
今までインターフェース部分としてLINEを使用しておりましたが、動かすだけであれば、LambdaにTest機能がありますので、そちらを用いて動かしたいと思います。
ですが、もちろん今までお伝えしていたLINEの設定を行えば、LINEから起動させることももちろん可能です。
Amazon S3について
では、S3とはなんぞや?という方の為に、簡潔に説明していきましょう!
Amazon S3について
『Amazon Simple Storage Service』を、略してS3と言います。
要するにストレージサービスのことです。
もっと簡単に言うと、ファイルサーバーですね。
(ちなみにAPサーバは、EC2です。)
勿論無料枠も御座います。
5 GB の Amazon S3 ストレージ、20,000 GET リクエスト、2,000 PUT、COPY、POST、あるいは LIST リクエスト、データ送信 100 GB を毎月利用できます(S3 Standard ストレージクラス)。
S3に接続してみよう
ということで、早速S3に接続してみましょう。
S3にファイルを新規作成(書き込み) ⇒ 読み込み ⇒ 削除 を一気にやっていきたいと思います。
(ファイルの更新は「読み込み+書き込み」と同じため、省略します。)
1.S3を作成。
使用するサービス:S3
使用する機能:バスケット
「バケットを作成」ボタンを押下し、下記のキャプチャーのように設定します。
一番下の「バケットを作成」ボタンを押下すれば、S3の作成が完了です。
2.ロールを作成する
使用するサービス:IAM
使用する機能:ロール
ロールを設定します。
「ロールを作成」ボタンを押下し、「AWSのサービス」を選択。
ユースケースはLambdaからS3にアクセスするので、「Lambda」を選択します。
そして、「次へ」ボタンを押下します。
権限を設定します。
次に権限を設定していくのですが、こちらは前回記載しましたが、
まず検索ウィンドウで「S3」と検索し、その後「FullAccess」と「Execution」がつくものにチェックをつけましょう!!
「次へ」を押下します。
名前と設定の確認をします
名前はもちろん任意です。
内容を確認して、「ロールを作成」を押下します。
3.Lambdaで関数を作成する。
使用するサービス:Lambda
使用する機能:関数
関数を作成する
「関数の作成」ボタンを押下し、下記のキャプチャーのように設定します。
注意点として、「実行ロール」は上で設定したロールを選択してください。
コーディングの前に補足させて頂きます。
boto3からS3をインスタンス化する際、やり方が2種類あります。
- boto3.client('s3')
- boto3.resource('s3')
です。
違いとしては以下のようにあります。
- Client APIはレスポンスが辞書型なので必要な情報を取り出しにくい
- Client APIはHTTP API 操作との 1 対 1 のマッピングが提供される
- Resource APIの方がオブジェクト指向っぽく書ける
- Resource APIが用意されていないことがあるサービスもある
そして、色々調べてみたところ、
S3へのファイル書き込み系の処理では『Resource API』を、読み込み系の処理では『Client API』を使っているサンプルが多い様に見えましたので、今回の記事でもそのようにしたいと思います。
以下のようにソースを書き換えます。
-import json
-
-def lambda_handler(event, context):
- # TODO implement
- return {
- 'statusCode': 200,
- 'body': json.dumps('Hello from Lambda!')
- }
+import json
+import boto3
+from datetime import datetime
+
+s3_resource = boto3.resource('s3')
+s3_client = boto3.client('s3')
+
+def lambda_handler(event, context):
+
+ ##########################################################
+
+ ###S3へデータを書き込みます。【Start】###
+ file_contents = '[{"name": "NAKAMURA","age": 80},{"name": "SATOU","age": 20},{"name": "KATOU","age": 30}]'
+ bucket = 'test-s3-2197-bucket'
+ key = 'test_s3.json'
+ bucketObj = s3_resource.Object(bucket,key)
+ response = bucketObj.put(Body=file_contents)
+
+ print("response:")
+ print(response)
+
+ ###S3へデータを書き込みます。【End】###
+
+ ##########################################################
+
+ ###S3のデータを読み込みます。【Start】###
+ #######################################
+ ###以下、本来は設定が必要だが、 ###
+ ###書き込みの際に設定しているため、 ###
+ ###今回はコメントアウト。 ###
+ #bucket = 'test-s3-2197-bucket' ###
+ #key = 'test_s3.json' ###
+ #######################################
+ response = s3_client.get_object(Bucket=bucket, Key=key)
+ body = response['Body'].read()
+
+ print("body:")
+ print(body)
+ ###S3のデータを読み込みます。【End】###
+
+ ##########################################################
+ ###S3のファイルの削除。【Start】###
+ #s3_client.delete_object(Bucket=bucket, Key=key)
+ ###S3のファイルの削除。【End】###
+
+ return body
↓↓↓コピー用↓↓↓
import json
import boto3
s3_resource = boto3.resource('s3')
s3_client = boto3.client('s3')
def lambda_handler(event, context):
##########################################################
###S3へデータを書き込みます。【Start】###
file_contents = '[{"name": "NAKAMURA","age": 80},{"name": "SATOU","age": 20},{"name": "KATOU","age": 30}]'
bucket = 'test-s3-2197-bucket'
key = 'test_s3.json'
bucketObj = s3_resource.Object(bucket,key)
response = bucketObj.put(Body=file_contents)
print("response:")
print(response)
###S3へデータを書き込みます。【End】###
##########################################################
###S3のデータを読み込みます。【Start】###
#######################################
###以下、本来は設定が必要だが、 ###
###書き込みの際に設定しているため、 ###
###今回はコメントアウト。 ###
#bucket = 'test-s3-2197-bucket' ###
#key = 'test_s3.json' ###
#######################################
response = s3_client.get_object(Bucket=bucket, Key=key)
body = response['Body'].read()
print("body:")
print(body)
###S3のデータを読み込みます。【End】###
##########################################################
###S3のファイルの削除。【Start】###
#s3_client.delete_object(Bucket=bucket, Key=key)
###S3のファイルの削除。【End】###
return body
実行は最初に記載した通り、Lambdaの『Test』機能を使っていきましょう!!
上記の『Test』を押下すると、下記のような設定画面が出てくるので、任意のイベント名を設定し、イベント共有の設定を『プライベート』、そして最後に『保存』を押下します。
するとTestが開始されます。
上記で貼り付けたLambdaのソースが実行され、以下のようなログが出ます。
そして、最初は何もファイルがなかったですが、関数実行後はファイルが作成されております!!
ソースコード解説
簡単にですが、ソース解説も行いたいと思います。
インポート
import boto3
『import boto3』はAWSのサービスを使う際に、ほぼ必須となるImportになります。
しかも、LambdaがAWSのサービスであるため、AWS Lambdaで開発をしていれば、デフォルトでインストールされている為レイヤーを追加する必要はありませんが、AzureやGoogleクラウドの場合はレイヤーの追加が必要だと思われます。
その場合は下記のようなコマンドを使って、インストールしましょう。
sudo pip install boto3
当方はよく、Cloud9というAWSのサービスからインストールするようにしております。
(お手軽で便利ですよー!!)
今度それも記事にしたいと思います。
S3の呼び出し方法について
s3_resource = boto3.resource('s3')
s3_client = boto3.client('s3')
AWSサービスを呼び出す際、2つの呼び出し方があります。
それが、「resource」メソッドを呼び出すやり方と、「client」メソッドを呼び出すやり方です。
2023年にどうやら「resource」メソッドの方は非推奨となったようですが、一応2つの違いを記載します。
- resource
- ●REST APIを呼び出すクライアント・インターフェース
- ●高レイヤーのオブジェクト指向なサービスアクセスが可能
- client
- ●ORMっぽくAWSリソースを操作するリソース・インターフェース
- ⇒ORMとは『オブジェクト関係マッピング』のことです。
- ●低レイヤーのサービスのアクセスが可能
バケット名とキーについて
bucket = 'test-s3-2197-bucket'
key = 'test_s3.json'
途中、bucketとkeyを指定する箇所が御座いますが、bucketはS3で設定するので分かるかと思いますが、keyというのは、今回の例だとファイル名になりますが、本来的な意味では『フォルダ名+ファイル名』になります。
気をつけましょう!!
躓きやすい所に絞って解説しましたが、「名は体を現す」という言葉の通り、他はメソッド名を見れば解説は不要だと判断しました。
(それにハッカソンでサクッと読めて実装が出来るというのが、この備忘録の売りとしたいので、長々と書き続けるのはコンセプトと違うと思い・・・)
ということで、どうしてもわからない箇所がありましたら、コメント頂ければと思います。
総括
はい。
今回は一番簡単なLambdaとS3の連結部分について、記事を記載させて頂きました。
今回記載したことは、ほかのサービスでも基本となるところなので、覚えておくと他のサービスも簡単に連結させることが出来ると思います。
まとめ
- 1.S3のバケットを作成する。
- 2.IAMでロールを作成する。
- 3.Lambdaで関数を作成する。
- 4.Lambdaのソースを改修する。
※細かな設定がありますので、本編でちゃんと確認しながら進めることが、時間短縮のコツです。
次回は、AWSのAIサービスのAIサービスの一つ。
Rekoginitionに繋いでみたいと思います。
ということで、本日はここまでです。
少しでも参考になったと思いましたら、「いいね」や「ストック」を押していただけますと、今後の励みになりますので、是非とも宜しくお願い致します。
最後までお読み頂きありがとうございました。