Bare Minimum Requirements
- 이미지가 업로드되면, 원본과 별도로 썸네일을 생성하고, 이를 별도의 버킷에 저장해야 합니다.
- 썸네일 이미지는 가로 200px의 크기를 가집니다.
- 썸네일을 저장할 별도의 버킷은 람다 함수의 환경 설정으로 구성되어야 합니다.
- 썸네일 생성이 완료되면, 메일로 해당 썸네일 URL과 함께 전송이 되어야 합니다.
- Amazon SNS를 활용합니다.
- 아래 과제 제출 방법을 참고해 GitHub에 제출합니다.
Homebrew 사전 설치가 필요하다 (MacOS 기준)
참고 링크
1. Quick Start Template 를 이용해 Standalone Function을 생성한다
- sam init
- 입력한 프로젝트 이름으로 생성된 디렉토리 확인
- cd <프로젝트 이름>
2. Lambda 함수의 파라미터를 정의한다
- Lambda Handler 내 함수를 수정함
- event, context 를 CloudWatch 에서 확인하고자함
exports.helloFromLambdaHandler = async (event, context) => {
console.log(event)
console.log(context)
return 'Hello from Lambda!';
}
3. sam build 와 sam deploy -g 명령어 를 통해 빌드 & 배포 진행
- sam build ==> .aws-sam 폴더 생성 (안에 build 폴더 생성됨)
- sam deploy -g (-g 옵션은 이후부턴 안붙여도 됨 -- samconfig.toml 파일을 통해 같은 조건으로 배포됨)
4. Lambda 내 함수 생성 확인
5. S3 버킷 생성
6. Lambda 내 S3 트리거 추가
7. S3 내 .jpeg 파일 업로드 후 Cloud Watch log 확인
=> CloudWatch -> 로그 -> 로그그룹 -> 로그스트림 -> event, context 로그 확인
8. 썸네일 저장을 위한 별도 S3 생성
- 원본 사진 저장 버킷과 같이 생성하지만 ACL 활성화 해야함
9. 썸네일 저장
- Mac Os M1 사용 시 package.json 내 코드 수정
- 아래 코드를 기존 코드에 삽입
- 람다 함수가 잘 실행되려면 npm dependency로 sharp 모듈이 필요한데 npm install 명령을 통해서 관련 모듈을 설치함
"dependencies": {
"aws-sdk": "^2.1111.0"
},
"scripts": {
"preinstall": "npm install --platform=linux --arch=x64 --no-save sharp"
}
- 제공받은 소스코드 활용 (hello-from-lambda.js 코드에 적용)
// 원본 버킷으로부터 파일 읽기
const s3Object = await s3.getObject({
Bucket: 원본_버킷_이름,
Key: 업로드한_파일명
}).promise()
// 이미지 리사이즈, sharp 라이브러리가 필요합니다.
const data = await sharp(s3Object.Body)
.resize(200)
.jpeg({ mozjpeg: true })
.toBuffer()
// 대상 버킷으로 파일 쓰기
const result = await s3.putObject({
Bucket: 대상_버킷_이름,
Key: 업로드한_파일명과_동일,
ContentType: 'image/jpeg',
Body: data,
ACL: 'public-read'
}).promise()
- 작성한 코드
/**
* A Lambda function that returns a static string
*/
/*
exports.helloFromLambdaHandler = async () => {
// If you change this message, you will need to change hello-from-lambda.test.js
const message = 'Hello from Lambda!';
// All log statements are written to CloudWatch
console.info(`${message}`);
return message;
}
*/
const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01' });
const sharp = require('sharp');
exports.helloFromLambdaHandler = async (event, context) => {
console.log(event);
console.log(context);
const bucket = event.Records[0].s3.bucket.name; // 원본 버킷 이름
const key = event.Records[0].s3.object.key; // 원본 버킷 키
console.log(bucket);
console.log(key);
const dstBucket = 'photo-sam-bucket-test-resize' // 썸네일 버킷 이름
// 원본 버킷으로부터 파일 읽기
const s3Object = await s3.getObject({
Bucket: bucket,
Key: key
}).promise()
// 이미지 리사이즈, sharp 라이브러리가 필요합니다.
const data = await sharp(s3Object.Body)
.resize(200)
.jpeg({ mozjpeg: true })
.toBuffer()
// 대상 버킷으로 파일 쓰기
const result = await s3.putObject({
Bucket: dstBucket,
Key: key, // 원본 버킷 키와 동일
ContentType: 'image/jpeg', // 컨텐츠 타입
Body: data,
ACL: 'public-read'
}).promise()
return result;
}
- 원본 버킷에 .jpeg 업로드 시 200픽셀로 resize 된 썸네일 파일이 다른 resize 버킷에 저장됨
10. Amazon SNS 를 통한 e-mail 알림
- 썸네일 URL 함께 전송해야함 - 코드 수정 후 재 빌드 및 배포 (sam build, sam deploy)
/**
* A Lambda function that returns a static string
*/
/*
exports.helloFromLambdaHandler = async () => {
// If you change this message, you will need to change hello-from-lambda.test.js
const message = 'Hello from Lambda!';
// All log statements are written to CloudWatch
console.info(`${message}`);
return message;
}
*/
const aws = require('aws-sdk');
const s3 = new aws.S3({ apiVersion: '2006-03-01' });
const sharp = require('sharp');
const REGION = "ap-northeast-2"
const snsClient = new aws.SNS(REGION)
exports.helloFromLambdaHandler = async (event, context) => {
console.log(event);
console.log(context);
const bucket = event.Records[0].s3.bucket.name;
const key = event.Records[0].s3.object.key;
console.log(bucket);
console.log(key);
const dstBucket = 'photo-sam-bucket-test-resize'
// 원본 버킷으로부터 파일 읽기
const s3Object = await s3.getObject({
Bucket: bucket,
Key: key
}).promise()
// 이미지 리사이즈, sharp 라이브러리가 필요합니다.
const data = await sharp(s3Object.Body)
.resize(200)
.jpeg({ mozjpeg: true })
.toBuffer()
// 대상 버킷으로 파일 쓰기
const result = await s3.putObject({
Bucket: dstBucket,
Key: key,
ContentType: 'image/jpeg',
Body: data,
ACL: 'public-read'
}).promise()
const snsService = {
TopicArn: '<SNS Arn 직접 입력>',
Subject: "Creating a Successful Thumbnail",
Message: `https://${dstBucket}.s3.ap-northeast-2.amazonaws.com/${key}`
}
const value = await snsClient.publish(snsService).promise();
console.log('Send a successful thumbnail link')
return value;
}
- AWS SNS 생성
- 생성된 SNS 주제 내 구독 생성
- 프로토콜 = 이메일, 엔드포인트 = 이메일 입력
- 이메일 확인하여 구독 확인 하여야함 꼭!! - 링크 눌러서 꼭 컴펌 하기
- 대상추가 - Amazon SNS
- 버킷 내 사진 업로드 & 썸네일 생성 확인 & e-mail 링크 확인
- 링크 접속하여 업로드 한 .jpeg 파일 정상 출력 확인
트러블슈팅
#1. sam deploy -g 오류 2가지
Error: Failed to create managed resources: An error occurred (InvalidClientTokenId) when calling the CreateChangeSet operation: The security token included in the request is invalid.
*** root 의 액세스 키를 설정하면 해결되지만 위험한 행동임
=> IAM 권한 오류라 AWS_ACCESS_KEY_ID 및 AWS_SECRET_ACCESS_KEY를 재설정 해주었다.
(aws configure 로 키를 먼저 확인함
export AWS_ACCESS_KEY_ID=********
export AWS_SECRET_ACCESS_KEY=******* 이 두줄 명령어 실행으로 바꿈)
아래 오류도 권한 설정으로 해결함
#2. s3 is not defined
- S3에 .jpeg 를 삽입한 후 썸네일 파일이 생성 되지 않음
- hello-from-lambda.js 코드 내 S3 객체 선언 추가
const aws = require('aws-sdk');
- 아래 공식문서 참고
https://docs.aws.amazon.com/ko_kr/lambda/latest/dg/with-s3-example.html
#3. sharp is not defined
- const sharp = require('sharp'); 를 hello-from-lambda.js 에 추가 해줘야함 (맨위에 선언)
- npm install 미실행 후 배포해버림
- scripts 내 npm install sharp 를 통해 sharp 설치 진행됨 (npm install 만 진행 하면 됨)
- 그래도 안되면 mac 의 경우 node_modules 지우고 npm install --platform=linux --arch=x64 --no-save sharp 실행
"scripts": {
"test": "jest",
"preinstall": "npm install --platform=linux --arch=x64 --no-save sharp"
}
#4. 해결못한 오류
- 가끔 Cloud Watch에 로그가 안뜸
- 최신 로그에 쌓이지도 않음
- 다 지우고 로그를 쌓으려고 해도 뜨지 않음
- 갑자기 그럼
#5. TopicArn or TargetArn Reason: no value for required parameter
- 코드 내 TopicArn 오타 수정
참고링크
https://docs.aws.amazon.com/ko_kr/sns/latest/dg/sns-publishing.html
https://docs.aws.amazon.com/ko_kr/AmazonS3/latest/userguide/notification-content-structure.html
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/SNS.html#publish-property
'클라우드 > AWS' 카테고리의 다른 글
DynamoDB 란? (DynamoDB Stream, Kinesis Stream) (0) | 2023.03.09 |
---|---|
AWS Burst 기능이란? (0) | 2023.03.03 |
[Mac OS]API Gataway 와 서버리스 어플리케이션 (0) | 2023.02.04 |
[Mac OS]AWS Certificate Manager, Route53, CloudFront (AWS ACM, ACM 인증서, Route 53) (0) | 2023.01.25 |
[Mac OS]ECS exec format error (ECR, ECS 오류, task, cluster) (0) | 2023.01.25 |