CloudFormation 을 사용한 이미지 변환 및 리사이징
기존엔 프론트 단에서 이미지를 압축한후 S3 로 이미지를 업로드
그후 CloudFront 를 통하여 캐싱된 이미지를 가져오는 방식을 사용했습니다.
해당 방식을 사용하다 발생한 문제는 프론트 단에서 이미지를 압축하는데 리소스가 든다는 것이었고, 그렇다고 서버측에서 이미지를 바이너리 형태로 받아, 압축하는것또한 서버측 부담이 커져 AWS 에서 제공하는 CloudFormation 을 통해 해당 문제를 해결했습니다.
CloudFormation을 이용하면 AWS에서 제공하는 Serverless Image Handler 스택을 한 번에 배포할 수 있습니다. 이 스택은 다음과 같은 주요 기능을 제공합니다.
온디맨드(On-demand) 이미지 리사이징
이미지를 “업로드 시점”에 리사이징하는 것이 아니라 사용자가 이미지를 요청하는 순간 필요한 규격대로 변환합니다.
- 예: 1200px 필요하면 1200px로
- 모바일에서는 600px로
- 썸네일이면 300px로
이미지 가공은 전적으로 CloudFront + Lambda@Edge가 수행하고,애플리케이션 서버는 URL만 만들어 내려주면 됩니다.
CloudFormation 을 사용하면, 자동적으로 CDN 을 사용하기 때문에, 캐싱문제를 해결할수 있습니다.
모든 이미지를 WebP 등으로 자동 변환 가능 합니다.
이미지 처리 로직을 FE, BE 단에서 처리하지 않아도 됩니다.
1. CloudFormation 스택 생성
1.1 스택 생성
문서에서 AWS CloudFormation template 섹션에 있는 최신 템플릿 URL을 복사합니다.
예시:
https://solutions-reference.s3.amazonaws.com/dynamic-image-transformation-for-amazon-cloudfront/latest/dynamic-image-transformation-for-amazon-cloudfront.template
AWS 콘솔에서 CloudFormation → 스택 생성으로 이동한 뒤,
템플릿 준비 완료Amazon S3 URL 지정
을 선택하고, 위에서 복사한 템플릿 URL을 그대로 붙여넣습니다.

1.2 스택 세부 정보 지정
Stack 이름
- CloudFormation 스택 이름입니다. 원하는 이름을 자유롭게 설정하면 됩니다.
CORS Options
- 이미지 핸들러 API에서 CORS를 허용할지 여부입니다.
- 보통 프론트에서 직접 이 엔드포인트를 호출한다면
Yes로 두고, 허용할 Origin을 지정합니다.
Image Sources
- 원본 이미지를 저장하는 S3 버킷 이름들을 적는 곳입니다.
- 여러 버킷을 사용할 경우 쉼표로 구분해서 입력합니다.
예)
test-dev
Demo UI
Yes로 설정하면 AWS가 샘플 뷰어(이미지 리사이즈/포맷 테스트용 웹 페이지)를 함께 배포합니다.- 처음 도입할 때는 Demo UI를 통해 요청 JSON과 Encoded URL을 쉽게 확인할 수 있으므로
Yes로 설정하는 것을 추천합니다.
Event Logging
- 이 솔루션에서 발생하는 Lambda 로그를 CloudWatch에 얼마나 오래 보관할지 선택합니다.
- 특별한 이유가 없다면 기본값으로 두어도 무방합니다.
Image URL Signature
URL 서명을 강제할지 여부입니다.
만약 “아무나 임의로 리사이즈 URL을 만들지 못하게” 하고 싶다면
Yes로 두고별도의 시크릿을 설정해야 합니다.
내부 서비스이거나 보안 위협이 크지 않다면 초기에는
No로 두고 시작해도 됩니다.
Default Fallback Image
이미지 키가 잘못되었을 때 JSON 에러를 반환하는 대신
특정 기본 이미지를 내려줄지 여부입니다.
Yes로 설정하면, Fallback Image S3 Bucket/Key를 함께 입력해야 합니다.
Auto WebP
브라우저의
Accept헤더를 보고 WebP를 지원하면 자동으로 WebP로 변환해서 내려줄지 여부입니다.이미지를 최대한 가볍게 전달하고 싶다면
Yes로 설정하면 됩니다.
CloudFront PriceClass
CloudFront 엣지 로케이션 범위를 선택합니다.
PriceClass_All: 전 세계 POP 사용 (가장 빠르지만 상대적으로 비용이 높습니다)PriceClass_200: 대표적인 리전 위주 (보통 이 옵션으로도 충분합니다)
1.3 스택 옵션 구성
해당 단계에서는 태그를 제외한 나머지는 굳이 건드릴 필요가없습니다.

IAM 역할 설정 역시 별도의 조직 정책이 없다면 별도의 Role을 지정하지 않고, CloudFormation이 자동으로 필요한 Execution Role을 생성하도록 두면 됩니다.
- CloudFormation이 IAM 리소스를 생성하도록 허용 체크만 되어 있으면 추가 설정 없이 스택이 정상적으로 생성됩니다.
2. Demo 를 이용한 테스트
테스트를 위해 위 1.2 스택 세부 정보 지정 단계에서 연결했던 S3 버킷에 이미지를 하나 업로드합니다.

그 다음 CloudFront 콘솔에 들어가 보면, 스택 생성 과정에서 자동으로 만들어진 두 개의 CloudFront Distribution 을 확인할 수 있습니다.

그 후 Demo 페이지의 배포 도메인으로 접속해 Image Source 영역에 저희가 테스트용으로 업로드했던 버킷명과 객체 키(Object Key)를 입력한 뒤 Import 버튼을 클릭합니다.
이제 Editor 화면에서 원하는 Width 와 Height 값을 입력하면 이미지 변환이 즉시 적용됩니다.
변환 전·후의 해상도와 용량도 함께 확인할 수 있습니다.


- 해상도:
원본 8636x5828 → 400x400 - 용량:
원본 4.9mb → 17kb
변환된 결과를 통해 Serverless Image Handler 가 정상적으로 이미지 리사이징 및 최적화를 수행하는 것을 확인할 수 있습니다.
3. 실사용
Demo 를 통해 테스트를 완료했습니다.
CloudFormation Stack 배포를 통해 생성된 CloudFront Distribution 을 사용하여, S3 객체에 대해 요청 시점에 원하는 해상도로 변환된 이미지를 받아올 수 있게 되었습니다.
이미지 변환 요청을 수행하기 위해서는, 아래 화면에 표시되는 Request Body JSON 을 Base64 URL-safe 방식으로 인코딩한 뒤, CloudFront CDN URL 뒤에 붙여주는 방식을 사용합니다.
{
"bucket": "버킷명",
"key": "image-test.jpg",
"edits": {
"resize": {
"width": 4000,
"height": 4000,
"fit": "contain"
}
}
}
해당 JSON 전체를 Base64 URL-safe 로 인코딩한 후, 아래와 같은 형태로 요청을 보내면 됩니다.
https://{cloudfront-domain}/{base64-encoded-json}

3.1 Java 예시 — 요청 JSON Base64 인코딩
아래는 Java를 사용해 테스트용 인코딩 로직을 작성한 예시입니다.
public static void main(String[] args) throws JsonProcessingException {
// JSON payload 구성
Map<String, Object> payload = Map.of(
"bucket", "버킷명",
"key", "image-test.jpg",
"edits", Map.of(
"resize", Map.of(
"width", 4000,
"height", 4000,
"fit", "contain"
)
)
);
// JSON → String 변환
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(payload);
// Base64 URL-safe 인코딩
String encoded = Base64.getUrlEncoder()
.withoutPadding()
.encodeToString(json.getBytes(StandardCharsets.UTF_8));
// CloudFront URL 결합
String cdnUrl = "CDN URL 입력";
System.out.println(cdnUrl + "/" + encoded);
}
이 방식으로 인코딩된 URL을 요청하면, 해당 이미지가 지정된 해상도(4000 × 4000, fit: contain)로 변환된 뒤 CloudFront 캐시에 저장되어 반환됩니다.
즉, 원본 이미지는 그대로 S3에 두고, 원하는 규격의 이미지를 요청 시 즉시 생성하는 구조 가 완성이 되었습니다.
'AWS' 카테고리의 다른 글
| [AWS 비용 절감 #3]slack과 aws의 lambda 연동 (3) | 2025.07.09 |
|---|---|
| [AWS 비용 절감 #2] EC2 인스턴스 예약 실행으로 비용 최적화 (2) | 2025.07.04 |
| [AWS 비용 절감 #1] S3 + CloudFront + HTTPS 정적 웹사이트 (0) | 2025.05.19 |





















