🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

AWS S3 문서 연동 완벽 가이드 - 슬라이드 1/7
A

AI Generated

2025. 12. 18. · 4 Views

AWS S3 문서 연동 완벽 가이드

AWS S3에 저장된 문서를 애플리케이션과 연동하는 방법을 단계별로 배웁니다. 버킷 준비부터 문서 동기화, 업데이트 처리까지 실무에서 바로 활용할 수 있는 내용을 다룹니다.


목차

  1. S3_버킷_준비하기
  2. 지원_문서_형식
  3. 데이터_소스_추가
  4. 문서_동기화_실행
  5. 동기화_상태_확인
  6. 문서_업데이트_처리

1. S3 버킷 준비하기

김개발 씨는 신입 개발자로 입사한 지 한 달이 지났습니다. 팀장님이 다가와 말했습니다.

"김개발 씨, 우리 회사 기술 문서들을 S3에 저장하고 있는데, 이걸 검색 시스템과 연동해야 해요. S3 버킷부터 준비해 볼까요?"

S3 버킷은 AWS에서 제공하는 클라우드 스토리지의 최상위 컨테이너입니다. 마치 컴퓨터의 폴더처럼 문서를 보관하는 공간이지만, 인터넷 어디서나 접근할 수 있고 용량 제한이 거의 없다는 장점이 있습니다.

버킷을 제대로 준비하면 수백만 개의 문서도 안정적으로 관리할 수 있습니다.

다음 코드를 살펴봅시다.

import boto3

# S3 클라이언트 생성 - AWS와 연결하는 첫 단계
s3_client = boto3.client(
    's3',
    aws_access_key_id='YOUR_ACCESS_KEY',
    aws_secret_access_key='YOUR_SECRET_KEY',
    region_name='ap-northeast-2'  # 서울 리전
)

# 버킷 생성 - 문서를 보관할 공간 만들기
bucket_name = 'company-documents-2025'
s3_client.create_bucket(
    Bucket=bucket_name,
    CreateBucketConfiguration={'LocationConstraint': 'ap-northeast-2'}
)

print(f"버킷 '{bucket_name}'이 생성되었습니다.")

김개발 씨는 처음 들어보는 용어에 조금 당황했습니다. "S3 버킷이요?

버킷이면 양동이 아닌가요?" 팀장님이 웃으며 설명했습니다. "맞아요, 양동이처럼 뭔가를 담는 그릇이죠.

다만 이 양동이는 엄청나게 크고, 전 세계 어디서나 접근할 수 있답니다." **S3(Simple Storage Service)**는 아마존 웹 서비스에서 제공하는 클라우드 스토리지입니다. 여러분의 컴퓨터 하드디스크처럼 파일을 저장하는 공간인데, 물리적인 하드디스크가 아니라 인터넷 상에 존재하는 가상의 저장 공간입니다.

그렇다면 버킷이란 무엇일까요? 쉽게 비유하자면, 버킷은 마치 도서관의 서가와 같습니다.

도서관에는 여러 개의 서가가 있고, 각 서가마다 다른 종류의 책을 보관합니다. 예를 들어 한 서가에는 소설책을, 다른 서가에는 기술 서적을 보관하는 식이죠.

S3도 마찬가지입니다. 하나의 AWS 계정에 여러 개의 버킷을 만들 수 있고, 각 버킷마다 다른 목적의 파일을 저장합니다.

S3가 없던 시절에는 어땠을까요? 회사들은 자체 서버실에 거대한 스토리지 장비를 구축해야 했습니다.

비용도 많이 들었고, 용량이 부족하면 장비를 추가로 구매해야 했습니다. 더 큰 문제는 재해 상황이었습니다.

서버실에 화재가 나거나 홍수가 나면 모든 데이터가 사라질 수 있었죠. 또한 전 세계 여러 지역에서 접근할 때 속도가 느린 문제도 있었습니다.

바로 이런 문제를 해결하기 위해 AWS S3가 등장했습니다. S3를 사용하면 무제한에 가까운 저장 공간을 얻을 수 있습니다.

파일을 올리면 AWS가 자동으로 여러 곳에 복사본을 만들어 보관하므로 데이터 손실 위험이 거의 없습니다. 무엇보다 사용한 만큼만 비용을 지불하므로 초기 투자 비용이 거의 들지 않는다는 큰 이점이 있습니다.

위의 코드를 한 줄씩 살펴보겠습니다. 먼저 boto3.client를 호출하는 부분을 보면 AWS와 연결하는 클라이언트 객체를 생성한다는 것을 알 수 있습니다.

이 부분이 핵심입니다. 여기서 aws_access_key_idaws_secret_access_key는 AWS에 접근하기 위한 인증 정보입니다.

마치 은행 앱에 로그인할 때 아이디와 비밀번호를 입력하는 것과 같습니다. 다음으로 region_name에서는 버킷을 어느 지역에 만들지 지정합니다.

ap-northeast-2는 서울 리전을 의미합니다. 한국 사용자가 많다면 서울 리전에 버킷을 만드는 것이 접속 속도 면에서 유리합니다.

마지막으로 create_bucket 메서드로 실제 버킷이 생성됩니다. 버킷 이름은 전 세계에서 고유해야 합니다.

다른 누군가가 이미 사용 중인 이름은 쓸 수 없습니다. 실제 현업에서는 어떻게 활용할까요?

예를 들어 스타트업에서 고객이 업로드한 이미지를 저장하는 서비스를 개발한다고 가정해봅시다. 처음에는 사용자가 적어서 1GB 정도만 필요하지만, 서비스가 성장하면 수 TB까지 늘어날 수 있습니다.

S3를 활용하면 용량 걱정 없이 시작할 수 있고, 사용량이 늘어날 때 자동으로 확장됩니다. 실제로 넷플릭스, 에어비앤비 같은 글로벌 기업들이 S3를 적극적으로 사용하고 있습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수 중 하나는 액세스 키를 코드에 직접 하드코딩하는 것입니다.

이렇게 하면 코드가 깃허브에 올라갔을 때 누구나 여러분의 AWS 계정에 접근할 수 있어 보안 사고가 발생할 수 있습니다. 따라서 환경 변수나 AWS IAM 역할을 사용하는 것이 올바른 방법입니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 팀장님의 설명을 들은 김개발 씨는 고개를 끄덕였습니다.

"아, 그래서 클라우드 스토리지라고 부르는 거군요!" S3 버킷을 제대로 준비하면 안정적이고 확장 가능한 문서 저장 시스템을 구축할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 버킷 이름은 DNS 규칙을 따라야 하므로 소문자, 숫자, 하이픈만 사용하세요

  • 실무에서는 환경 변수로 AWS 인증 정보를 관리하세요
  • 서울 리전(ap-northeast-2)을 사용하면 한국 사용자에게 빠른 응답 속도를 제공할 수 있습니다

2. 지원 문서 형식

버킷을 만들고 나니 김개발 씨는 궁금해졌습니다. "그런데 팀장님, S3에는 어떤 파일들을 올릴 수 있나요?

PDF만 되나요?" 팀장님이 답했습니다. "아니요, 생각보다 훨씬 다양한 형식을 지원해요.

하나씩 살펴볼까요?"

S3 문서 연동에서 지원하는 파일 형식은 매우 다양합니다. PDF, Word, PowerPoint 같은 일반 문서부터 HTML, 텍스트 파일, 심지어 마크다운 파일까지 처리할 수 있습니다.

각 형식마다 메타데이터를 추출하는 방식이 다르므로, 올바른 Content-Type을 설정하는 것이 중요합니다.

다음 코드를 살펴봅시다.

import boto3
from pathlib import Path

s3_client = boto3.client('s3')
bucket_name = 'company-documents-2025'

# 지원하는 파일 형식과 Content-Type 매핑
SUPPORTED_FORMATS = {
    '.pdf': 'application/pdf',
    '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    '.txt': 'text/plain',
    '.md': 'text/markdown',
    '.html': 'text/html'
}

# 파일 업로드 함수 - Content-Type 자동 설정
def upload_document(file_path):
    path = Path(file_path)
    content_type = SUPPORTED_FORMATS.get(path.suffix, 'application/octet-stream')

    s3_client.upload_file(
        file_path,
        bucket_name,
        path.name,
        ExtraArgs={'ContentType': content_type, 'Metadata': {'original-name': path.stem}}
    )
    print(f"{path.name} 업로드 완료 (타입: {content_type})")

김개발 씨는 회사 공유 폴더를 살펴봤습니다. 기술 문서가 정말 다양한 형식으로 저장되어 있었습니다.

어떤 것은 PDF였고, 어떤 것은 워드 문서였으며, 개발자들이 작성한 마크다운 파일도 있었습니다. "이걸 다 S3에 올려야 하는데, 형식마다 다르게 처리해야 하나요?" 선배 개발자 이시니어 씨가 지나가다 말했습니다.

"걱정 마세요. S3는 거의 모든 파일 형식을 저장할 수 있어요.

다만 나중에 검색하거나 처리할 때를 위해 Content-Type을 제대로 지정하는 게 중요하죠." Content-Type이란 무엇일까요? 쉽게 비유하자면, Content-Type은 마치 택배 상자에 붙이는 라벨과 같습니다.

"이 상자 안에는 깨지기 쉬운 유리가 들어 있습니다"라고 적어두면 택배 기사님이 조심히 다루듯이, Content-Type을 지정하면 시스템이 그 파일을 어떻게 처리해야 할지 알 수 있습니다. application/pdf라고 적으면 "이건 PDF 문서구나" 하고 인식하는 것이죠.

Content-Type을 제대로 지정하지 않으면 어떻게 될까요? 예전에 어떤 회사에서는 모든 파일을 application/octet-stream이라는 기본값으로 업로드했습니다.

이건 "이진 데이터"라는 뜻으로, 구체적으로 어떤 파일인지 알 수 없다는 의미입니다. 나중에 웹 브라우저에서 파일을 열려고 하면 다운로드만 되고 미리보기가 안 되는 문제가 생겼습니다.

PDF를 바로 보려고 클릭했는데 다운로드부터 하라고 하니 사용자들이 불편해했죠. 바로 이런 문제를 해결하기 위해 파일 확장자별로 적절한 Content-Type을 매핑하는 것이 중요합니다.

위 코드에서는 딕셔너리를 사용해 확장자와 Content-Type을 연결했습니다. .pdf 파일이면 application/pdf를, .docx 파일이면 워드 문서용 MIME 타입을 자동으로 지정합니다.

이렇게 하면 나중에 파일을 다운로드하거나 처리할 때 시스템이 파일 형식을 정확히 알 수 있습니다. 코드를 자세히 살펴보겠습니다.

먼저 SUPPORTED_FORMATS 딕셔너리에서 지원하는 파일 형식을 정의합니다. 여기에는 실무에서 자주 사용하는 문서 형식들이 포함되어 있습니다.

PDF는 기술 문서로, DOCX는 공식 문서로, 마크다운은 개발 문서로 많이 쓰이죠. 다음으로 upload_document 함수를 보면 파일 경로에서 확장자를 추출합니다.

Path 객체의 suffix 속성을 사용하면 .pdf 같은 확장자를 쉽게 얻을 수 있습니다. 그런 다음 딕셔너리에서 해당하는 Content-Type을 찾습니다.

만약 지원하지 않는 형식이면 기본값인 application/octet-stream을 사용합니다. 마지막으로 upload_file 메서드로 파일을 업로드할 때 ExtraArgs 매개변수로 메타데이터를 함께 전달합니다.

ContentType뿐만 아니라 Metadata에 원본 파일명도 저장해 두면 나중에 유용하게 쓸 수 있습니다. 실제 현업에서는 어떻게 활용할까요?

한 IT 교육 회사에서는 강의 자료를 S3에 저장하는 시스템을 구축했습니다. 강사들이 PDF, PowerPoint, 마크다운 등 다양한 형식으로 자료를 제출했는데, Content-Type을 정확히 지정해 두니 학생들이 웹에서 바로 미리보기를 할 수 있었습니다.

다운로드 없이도 내용을 확인할 수 있어서 사용자 경험이 크게 개선되었죠. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수는 확장자만 보고 Content-Type을 결정하는 것입니다. 악의적인 사용자가 실행 파일의 확장자를 .pdf로 바꿔서 업로드하면 어떻게 될까요?

시스템이 이를 PDF로 인식해 보안 문제가 생길 수 있습니다. 따라서 파일 내용을 실제로 검증하는 로직을 추가하는 것이 안전합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 이시니어 씨의 설명을 들은 김개발 씨는 노트에 메모하며 말했습니다.

"아, Content-Type이 이렇게 중요했군요!" 지원 문서 형식을 제대로 이해하고 Content-Type을 정확히 설정하면, 사용자가 편리하게 문서를 활용할 수 있는 시스템을 만들 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 실무에서는 python-magic 라이브러리로 파일 내용을 검증하는 것이 안전합니다

  • 대용량 파일은 멀티파트 업로드를 사용하세요
  • 메타데이터에 업로드 날짜, 작성자 정보를 함께 저장하면 나중에 관리하기 편합니다

3. 데이터 소스 추가

파일 업로드까지 마친 김개발 씨는 이제 본격적으로 검색 시스템과 S3를 연동해야 했습니다. "데이터 소스를 추가하라는 게 무슨 뜻이죠?" 팀장님이 화이트보드에 그림을 그리며 설명하기 시작했습니다.

"S3 버킷은 그냥 저장소일 뿐이에요. 검색 엔진이 이 버킷을 알아야 문서를 찾을 수 있죠."

데이터 소스는 검색 시스템이나 AI 서비스가 참조할 문서의 위치를 의미합니다. S3 버킷을 데이터 소스로 추가하면 시스템이 자동으로 버킷을 모니터링하며 새 문서가 추가되거나 수정될 때마다 인덱싱을 수행합니다.

마치 도서관에 새 책이 입고되면 사서가 목록에 추가하는 것과 같은 원리입니다.

다음 코드를 살펴봅시다.

import boto3
import json

# AWS Kendra 클라이언트 생성 (검색 서비스)
kendra_client = boto3.client('kendra', region_name='ap-northeast-2')

# S3 데이터 소스 설정
data_source_config = {
    'Name': 'CompanyDocuments',
    'IndexId': 'your-kendra-index-id',  # Kendra 인덱스 ID
    'Type': 'S3',
    'Configuration': {
        'S3Configuration': {
            'BucketName': 'company-documents-2025',
            'InclusionPatterns': ['*.pdf', '*.docx', '*.txt'],  # 포함할 파일
            'ExclusionPatterns': ['temp/*', 'archive/*']  # 제외할 경로
        }
    },
    'RoleArn': 'arn:aws:iam::123456789012:role/KendraS3Role'  # IAM 역할
}

# 데이터 소스 생성
response = kendra_client.create_data_source(**data_source_config)
print(f"데이터 소스 생성 완료: {response['Id']}")

김개발 씨는 화이트보드의 그림을 보며 고개를 끄덕였습니다. 왼쪽에는 S3 버킷이, 오른쪽에는 검색 엔진이 그려져 있었고, 둘 사이에 화살표가 연결되어 있었습니다.

"아, S3와 검색 엔진을 연결하는 다리 같은 거네요?" 팀장님이 웃으며 답했습니다. "정확해요!

그 다리가 바로 데이터 소스입니다. 이걸 설정하지 않으면 검색 엔진은 S3에 어떤 문서가 있는지 전혀 모르죠." 데이터 소스란 정확히 무엇일까요?

쉽게 비유하자면, 데이터 소스는 마치 신문사의 취재원과 같습니다. 기자가 기사를 쓰려면 정보를 얻을 취재원이 필요하듯이, 검색 엔진이 검색 결과를 제공하려면 정보를 가져올 데이터 소스가 필요합니다.

S3 버킷이 바로 그 취재원 역할을 하는 것이죠. 데이터 소스를 추가하기 전에는 어떤 문제가 있었을까요?

예전에는 검색 시스템과 저장소가 완전히 분리되어 있었습니다. 개발자가 직접 S3에서 파일을 다운로드하고, 내용을 추출하고, 검색 엔진에 수동으로 등록해야 했습니다.

파일이 수정되면 이 과정을 처음부터 다시 반복해야 했죠. 회사 문서가 수백 개, 수천 개가 되면 이런 작업을 일일이 할 수 없었습니다.

바로 이런 문제를 해결하기 위해 자동화된 데이터 소스 연동이 등장했습니다. 데이터 소스를 한 번 추가해 두면 자동으로 S3를 모니터링합니다.

새 파일이 올라오면 감지해서 인덱싱하고, 파일이 수정되면 자동으로 업데이트합니다. 무엇보다 패턴을 사용해 원하는 파일만 선택할 수 있다는 큰 이점이 있습니다.

위의 코드를 자세히 살펴보겠습니다. 먼저 AWS Kendra 클라이언트를 생성합니다.

Kendra는 AWS에서 제공하는 지능형 검색 서비스로, 자연어로 질문하면 관련 문서를 찾아주는 기능을 제공합니다. 기업용 검색 엔진이라고 생각하면 됩니다.

다음으로 data_source_config 딕셔너리에 데이터 소스 설정을 정의합니다. 여기서 중요한 부분은 S3Configuration입니다.

BucketName으로 어떤 버킷을 연동할지 지정하고, InclusionPatterns로 포함할 파일 패턴을, ExclusionPatterns로 제외할 경로를 설정합니다. 예를 들어 '*.pdf'라고 하면 모든 PDF 파일을 포함한다는 뜻입니다.

반대로 'temp/*'라고 하면 temp 폴더의 모든 파일을 제외합니다. 임시 파일이나 백업 파일은 검색 대상에서 빼고 싶을 때 유용하죠.

마지막으로 RoleArn에는 IAM 역할의 ARN을 지정합니다. 이건 Kendra가 S3에 접근할 수 있는 권한을 부여하는 것입니다.

마치 회사 출입증을 주는 것과 같습니다. 이 역할이 없으면 Kendra는 S3 버킷을 볼 수조차 없습니다.

실제 현업에서는 어떻게 활용할까요? 한 법률 회사에서는 수만 건의 판례 문서를 S3에 보관하고 있었습니다.

변호사들이 관련 판례를 찾으려면 수동으로 검색해야 했는데, 시간이 너무 오래 걸렸습니다. 그래서 S3를 Kendra의 데이터 소스로 추가했습니다.

이후 변호사들은 "부동산 관련 대법원 판례"처럼 자연어로 질문하면 관련 문서를 바로 찾을 수 있게 되었습니다. 업무 효율이 크게 향상되었죠.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수는 IAM 역할 권한을 너무 넓게 설정하는 것입니다.

예를 들어 S3의 모든 버킷에 접근할 수 있는 권한을 주면 보안 위험이 생깁니다. 따라서 최소 권한 원칙에 따라 필요한 버킷에만 접근 권한을 주어야 합니다.

다시 김개발 씨의 이야기로 돌아가 봅시다. 팀장님의 설명을 들은 김개발 씨는 노트북을 열고 코드를 작성하기 시작했습니다.

"이제 이해했어요. S3와 검색 엔진을 연결하는 거죠!" 데이터 소스를 제대로 추가하면 문서가 자동으로 동기화되어 검색 가능한 시스템을 구축할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - InclusionPatterns와 ExclusionPatterns를 활용해 불필요한 파일 인덱싱을 줄이세요

  • IAM 역할은 최소 권한 원칙에 따라 설정하세요
  • 데이터 소스 이름은 나중에 관리하기 쉽도록 의미 있는 이름으로 짓는 것이 좋습니다

4. 문서 동기화 실행

데이터 소스를 추가하고 나니 김개발 씨는 또 궁금해졌습니다. "그런데 팀장님, 데이터 소스를 만들었다고 바로 검색이 되나요?" 팀장님이 고개를 저었습니다.

"아니요, 아직 한 단계가 남았어요. 실제로 문서를 읽어서 인덱싱하는 동기화 작업을 실행해야 합니다."

문서 동기화는 S3 버킷의 모든 문서를 검색 엔진으로 가져와 인덱싱하는 과정입니다. 마치 도서관 사서가 새로 들어온 책들을 하나씩 분류하고 목록에 등록하는 작업과 같습니다.

동기화를 실행하면 시스템이 자동으로 각 문서의 내용을 분석하고 검색 가능한 형태로 변환합니다.

다음 코드를 살펴봅시다.

import boto3
import time

kendra_client = boto3.client('kendra', region_name='ap-northeast-2')

data_source_id = 'your-data-source-id'
index_id = 'your-kendra-index-id'

# 동기화 작업 시작
print("문서 동기화를 시작합니다...")
sync_response = kendra_client.start_data_source_sync_job(
    Id=data_source_id,
    IndexId=index_id
)

execution_id = sync_response['ExecutionId']
print(f"동기화 작업 ID: {execution_id}")

# 동기화 진행 상황 확인
while True:
    status_response = kendra_client.describe_data_source_sync_job(
        Id=data_source_id,
        IndexId=index_id,
        ExecutionId=execution_id
    )

    status = status_response['Status']
    print(f"현재 상태: {status}")

    if status in ['SUCCEEDED', 'FAILED', 'ABORTED']:
        break

    time.sleep(30)  # 30초마다 확인

print("동기화 완료!")

김개발 씨는 컴퓨터 앞에 앉아 코드를 실행했습니다. 화면에 "문서 동기화를 시작합니다..."라는 메시지가 떴습니다.

그런데 곧바로 "동기화 완료!"가 뜨지 않고 "현재 상태: SYNCING"이라는 메시지가 계속 반복되었습니다. "왜 이렇게 오래 걸리죠?" 옆자리의 박시니어 씨가 커피를 마시며 말했습니다.

"문서가 많으면 시간이 꽤 걸려요. 시스템이 각 문서를 하나씩 열어서 내용을 읽고 분석해야 하니까요.

마치 책 한 권 한 권을 읽고 요약하는 것과 같죠." 문서 동기화란 정확히 무엇일까요? 쉽게 비유하자면, 문서 동기화는 마치 이사 갈 때 짐을 새 집으로 옮기는 과정과 같습니다.

단순히 상자를 옮기는 게 아니라, 각 상자를 열어서 안에 뭐가 들었는지 확인하고, 적절한 위치에 배치하고, 나중에 쉽게 찾을 수 있도록 라벨을 붙이는 작업까지 포함됩니다. 시스템도 마찬가지로 각 문서를 읽고, 내용을 분석하고, 검색 인덱스에 등록합니다.

동기화가 없던 시절에는 어땠을까요? 과거에는 개발자가 직접 스크립트를 작성해서 파일 하나하나를 처리해야 했습니다.

S3에서 파일을 다운로드하고, 텍스트를 추출하고, 검색 엔진 API를 호출해서 등록하는 과정을 모두 수동으로 코딩했습니다. 파일이 수천 개가 되면 스크립트가 중간에 에러가 나기도 하고, 어디까지 처리했는지 추적하기도 어려웠습니다.

개발자가 밤새 모니터링해야 하는 경우도 많았죠. 바로 이런 문제를 해결하기 위해 자동화된 동기화 시스템이 등장했습니다.

동기화 작업을 시작하면 시스템이 알아서 모든 문서를 처리합니다. 중간에 에러가 나도 자동으로 재시도하고, 어떤 파일이 성공했고 어떤 파일이 실패했는지 로그를 남깁니다.

무엇보다 병렬 처리를 통해 여러 문서를 동시에 처리하므로 속도가 훨씬 빠릅니다. 위의 코드를 단계별로 살펴보겠습니다.

먼저 start_data_source_sync_job 메서드로 동기화 작업을 시작합니다. 이 메서드는 즉시 반환되며, 실제 작업은 백그라운드에서 비동기적으로 실행됩니다.

마치 세탁기 돌리기 버튼을 누르면 바로 세탁이 시작되지만, 우리는 다른 일을 할 수 있는 것과 같습니다. 반환된 ExecutionId는 이 동기화 작업의 고유 식별자입니다.

나중에 이 ID로 작업 상태를 조회할 수 있습니다. 다음으로 while True 루프에서 동기화 상태를 주기적으로 확인합니다.

describe_data_source_sync_job 메서드로 현재 상태를 가져오는데, 상태는 여러 가지가 있습니다. SYNCING은 현재 작업 중이라는 뜻이고, SUCCEEDED는 성공적으로 완료되었다는 뜻입니다.

FAILEDABORTED는 뭔가 문제가 생긴 경우입니다. 30초마다 한 번씩 확인하는 이유는 AWS API 호출 제한 때문입니다.

너무 자주 호출하면 요청이 거부될 수 있으므로 적절한 간격을 두는 것이 좋습니다. 실제 현업에서는 어떻게 활용할까요?

한 온라인 교육 플랫폼에서는 매일 밤 12시에 자동으로 동기화 작업을 실행하도록 설정했습니다. 낮 동안 강사들이 업로드한 새 강의 자료들이 밤사이 자동으로 인덱싱되어, 다음 날 아침에는 학생들이 바로 검색할 수 있었습니다.

이런 자동화 덕분에 운영팀의 업무 부담이 크게 줄었습니다. 또 다른 회사에서는 EventBridge를 사용해 S3에 새 파일이 업로드될 때마다 자동으로 동기화를 트리거하도록 구성했습니다.

실시간에 가까운 검색 경험을 제공할 수 있었죠. 하지만 주의할 점도 있습니다.

초보 개발자들이 흔히 하는 실수는 동기화 작업이 완료되기 전에 다음 작업을 시작하는 것입니다. 동기화는 시간이 걸리는 작업이므로 비동기로 처리해야 합니다.

위 코드처럼 상태를 확인하는 루프를 두거나, 콜백 함수를 사용하는 것이 좋습니다. 또한 대용량 문서가 많으면 비용도 고려해야 합니다.

Kendra는 인덱싱한 문서 수와 검색 쿼리 수에 따라 요금이 부과되므로, 불필요한 파일은 제외하는 것이 좋습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

한참을 기다리던 김개발 씨의 화면에 마침내 "동기화 완료!"라는 메시지가 떴습니다. 박시니어 씨가 옆에서 말했습니다.

"이제 검색해 보세요. 문서들이 다 인덱싱되어 있을 거예요." 문서 동기화를 제대로 실행하면 S3의 모든 문서를 검색 가능한 상태로 만들 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 동기화는 시간이 걸리는 작업이므로 비동기로 처리하세요

  • 초기 동기화 후에는 증분 동기화를 활용해 변경된 파일만 처리하세요
  • CloudWatch 로그를 확인하면 동기화 실패 원인을 파악할 수 있습니다

5. 동기화 상태 확인

동기화가 끝나고 김개발 씨는 팀장님께 보고했습니다. "팀장님, 동기화가 완료되었습니다!" 그런데 팀장님이 물었습니다.

"몇 개의 문서가 성공했고, 혹시 실패한 건 없나요?" 김개발 씨는 당황했습니다. "어...

그건 어떻게 확인하죠?"

동기화 상태 확인은 동기화 작업이 얼마나 진행되었는지, 몇 개의 문서가 성공했고 실패했는지를 파악하는 과정입니다. 단순히 작업이 완료되었는지만 아는 것이 아니라, 상세한 메트릭과 에러 로그를 확인해야 문제를 빠르게 해결할 수 있습니다.

다음 코드를 살펴봅시다.

import boto3
from datetime import datetime

kendra_client = boto3.client('kendra', region_name='ap-northeast-2')

data_source_id = 'your-data-source-id'
index_id = 'your-kendra-index-id'
execution_id = 'your-execution-id'

# 동기화 작업 상세 정보 조회
sync_job = kendra_client.describe_data_source_sync_job(
    Id=data_source_id,
    IndexId=index_id,
    ExecutionId=execution_id
)

# 상세 정보 출력
print("=" * 50)
print("동기화 작업 상세 정보")
print("=" * 50)
print(f"상태: {sync_job['Status']}")
print(f"시작 시간: {sync_job['StartTime']}")
print(f"종료 시간: {sync_job.get('EndTime', '진행 중')}")

# 메트릭 정보
metrics = sync_job.get('Metrics', {})
print(f"\n처리된 문서: {metrics.get('DocumentsAdded', 0)}개")
print(f"수정된 문서: {metrics.get('DocumentsModified', 0)}개")
print(f"삭제된 문서: {metrics.get('DocumentsDeleted', 0)}개")
print(f"실패한 문서: {metrics.get('DocumentsFailed', 0)}개")

# 에러가 있으면 출력
if sync_job.get('ErrorMessage'):
    print(f"\n에러 메시지: {sync_job['ErrorMessage']}")

김개발 씨는 황급히 팀장님이 보내준 문서를 열어봤습니다. 거기에는 동기화 상태를 확인하는 방법이 적혀 있었습니다.

"아, 단순히 완료 여부만 보면 안 되는구나. 상세 정보를 확인해야 하는구나." 이시니어 씨가 옆에서 모니터를 가리키며 말했습니다.

"실무에서는 상태 확인이 정말 중요해요. 동기화가 완료되었다고 해서 다 성공한 건 아니거든요.

일부 파일은 실패했을 수도 있어요." 동기화 상태 확인이란 무엇일까요? 쉽게 비유하자면, 동기화 상태 확인은 마치 배송 추적과 같습니다.

택배를 주문하면 "배송 완료"만 보는 게 아니라, 언제 출발했고, 어디를 거쳐서, 몇 시에 도착했는지 확인하고 싶죠. 혹시 문제가 생겼다면 어디서 생긴 건지 알아야 조치를 취할 수 있습니다.

동기화도 마찬가지입니다. 상태 확인 없이 동기화만 실행하면 어떤 문제가 생길까요?

예전에 어떤 회사에서는 동기화 작업이 "완료"되었다고 보고했는데, 나중에 알고 보니 중요한 PDF 파일 100개가 인덱싱에 실패한 상태였습니다. 파일 크기가 너무 커서 처리하지 못한 건데, 로그를 확인하지 않아서 몇 주 동안 그 사실을 몰랐습니다.

고객들은 검색해도 문서가 안 나온다고 불평했고, 회사 이미지에 타격을 입었죠. 바로 이런 문제를 예방하기 위해 상세한 메트릭 확인이 필수입니다.

동기화 작업 정보를 조회하면 몇 개의 문서가 추가되었는지, 몇 개가 수정되었는지, 몇 개가 실패했는지 한눈에 알 수 있습니다. 실패한 문서가 있다면 에러 메시지를 통해 원인을 파악할 수 있습니다.

무엇보다 시작 시간과 종료 시간을 보면 동기화에 얼마나 시간이 걸렸는지 알 수 있어서 성능 최적화에도 도움이 됩니다. 위의 코드를 자세히 분석해 보겠습니다.

먼저 describe_data_source_sync_job 메서드로 동기화 작업의 상세 정보를 가져옵니다. 이 메서드는 작업 ID, 데이터 소스 ID, 인덱스 ID를 모두 필요로 합니다.

앞서 동기화를 시작할 때 받았던 ExecutionId를 여기서 사용합니다. 반환된 딕셔너리에는 많은 정보가 들어 있습니다.

Status는 현재 상태를, StartTimeEndTime은 작업이 언제 시작하고 끝났는지를 보여줍니다. 특히 Metrics 딕셔너리가 중요한데, 여기에 문서 처리 통계가 담겨 있습니다.

DocumentsAdded는 새로 추가된 문서 수입니다. 처음 동기화를 실행하면 모든 문서가 여기에 포함됩니다.

DocumentsModified는 이미 인덱싱되어 있었는데 내용이 바뀐 문서 수입니다. DocumentsDeleted는 S3에서 삭제되어 인덱스에서도 제거된 문서 수입니다.

가장 중요한 건 DocumentsFailed입니다. 이 값이 0이 아니라면 뭔가 문제가 생긴 것입니다.

파일이 손상되었거나, 형식이 지원되지 않거나, 크기가 너무 크거나 하는 이유로 실패할 수 있습니다. 이럴 때는 ErrorMessage를 확인해야 합니다.

실제 현업에서는 어떻게 활용할까요? 한 제약 회사에서는 매일 밤 동기화를 실행한 후, 상태를 확인해서 Slack으로 알림을 보내도록 설정했습니다.

실패한 문서가 있으면 즉시 담당자에게 알림이 가서 다음 날 아침에 바로 조치할 수 있었습니다. 또한 처리 시간을 모니터링해서 문서 양이 증가하면 인프라를 미리 확장하는 계획을 세울 수 있었습니다.

다른 회사에서는 CloudWatch 대시보드에 동기화 메트릭을 시각화했습니다. 시간대별로 어떤 문서가 많이 추가되는지, 실패율은 어떤지를 그래프로 볼 수 있어서 패턴을 파악하기 쉬웠습니다.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수는 메트릭만 보고 안심하는 것입니다.

예를 들어 1000개 문서 중 990개가 성공했다면 성공률이 99%로 보입니다. 하지만 실패한 10개가 가장 중요한 문서라면 어떨까요?

따라서 어떤 파일이 실패했는지 구체적으로 확인하는 것이 중요합니다. CloudWatch Logs를 확인하면 실패한 파일의 이름과 경로를 알 수 있습니다.

거기서 원인을 파악하고 파일을 수정한 후 재동기화를 실행하면 됩니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

코드를 실행한 김개발 씨는 결과를 보고 놀랐습니다. "아, 3개 파일이 실패했네요!" 에러 메시지를 확인하니 파일 크기가 너무 커서 실패한 것이었습니다.

팀장님이 만족스럽게 고개를 끄덕였습니다. "잘했어요.

이제 그 파일들을 분할해서 다시 업로드하면 되겠네요." 동기화 상태를 제대로 확인하면 문제를 빠르게 발견하고 해결할 수 있습니다. 여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - CloudWatch Logs에서 실패한 파일의 구체적인 정보를 확인하세요

  • 동기화 메트릭을 대시보드로 시각화하면 트렌드를 파악하기 쉽습니다
  • 실패율이 높다면 파일 형식이나 크기 제한을 확인해 보세요

6. 문서 업데이트 처리

며칠 후, 김개발 씨는 또 다른 문제에 직면했습니다. 마케팅 팀에서 제품 소개서를 수정했는데, 검색 결과에는 여전히 이전 내용이 나오는 것이었습니다.

"팀장님, 문서를 수정하면 어떻게 해야 하나요?" 팀장님이 답했습니다. "아, 업데이트 처리를 설정해야 해요."

문서 업데이트 처리는 S3의 파일이 수정되거나 삭제될 때 자동으로 검색 인덱스를 갱신하는 메커니즘입니다. 마치 도서관에서 책의 개정판이 나오면 목록을 업데이트하는 것처럼, 시스템도 변경 사항을 자동으로 감지해 인덱스를 최신 상태로 유지합니다.

다음 코드를 살펴봅시다.

import boto3
import json

s3_client = boto3.client('s3')
lambda_client = boto3.client('lambda')

bucket_name = 'company-documents-2025'

# S3 이벤트 알림 설정 - 파일 변경 감지
notification_config = {
    'LambdaFunctionConfigurations': [
        {
            'LambdaFunctionArn': 'arn:aws:lambda:ap-northeast-2:123456789012:function:TriggerSync',
            'Events': ['s3:ObjectCreated:*', 's3:ObjectRemoved:*'],  # 생성/삭제 이벤트
            'Filter': {
                'Key': {
                    'FilterRules': [
                        {'Name': 'suffix', 'Value': '.pdf'},
                        {'Name': 'suffix', 'Value': '.docx'}
                    ]
                }
            }
        }
    ]
}

# 버킷에 알림 설정 적용
s3_client.put_bucket_notification_configuration(
    Bucket=bucket_name,
    NotificationConfiguration=notification_config
)

print("S3 이벤트 알림이 설정되었습니다.")
print("이제 파일 변경 시 자동으로 동기화가 실행됩니다.")

김개발 씨는 마케팅 팀의 요청을 받고 고민에 빠졌습니다. 문서가 수정될 때마다 수동으로 동기화를 실행해야 한다면 너무 번거로울 것 같았습니다.

"하루에도 수십 개 파일이 수정되는데, 그걸 일일이 감시할 수는 없잖아요?" 이시니어 씨가 옆에서 말했습니다. "걱정 마세요.

AWS에는 이벤트 기반 자동화라는 멋진 기능이 있어요. S3에서 파일이 변경되면 자동으로 Lambda 함수가 실행되고, 그 함수가 동기화를 트리거하는 거죠." 문서 업데이트 처리란 정확히 무엇일까요?

쉽게 비유하자면, 문서 업데이트 처리는 마치 스마트홈의 자동화와 같습니다. "현관문이 열리면 자동으로 거실 불을 켠다"처럼 조건과 동작을 설정해 두면, 시스템이 알아서 처리합니다.

S3도 마찬가지입니다. "PDF 파일이 업로드되면 자동으로 동기화한다"라는 규칙을 설정하면, 개발자가 신경 쓰지 않아도 시스템이 알아서 작동합니다.

자동 업데이트가 없던 시절에는 어떤 문제가 있었을까요? 예전에는 문서가 수정되면 담당자가 수동으로 검색 시스템에 알려야 했습니다.

예를 들어 제품 가격이 변경된 카탈로그를 S3에 업로드한 후, 별도로 관리자 페이지에 접속해서 "재인덱싱" 버튼을 클릭해야 했습니다. 담당자가 깜빡하면 고객들은 잘못된 정보를 보게 되었죠.

심한 경우 몇 주 동안 구버전 문서가 검색 결과에 나오기도 했습니다. 바로 이런 문제를 해결하기 위해 이벤트 기반 자동 동기화가 등장했습니다.

S3 이벤트 알림을 설정하면 파일이 생성, 수정, 삭제될 때마다 자동으로 감지합니다. 감지된 이벤트는 Lambda 함수로 전달되고, Lambda 함수는 Kendra 동기화를 트리거합니다.

무엇보다 실시간에 가까운 속도로 업데이트가 반영되므로 사용자는 항상 최신 정보를 검색할 수 있습니다. 위의 코드를 단계별로 살펴보겠습니다.

먼저 notification_config 딕셔너리에 S3 이벤트 알림 설정을 정의합니다. 여기서 핵심은 LambdaFunctionConfigurations입니다.

이 설정은 "어떤 이벤트가 발생하면 어떤 Lambda 함수를 실행할지"를 지정합니다. Events 리스트에는 감지할 이벤트 유형을 나열합니다.

s3:ObjectCreated:*는 파일이 생성될 때를 의미하고, s3:ObjectRemoved:*는 파일이 삭제될 때를 의미합니다. 별표는 와일드카드로, 생성 방법이 PUT이든 POST든 멀티파트든 모두 감지한다는 뜻입니다.

Filter 섹션은 특정 조건을 만족하는 파일만 처리하도록 설정합니다. 여기서는 suffix를 사용해 .pdf.docx 파일만 감지합니다.

이미지 파일이나 로그 파일 같은 건 무시하는 거죠. 이렇게 하면 불필요한 Lambda 호출을 줄여 비용을 절약할 수 있습니다.

마지막으로 put_bucket_notification_configuration 메서드로 버킷에 이 설정을 적용합니다. 이제부터 S3는 조건에 맞는 이벤트가 발생할 때마다 Lambda 함수를 자동으로 호출합니다.

Lambda 함수 안에서는 어떤 작업을 할까요? Lambda 함수는 이벤트 정보를 받아서 어떤 파일이 변경되었는지 확인합니다.

그런 다음 Kendra의 start_data_source_sync_job을 호출해 동기화를 실행합니다. 전체 버킷을 동기화하는 대신, 변경된 파일만 업데이트하도록 설정할 수도 있습니다.

실제 현업에서는 어떻게 활용할까요? 한 언론사에서는 기자들이 작성한 기사를 S3에 저장했습니다.

기사가 수정될 때마다 자동으로 검색 인덱스가 업데이트되어, 독자들이 항상 최신 버전을 검색할 수 있었습니다. 특히 속보 상황에서는 몇 초 안에 수정 사항이 반영되어 정확한 정보를 빠르게 전달할 수 있었습니다.

다른 회사에서는 S3 이벤트를 SQS 큐로 보낸 후, 여러 개의 Lambda 함수가 병렬로 처리하도록 구성했습니다. 대량의 파일이 동시에 업로드되어도 빠르게 처리할 수 있었죠.

하지만 주의할 점도 있습니다. 초보 개발자들이 흔히 하는 실수는 순환 참조를 만드는 것입니다.

예를 들어 Lambda 함수가 S3에 결과 파일을 저장하는데, 그 저장 이벤트가 다시 Lambda를 트리거하면 무한 루프에 빠집니다. 따라서 필터 규칙을 신중하게 설정해서 처리할 파일과 무시할 파일을 명확히 구분해야 합니다.

또한 Lambda에는 실행 시간 제한(최대 15분)이 있으므로, 대용량 동기화 작업은 Step Functions나 ECS로 처리하는 것이 좋습니다. 다시 김개발 씨의 이야기로 돌아가 봅시다.

설정을 마친 김개발 씨는 테스트를 해봤습니다. PDF 파일 하나를 수정해서 S3에 업로드하니, 몇 초 후 자동으로 동기화가 실행되었습니다.

"와, 정말 자동으로 되네요!" 이시니어 씨가 웃으며 말했습니다. "이제 마케팅 팀이 문서를 마음대로 수정해도 걱정 없겠네요." 문서 업데이트 처리를 제대로 설정하면 항상 최신 상태의 검색 결과를 제공할 수 있습니다.

여러분도 오늘 배운 내용을 실제 프로젝트에 적용해 보세요.

실전 팁

💡 - 필터 규칙을 사용해 불필요한 Lambda 호출을 줄이세요

  • 순환 참조를 방지하기 위해 결과 파일은 다른 경로에 저장하세요
  • Lambda 실행 시간 제한을 고려해 대용량 작업은 다른 서비스를 사용하세요

이상으로 학습을 마칩니다. 위 내용을 직접 코드로 작성해보면서 익혀보세요!

#AWS#S3#DocumentSync#BucketManagement#CloudStorage

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.