Running S3-put-triggered Lambda function on existing S3 objects?

后端 未结 5 2116
青春惊慌失措
青春惊慌失措 2021-02-15 03:59

I have a Lambda function in Node.js that processes new images added to my bucket. I want to run the function for all existing objects. How can I do this? I figured the easiest w

5条回答
  •  故里飘歌
    2021-02-15 04:41

    As I had to do this on a very large bucket, and lambda functions have a max. execution time of 10 minutes, I ended up doing a script with the Ruby AWS-SDK.

    require 'aws-sdk-v1'
    
    class LambdaS3Invoker
    
      BUCKET_NAME = "HERE_YOUR_BUCKET"
      FUNCTION_NAME = "HERE_YOUR_FUNCTION_NAME"
      AWS_KEY = "HERE_YOUR_AWS_KEY"
      AWS_SECRET = "HERE_YOUR_AWS_SECRET"
      REGION = "HERE_YOUR_REGION"
    
      def execute
        bucket.objects({ prefix: 'products'}).each do |o|
          lambda_invoke(o.key)
        end
      end
    
      private
    
      def lambda_invoke(key)
        lambda.invoke({
          function_name: FUNCTION_NAME,
          invocation_type: 'Event',
          payload: JSON.generate({
            Records: [{
              s3: {
                object: {
                  key: key,
                },
                bucket: {
                  name: BUCKET_NAME,
                }
              }
            }]
          })
        })
      end
    
      def lambda
        @lambda ||= Aws::Lambda::Client.new(
          region: REGION,
          access_key_id: AWS_KEY,
          secret_access_key: AWS_SECRET
        )
      end
    
      def resource
        @resource ||= Aws::S3::Resource.new(
          access_key_id: AWS_KEY,
          secret_access_key: AWS_SECRET
        )
      end
    
      def bucket
        @bucket ||= resource.bucket(BUCKET_NAME)
      end
    end
    

    And then you can call it like:

    LambdaS3Invoker.new.execute
    

提交回复
热议问题