본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 21. 09:08

검증 환경의 DB 데이터를 에스포트하여 로컬로 가져오는 작업을 AI에게 시켜보았다

요약

AWS VPC 내 RDS의 데이터를 로컬로 가져오는 번거로운 과정을 AI 에이전트(Antigravity)를 활용해 자동화한 사례입니다. AI는 기존의 S3 경유 방식 대신 SSH 터널링과 Docker를 활용한 직접 스트리밍 방식을 제안하여 훨씬 효율적으로 작업을 수행했습니다.

핵심 포인트

  • AI 에이전트를 활용한 복잡한 클라우드 인프라 작업 자동화
  • 기존 수동 절차(S3 경유)보다 효율적인 최적의 워크플로우 제안
  • SSH 터널링 및 Docker를 이용한 데이터 직접 스트리밍 방식 적용
  • 환경 변수와 설정 파일을 기반으로 한 AI의 자율적 문제 해결 능력

서론

검증 환경의 DB 데이터를 에스포트(Export)하여 로컬 PC로 가져오는――이라는, 수수하지만 가끔 발생하는 작업이 있습니다.

이것이 의외로 번거로웠습니다. 왜냐하면 DB(PostgreSQL)는 AWS의 RDS에서 동작하고 있으며, VPC 안에 있기 때문입니다. 로컬에서 직접 연결할 수 없기 때문에, 평소에는 다음과 같은 절차를 밟고 있었습니다.

  • 평소에는 꺼두는 배스천(bastion) EC2를 기동한다
  • 배스천 서버에 SSH로 로그인한다
  • 배스천에서 pg_dump로 RDS의 덤프(Dump)를 취득한다
  • 덤프를 S3에 업로드한다
  • 로컬 PC로 돌아와서 S3에서 다운로드한다
  • 용무가 끝나면 배스천 EC2를 정지한다

하나하나가 어렵지는 않지만, 단계가 많고 게다가 매번 절차를 기억해내는 것부터 시작해야 합니다. 배스천은 사용할 때만 기동하고 끝나면 끄는 운용을 하고 있기 때문에, 그 기동·정지도 잊지 않고 수행해야 합니다. 이번에는 이것을 통째로 AI 에이전트(AI Agent)에게 맡겨보았습니다.

맡긴 것은 Antigravity입니다. 2900엔 플랜을 계약하고 있지만, 별로 사용하지 않고 있습니다. 사용하지 않으면 아깝다는 생각이 들어서, 이런 작업에 사용할 수 있을지 시험해 보았습니다.

결론부터 말하자면, 문제없이 가져올 수 있었습니다. 게다가 제가 항상 하던 절차를 그대로 따라 하는 것이 아니라, 훨씬 효율적인 방법을 구성하여 작업해 주어서 솔직히 "대단하다-"며 놀랐기에 그 기록을 남겨둡니다.

하고 싶었던 것

하고 싶었던 것은 심플하며,

  • VPC 내의 RDS(검증 환경)에서 동작하는 PostgreSQL의 데이터를 에스포트한다
  • 그 덤프 파일을 로컬 PC로 가져온다

라는, 단지 그것뿐입니다. 다만, 직접 하면 중간에 "배스천 경유"와 "S3 경유"가 끼어들기 때문에 은근히 귀찮은 것이 실정이었습니다. 운영 환경이 아닌 검증 환경이므로, 다소 거칠게 처리해도 큰 사고로 이어지지는 않는다는 가벼움도 있었습니다.

AI에게 내린 지시

세세한 절차는 적지 않고, 대략 이런 느낌으로 부탁했습니다.

stag 환경의 데이터베이스에서 데이터를 에스포트해줘. 로컬 시험에 사용하고 싶어.

이것뿐입니다. 배스천의 호스트나 RDS의 엔드포인트(Endpoint)와 같은 정보는 이미 수중에 있는 설정 파일(또는 환경 변수)로부터 읽어올 수 있는 상태였기에, 그 부분은 알아서 해주겠지 하는 기대도 포함되어 있었습니다.

AI가 해준 것

그런데 AI는 제 절차를 그대로 따라 한 것이 아니었습니다. 지시를 내리자 제가 상정했던 것보다 훨씬 효율적이고, 또한 잘 생각된 방법을 구성하여 작업해 주었습니다.

대략 말하자면 "일회용 SSH 키와 EC2 Instance Connect(EIC)로 터널을 뚫고, 로컬의 Docker 컨테이너에서 직접 pg_dump를 하여, 그 출력을 Mac 위의 파일에 그대로 쓰는" 흐름입니다. S3를 거치지 않고, AWS에서 로컬로 데이터를 직접 스트리밍(Streaming)하고 있었습니다.

수동으로 한다면 다음과 같은 이미지입니다 (인스턴스 ID나 프로파일 이름, 내부 IP 등은 숨겼습니다).

1. 일시적인 SSH 키 쌍 생성

리포지토리의 루트에서 일회용 SSH 키를 생성합니다. 영구적인 키를 갖지 않고 매번 일회용으로 만드는 것이 안전하다는 생각입니다.

ssh-keygen -t ed25519 -N "" -f ./temp_key

2. DB 조작용 EC2 인스턴스 기동

평소에는 꺼두는 EC2 인스턴스를 기동하고, 기동 완료까지 기다립니다.

aws --profile myprofile ec2 start-instances --instance-ids i-xxxxxxxxxxxxxxxxx
aws --profile myprofile ec2 wait instance-running --instance-ids i-xxxxxxxxxxxxxxxxx

3. SSH 공개키 전송

생성한 공개키를 EC2 인스턴스에 전송합니다. EC2 Instance Connect를 통해 보내는 키의 유효 기간은 60초이며, 그 이후에는 무효화됩니다.

aws --profile myprofile ec2-instance-connect send-ssh-public-key \
--instance-id i-xxxxxxxxxxxxxxxxx \
--instance-os-user ec2-user \
...

4. SSH 터널 확립

백그라운드에서 SSH 터널을 구축합니다. 로컬의 15432 포트로의 액세스가 EIC Endpoint의 프록시를 경유하여 스테이징 RDS의 프라이빗 IP(10.x.x.x:5432)로 매핑됩니다.

ssh -i ./temp_key -N -L 15432:10.x.x.x:5432 \
-o "ProxyCommand=aws --profile myprofile ec2-instance-connect open-tunnel --instance-id i-xxxxxxxxxxxxxxxxx --remote-port 22" \
-o "StrictHostKeyChecking=no" \
...

※ 나중에 중단하기 위해, 이 SSH 프로세스의 PID를 기록해 둡니다.

5. SSM Parameter Store에서 인증 정보 가져오기

DB의 사용자 이름과 비밀번호는 코드나 설정에 직접 작성하지 않고, SSM Parameter Store에서 가져옵니다.

DB_USER=$(aws --profile myprofile ssm get-parameter --name "/myapp-stag/DB_USERNAME" --with-decryption --query "Parameter.Value" --output text)
DB_PASS=$(aws --profile myprofile ssm get-parameter --name "/myapp-stag/DB_PASSWORD" --with-decryption --query "Parameter.Value" --output text)

6. docker-compose로 덤프 실행

로컬의 db 서비스 컨테이너에서 pg_dump를 실행합니다. 컨테이너에서는 host.docker.internal:15432를 경유하여 터널에 접속합니다. 현재 디렉토리를 /workspace에 마운트했으므로, 출력은 그대로 Mac 상의 staging_dump.sql로 쓰여집니다.

docker-compose run --rm \
-v "$(pwd):/workspace" \
-e PGPASSWORD="$DB_PASS" \
...

이 때문에 데이터는 AWS에서 로컬 PC로 직접 스트리밍되고 있으며, S3 등에 한 번 저장하는 절차나 추가적인 다운로드 조작은 필요하지 않았습니다.

7. 뒷정리 (과금을 방지하기 위해 중요)

마지막으로, 열어둔 것들을 순서대로 닫아 나갑니다.

  • SSH 터널 프로세스를 중단한다 (kill로 기록해 둔 PID를 사용)
  • EC2 인스턴스를 중지한다
    aws --profile myprofile ec2 stop-instances --instance-ids i-xxxxxxxxxxxxxxxxx
  • 임시 SSH 키 파일을 삭제한다
    rm ./temp_key ./temp_key.pub

처음에 "어떤 인스턴스를 기동/중지할지", "어떤 RDS/어떤 DB를 대상으로 할지"를 확인하는 형태로 제시해 주었기에, 저는 "그대로 진행해 주세요(OK)"라고 답하기만 하면 되었습니다. 나머지는 이 일련의 과정을 알아서 진행해 주었습니다.

쓰기 작업이 끝난 후에도,

ls -lh staging_dump.sql
head -n 30 staging_dump.sql

와 같이 파일 크기와 내용의 앞부분을 체크하여, "덤프가 제대로 추출되었습니다"라고 보고까지 해주었습니다. 이 정도까지 해주니 저는 결과만 확인하면 되었습니다.

내 방식보다 훨씬 효율적이었다

저는 항상 "Bastion Host에서 pg_dump → S3에 업로드 → 로컬에서 S3로부터 다운로드"와 같이 파일을 두 번 복사하곤 했습니다. AI의 방식은 S3를 전혀 거치지 않고 터널을 통해 직접 Mac으로 쓰기 때문에,

  • S3 업로드/다운로드라는 2단계가 통째로 사라짐
  • 중계 파일이 S3에 남지 않으므로 뒷정리도 불필요
  • 쓰기가 끝난 시점에 이미 Mac 상에 파일이 존재함

과 같이 제 절차보다 훨씬 스마트했습니다. 솔직히 "그런 방법이 있었나" 싶었습니다.

어디에 놀랐는가

시킨 절차를 그대로 따르는 것이 아니라, 더 좋은 방법을 선택했다

가장 놀라웠던 점은 바로 이 부분이었습니다. 저는 내심 "평소처럼 Bastion Host(踏み台) + S3를 사용하는 절차를 수행해 주면 좋겠다" 정도로 생각하고 있었는데, AI는 그보다 더 효율적인 "SSH 터널(SSH Tunnel) + Docker를 이용한 직접 쓰기"를 선택했습니다.

"데이터를 에스포트(Export)하여 로컬로 가져온다"라는 목적만 전달했을 뿐인데, 그 목적을 달성하기 위한 "더 나은 경로"까지 고민해 주었습니다. 지시를 기계적으로 따라가는 것에 그치지 않는다는 것을 체감했습니다.

VPC 특유의 우회 경로를 스스로 메워주었다

VPC 내의 RDS에 로컬에서 직접 연결할 수 없다는 제약에 대해, EC2 Instance Connect로 터널을 구축하여 해결한다는 발상을 제가 지시하지 않았음에도 스스로 구성해 주었습니다. pg_dump의 접속 대상(host.docker.internal:15432)이나 Docker 마운트를 사용한 직접 쓰기 방식도 타당한 형태로 구현해 주었습니다.

보안 측면의 세심한 배려가 있었다

단순히 동작하기만 하면 되는 것이 아니라, 세세한 부분에서 안전한 방향을 선택했다는 점이 인상적이었습니다.

  • 일회용 SSH 키를 사용한다. 영구적인 키를 두지 않고, 매번 그 자리에서 생성한 뒤 작업이 끝나면 삭제한다.
  • 키의 유효 기간이 짧다. EC2 Instance Connect로 전송하는 공개 키는 60초 후에 무효화된다.
  • 인증 정보를 직접 작성하지 않는다. DB 사용자 이름과 비밀번호는 SSM Parameter Store에서 가져와서 파일이나 커맨드 히스토리(Command History)에 남지 않도록 한다.

이러한 부분들은 제가 수동으로 작업할 때 "번거롭다"는 이유로 생략하기 쉬운 부분들입니다. 이를 당연하다는 듯이 포함해 준 것이, 화려하진 않지만 가장 감탄했던 지점이었습니다.

뒷정리(중지·삭제)까지 포함해서 수행한다

수동 작업 시에는 덤프(Dump)를 성공시켜 안도하는 순간 EC2를 중지하는 것을 잊어 다음 날까지 계속 켜두는 실수를 몇 번이나 저지르곤 했습니다. AI는 터널 프로세스 중지, EC2 중지, 임시 키 삭제까지를 일련의 절차로 취급하기 때문에, 삭제 누락으로 인한 불필요한 과금이나 쓰레기 파일이 남지 않는다는 것도 장점이었습니다.

주의했던 점

편리하긴 했지만, 몇 가지 스스로 주의했던 점도 있습니다.

  • 대상은 검증 환경에 한정한다. 운영(Production) DB에 대해 같은 가벼운 마음으로 실행하는 것은 위험하므로, 이번에는 어디까지나 검증 환경으로 한정했습니다.
  • 뒷정리가 제대로 수행되었는지 확인한다. 과금 및 보안과 직결되므로, 터널 프로세스가 남아있지 않은지, EC2가 중지되었는지, 임시 키가 삭제되었는지는 제 눈으로 직접 확인했습니다(ps, 매니지먼트 콘솔, ls).
  • 최종 확인은 직접 한다. "가져올 수 있었습니다"라는 보고를 맹신하지 않고, 내려받은 파일의 크기와 내용물은 제 눈으로 직접 확인했습니다.

재현성을 높이기 위해 Agent Skill화 했다

여기까지 잘 진행된 것은 좋았지만, 한 가지 우려되는 점이 있었습니다. 이번 절차는 그 자리에서 AI가 구성해 준 것이라는 점입니다. 다음에 같은 일을 부탁했을 때, 다시 똑같이 효율적인 절차를 선택해 줄 것이라는 보장이 없습니다. 지시 방식이나 당시의 문맥에 따라 평소처럼 Bastion Host + S3 방식으로 돌아가 버릴지도 모릅니다.

이 작업은 앞으로도 반복할 것이기에, 어렵게 성공한 단계를 "일회용"으로 만드는 것은 아깝다고 생각했습니다. 그래서 이번 일련의 절차를 Agent Skill로 작성하여, 매번 동일한 절차를 재현할 수 있도록 했습니다.

한 작업은 단순했습니다. AI가 실행해 준 절차를 그대로 SKILL.md에 옮겨 적었을 뿐입니다.

---
name: export-staging-db
description: 스테이징 환경의 RDS에서 데이터를 에스포트하여 로컬로 가져오기
...

이렇게 해두면 다음부터는 "이 스킬을 사용해서 스테이징 DB를 에스포트해 줘"라고 부탁하는 것만으로도, 매번 흔들림 없이 동일한 절차를 밟아줄 것입니다. 인스턴스 ID나 프로파일 이름 같은 환경 고유 값도 스킬 측(또는 설정 파일)에 모아두면 지시는 더욱 짧아질 수 있다고 생각합니다.

Discussion

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0