LoginSignup
1
0

[パート2:実行]S3に保存する前ラムダでサムネイルに画像圧縮の前処理

Posted at

前提

せめてS3・Lambda・IAM権を持っているAWSアカウントそれともIAMアカウント用意

概要

こちら記事では詳細な実行を説明させて頂きます。

主な内容が下記のように進めています。
  1. バケツ作成
    1.1 バケツ作成
    2.2 ライフサイクル作成
  2. ポロシー・ロール作成
    2.1 ポリシー作成
    2.2 ロール作成
  3. ラムダファンクション作成
    3.1 環境作成
    3.1.1 初期設定
    3.2 ファンクション作成
    3.2.1 ロールや処理時間を設定
    3.2.2 トリガー設定
    3.2.3 環境変数
    3.3 ラムダのNode modulesについて
  4. テスト行い
    4.1 S3アップロード
    4.2 結果をチェック
    4.3 ログをチェック

1. バケツ作成

2つのバケツを作成し、そのうち1つを一時的なバケツとして使用します。この一時的なバケツにはライフサイクルを設定します。

一時的なバケツとは、画像を一時的に保存し、ある期間を経過する後にライフサイクルポリシーに従って画像を自動的に削除するバケットのことです。

1.1 バケツ作成

手順

1. S3に入る
2.「バケツ作成」を押下

create s3.png

3.バケツ作成画面に遷移される
4.バケツ名のみを設定して、他の項目をそのままにしてもいいです 

s3 step 1.png

第2台目も同じようにしてください

1.2 ライフサイクル作成

1. 一時的なバケツ「temp-images-bucket」を選ぶ
2. マネジメント
3. ライフサイクル作成

create ライフサイクル.png

3. ライフサイクル作成に遷移された
4. 以下のように設定してくだい

life cycle 1.png

life cycle2.png
貴方の要件次第でルールを作成してください。
この記事の限りでは載せった画像を5日後削除させます。

ルールについて詳しくAWSドキュメントに参考して下さい。

2. ロール作成

AWSリソースをアクセスするために該当するポリシーが必要です。そして、あんなポリシーをユーザー(ユーザグループ経過※)やロールなどに付けます。

(※)AWSのベストプラクティスによると、ユーザーに直接ポリシーを付与するのではなく、ユーザーをユーザーグループに追加し、ユーザーグループにポリシーを付与する方が良いとされています。

前述の記事では、ユーザーのクレデンシャルを使用してS3へのアップロードやダウンロードを行いましたが、これはベストプラクティスではありません。本番環境では、クレデンシャルが漏れるリスクがあるためです。

ベストプラクティスとしては、適切な権限を持つロールを作成し、そのロールをLambdaやEC2などのAWSリソースに付与することです。

2.1 ボリシー作成

手順

1. IAMサービスに入る -> 左メニューにてポリシーを選ぶ
2. ポリシー作成を押下

create polici.png

3.JSONを選んでください

create policy step1.png

最小特権アクセス(Least Privilege)によって

サービス 対象 権利
Cloud watch 全て ログ記録
S3 一時的なバケツ
temp-images-bucket
画像読み込む(GET)
S3 主なバケツ名
final-images-bucket
画像アップロード(PUT)
{
	"Version": "2012-10-17",
	"Statement": [
		{
			"Effect": "Allow",
			"Action": [
				"logs:PutLogEvents",
				"logs:CreateLogGroup",
				"logs:CreateLogStream"
			],
			"Resource": "arn:aws:logs:*:*:*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"s3:GetObject"
			],
			"Resource": "arn:aws:s3:::<一時的なバケツ名(貴方次第)>/*"
		},
		{
			"Effect": "Allow",
			"Action": [
				"s3:PutObject"
			],
			"Resource": "arn:aws:s3:::<主なバケツ名(貴方次第)>/*"
		}
	]
}
4. ポリシー名を設定して完了します。

記事ではdemo-resized-image-s3-policyを設定しました

2.2ロール作成

手順

1. 左メニューにロールを押下

TAO ROLE.png

2.以下のように選択

tạo role step1.png

3.次は上に作成したポリシー```demo-resized-image-s3-policy```を選んでください

(サーチで検索した方がいいです)

chọn policy.png

4.最後ステップはロール名を設定

review dat ten role.png

3. ラムダファンクション作成

3.1 環境構成

3.1.1 初期設定

手順

1. 以下のように設定
2. Advance settingをそのままにします

setting lambda.png

以下のSharpライブラなので、Architerture の設定を注意してください。

3.2 ファンクション設定

3.2.1 ロールや処理時間を設定

手順

 1. Configuration -> Permission -> Edit

permissonst1.png

2. 設定画面に遷移します。

permission2.png

項目 意味
Memory 重い画像を処理する場合は高い値を設定
Time out 画像処理は時間が結構かかって、念の為1分を設定します。設定しない場合は以下のエラーのように出てくる
 "errorMessage": "2018-04-26T08:40:15.398Z …..Task timed out after 3.00 seconds"
Role ロールをファンクションに付ける
設定しない場合はAccess deny というエラーが出て来る

3.2.2 トリガー設定

手順

1. 左メニューにてTriggers 
2. Add trigger
3. 以下のように設定*

trigger.png

バケツはなぜ2台が必要ですか?

理由: recursive invocationを避けます。サークルトリガー形でラムダが繰り替えてトリガーして止まりません。したがって、利用金がすごく発生します

3.2.3環境変数

手順

1. 左メニューにて**Environment variables 
2. EDIT
3.以下のように設定

env.png

3.3 ラムダのNode modulesについて

ラムダでライブラを輸入するために、Node modulesをアップロードが必要です

方法としては2つあります

  • 処理ファイルとNode modulesを圧縮してアップロードします

upload code.png

こちらファンクションしか利用できません。そのため一番良い方向ではありません。

  • Layer の方向

そうしたら他のファンクションに共有できます。ファンクションサイズを下げて料金が下がる

手順

1. ローカルにてライブラリをダウンロード

Sharp は環境によってエラーが発生しますか。しっかりOSとCPUを指摘するのは必要です

## 2. ローカル環境で適当なOSとCPUをダウンロード
npm install --os=linux --cpu=x64 sharp
3.「node_modules」を圧縮します

compress.png

4.レイヤを作成

created layer.png

5.環境区別のため、「compatible architertures」指摘した方がいいです

tao layer.png

私はfor-test-sharpを既に作成ました。

6.ラムダに戻って下スクロールしてレイヤを追加しよう

add layer.png

7.作成したレイヤのARNを貼り付け

add layor 2.png

3.4 処理ソースコード

  • node_modulesがレイヤに保存していますから、先頭のパーツは/opt/node_modules/<lib>/...
    のようにする
  • デプロイを押下しないと新しいコードが反映されません
import {
  S3Client,
  GetObjectCommand,
  PutObjectCommand,
} from "@aws-sdk/client-s3";
import Sharp from '/opt/node_modules/sharp/lib/index.js'; 

const IMAGE_HEIGH = parseInt(process.env.IMAGE_HEIGH) || 200;
const IMAGE_WIDTH = parseInt(process.env.IMAGE_WIDTH) || 200;
const DEST_BUCKET_NAME = process.env.DEST_BUCKET_NAME;
const S3 = new S3Client();

export const handler = async (event,context) => {
  try {
    //GET object name from event
    const { eventTime, s3 } = event.Records[0];
    const srcKey = decodeURIComponent(s3.object.key.replace(/\+/g, " "));
    const srcBucket = s3.bucket.name;
    
    // ログ出す
    console.log(`${eventTime} --------- ${srcBucket}/${srcKey}`);
    
    // 画像をダウンロード
    const commandGET = new GetObjectCommand({
      Bucket: srcBucket,
      Key: srcKey,
    });
    const {Body, ContentType} = await S3.send(commandGET);
 

    //画像処理
    const image = await Body.transformToByteArray();
    const imageBuffer = await Sharp(image)
      .resize({
        height: IMAGE_HEIGH,
        width: IMAGE_WIDTH,
      })
      .toBuffer();
    
    // 処理済み画像を主なバケツにアップロード
    const commandPUT = new PutObjectCommand({
      Bucket: DEST_BUCKET_NAME,
      Key: srcKey,
      Body: imageBuffer,
      ContentType
    });
    
    await S3.send(commandPUT);
    const message = `Successfully resized ${srcBucket}/${srcKey} and uploaded to ${DEST_BUCKET_NAME}/${srcKey}`;
    console.log(message)
    return {
      statusCode: 200,
      body: message,
    };

  } catch (error) {
    console.error('error-------->',error);
  }
};

const handler = async (event,context)

どのようにeventの詳細を見ますか?

1. [Test]
2. [Configure test event]
3. TemplateにてS3put 選んで
→ eventはeven JSON に書いていあります。

checkevent.png

check event 2.png

4テスト行い

4.1 S3アップロード

手順

1.  S3サービスに入る
2. 一時的なバケツ(temp-images-bucket)を選ぶ 

add file.png

chon file.png

4.2 結果をチェック

手順

1. 主なバケツに入る(final-images-bucket)
2. 画像を選んで
3. Open押下

xem file.png

4.3 ログをチェック

手順

1.CloudWatch サービスに入る
2.Log groups
3.AWSは既にグループを作成してくれます。

グループのパターン:/aws/lambda/<ラムダファンクション名>

log.png

時間合わせてログを開けてログをチェックします

最後

最後までご覧いただき、誠にありがとうございました。
もし記事にご興味や意味を感じていただけましたら、ハートやコメントを残して共有していただけると嬉しいです。
:bow::bow::bow:

1
0
1

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
1
0