OpenSearch Nori Plugin 설치 중 타임아웃·409·403 연속 발생
AWS OpenSearch에 Nori 플러그인 설치 중 Terraform 타임아웃, 409 Conflict, 403 Forbidden이 연속 발생했다. Blue/Green 배포 특성에 의한 타임아웃, 단일 설정 변경 제한에 의한 409, Access Policy 덮어쓰기에 의한 403이 각각의 원인이었다.
환경: AWS OpenSearch Service, Terraform, EKS 날짜: 2026-02-28
상황
검색 기능 강화를 위해 AWS OpenSearch Service에 한국어 형태소 분석기인 analysis-nori 플러그인을 설치해야 했다. Terraform으로 aws_opensearch_package_association 리소스 하나만 추가하면 끝날 것으로 예상했다. 실제로는 타임아웃, 리소스 충돌, API 접근 거부가 연달아 터졌다.
이 글에서는 세 가지 문제를 만나고 해결한 과정을 다룬다. 전체 흐름을 먼저 보면:
sequenceDiagram participant TF as Terraform participant AWS as OpenSearch (AWS) participant App as Application TF->>AWS: apply (Nori Association) AWS-->>AWS: Blue/Green 배포 시작 Note over AWS: 수십 분 소요 TF--xTF: 10분 타임아웃 → tainted TF->>AWS: destroy / re-apply 시도 AWS--xTF: 409 Conflict (배포 진행 중) AWS-->>AWS: Blue/Green 완료 + Access Policy 덮어쓰기 App->>AWS: curl /health (unsigned) AWS--xApp: 403 Forbidden (anonymous)
가설과 검증 과정
문제 1: Terraform 타임아웃 — “왜 10분 안에 안 끝나는가?”
terraform apply를 실행했지만, 10분이 지나자 Error: timeout으로 실패했다. 리소스 하나를 연결하는 작업이 왜 10분이 넘게 걸리는지 의아했다.
원인을 찾아보니, 패키지 연결(Association)이 도메인의 Blue/Green 배포를 트리거한다는 것을 알게 됐다. Blue/Green 배포란 새 노드를 띄우고 데이터를 옮긴 뒤 트래픽을 전환하는 방식인데, 데이터 양과 노드 규모에 따라 수십 분 이상 걸릴 수 있다. 플러그인을 “연결”하는 게 아니라 사실상 도메인 전체를 재배포하는 것이었고, Terraform의 기본 타임아웃(10분)으로는 부족한 것이었다.
여기서 중요한 건, Terraform은 타임아웃으로 실패 판정을 내리고 리소스를 tainted(다음 apply 시 삭제 후 재생성 대상)로 표시했지만, AWS 백그라운드에서는 Blue/Green 배포가 여전히 진행 중이었다는 점이다. Terraform과 AWS의 상태가 어긋나기 시작했고, 이것이 다음 문제의 씨앗이 됐다.
문제 2: 409 Conflict — “왜 재시도도 삭제도 안 되는가?”
Taint된 리소스를 정리하려고 terraform destroy와 재 apply를 시도했다. 이번엔 409 Conflict 에러가 발생했다.
AWS OpenSearch는 한 번에 하나의 설정 변경(Config Change)만 허용한다. 첫 번째 시도로 촉발된 Blue/Green 배포가 아직 끝나지 않았기 때문에, 추가적인 수정이나 삭제 요청이 전부 거부된 것이다.
이 상황에서 할 수 있는 건 기다리는 것뿐이었다. AWS 콘솔에서 도메인 상태가 Active로 돌아오는 것을 확인한 뒤, terraform untaint와 terraform apply -refresh-only로 Terraform 상태를 실제 AWS 상태와 동기화했다. 이 과정에서 배운 건, Terraform apply 실패가 곧 AWS 작업 실패가 아니라는 것이다. 둘의 상태가 어긋났을 때는 refresh-only로 먼저 동기화해야 한다.
문제 3: 403 Forbidden — “Nori가 뭔가를 깨뜨렸는가?”
Nori 플러그인 설치가 완료(Active)된 직후, 애플리케이션의 헬스 체크가 실패하며 Response Error가 발생했다. 세 번째 문제인데, 이번엔 Terraform이 아니라 애플리케이션 쪽이었다.
첫 반응은 “Nori 설치가 도메인 접근에 영향을 줬나?”였다. 검증을 위해 파드 내부에서 OpenSearch에 직접 요청을 보내봤다.
curl https://vpc-....es.amazonaws.com/
# 403 Forbidden
# "User: anonymous is not authorized ..."응답 메시지가 anonymous is not authorized였다. 이건 Nori와는 무관한, 인증(Authentication) 문제였다. Nori 플러그인은 검색 기능을 추가하는 것이지 접근 정책을 바꾸는 것이 아니다.
결과: 기각. 진짜 원인은 다른 곳에 있었다. Terraform은 선언적 도구이므로, apply 시 코드에 명시된 설정 전체를 AWS에 적용한다. tainted 리소스를 정리하려고 재 apply를 반복하는 과정에서 Access Policy가 코드의 기본값(root 계정만 허용)으로 덮어쓰여진 것이었다. 애플리케이션은 SigV4 서명 없이(Basic Auth로) 요청을 보내고 있었고, 엄격해진 Access Policy에 의해 anonymous로 분류되어 차단됐다.
해결 방법
타임아웃 해결
aws_opensearch_package_association 리소스에 timeouts { create = "60m" }을 명시적으로 설정했다. Blue/Green 배포 지연은 AWS의 구조적 특성이므로, Terraform이 이를 충분히 기다리도록 해야 한다.
403 해결
단기적으로는 Access Policy의 Principal을 *(모든 AWS 계정)로 열어 가용성을 확보했다. 보안은 Security Group(EKS Node, Bastion만 허용)과 FGAC(Basic Auth)로 유지된다. Principal을 여는 게 불안할 수 있지만, 네트워크 계층(SG)과 인증 계층(FGAC)이 독립적으로 동작하므로 한쪽을 열더라도 다른 계층이 여전히 통제한다.
장기적으로는 애플리케이션에 AWS SDK(SigV4) 서명 로직을 추가하여 IAM 기반 접근 제어로 전환하기로 했다. 코드 복잡도는 늘지만 보안이 강화되는 방향이다.
교훈
- 관리형 서비스의 설정 변경은 인프라 교체를 수반할 수 있다. 플러그인 하나 연결하는 것도 Blue/Green 배포를 트리거한다. Terraform
timeouts를 넉넉히 잡아야 하고, 409가 나오면 AWS 콘솔에서 도메인 상태부터 확인해라. - Terraform apply 실패가 곧 AWS 작업 실패가 아니다. Terraform은 타임아웃으로 실패 처리했지만 AWS는 계속 작업 중이었다. 관리형 서비스 작업 후 State 불일치가 생기면
refresh-only로 먼저 동기화해라. - 보안은 계층이다. 네트워크(SG)와 인증(IAM/FGAC)은 별개 계층이다. 한쪽을 열더라도 다른 계층이 통제하는 구조라야 안전하게 운영할 수 있다.