본문으로 건너뛰기
모든 기록
트러블슈팅 / AWS EKS · IRSA · Spring Boot · Troubleshooting

라이브러리 버전 호환 이슈로 돌아본 EKS IRSA와 AWS Credentials Provider Chain

AWS EKS에 배포한 앱이 IRSA 대신 노드의 EC2 Role을 사용하던 문제를 SDK 버전 차이에서 찾아 해결한 경험

이 글에서 다루는 것
  1. 문제상황
  2. 문제 분석 과정
  3. 최종 해결 방법
  4. 마무리
  5. 참고

문제상황

AWS EKS에 배포한 앱이 배포 환경에서만 AWS Secrets Manager 접근이 불가하였습니다.

문제 분석 과정

로컬 테스트

우선 AWS Secrets Manager의 생성 여부와 오탈자를 확인하기 위해 로컬 환경에서 테스트를 진행했습니다. 개발 환경에서는 정상적으로 Secrets 값을 불러올 수 있었고, 로컬에서는 문제가 없음을 확인했습니다.

EKS pod에서의 IRSA 사용

EKS에 배포된 Pod가 IRSA를 통해 올바르게 Role을 Assume하는지 확인했습니다.

kubectl exec -it <pod-name> -n <namespace> -- aws sts get-caller-identity

실행 결과, 기대한 IAM Role로 정상적으로 Assume된 것을 확인할 수 있었습니다.

{
  "UserId": "AROAxxxxxxxxxxxx:sample-service-account",
  "Account": "<AWS_ACCOUNT_ID>",
  "Arn": "arn:aws:sts::<AWS_ACCOUNT_ID>:assumed-role/<IAM_ROLE_NAME>/sample-service-account"
}

Pod 레벨에서 IRSA가 정상적으로 작동하는 것을 확인한 후, 문제의 원인이 AWS IAM Trust Policy나 EKS 설정이 아니라 다른 부분에 있을 것으로 판단했습니다.

최종 해결 방법

AWS 리소스 설정과 EKS 환경 자체에는 문제가 없다는 것을 확인한 후, 애플리케이션 로그를 집중적으로 살펴보기 시작했습니다.

그 과정에서, 의도하지 않은 Assume Role이 사용되고 있다는 경고 로그를 발견했습니다!

2025-04-26T10:45:00.169Z  WARN 1 --- [xxx-yyy-api] [           main] i.a.c.s.AwsSecretsManagerPropertySources : Unable to load AWS secret from some-namespace/some-secrets-name. User: arn:aws:sts::123456789012:assumed-role/eks-ap-northeast-2-some-namespace-node/i-0e12345b6b789a012 is not authorized to perform: secretsmanager:GetSecretValue on resource: eks-namespace/xxx-yyy-api because no identity-based policy allows the secretsmanager:GetSecretValue action (Service: AWSSecretsManager; Status Code: 400; Error Code: AccessDeniedException; Request ID: 2613802c-661a-44b2-addd-fa5d3c2f9dc1; Proxy: null)

로그를 통해 애플리케이션이 Pod의 IRSA Role 대신 노드의 EC2 Role을 통해 SecretsManager에 접근하려 한다는 것을 알게 되었습니다.

Pod 자체에서는 IRSA Role을 사용하고 있었기 때문에, 문제를 바로 찾지 못하고 있던 중 팀장님께서 build.gradle.kts에서 Vulnerability Warning이 뜨는 라이브러리를 확인해보라고 조언해주셨습니다.

기존에 사용하던 라이브러리는 aws-java-sdk-core:1.12.395를 의존하고 있었고, AWS SDK for Java v1과 v2 간의 Default Credentials Provider Chain 동작 방식이 다르다는 점을 알게 되었습니다.

결국, SDK 버전 차이로 인해 IRSA Role보다 노드 Role이 먼저 사용되는 이슈가 발생했던 것입니다.

이를 해결하기 위해 io.awspring.cloud:spring-cloud-aws-starter-secrets-manager으로 교체하여 SDK 버전을 업그레이드하고 문제를 해결했습니다.

마무리

이번 트러블슈팅을 통해서 아래의 것들을 배울 수 있게 되었습니다:

이번 트러블슈팅을 통해 새로운 지식들을 얻게 되었지만, 라이브러리 버전 및 호환성 검토, 빌드 경고(Warnings) 확인과 같은 기본적인 부분을 소홀히 하여 쉽게 해결할 수 있었던 문제를 어렵게 돌아가게 된 점이 아쉬웠습니다.

특히, 최근 스터디하는 개발 서적에서 중요하다고 강조하던 기본 원칙들을 스스로 간과하고 있었다는 사실이 부끄럽게 느껴졌습니다.

이번 경험을 교훈 삼아, 앞으로는 이러한 실수를 반복하지 않기 위해 문제를 더 꼼꼼히 점검하고 기본을 철저히 지키려 합니다. :)

참고

트러블슈팅AWS EKSIRSASpring BootTroubleshooting
Markdown
다음으로 읽어볼 기록 ↗

검색마다 달라지는 Elasticsearch score (Bouncing Results)