AWS EC2 IAM Role 설정: Access Key 없이 Spring Boot에서 S3 접근하기
Spring Boot 애플리케이션이 EC2에서 S3를 사용해야 할 때 application.yml에 Access Key를 넣는 경우가 있습니다. 처음에는 간단하지만 키 유출, 교체 누락, 여러 서버에 대한 재배포 문제가 생깁니다.
EC2에서는 장기 Access Key를 저장할 필요가 없습니다. 인스턴스에 IAM Role을 연결하면 AWS SDK가 임시 자격 증명을 자동으로 가져오고 만료 전에 갱신합니다.
이번 글에서는 EC2의 Spring Boot 애플리케이션이 Access Key 없이 S3에 접근하는 구조와 설정 방법을 설명합니다.
Access Key를 서버에 저장하면 생기는 문제
다음 설정은 동작할 수 있지만 운영 환경에서는 피해야 합니다.
aws:
access-key: AKIA...
secret-key: ...
설정 파일이 Git에 올라가거나 로그·백업 파일에 남으면 자격 증명이 노출됩니다. 키를 교체할 때마다 모든 서버의 설정도 바꿔야 합니다.
IAM Role은 EC2에 권한을 연결하고 짧은 수명의 임시 자격 증명을 제공합니다. 애플리케이션은 실제 키를 보관하지 않고 AWS SDK를 통해 필요한 시점에 자격 증명을 가져옵니다.
| 구분 | IAM User Access Key | EC2 IAM Role |
|---|---|---|
| 자격 증명 수명 | 직접 교체하는 장기 키 | 자동 갱신되는 임시 키 |
| 서버 저장 | 환경 변수나 설정 파일 필요 | 저장하지 않음 |
| 권한 변경 | 키 사용자와 배포 환경 확인 필요 | Role 정책 변경으로 반영 |
| 운영 권장도 | 예외적인 상황에만 사용 | EC2 워크로드의 기본 선택 |
AWS도 가능한 경우 장기 키보다 IAM Role의 임시 자격 증명을 사용하도록 권장합니다.
EC2 IAM Role의 동작 과정
전체 흐름은 다음과 같습니다.
Spring Boot
↓ AWS SDK 기본 자격 증명 공급자
EC2 Instance Metadata Service
↓ 임시 자격 증명
EC2 Instance Profile
↓ 포함된 IAM Role의 권한
Amazon S3
EC2 콘솔에서 Role을 연결하면 Role을 담은 Instance Profile이 인스턴스에 연결됩니다. 임시 자격 증명은 만료되지만 AWS SDK가 주기적으로 갱신합니다.
S3 접근 정책은 필요한 경로만 허용한다
예제에서는 techcurrent-upload 버킷의 images/ 경로에 있는 객체만 읽고 쓰도록 허용합니다.
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadWriteImageObjects",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject"
],
"Resource": "arn:aws:s3:::techcurrent-upload/images/*"
}
]
}
버킷 전체에 s3:*를 허용하지 말고 애플리케이션이 사용하는 작업과 객체 접두사만 허용합니다.
객체 목록 조회가 필요하다면 s3:ListBucket을 버킷 ARN에 별도 추가해야 합니다. 객체 작업의 리소스는 버킷/*, 버킷 작업의 리소스는 버킷이므로 구분해야 합니다.
EC2에 Role 연결하기
AWS 콘솔에서는 다음 순서로 설정합니다.
- IAM에서 신뢰할 서비스가
EC2인 Role을 생성합니다. - 앞에서 만든 최소 권한 정책을 Role에 연결합니다.
- EC2 인스턴스의
Actions → Security → Modify IAM role을 선택합니다. - 생성한 Role을 연결합니다.
Auto Scaling을 사용한다면 시작 템플릿에도 Instance Profile을 설정해야 새 인스턴스가 같은 권한을 받습니다.
Spring Boot에서는 Access Key 코드를 제거한다
AWS SDK for Java 2.x는 클라이언트를 builder().build() 방식으로 만들면 기본 자격 증명 공급자 체인을 사용합니다.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
@Configuration(proxyBeanMethods = false)
public class AwsConfig {
@Bean
S3Client s3Client() {
return S3Client.builder()
.region(Region.AP_NORTHEAST_2)
.build();
}
}
코드에 StaticCredentialsProvider, Access Key, Secret Key를 넣지 않습니다. 로컬에서는 AWS_PROFILE=dev와 AWS SSO 또는 개발용 프로필을 사용하고, EC2에서는 Instance Profile의 Role이 선택됩니다.
연결 상태 확인하기
EC2에서 다음 명령으로 현재 호출 주체를 확인합니다.
aws sts get-caller-identity
응답 ARN에 연결한 Role 이름이 보이면 자격 증명 연결은 정상입니다. 허용한 S3 경로와 금지한 경로도 각각 테스트합니다.
Instance Metadata Service는 IMDSv2만 허용하는 것이 안전합니다. EC2 Metadata options에서 Http tokens를 required로 설정하면 IMDSv1 요청을 차단할 수 있습니다.
자주 발생하는 오류
| 증상 | 주요 원인 | 확인 방법 |
|---|---|---|
Unable to load credentials |
Role 또는 Instance Profile이 없음 | EC2의 IAM Role 연결 상태 확인 |
AccessDenied |
S3 작업이나 ARN 권한 부족 | 요청 Action과 객체 경로 비교 |
| 로컬에서는 되지만 EC2에서 실패 | 로컬 Access Key가 더 넓은 권한 보유 | get-caller-identity 결과 비교 |
| 새 인스턴스만 실패 | 시작 템플릿에 Instance Profile 누락 | Auto Scaling 시작 템플릿 확인 |
Role은 자격 증명을 전달하며 실제 허용 범위는 연결된 IAM 정책이 결정합니다.
핵심 요약
- EC2 애플리케이션에는 장기 Access Key를 저장하지 않습니다.
- EC2용 IAM Role과 Instance Profile로 임시 자격 증명을 제공합니다.
- AWS SDK 기본 자격 증명 공급자 체인을 사용하면 키 갱신을 자동 처리합니다.
- IAM 정책은 필요한 S3 Action과 객체 접두사만 허용합니다.
aws sts get-caller-identity로 실제 실행 주체를 확인합니다.- EC2의 Instance Metadata Service는 IMDSv2만 허용하는 편이 안전합니다.
마무리
EC2에서 AWS 서비스에 접근할 때 핵심은 키를 안전하게 보관하는 방법이 아니라 장기 키 자체를 배포하지 않는 것입니다.
Spring Boot 코드에서는 기본 자격 증명 공급자 체인을 사용하고, EC2에는 최소 권한 IAM Role을 연결해야 합니다. 이 구조를 적용하면 자격 증명 유출 위험과 수동 교체 작업을 함께 줄일 수 있습니다.
함께 읽기:
공식 자료:
최종 확인: 2026-07-29
'ETC > AWS' 카테고리의 다른 글
| AWS Lambda MicroVM, AI 생성 코드 안전하게 실행하는 법 (0) | 2026.07.24 |
|---|---|
| S3 Presigned URL로 파일 업로드 구현 (0) | 2026.07.17 |
| AWS RDS vs EC2 직접 설치, DB 운영 방식 비교 (0) | 2026.07.10 |
| AWS EC2에 Spring Boot 배포하는 전체 흐름: 초보자를 위한 서버 배포 입문 (0) | 2026.06.25 |
| Amazon linux EC2 jenkins와 JDK 11 설치 (0) | 2022.08.18 |