IAM 역할 & 접근 제어
"서버에 AWS 서비스 사용 권한을 안전하게 부여하자"
학습 목표
- Access Key를 코드에 넣으면 안 되는 이유를 이해한다
- IAM 정책(Policy), 역할(Role), 인스턴스 프로파일(Instance Profile)의 관계를 이해한다
- S3, DynamoDB 접근을 위한 IAM 역할을 생성하고 EC2에 연결한다
- EC2에서 Access Key 없이 AWS 서비스에 접근할 수 있는지 확인한다
왜 IAM Role이 필요한가?
Access Key를 .env에 넣으면 왜 위험한가?
AWS 서비스(S3, DynamoDB 등)를 사용하려면 인증이 필요합니다. 가장 단순한 방법은 Access Key(액세스 키 ID + 시크릿 키)를 발급받아 코드나 환경변수에 넣는 것입니다. 하지만 이 방법은 매우 위험합니다.
- 코드 유출 시 즉시 해킹 - .env 파일이나 소스코드에 키가 있으면, 코드가 유출되는 순간 해커가 여러분의 AWS 계정을 마음대로 사용할 수 있습니다. 실제로 매년 수많은 기업이 이 방식으로 해킹당합니다.
- GitHub에 실수로 올릴 수 있음 - .gitignore를 설정하더라도 실수는 일어납니다. GitHub에 Access Key가 올라가면 수 분 내에 봇이 발견하고 악용합니다. AWS도 GitHub을 스캔해서 노출된 키를 자동 비활성화할 정도로 흔한 사고입니다.
- 키 로테이션이 어려움 - Access Key를 바꾸려면 키를 사용하는 모든 서버, 모든 코드를 찾아서 교체해야 합니다. 서버가 10대면 10번, 100대면 100번 바꿔야 합니다.
그럼 어떻게 해야 할까? - IAM Role!
AWS가 제공하는 안전한 방법이 바로 IAM 역할(IAM Role)입니다. IAM 역할을 EC2에 연결하면, EC2 안에서 실행되는 코드가 별도의 Access Key 없이 자동으로 AWS 서비스에 접근할 수 있습니다.
| Access Key (집 열쇠 복사) | IAM Role (지문인식) | |
|---|---|---|
| 방식 | 열쇠를 복사해서 들고 다님 | 지문으로 인증 (본인만 사용 가능) |
| 분실 위험 | 잃어버리면 아무나 들어감 | 도난 불가 (지문은 복사 불가) |
| 관리 | 열쇠 바꾸면 복사본 전부 교체 | 중앙에서 권한만 변경하면 끝 |
| 추적 | 누가 열쇠를 쓰는지 모름 | 누가 문을 열었는지 정확히 기록 |
IAM Role은 지문인식과 같습니다. EC2 인스턴스 본인만 사용할 수 있고, 유출되거나 도난당할 위험이 없습니다. AWS SDK(Node.js의 aws-sdk 등)는 EC2에 IAM Role이 연결되어 있으면 자동으로 역할의 임시 자격증명을 사용합니다. 코드를 한 줄도 바꿀 필요가 없습니다.
AWS SDK는 다음 순서로 자격증명을 찾습니다:
- 환경변수 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
- 공유 자격증명 파일 (~/.aws/credentials)
- EC2 인스턴스 메타데이터 (= IAM Role) ← 우리가 사용할 방식
EC2에 IAM Role이 연결되어 있으면 SDK가 자동으로 3번 방식을 사용합니다. 별도의 코드 변경이 필요 없습니다.
IAM 핵심 개념
세 가지 구성 요소
IAM 역할을 EC2에 연결하려면 세 가지 개념을 이해해야 합니다.
"DynamoDB에 접근 가능"
신뢰 엔터티: EC2 서비스
Access Key 없이 S3, DynamoDB 사용
JSON 형식으로 작성된 권한 규칙 문서입니다. "어떤 서비스의 어떤 작업을 허용/거부할 것인가"를 정의합니다.
- AmazonS3FullAccess - S3의 모든 작업 허용 (AWS 관리형 정책)
- AmazonDynamoDBFullAccess - DynamoDB의 모든 작업 허용 (AWS 관리형 정책)
참고: Chapter 7(보안 강화)에서 FullAccess를 최소 권한 정책으로 변경합니다.
역할은 신뢰할 수 있는 엔터티(Trusted Entity)를 지정합니다. 우리의 경우 "EC2 서비스"를 신뢰 엔터티로 지정하면, EC2 인스턴스가 이 역할을 맡을(assume) 수 있습니다.
역할에 정책을 연결하면, 해당 역할을 맡은 EC2가 정책에 정의된 권한을 갖게 됩니다.
IAM 역할을 EC2에 연결하는 실제 메커니즘이 인스턴스 프로파일입니다. 회사에서 사원증을 만들어서 직원에게 건네주는 것과 같습니다.
- 웹 콘솔에서 역할을 만들면 같은 이름의 인스턴스 프로파일이 자동 생성됩니다
- CLI에서는 인스턴스 프로파일을 별도로 만들고 역할을 추가해야 합니다
IAM을 회사 출입 시스템에 비유하면 이해하기 쉽습니다:
- IAM 정책 = 출입 권한 규칙 ("3층 서버실 출입 가능", "2층 회의실 출입 가능")
- IAM 역할 = 직급/직무 ("백엔드 개발자" 역할에 서버실+회의실 권한 부여)
- 인스턴스 프로파일 = 사원증 (실제로 직원에게 건네주는 출입증)
- EC2 = 직원 (사원증을 걸면 허용된 구역에 출입 가능)
실습: IAM 역할 생성 & EC2에 연결
- Chapter 2에서 생성한 EC2 인스턴스가 실행 중이어야 합니다
- 리전이 ap-northeast-2 (서울)인지 확인하세요
- IAM은 글로벌 서비스이지만, EC2 연결은 해당 리전에서 수행합니다
EC2가 S3에 접근할 수 있도록 AmazonS3FullAccess 정책을 사용합니다. 이 정책은 AWS가 미리 만들어둔 관리형 정책(Managed Policy)이므로 별도로 생성할 필요 없이 역할에 연결만 하면 됩니다.
IAM 콘솔에서 AmazonS3FullAccess 정책이 있는지 확인하세요.
경로: IAM 콘솔 > 정책 > 검색: "AmazonS3FullAccess"
지금은 실습 진행을 위해 FullAccess 정책을 사용합니다. Chapter 7(보안 강화)에서 필요한 최소 권한만 허용하는 커스텀 정책으로 교체할 예정입니다. 실무에서는 처음부터 최소 권한 원칙을 적용해야 합니다.
IAM 콘솔 > 왼쪽 메뉴 "정책" > 검색창에 "S3Full" 입력 > AmazonS3FullAccess가 나타나면 성공입니다.
정책을 클릭하면 JSON으로 어떤 권한이 포함되어 있는지 확인할 수 있습니다.
EC2가 DynamoDB에 접근할 수 있도록 AmazonDynamoDBFullAccess 정책도 함께 사용합니다.
IAM 콘솔에서 AmazonDynamoDBFullAccess 정책이 있는지 확인하세요.
경로: IAM 콘솔 > 정책 > 검색: "AmazonDynamoDBFullAccess"
검색창에 "DynamoDBFull" 입력 > AmazonDynamoDBFullAccess가 나타나면 됩니다.
이제 EC2가 사용할 IAM 역할을 생성합니다. 다음 설정으로 역할을 만드세요:
| 항목 | 설정값 |
|---|---|
| 신뢰할 수 있는 엔터티 유형 | AWS 서비스 |
| 사용 사례 (Use case) | EC2 |
| 연결할 정책 1 | AmazonS3FullAccess |
| 연결할 정책 2 | AmazonDynamoDBFullAccess |
| 역할 이름 | ShopEasy-EC2-Role |
경로: IAM 콘솔 > 역할 > 역할 생성
- IAM 콘솔 > 왼쪽 메뉴 "역할" > "역할 생성" 클릭
- 1단계 - 신뢰할 수 있는 엔터티: "AWS 서비스" 선택, 서비스에서 "EC2" 선택 > 다음
- 2단계 - 권한 추가: 검색창에서 "AmazonS3FullAccess" 검색하여 체크, "AmazonDynamoDBFullAccess" 검색하여 체크 > 다음
- 3단계 - 이름:
ShopEasy-EC2-Role입력 > "역할 생성" 클릭
생성한 역할을 Chapter 2에서 만든 EC2 인스턴스에 연결합니다. 이것이 바로 인스턴스 프로파일을 EC2에 걸어주는 작업입니다.
경로: EC2 콘솔 > 인스턴스 > 인스턴스 선택 > 작업 > 보안 > IAM 역할 수정
IAM 역할은 실행 중인 EC2에 바로 연결할 수 있습니다. 인스턴스를 중지하거나 재부팅할 필요가 없습니다.
- EC2 콘솔로 이동 (리전: ap-northeast-2)
- 왼쪽 메뉴 "인스턴스" 클릭
- ShopEasy EC2 인스턴스 선택 (체크박스)
- 상단 "작업" 버튼 > "보안" > "IAM 역할 수정" 클릭
- 드롭다운에서
ShopEasy-EC2-Role선택 - "IAM 역할 업데이트" 클릭
EC2에 SSH로 접속한 후, AWS CLI로 S3에 접근할 수 있는지 확인합니다. Access Key를 설정하지 않았는데도 IAM Role 덕분에 자동으로 인증됩니다.
# EC2에 SSH 접속 후 실행
aws s3 ls
S3 버킷 목록이 출력되거나, 버킷이 없는 경우 빈 결과가 나오면 성공입니다. "Unable to locate credentials" 에러가 나오면 IAM 역할이 제대로 연결되지 않은 것입니다.
AWS CLI가 설치되어 있지 않다면 먼저 설치해야 합니다:
# Amazon Linux 2023의 경우 AWS CLI가 기본 설치되어 있음
aws --version
# 설치되어 있지 않다면
sudo yum install -y aws-cli
IAM 역할 연결 후 적용까지 몇 분 정도 걸릴 수 있습니다. 에러가 나면 1-2분 후 다시 시도하세요.
현재 EC2가 어떤 IAM 역할을 사용하고 있는지 확인합니다.
aws sts get-caller-identity 명령어를 사용합니다.
# EC2에 SSH 접속 후 실행
aws sts get-caller-identity
출력 결과에서 다음 내용을 확인하세요:
- Arn 필드에
ShopEasy-EC2-Role이 포함되어 있어야 합니다 assumed-role/ShopEasy-EC2-Role/형태로 표시됩니다
정상적인 출력 예시:
{
"UserId": "AROA...:i-0abcdef1234567890",
"Account": "123456789012",
"Arn": "arn:aws:sts::123456789012:assumed-role/ShopEasy-EC2-Role/i-0abcdef1234567890"
}
Arn에 assumed-role/ShopEasy-EC2-Role이 보이면 성공입니다.
이는 EC2가 ShopEasy-EC2-Role 역할을 성공적으로 맡고(assume) 있다는 뜻입니다.
확인 사항
다음 항목을 모두 완료했는지 확인하세요:
- IAM 콘솔에서 AmazonS3FullAccess 정책 확인 완료
- IAM 콘솔에서 AmazonDynamoDBFullAccess 정책 확인 완료
- IAM 역할 ShopEasy-EC2-Role 생성 완료 (신뢰 엔터티: EC2, 정책 2개 연결)
- EC2 인스턴스에 ShopEasy-EC2-Role 연결 완료
- EC2에서
aws s3 ls명령어 성공 (권한 에러 없음) - EC2에서
aws sts get-caller-identity로 역할 확인 완료
- 절대로 Access Key를 코드나 .env 파일에 넣지 마세요
- EC2에서 AWS 서비스를 사용할 때는 항상 IAM Role을 사용하세요
- 처음에는 FullAccess로 시작하더라도, 운영 전 반드시 최소 권한 원칙을 적용하세요
- IAM 역할 이름은 용도를 알 수 있게 작성하세요 (예: ShopEasy-EC2-Role)
이제 EC2가 S3와 DynamoDB에 접근할 수 있는 권한을 갖게 되었습니다. Chapter 5에서는 실제로 S3 버킷과 DynamoDB 테이블을 만들고, ShopEasy 앱의 리뷰 이미지를 S3에 저장하고, 리뷰 데이터를 DynamoDB에 저장하는 실습을 진행합니다.