LambdaでS3の権限を変更する

2023/04/19に公開

概要

HLS形式の動画を配信するために構築していたところ、S3に保存されたHLS動画が見れないことがありました。

CloudFrontなどを使って配信する方が多いと思いますが、私の今回の案件ではS3のオブジェクトURLを、サービスのVideoタグに設定するようにしていてハマりました。

S3に保存されたmp4動画ファイルをElastic Transcorderでm3u8(HLS動画)に変換してS3に保存していたので権限が付与されていませんでした。

試したこと

S3のバケットをパブリックで公開してみましたが、オブジェクトの方に反映されずダメでした。

Lambda関数で権限を変更することに

  • Node.js 16を選びました。
  • トリガーには、.m3u8と.tsを指定しました。
'use strict';

const AWS = require('aws-sdk');
const s3 = new AWS.S3({
    apiVersion: '2012-09-25'
});

exports.handler = function(event, context) {
    console.log('m3u8の権限変更');
    const bucket = event.Records[0].s3.bucket.name;
    
    // ディレクトリ名/example.mp4
    const key = event.Records[0].s3.object.key;
    
    // オブジェクトをパブリックにする
      const publicObjects = [
         {
          Bucket: bucket,
          Key: key,
          ACL: 'public-read',
        }
      ];
      
      for (const publicObject of publicObjects) {
        s3.putObjectAcl(publicObject, function(err, data) {
          if (err) {
            console.log(err);
          } else {
            console.log(data);
            console.log('Object uploaded successfully');
          }
        });
      }

};

注意!

s3.putObjectAclメソッドで動画の権限を変更しています。
検索すると、s3.putObjectメソッドも出てきますが、こちらは新しくファイルを作成するようなので、**「再帰処理で無限ループ」**になってしまいますのでやらないようにしましょう。

その他

exports.handler = function(event, context) にしているのは、
exports.handler = async (event, context) => だとうまくいかなかったからです。

Discussion