s3와 lambda를 이용하여 이미지 리사이징 서버 만들기

aws lambda를 이용하여 이미지 리사이징 서버 만들기

awsLambda라는 서버리스 기능을 이용하여 이미지 리사이징 서버를 만들어보겠습니다. S3에 이미지 원본과 썸네일을 한번에 저장하게 되면 저장소 용량을 많이 사용하게 됩니다. 따라서 원본만 S3에 저장하고 나머지 썸네일 이미지는 LambdaCloudFront, Lambda@Edge를 이용하여 이미지 리사이징 서버를 만들어 보곘습니다.

설정 방법

IAM

IAM 설정입니다.
IAM에서 역할을 추가하겠습니다.

IAM에서 역할을 선택 후 역할 만들기를 선택합니다.

AWS 서비스에서 Lambda를 선택합니다.

다음으로 이동하여 정책 필터에서 AWSLambdaExecute를 검색 후 체크하여 AWSLambdaExecute선택합니다.

3번은 건너 뛴 후 역할이름을 사용자가 알아 볼 수 있도록 지정합니다. 정책 부분에 AWSLambdaExecute가 잘 추가 되었는지 확인합니다.

역할을 생성 후 역할 리스트에 생성한 역할이 있는지 확인 후 생성한 역할을 선택합니다.

신뢰관계를 추가해야해서 신뢰관계편집을 선택합니다.

신뢰관계를 아래와 같이 동일하게 편집합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"lambda.amazonaws.com",
"edgelambda.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}

편집 후 신뢰 정책 업데이트를 선택하여 신뢰관계를 업데이트합니다.

신뢰할 수 있는 개체에 위와 같이 두개의 리스트가 나타나있어야합니다.

S3

S3 버킷을 만들어줍니다.

위와 같이 S3 리전은 서울로 지정하겠습니다.

CloudFront

CloudFront 설정입니다.
CloudFront로 이동하겠습니다.

Create Distribution을 선택합니다.

콘텐츠 전송 방법은 Web을 선택합니다.

Origin Domain Name에서 생성한 S3의 버킷을 선택합니다.

Origin Domain Name에서 버킷 선택 후 Restrict Bucket Access 설정은 Yes로 설정합니다.
Origin Access Identity 설정은 Create a New Identity로 설정합니다.
Grant Read Permissions on Bucket 설정은 Yes, Update Bucket Policy로 설정합니다.
Origin Access Identity 설정과 Grant Read Permissions on Bucket 설정은 S3CloudFront만 접근 가능하도록 하는 설정입니다.

Query String Whitelist 설정에 d를 추가합니다.
Compress Objects Automatically 설정은 Yes로 설정합니다.
쿼리 스트링에 d를 키값으로 이미지 리사이징을 진행 할 예정이라 추가하였습니다. Compress Objects Automatically 설정을 Yes로 설정하면 컨텐츠를 압축하여 전송함으로 다운로드 속도가 빨라지게 됩니다. 따라서 설정을 활성화 하였습니다.

Lambda

Lambda 설정을 시작해보겠습니다.

Lambda의 리전은 꼭 미국 동부(버지니아 북부)로 선택합니다. LambdaLambda@EdgeCloudFront는 버지니아 북부 리전에서만 설정 할 수 있습니다. 하지만 리전을 걱정 안하셔도 되는게 람다함수는 모든 리전에 복사되어 가까운 리전에서 응답을 받을 수 있습니다. 따라서 버지니아 북부로 꼭 선택하고 함수만들기를 선택합니다.

함수생성에서 함수 이름은 사용자가 알아서 입력을 합니다. Lambda 함수 리스트에서 알아 볼 수 있도록 이름을 설정합니다. 런타임Node.js 8.10으로 설정하겠습니다. 현제 Node.js 10버전을 사용 할 수 있긴 하지만 현재 쓰는 노드버전이 8버전이므로 8버전을 선택하였습니다. 권한설정에서 실행 역할기존 역할 사용으로 설정합니다. 여기서 권한은 위에서 IAM의 역할을 추가했던 그 역할을 사용 할 것입니다. 기존 역할에서 IAM에서 생성한 역할을 선택합니다. 설정 완료 후 함수 생성을 선택하여 함수를 생성합니다.

람다 설정에서 람다 함수 코드를 작성해보도록 하겠습니다.

바탕화면에 swt-lambda라는 폴더를 생성해주었습니다.
폴더로 이동하여 npm init -y를 실행하여 package.json파일을 생성합니다. 실행 후 npm install querystring sharp aws-sdk를 실행하여 3개의 패키지를 설치합니다.

index.js파일을 생성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
const querystring = require('querystring');
const Sharp = require('sharp');
const AWS = require('aws-sdk');
const S3 = new AWS.S3({ region: 'ap-northeast-2' });
const BUCKET = 'swt-lambda';

exports.handler = async (event, context, callback) => {
const response = event.Records[0].cf.response;
const request = event.Records[0].cf.request;
const params = querystring.parse(request.querystring);

// https://cloudfront.com/image.jpg?d=100x100와 일치하지 않은 주소 일 경우 원본 이미지를 반환합니다.
if (!params.d) {
callback(null, response);
return;
}

const uri = request.uri;
// d=100x100의 쿼리를 .split('x')를 이용하여 배열로 설정합니다.
const imageSize = params.d.split('x');
// 배열의 0번째를 가로로 설정합니다.
const width = parseInt(imageSize[0]);
// 배열의 1번쨰를 세로로 설정합니다.
const height = parseInt(imageSize[1]);
const [, imageName, extension] = uri.match(/\/(.*)\.(.*)/);
const requiredFormat = extension == 'jpg' ? 'jpeg' : extension;
const originalKey = imageName + '.' + extension;

try {
// aws-sdk를 이용하여 s3에서 이미지를 받아옵니다.
const s3Object = await S3.getObject({
Bucket: BUCKET,
Key: originalKey,
}).promise();

// sharp를 이용하여 이미지를 리사이징 합니다.
const resizedImage = await Sharp(s3Object.Body)
.resize(width, height)
.toFormat(requiredFormat)
.toBuffer();

response.status = 200;
response.body = resizedImage.toString('base64');
response.bodyEncoding = 'base64';
response.headers['content-type'] = [
{ key: 'Content-Type', value: 'image/' + requiredFormat },
];

return callback(null, response);
} catch (error) {
return callback(error);
}
};


index.js 파일과 node_modules폴더를 한번에 선택 후 압축합니다.

Lambda로 이동하여 함수코드 부분에서 코드 입력 유형을 .zip 파일 업로드로 선택합니다.

업로드를 선택하여 index.js 파일과 node_modules폴더를 압축 한 압축파일을 업로드합니다.

파일이 업로드가 완료 된 후 저장합니다.

기본설정을 위와 같이 설정합니다.

트리거 추가 목록에서 CloudFront를 선택합니다.

트리거 구성에서 Lambda@Edge로 배포를 선택합니다.

CloudFront 이벤트오리진 응답으로 선택합니다. Lambda@Edge로 배포 확인에서 체크 후 배포를 선택하여 배포합니다.

공유하기