• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

람다 접근 에러

23.11.23 22:19 작성 조회수 331

0

너무 자주 잘문드려 죄송합니다...

2023-11-23T13:10:50.588Z 50b59392-754b-4b9c-90a1-ed48e95f40e1 ERROR AccessDenied: Access Denied
at throwDefaultError (/var/task/node_modules/@smithy/smithy-client/dist-cjs/default-error-handler.js:8:22)
at /var/task/node_modules/@smithy/smithy-client/dist-cjs/default-error-handler.js:18:39
at de_GetObjectCommandError (/var/task/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:4330:20)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async /var/task/node_modules/@smithy/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24
at async /var/task/node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddleware.js:14:20
at async /var/task/node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:46
at async /var/task/node_modules/@aws-sdk/middleware-flexible-checksums/dist-cjs/flexibleChecksumsMiddleware.js:63:20
at async /var/task/node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/region-redirect-endpoint-middleware.js:14:24
at async /var/task/node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/region-redirect-middleware.js:9:20 {
'$fault': 'client',
'$metadata': {
httpStatusCode: 403,
requestId: 'S3JVT25F4WT5TH9H',
extendedRequestId: 'i2FSNxeCIH5smb0tHWggtUQ7WWZIvDurOoQ4UGIZ1eVgwIPsJwrNC85V8Oh2XHVpCaFyITlXaaM=',
cfId: undefined,
attempts: 1,
totalRetryDelay: 0
},
Code: 'AccessDenied',
RequestId: 'S3JVT25F4WT5TH9H',
HostId: 'i2FSNxeCIH5smb0tHWggtUQ7WWZIvDurOoQ4UGIZ1eVgwIPsJwrNC85V8Oh2XHVpCaFyITlXaaM='
}

이러한 에러가 발생했습니다. 찾아보니깐 s3 버컷 정책과 관련이 있는 것 같습니다.

{

"Version": "2012-10-17",

"Statement": [

{

"Sid": "AddPerm",

"Effect": "Allow",

"Principal": "*",

"Action": [

"s3:GetObject",

"s3:PutObject"

],

"Resource": "arn:aws:s3:::whatsup1/*"

}

]

}

이게 저의 s3 버캣 정책입니다.

그리고 아래는 aws-upload의 index.js입니다

//이미지 리사이징 라이브러리
const sharp = require("sharp");

const {
  S3Client,
  GetObjectCommand,
  PutObjectCommand,
} = require("@aws-sdk/client-s3");

//함수가 aws 람다에서 돌아가기 때문에 스크릿키랑 아이디를 자동으로 넣어준다 = > 아무것도 넣어줄 필요 x
const s3 = new S3Client();

//람다는 3개의 매개변수를 제공하고 이 함수를 호출해준다.
exports.handler = async (event, context, callback) => {
  const Bucket = event.Records[0].s3.bucket.name;
  const Key = decodeURIComponent(event.Records[0].s3.object.key); //original/리버풀.png
  const filename = Key.split("/").at(-1);
  const ext = Key.split(".").at(-1).toLowerCase();
  const requiredFormat = ext === "jpg" ? "jpeg" : ext;
  console.log("name", filename, "ext", ext);
  try {
    const getObject = await s3.send(new GetObjectCommand({ Bucket, Key }));
    const buffers = [];
    for await (const data of getObject.Body) {
      buffers.push(data);
    }
    const imageBuffer = Buffer.concat(buffers);
    console.log("original", getObject);
    const resizedImage = await sharp(imageBuffer)
      .resize(200, 200, { fit: "inside" })
      .toFormat(requiredFormat)
      .toBuffer();
    await s3.send(
      new PutObjectCommand({
        Bucket,
        Key: `thumb/${filename}`,
        Body: resizedImage,
      })
    );

    console.log("put", resizedImage.length);
    return callback(null, `thumb/${filename}`);
  } catch (error) {
    console.error(error);
    return callback(error);
  }
};

구글링 해보니깐 s3정책들이 비슷하면서 약간씩 다르던데 뭐가 맞는건지 잘 모르겠습니다..

답변 1

답변을 작성해보세요.

0

image이런 식으로 람다에 s3 접근 권한이 있어야 합니다.

김명재님의 프로필

김명재

질문자

2023.11.23

IAM에서 역할 들어가서 역할 생성 누른 후에 생성하는게 맞나요? 일단 lamda 선택 후 AmazonS3FullAccess 선택해서 생성하면 되는거 아닌가요? 그렇게 만들었는데 람다 권한에 s3가 생기지가 않습니다...

이미지에 실행 역할 및에 역할 이름 나와있는데 그 역할 누르고 거기에 권한을 추가하셔야 합니다.

김명재님의 프로필

김명재

질문자

2023.11.24

{ "errorType": "NoSuchKey", "errorMessage": "The specified key does not exist.", "name": "NoSuchKey", "$fault": "client", "$metadata": { "httpStatusCode": 404, "requestId": "5WP7H6TJ89PNXY1K", "extendedRequestId": "UX2dQCq5GAsbRwXmK6h2Sm3Y7wV16U2p1hheLNOwmwXmBCpnGQvYM0DXNty1TT6DuZu0zWs4+Ao=", "attempts": 1, "totalRetryDelay": 0 }, "Code": "NoSuchKey", "Key": "original/1700755094030_%C3%A1%C2%84%C2%89%C3%A1%C2%85%C2%B3%C3%A1%C2%84%C2%8F%C3%A1%C2%85%C2%B3%C3%A1%C2%84%C2%85%C3%A1%C2%85%C2%B5%C3%A1%C2%86%C2%AB%C3%A1%C2%84%C2%89%C3%A1%C2%85%C2%A3%C3%A1%C2%86%C2%BA+2023-11-23+%C3%A1%C2%84%C2%8B%C3%A1%C2%85%C2%A9%C3%A1%C2%84%C2%92%C3%A1%C2%85%C2%AE+11.11.21.png", "RequestId": "5WP7H6TJ89PNXY1K", "HostId": "UX2dQCq5GAsbRwXmK6h2Sm3Y7wV16U2p1hheLNOwmwXmBCpnGQvYM0DXNty1TT6DuZu0zWs4+Ao=", "message": "The specified key does not exist.", "stack": [ "NoSuchKey: The specified key does not exist.", " at de_NoSuchKeyRes (/var/task/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:6082:23)", " at de_GetObjectCommandError (/var/task/node_modules/@aws-sdk/client-s3/dist-cjs/protocols/Aws_restXml.js:4327:25)", " at process.processTicksAndRejections (node:internal/process/task_queues:95:5)", " at async /var/task/node_modules/@smithy/middleware-serde/dist-cjs/deserializerMiddleware.js:7:24", " at async /var/task/node_modules/@aws-sdk/middleware-signing/dist-cjs/awsAuthMiddleware.js:14:20", " at async /var/task/node_modules/@smithy/middleware-retry/dist-cjs/retryMiddleware.js:27:46", " at async /var/task/node_modules/@aws-sdk/middleware-flexible-checksums/dist-cjs/flexibleChecksumsMiddleware.js:63:20", " at async /var/task/node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/region-redirect-endpoint-middleware.js:14:24", " at async /var/task/node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/region-redirect-middleware.js:9:20", " at async /var/task/node_modules/@aws-sdk/middleware-logger/dist-cjs/loggerMiddleware.js:7:26" ] }

여기서 말하는 Key가 파일이름 같은데 왜 파일 이름을 못찾는다는 건지 잘 모르겠습니다..

//이미지 리사이징 라이브러리
const sharp = require("sharp");

const {
  S3Client,
  GetObjectCommand,
  PutObjectCommand,
} = require("@aws-sdk/client-s3");

//함수가 aws 람다에서 돌아가기 때문에 스크릿키랑 아이디를 자동으로 넣어준다 = > 아무것도 넣어줄 필요 x
const s3 = new S3Client();

//람다는 3개의 매개변수를 제공하고 이 함수를 호출해준다.
exports.handler = async (event, context, callback) => {
  const Bucket = event.Records[0].s3.bucket.name;
  const Key = decodeURIComponent(event.Records[0].s3.object.key); //original/리버풀.png
  const filename = Key.split("/").at(-1);
  const ext = Key.split(".").at(-1).toLowerCase();
  const requiredFormat = ext === "jpg" ? "jpeg" : ext;
  console.log("name", filename, "ext", ext);
  try {
    const getObject = await s3.send(new GetObjectCommand({ Bucket, Key }));
    const buffers = [];
    for await (const data of getObject.Body) {
      buffers.push(data);
    }
    const imageBuffer = Buffer.concat(buffers);
    console.log("original", getObject);
    const resizedImage = await sharp(imageBuffer)
      .resize(200, 200, { fit: "inside" })
      .toFormat(requiredFormat)
      .toBuffer();
    await s3.send(
      new PutObjectCommand({
        Bucket,
        Key: `thumb/${filename}`,
        Body: resizedImage,
      })
    );

    console.log("put", resizedImage.length);
    return callback(null, `thumb/${filename}`);
  } catch (error) {
    console.error(error);
    return callback(error);
  }
};

이것도 혹시 s3 권한 문제 일까요?
아까 권한 추가 만들때
스크린샷 2023-11-24 오전 1.04.39.png정책 연결로 s3FullAccess로 권한 정책 추가 했는데 인라인 정책 생성으로 만들어야 했나요?

파일명 영어로 띄어쓰기 없는 것으로 올려보세요

김명재님의 프로필

김명재

질문자

2023.11.24

드디어 됐습니다... 그런데 왜 한글 파일명은 안되는건가요?

한글도 원래 돼야하긴 합니다. 띄어쓰기는 +를 스페이스로 replace하는 코드를 추가하면 됩니다.