1. EC2 Instance Metadata (IMDS)
IMDS란?
- EC2 인스턴스가 자기 자신에 대한 정보를 조회할 수 있는 기능
- IAM Role 없이도 인스턴스 정보 조회 가능
- 개발자들에게 잘 알려지지 않았지만 매우 강력한 기능
접근 URL
http://169.254.169.254/latest/meta-dataMetadata vs Userdata
| 구분 | 설명 |
|---|---|
| Metadata | EC2 인스턴스에 대한 정보 |
| Userdata | EC2 인스턴스 시작 스크립트 |
조회 가능/불가능 항목
| 항목 | 조회 가능 여부 |
|---|---|
| IAM Role 이름 | ✅ 가능 |
| IAM Policy 내용 | ❌ 불가능 |
2. IMDSv1 vs IMDSv2
버전 비교
| 버전 | 방식 | 보안 |
|---|---|---|
| IMDSv1 | URL 직접 접근 | 기본 |
| IMDSv2 | 세션 토큰 기반 | 더 안전 |
IMDSv2 사용 방법 (2단계)
# 1단계: 세션 토큰 획득 (PUT 요청 + 헤더)
TOKEN=$(curl -X PUT "http://169.254.169.254/latest/api/token" \
-H "X-aws-ec2-metadata-token-ttl-seconds: 21600")
# 2단계: 토큰을 사용하여 메타데이터 조회
curl http://169.254.169.254/latest/meta-data/ \
-H "X-aws-ec2-metadata-token: $TOKEN"💡 Tip: AWS CLI Profile 사용하기
Profile이란?
- 여러 AWS 계정/환경의 자격 증명을 이름으로 구분하여 관리
- 개발/스테이징/프로덕션 등 환경별로 쉽게 전환 가능
Profile 설정 방법
방법 1: aws configure 명령어 사용
# 기본 프로파일 설정
aws configure
# 이름 지정 프로파일 설정
aws configure --profile dev
aws configure --profile prod입력 항목:
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: ap-northeast-2
Default output format [None]: json방법 2: 직접 파일 편집
~/.aws/credentials (자격 증명)
[default]
aws_access_key_id = AKIAIOSFODNN7EXAMPLE
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
[dev]
aws_access_key_id = AKIAI44QH8DHBEXAMPLE
aws_secret_access_key = je7MtGbClwBF/2Zp9Utk/h3yCo8nvbEXAMPLEKEY
[prod]
aws_access_key_id = AKIAIOSFODNN7PRODKEY
aws_secret_access_key = wJalrXUtnFEMI/K7MDENG/PRODEXAMPLEKEY~/.aws/config (리전, 출력 형식 등)
[default]
region = ap-northeast-2
output = json
[profile dev]
region = ap-northeast-2
output = json
[profile prod]
region = us-east-1
output = table⚠️ 주의: credentials 파일에는
[dev], config 파일에는[profile dev]로 작성
Profile 사용 방법
CLI에서 사용
# 기본 프로파일 사용
aws s3 ls
# 특정 프로파일 사용 (--profile 옵션)
aws s3 ls --profile dev
aws s3 ls --profile prod
# 환경 변수로 프로파일 지정
export AWS_PROFILE=dev
aws s3 ls # dev 프로파일 사용됨SDK에서 사용 (Python boto3 예시)
import boto3
# 기본 프로파일
s3 = boto3.client('s3')
# 특정 프로파일
session = boto3.Session(profile_name='dev')
s3 = session.client('s3')프로파일 활용 예시
┌─────────────────────────────────────────────────────┐
│ 개발자 PC │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ default │ │ dev │ │ prod │ │
│ │ (개인계정) │ │ (개발환경) │ │ (운영환경) │ │
│ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │
└─────────┼────────────────┼────────────────┼────────┘
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ AWS 계정 │ │ AWS 계정 │ │ AWS 계정 │
│ (개인) │ │ (개발) │ │ (운영) │
└─────────┘ └─────────┘ └─────────┘자주 사용하는 명령어
| 명령어 | 설명 |
|---|---|
aws configure list | 현재 사용 중인 설정 확인 |
aws configure list-profiles | 설정된 모든 프로파일 목록 |
aws sts get-caller-identity | 현재 자격 증명 정보 확인 |
aws sts get-caller-identity --profile dev | 특정 프로파일 자격 증명 확인 |
3. CLI에서 MFA 사용
개요
- CLI에서 MFA를 사용하려면 임시 세션 생성 필요
- STS GetSessionToken API 호출
명령어
aws sts get-session-token \
--serial-number arn-of-the-mfa-device \
--token-code code-from-token \
--duration-seconds 3600반환값 활용
- 반환된 임시 자격 증명(AccessKeyId, SecretAccessKey, SessionToken)을 환경 변수나 프로파일에 설정
왜 임시 토큰이 필요한가?
CLI는 웹 콘솔처럼 MFA 코드를 직접 입력받는 UI가 없기 때문에, STS(Security Token Service)를 통해 임시 자격 증명을 발급받는 방식으로 MFA를 처리합니다.
일반 로그인 (콘솔):
ID/PW 입력 → MFA 코드 입력 → 로그인 완료
CLI 사용:
Access Key → STS GetSessionToken + MFA 코드 → 임시 토큰 발급 → API 호출임시 토큰 유효 기간
토큰이 만료될 때마다 다시 발급받아야 합니다.
aws sts get-session-token \
--duration-seconds 3600 # 1시간 (기본값: 12시간, 최대: 36시간)| 설정 | 유효 기간 |
|---|---|
| 기본값 | 12시간 |
| 최소 | 15분 (900초) |
| 최대 | 36시간 (129,600초) |
실제 사용 흐름:
오전 9시: 토큰 발급 (12시간 유효)
↓
오전 9시 ~ 오후 9시: 자유롭게 AWS CLI 사용
↓
오후 9시: 토큰 만료 → 다시 발급 필요MFA 사용 시 권장 방법
매번 토큰을 갱신하는 것은 불편하기 때문에 실무에서는:
| 상황 | 권장 방법 |
|---|---|
| EC2/Lambda/ECS 내부 | IAM Role 사용 (MFA 불필요, 자동 갱신) |
| 로컬 개발 (MFA 필수) | 스크립트로 자동화하거나, aws-mfa 같은 도구 사용 |
| 로컬 개발 (MFA 선택) | MFA 없는 개발용 IAM 사용자 (권한 최소화) |
💡 시험 포인트: AWS 내부 리소스(EC2, Lambda 등)에서는 IAM Role을 사용하면 MFA 없이도 안전하게 자격 증명이 자동 갱신됩니다. 그래서 "AWS 내부에서는 항상 IAM Role 사용"이 모범 사례입니다.
4. AWS SDK 개요
SDK란?
- 애플리케이션 코드에서 직접 AWS 서비스와 상호작용
- CLI 없이 프로그래밍 방식으로 AWS API 호출
공식 SDK 지원 언어
| 언어 | SDK 이름 |
|---|---|
| Python | boto3 / botocore |
| Node.js | aws-sdk |
| Java | AWS SDK for Java |
| .NET | AWS SDK for .NET |
| Go | AWS SDK for Go |
| Ruby | AWS SDK for Ruby |
| PHP | AWS SDK for PHP |
| C++ | AWS SDK for C++ |
알아두면 좋은 점
| 항목 | 설명 |
|---|---|
| AWS CLI 내부 | Python SDK (boto3) 사용 |
| 기본 리전 | 설정 안 하면 us-east-1 사용 |
| 사용 시점 | DynamoDB 등 AWS 서비스와 코드로 직접 통신 시 |
5. AWS Limits (Quotas)
API Rate Limits (API 호출 제한)
| 서비스 | API | 제한 |
|---|---|---|
| EC2 | DescribeInstances | 100 calls/sec |
| S3 | GetObject | 5,500 GET/sec/prefix |
에러 대응 방법
| 에러 유형 | 대응 방법 |
|---|---|
| 간헐적 에러 | Exponential Backoff 구현 |
| 지속적 에러 | API throttling limit 증가 요청 |
Service Quotas (서비스 한도)
| 항목 | 기본 한도 |
|---|---|
| On-Demand Standard 인스턴스 | 1,152 vCPU |
한도 증가 방법
- 티켓 오픈하여 요청
- Service Quotas API 사용
6. Exponential Backoff (지수 백오프)
개요
- ThrottlingException 발생 시 재시도 전략
- 재시도 간격을 지수적으로 증가시킴
동작 방식
1차 재시도: 1초 대기
2차 재시도: 2초 대기
3차 재시도: 4초 대기
4차 재시도: 8초 대기
5차 재시도: 16초 대기
...구현 시 주의사항
| 항목 | 설명 |
|---|---|
| AWS SDK | 자동으로 포함되어 있음 |
| AWS API 직접 호출 | 직접 구현 필요 |
| 적용 대상 | 5xx 서버 에러, Throttling만 |
| 적용 제외 | 4xx 클라이언트 에러 (재시도 의미 없음) |
🎯 시험 출제 포인트: 언제 Exponential Backoff를 구현해야 하는가?
✅ 직접 구현해야 하는 경우
| 상황 | 이유 |
|---|---|
| AWS API를 직접 HTTP 호출할 때 | SDK 없이 REST API 직접 호출 시 |
| 커스텀 애플리케이션 로직에서 재시도 필요 시 | SDK 기본 재시도로 부족할 때 |
| AWS SDK를 사용하지 않는 환경 | 레거시 시스템, 특수 환경 |
❌ 직접 구현하지 않아도 되는 경우
| 상황 | 이유 |
|---|---|
| AWS SDK 사용 시 | SDK에 이미 내장되어 있음 |
| AWS CLI 사용 시 | CLI도 내부적으로 자동 재시도 |
🚨 Exponential Backoff를 적용하면 안 되는 경우
| 에러 코드 | 설명 | 재시도 여부 |
|---|---|---|
| 5xx (500, 502, 503...) | 서버 측 에러 | ✅ 재시도 |
| ThrottlingException | API 호출 한도 초과 | ✅ 재시도 |
| 400 Bad Request | 잘못된 요청 파라미터 | ❌ 재시도 무의미 |
| 401 Unauthorized | 인증 실패 | ❌ 재시도 무의미 |
| 403 Forbidden | 권한 없음 | ❌ 재시도 무의미 |
| 404 Not Found | 리소스 없음 | ❌ 재시도 무의미 |
💡 핵심: 4xx 에러는 클라이언트 측 문제이므로 재시도해도 결과가 같음. 코드나 권한을 수정해야 함.
시험 문제 예시
Q: 애플리케이션이 AWS API를 직접 호출하는데 ThrottlingException이
간헐적으로 발생합니다. 어떻게 해결해야 할까요?
A: Exponential Backoff를 구현하여 재시도 간격을 지수적으로 증가시킵니다.
(SDK 사용 시에는 이미 내장되어 있으므로 별도 구현 불필요)Q: 400 Bad Request 에러가 발생할 때 Exponential Backoff를
적용해야 할까요?
A: 아니오. 4xx 에러는 클라이언트 측 문제이므로 재시도해도
동일한 에러가 발생합니다. 요청 파라미터를 수정해야 합니다.예시 코드 (Python)
import time
import random
def exponential_backoff(attempt, base_delay=1, max_delay=32):
delay = min(base_delay * (2 ** attempt), max_delay)
jitter = random.uniform(0, delay * 0.1)
return delay + jitter
for attempt in range(5):
try:
# AWS API 호출
response = call_aws_api()
break
except ThrottlingException:
wait_time = exponential_backoff(attempt)
time.sleep(wait_time)7. AWS CLI Credentials Provider Chain
자격 증명 검색 순서 (우선순위)
| 순위 | 소스 | 설명 |
|---|---|---|
| 1 | Command line options | --region, --output, --profile |
| 2 | Environment variables | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN |
| 3 | CLI credentials file | ~/.aws/credentials |
| 4 | CLI configuration file | ~/.aws/config |
| 5 | Container credentials | ECS 태스크용 |
| 6 | Instance profile credentials | EC2 Instance Profile |
파일 위치
| OS | credentials | config |
|---|---|---|
| Linux/Mac | ~/.aws/credentials | ~/.aws/config |
| Windows | C:\Users\USER\.aws\credentials | C:\Users\USER\.aws\config |
8. AWS SDK Default Credentials Provider Chain
Java SDK 예시 - 검색 순서
| 순위 | 소스 | 설명 |
|---|---|---|
| 1 | Java system properties | aws.accessKeyId, aws.secretKey |
| 2 | Environment variables | AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY |
| 3 | Default credential profiles file | ~/.aws/credentials |
| 4 | Amazon ECS container credentials | ECS 컨테이너용 |
| 5 | Instance profile credentials | EC2 인스턴스용 |
9. Credentials 시나리오 (시험 출제 포인트!)
문제 상황
EC2 인스턴스에 배포된 애플리케이션이 있음
├─ 환경 변수에 IAM User 자격 증명 설정 (S3FullAccess)
├─ EC2 Instance Profile에 IAM Role 할당 (특정 S3 버킷만 접근)
└─ 결과: 여전히 모든 S3 버킷에 접근 가능 😱원인
- Credentials Chain 우선순위 때문!
- 환경 변수(순위 2)가 Instance Profile(순위 6)보다 먼저 검색됨
해결 방법
- 환경 변수에서 자격 증명 제거
- Instance Profile의 IAM Role만 사용하도록 함
10. AWS Credentials 모범 사례
⚠️ 절대 금지
❌ 코드에 AWS 자격 증명 하드코딩 금지!
❌ 절대로 Access Key를 소스 코드에 넣지 말 것!✅ 권장 사항
| 환경 | 권장 방식 |
|---|---|
| EC2 인스턴스 | EC2 Instance Role |
| ECS 태스크 | ECS Task Role |
| Lambda 함수 | Lambda Execution Role |
| AWS 외부 | 환경 변수 / Named Profiles |
핵심 원칙
- Credentials Chain을 통해 자격 증명 상속
- AWS 내부에서는 항상 IAM Role 사용
11. AWS API 요청 서명 (Signing)
개요
- AWS HTTP API 호출 시 요청에 서명 필요
- AWS가 호출자를 식별하기 위함
- Access Key + Secret Key 사용
서명 방식
- Signature Version 4 (SigV4) 사용
SDK/CLI 사용 시
- 자동으로 서명됨 (직접 구현 불필요)
서명 전달 방법
| 방법 | 설명 | 예시 |
|---|---|---|
| HTTP Header | Authorization 헤더에 포함 | 일반 API 호출 |
| Query String | URL 파라미터로 포함 | S3 Pre-signed URL |
방법 1: HTTP Header (Authorization 헤더)
일반적인 AWS API 호출 시 사용됩니다.
GET /my-bucket/my-object HTTP/1.1
Host: s3.amazonaws.com
x-amz-date: 20260110T120000Z
x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Authorization: AWS4-HMAC-SHA256
Credential=AKIAIOSFODNN7EXAMPLE/20260110/us-east-1/s3/aws4_request,
SignedHeaders=host;x-amz-content-sha256;x-amz-date,
Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024Authorization 헤더 구성:
| 요소 | 설명 |
|---|---|
AWS4-HMAC-SHA256 | 서명 알고리즘 |
Credential | Access Key ID / 날짜 / 리전 / 서비스 / aws4_request |
SignedHeaders | 서명에 포함된 헤더 목록 |
Signature | 계산된 서명 값 |
방법 2: Query String (URL 파라미터)
Pre-signed URL 등에서 사용됩니다. URL 자체에 서명 정보가 포함됩니다.
https://my-bucket.s3.amazonaws.com/my-object
?X-Amz-Algorithm=AWS4-HMAC-SHA256
&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE/20260110/us-east-1/s3/aws4_request
&X-Amz-Date=20260110T120000Z
&X-Amz-Expires=3600
&X-Amz-SignedHeaders=host
&X-Amz-Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024Query String 파라미터:
| 파라미터 | 설명 |
|---|---|
X-Amz-Algorithm | 서명 알고리즘 |
X-Amz-Credential | 자격 증명 정보 |
X-Amz-Date | 요청 시간 |
X-Amz-Expires | URL 유효 기간 (초) |
X-Amz-SignedHeaders | 서명에 포함된 헤더 |
X-Amz-Signature | 계산된 서명 값 |
두 방법 비교
| 구분 | HTTP Header | Query String |
|---|---|---|
| 사용 시점 | 서버에서 API 호출 시 | URL을 공유해야 할 때 |
| 보안 | 헤더가 노출되지 않음 | URL에 서명 정보 노출 |
| 유효 기간 | 요청 시점에만 유효 | Expires 설정 가능 |
| 예시 | SDK/CLI API 호출 | S3 Pre-signed URL |
S3 예외
- 일부 S3 요청은 서명 없이도 가능 (퍼블릭 객체 등)
12. S3 Pre-signed URL
개요
- 서명이 Query String에 포함된 URL
- 임시로 S3 객체에 접근 권한 부여
사용 사례
- 비공개 S3 객체를 임시로 공유
- 파일 업로드 URL 제공
생성 예시
# CLI로 Pre-signed URL 생성 (1시간 유효)
aws s3 presign s3://my-bucket/my-file.txt --expires-in 3600# Python SDK (boto3)
import boto3
s3_client = boto3.client('s3')
url = s3_client.generate_presigned_url(
'get_object',
Params={'Bucket': 'my-bucket', 'Key': 'my-file.txt'},
ExpiresIn=3600
)핵심 요약
| 개념 | 핵심 포인트 |
|---|---|
| IMDS | EC2 인스턴스 자체 정보 조회, IMDSv2가 더 안전 |
| SDK | 코드에서 AWS API 호출, CLI도 boto3 사용 |
| Exponential Backoff | 5xx/Throttling만 적용, 4xx는 적용 안 함 |
| Credentials Chain | 우선순위 이해 필수, 환경 변수 > Instance Profile |
| 모범 사례 | 코드에 자격 증명 ❌, AWS 내부에선 IAM Role 사용 |
| SigV4 | API 요청 서명, SDK/CLI는 자동 처리 |