> Tesilio's Blog
기록하는 공간
기록하는 공간

origin을 S3로 두고있는 Cloud Front의 트래픽 비용절감을 위해 사용했다. S3에 적재되어 있는 객체들 대부분이 jpg이다. 따라서 압축이나 리사이즈를 통해 최소 30% 이상 비용절감이 기대되었다.
해당 항목들 때문에 적용하는데 어려움도 있었고, 아쉬움도 남았다.
해당 제한사항 때문에 압축 혹은 리사이즈 한 이미지의 크기가 1MB가 넘으면 에러가 발생했다. 그래서 프로세싱한 이미지를 S3에 저장하고 요청 uri를 변경하는 로직으로 진행하였다.
S3 Bucket명 이라던지 이미지 압축률 같은 것들을 변수처리 하지 못해 소스코드상에 적용시켰다.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "arn:aws:logs:*:*:*"
},
{
"Effect": "Allow",
"Action": "s3:*",
"Resource": "*"
}
]
}이렇게 입력 후 '허용'을 누른다. 7. 그리고 일단 함수를 생성한다. 8. 역할에 대한 신뢰 관계를 수정해야한다. 여기로 간다. 9. 방금 생성 한 역할을 찾아 '신뢰 관계' 탭 클릭 > '신뢰 관계 편집' 을 클릭힌다.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": [
"edgelambda.amazonaws.com",
"lambda.amazonaws.com"
]
},
"Action": "sts:AssumeRole"
}
]
}이렇게 입력 후 '신뢰 정책 업데이트'를 누른다. 10. 이러면 함수생성은 끝이다. 이제 실제로 동작하게끔 만들어보자.
실제 코드를 작성하기 전에 어느 이벤트타입에서 동작해야 하는지 정해야 한다. 이 포스트에서는 origin-request에 연결 할 함수를 만들 것이다.
기본적으로 생성 된 람다 함수의 handler는 index.handler이다. 따로 변경하지는 않겠다.
이미지 프로세싱을 위해 sharp라는 모듈을 사용한다.
npm install sharp
npm install aws-sdk
const AWS = require('aws-sdk');
const SHARP = require('sharp');
const S3 = new AWS.S3({
signatureVersion: 'v4',
});
const BUCKET = '버킷명';
exports.handler = (event, context, callback) => {
let cf = event.Records[0].cf;
let originRequest = cf.request;
let decodedUri = decodeURIComponent(originRequest.uri);
let uriMatch = decodedUri.match(/\/(.*)\.(.*)/);
let [originKey, imageName, extension] = uriMatch;
originKey = decodedUri.replace(/^\//, "");
S3.getObject({Bucket: BUCKET, Key: originKey}).promise()
.then(getResponse => {
let sharpObject = SHARP(getResponse.Body);
let newKey = "ProcessedImages/" + originKey;
sharpObject.jpeg({quality: 90}).toBuffer()
.then(buffer => {
S3.putObject({
Body: buffer,
Bucket: BUCKET,
ContentType: 'image/jpeg',
Key: newKey,
StorageClass: 'STANDARD'
}).promise()
.catch(putObjectErr => {
throw putObjectErr;
});
})
.catch(toBufferErr => {
throw toBufferErr;
});
let newUri = "/" + encodeURIComponent(newKey);
originRequest.uri = newUri; // 바뀐 uri 로 변경!
callback(null, originRequest);
})
.catch(error => {
console.log(error);
callback(null, originRequest);
});
};동작하는 최소한의 참고용 코드이다. 흐름은 이렇다.
배포패키지(zip)를 람다가 작동할 환경에 맞게 만들어야 한단다. sharp 설치 문서.
$ rm -rf node_modules
$ docker run -v "$PWD":/var/task lambci/lambda:build-nodejs8.10 npm install
드디어 배포 할 시간이다.



index.js의 코드나 람다 함수 설정에 대한 세세한 부분은 각자의 상황에 맞춰 적용하면 되겠다. 회사 프로젝트에 적용한지 얼마 되진 않았지만, Cloud Front 트래픽 절감에 효과를 보이고 있다.
이 포스트가 누군가에게 조그마한 도움이 되길 바란다.
잘못된 정보에 대한 지적, 더 좋은 방법에 대한 의견 등은 언제나 많이많이 환영합니다.😆