읽는 데 9분
AWS Emulator로 옮길 CI, 실제 AWS에 남길 시험
AWS를 쓰는 자동 테스트(CI)를 로컬 환경으로 옮길 때, 초록색 성공 표시가 무엇을 확인했는지부터 정해야 해요. AWS Emulator는 자체 생성 키로 서명한 요청을 거부하지 않고, S3 저장소의 버킷 정책과 암호화 키 관리 서비스인 KMS의 키 정책도 검사하지 않아요. 로컬 API 시험의 성공을 권한 검증의 성공으로 쓰면 안 돼요.
AWS가 공개한 AWS Emulator는 계정 없이 AWS API를 로컬에서 시험하는 도구예요. Linux 패키지와 Windows·macOS용 Docker 실행 경로, Rust 테스트 안에 넣는 임베디드 모드를 제공해요. 기본 라이선스는 CC0-1.0이고 vendor/ 코드는 Apache-2.0이에요. 이 글은 실행 후기가 아니라 공식 문서들을 대조해 만든 CI 이관 판단 안내예요. 연결 설정은 서버 모드를 기준으로 설명해요.
어떤 시험부터 옮길까요
먼저 프로젝트가 호출하는 API 작업 목록을 만들어요. 프로젝트 호환성 문서는 이 목록을 평가 저장소의 manifest.jsonl과 대조하고, 사용할 릴리스의 서비스별 충실도 점수를 확인하라고 안내해요. 여기서 충실도는 실제 AWS 동작과 얼마나 일치하는지예요.
점수는 해당 서비스의 충실도 테스트 중 통과한 범위를 보여 줘요. 프로젝트가 쓰는 모든 동작을 포괄하지는 않아요. 시험 항목이 없는 동작은 미지원으로 단정할 수도 없고, 지원을 확인했다고 볼 수도 없어요. 공식 안내는 이런 동작을 에뮬레이터와 실제 AWS 양쪽에서 시험해 결과를 비교하라고 해요.
이 기준으로 나누면 이관 단위는 ‘S3를 쓰는 테스트 전부’가 아니라 ‘어떤 요청과 응답을 확인하는 테스트인가’가 돼요.

보안 문서에 따르면 일부 서비스는 에뮬레이터 안에서 만든 IAM 사용자와 역할의 정책을 평가해요. IAM은 사용자와 역할의 접근 권한을 관리하는 서비스예요. 다만 실제 AWS와 같은 방식이 아니에요. ‘IAM이 전혀 없다’고 이해하기보다, 허용과 거부의 판정을 맡길 수 없다고 이해하는 편이 정확해요. 계정이나 리전을 넘는 호출도 지원하지 않으므로 이 경계를 다루는 시험은 실제 AWS에 남겨야 해요.
연결 성공 전에 목적지부터 확인해요
공식 SDK 안내는 테스트를 실행하는 같은 스크립트에서 연결 변수를 설정하고 실제 자격증명을 제거하라고 해요. SDK는 앱에서 AWS를 호출하는 라이브러리예요. AWS_ENDPOINT_URL이 빠지면 코드는 발견한 자격증명으로 실제 AWS를 호출할 수 있어요.
자격증명 파일을 에뮬레이터용으로 바꿔도 환경 변수의 키가 우선해요. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_PROFILE이 남아 있는지 따로 확인해야 하죠. 실제 키로 서명하면 기본 인증이 켜진 에뮬레이터는 요청을 거부해요. 이 오류를 없애려고 인증을 끄기 전에, 어떤 키를 읽었는지부터 보는 게 순서예요.
공식 문서의 목적지 확인 예시는 aws sts get-caller-identity예요. 에뮬레이터에 도달했다면 계정은 000000000000, ARN은 arn:aws:iam::000000000000:user/emulator로 나와요. 다만 이 명령이 확인하는 것은 해당 셸의 CLI예요. 앱이 별도로 SDK 클라이언트를 구성한다면, CLI 결과만으로 앱의 모든 요청 목적지까지 확인했다고 볼 수는 없어요.
호스트 이름도 그대로 유지해야 해요. AWS_ENDPOINT_URL의 127.0.0.1을 localhost로 바꾸면 JavaScript·Java·Go SDK가 기본적으로 S3 버킷 이름을 호스트 앞에 붙여요. 에뮬레이터는 이 형식의 S3 요청을 받지 않아요. Cloud Map 같은 작업의 호스트 접두사도 별도 설정이 필요하고, S3 Control은 계정 ID 접두사를 끌 수 없어 요청이 에뮬레이터에 도달하지 못해요.
즉 연결 실패를 곧바로 API 미지원으로 분류하면 안 돼요. 사용 SDK의 주소 변경 규칙을 먼저 확인해야 해요.
CA 설정은 로컬 잡 안에 가둬요
에뮬레이터의 자체 인증서를 신뢰하도록 설정할 때, 같은 프로세스가 다른 HTTPS 서버에도 접속하는지가 판단 기준이에요. CA는 서버 인증서를 신뢰할지 결정하는 인증 기관 정보예요.
| 클라이언트 | 공식 로컬 연결 설정 | CI에서 함께 볼 범위 |
|---|---|---|
| AWS CLI v2, Boto3, Go v2 | AWS_CA_BUNDLE로 ca.pem 지정 |
기본 신뢰 인증서를 대체하므로 다른 HTTPS 연결도 필요하면 합친 인증서 묶음을 써요 |
| JavaScript v3의 Node.js | NODE_EXTRA_CA_CERTS로 ca.pem 지정 |
기본 인증서에 추가해요. 다른 SDK의 대체 방식과 달라요 |
| Java 2.x | JVM의 truststore를 truststore.p12로 지정 |
기본 truststore를 대체해요. 테스트 JVM에만 적용하는 편이 범위를 좁혀요 |
Java 예시의 JAVA_TOOL_OPTIONS는 그 셸에서 시작한 모든 JVM에 적용돼요. Gradle과 Maven도 포함되므로 테스트 밖 빌드 도구의 HTTPS 통신까지 바꿀 수 있어요. 공식 문서는 테스트 JVM에만 옵션을 전달하거나, 외부 HTTPS도 필요하면 기존 신뢰 저장소에 에뮬레이터 인증서를 추가한 사본을 쓰라고 안내해요. 인증서는 시작할 때마다 새로 생기므로 복사하거나 가져온 인증서도 갱신해야 해요.
연결용 설정은 실제 AWS 시험으로 가져가지 않아야 해요. 특히 AWS_DISABLE_HOST_PREFIX_INJECTION=true는 로컬 연결에는 필요할 수 있지만, AWS에서는 호스트 접두사를 쓰는 작업을 실패하게 해요. 제가 권하는 구성은 로컬용 테스트 작업과 실제 AWS용 테스트 작업을 나누고, 엔드포인트·자격증명·CA·호스트 접두사 설정을 로컬 작업에서만 주입하는 방식이에요. CI에서는 이런 실행 단위를 잡이라고 불러요.
함수 실행은 별도의 신뢰 경계예요
공식 보안 문서는 에뮬레이터가 함수 코드 등을 실행할 때 그 코드를 호스트와 격리하지 않는다고 명시해요. 코드는 실행 사용자의 권한으로 파일을 읽고 바꿀 수 있어요. 따라서 외부 기여자의 PR처럼 신뢰하지 않는 코드를 실행하는 CI라면, API 에뮬레이터를 도입했다는 이유로 코드 격리까지 해결됐다고 판단하면 안 돼요.
또 기본 API 주소가 루프백이라고 해도 같은 머신의 다른 사용자와 프로그램은 포트에 접근할 수 있어요. 데이터베이스 등 리소스별 별도 포트는 요청 서명 검사 없이 해당 리소스 자체의 인증에 의존해요. 공유 러너에 올릴 때는 메인 API의 서명 검사만으로 모든 포트가 보호된다고 보지 않아야 해요.
이관을 시작한다면, 테스트 데이터로 API 흐름을 확인하는 잡부터 충실도 범위를 대조해요. 권한 거부 시험은 실제 AWS에 남기고, SDK 설정의 적용 범위와 실행할 코드의 신뢰 조건을 따로 점검하면 돼요. Rust 임베디드는 주소·CA 설정이 필요 없지만 소스 빌드와 비슷한 첫 빌드 비용이 있어요. README가 요구하는 target/ 여유 공간도 최소 100GB이므로 모드 선택 때 함께 고려해야 해요.
확인한 범위
- 기준일: 2026-11-12
- 직접 한 것: README 및 기존 한국어 소개와 공식 보안·SDK 연결·프로젝트 호환성 문서를 대조해, 테스트 질문별 이관 판정과 SDK별 인증서 적용 범위를 정리했어요.
- 읽은 것: AWS Emulator README, 공식 문서 세 편, GeekNews의 같은 프로젝트 소개예요.
- 확인하지 못한 것: 에뮬레이터 실행, 실제 AWS와의 요청 대조, 개별 프로젝트의 호환성과 성능은 검증하지 않았어요. 위 표는 문서 기준의 이관 판단이며 실행 결과가 아니에요.
출처

보안과 호스트 실행 경계, SDK 목적지와 인증서 설정, 프로젝트 호환성 확인 절차를 함께 대조했어요. 기존 한국어 소개는 GeekNews에서 볼 수 있어요.


