Help us understand the problem. What is going on with this article?

S3に画像をアップロードしたらLambdaでサムネイルを生成する(node-imagemagick)

More than 5 years have passed since last update.

公式ドキュメントでは gm でサムネイルを作っているが node-imagemagick が入っているのでそのまま貼れば一応動く。
node-imagemagick はメンテされてないので gm を使ったほうがいいとは思う。

http://docs.aws.amazon.com/lambda/latest/dg/walkthrough-s3-events-adminuser.html

元画像用のバケットと、そのバケット名に -thumbnail のサフィックスを付けたサムネイル用バケットが必要。

S3 バケットを作る

バケットとファンクションは同じリージョンに作る必要がある。
今回は US Standard に作った。

Lambda ファンクションを作る

Lambda function code

handler
var fs = require('fs');
var im = require('imagemagick');
var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});

exports.handler = function(event, context) {
    console.log(JSON.stringify(event, null, 2));
    console.log(JSON.stringify(context, null, 2));

    var bucket = event.Records[0].s3.bucket.name;
    var key = event.Records[0].s3.object.key;

    s3.getObject({
        Bucket: bucket,
        Key: key,
        IfMatch: event.Records[0].s3.object.eTag
    }, function(err,data) {
        if (err) {
            context.done('error getting object', err);
        } else {
            console.log(data);

            var contentType = data.ContentType;
            var extension = contentType.split('/').pop();

            im.resize({
                srcData: data.Body,
                format: extension,
                width: 256
            }, function(err, stdout, stderr) {
                if (err) {
                    context.done('resize failed', err);
                } else {
                    var thumbnailBucket = bucket + "-thumbnail";
                    var thumbnailKey = key.split('.')[0] + "-thumbnail." + extension;

                    s3.putObject({
                        Bucket: thumbnailBucket,
                        Key: thumbnailKey,
                        Body: new Buffer(stdout, 'binary'),
                        ContentType: contentType
                    }, function(err, res) {
                        if (err) {
                            context.done('error putting object', err);
                        } else {
                            console.log(JSON.stringify(res, null, 2));
                            context.done();
                        }
                    });
                }
            });
        }
    });
};

Execution role

Lambda がファンクション実行時に使う権限を定義する。

access-policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:*"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject"
      ],
      "Resource": [
        "arn:aws:s3:::*"
      ]
    }
  ]
}
trust-policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

その他

メモリやタイムアウトの設定はデフォルトのまま。

S3 の通知先に登録する

Lambda コンソールから Configure event source ボタンを押下。
先ほど作ったバケットを選択し Create/Select Role ボタンを押下。
Invocation Role を作成/選択する。

access-policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "lambda:InvokeFunction"
      ],
      "Resource": [
        "*"
      ]
    }
  ]
}
trust-policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringLike": {
          "sts:ExternalId": "arn:aws:s3:::*"
        }
      }
    }
  ]
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした