2

I’m trying to get a DeepLens Lambda function to upload an image to S3. I got the code for uploading from this tutorial.

def write_image_to_s3(img):
    session = Session()
    s3 = session.create_client('s3')
    file_name = 'DeepLens/face.jpg'
    encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),90]
    _, jpg_data = cv2.imencode('.jpg', img, encode_param)
    response = s3.put_object(ACL='public-read-write', Body=jpg_data.tostring(),Bucket='MY-BUCKET-NAME',Key=file_name)
    image_url = 'https://s3.amazonaws.com/MY-BUCKET-NAME/'+file_name
    return image_url

However, I keep getting the error:

Error in face detection lambda: An error occurred (AccessDenied) when calling the PutObject operation: Access Denied

I made an IAM role and attached it to the Deeplens lambda function and attached the following policies: AWSDeepLensLambdaFunctionAccessPolicy, AWSLambdaExecute, AWSDeepLensServiceRolePolicy, AmazonS3FullAccess, and a custom policy with the following JSON:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:PutObjectAcl"
            ],
            "Resource": [
                "arn:aws:s3:::MY-BUCKET-NAME”,
                "arn:aws:s3:::MY-BUCKET-NAME/*"
            ]
        }
    ]
}

I even gave the bucket public access through the access control list:

[IMAGE]

and made the bucket policy public:

{
    "Version": "2012-10-17",
    "Id": "Policy1534108093104",
    "Statement": [
        {
            "Sid": "Stmt1534108083533",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::MY-BUCKET-NAME”
        }
    ]
}

(I know it's a bad idea to make buckets public)

I looked at this and this and yet I’m still getting the AccessDenied error.

liver
  • 498
  • 4
  • 21
  • 1
    The (public, temporary, test) bucket policy would also need the variant of the resource ending in `/*` to have the intended effect, though there is -- as you clearly already realize -- no reason why this policy should be necessary. Still, you might change `"Resource"` there to an array and include both values. Verify also that there are no explicit `Deny` policies, since they always override `Allow`. Additionally, note that there's a potential propagation delay on *role* policy updates and a shorter one on *bucket* policy updates. There isn't a way to confirm complete propagation. – Michael - sqlbot Aug 13 '18 at 01:45
  • 1
    Why are you calling "toString()" in "Body=jpg_data.tostring()". Normally you would not attempt to convert binary data to a string. Use "Body=jpg_data". However, this is an example where including your entire code helps with the best answer. – John Hanley Aug 13 '18 at 05:04
  • @Michael-sqlbot Adding the `/*` actually worked, but I'd rather the bucket policy was not public, so I'm still trying to figure it out. – liver Aug 13 '18 at 16:59
  • @JohnHanley I used code from this tutorial: https://aws.amazon.com/blogs/machine-learning/customize-and-display-aws-deeplens-project-output-on-your-laptop/. I've updated the post with more details. – liver Aug 13 '18 at 17:21
  • @Olivia what that test does establish is that there isn't another "Deny" policy that's stopping you. – Michael - sqlbot Aug 13 '18 at 22:59

0 Answers0