소개
EC2 애플리케이션이 S3에서 보고서를 읽어야 합니다. 인스턴스 프로파일을 통해 애플리케이션에 IAM 역할을 부여하고 실제 보고서 읽기를 확인한 뒤 권한을 취소했을 때의 동작을 관찰합니다.
EC2 시작, User Data 및 기본 IAM 정책을 알고 있어야 합니다. 이 새로운 환경에는 애플리케이션 이미지, 네트워크, 키 페어 및 가상 데이터를 포함하는 S3 버킷이 제공됩니다. 애플리케이션 인스턴스와 인가 리소스는 직접 생성합니다.
자격증과의 관련성
이 실습에서는 최소 권한과 워크로드 역할을 연습하며, AWS Certified Cloud Practitioner 보안 목표의 작업 2.3과 컴퓨팅 목표의 작업 3.3을 익힙니다.
역할 없이 애플리케이션 시작하기
이 단계에서는 보고서 서버를 시작하고 애플리케이션이 아직 S3를 읽을 수 없음을 관찰합니다.
작업 디렉터리에서 제공된 이미지, 네트워크 및 보고서 버킷 ID를 불러옵니다.
cd /home/labex/project
source launch.env
제공된 시작 스크립트를 확인합니다. 애플리케이션의 S3 버킷과 객체 키를 설정하지만 자격 증명을 제공하지는 않습니다.
cat role-user-data.sh
이 설정으로 role-server라는 서버를 시작합니다.
aws ec2 \
run-instances \
--image-id "$AMI_ID" \
--instance-type t3.micro \
--subnet-id "$SUBNET_ID" \
--security-group-ids "$SECURITY_GROUP_ID" \
--key-name report-key \
--count 1 \
--user-data file://role-user-data.sh \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=role-server}]'
ID를 저장합니다.
INSTANCE_ID=$(aws ec2 \
describe-instances \
--filters Name=tag:Name,Values=role-server \
--query 'Reservations[0].Instances[0].InstanceId' \
--output text)
aws ec2 \
wait instance-running \
--instance-ids "$INSTANCE_ID"
AWS View를 열고 Refresh resources를 클릭한 다음 role-server를 선택하고 Check application을 클릭합니다. HTTP 200과 Role report server를 확인합니다. 이제 Read S3 report를 클릭합니다. HTTP 503과 Application storage unavailable이 예상 결과입니다. 실행 중인 애플리케이션에는 아직 역할 자격 증명이 없습니다.
EC2의 애플리케이션은 인스턴스 메타데이터를 통해 할당된 역할의 임시 자격 증명을 얻을 수 있습니다. AWS SDK는 해당 자격 증명으로 API 요청에 서명합니다. 공식 EC2 역할 안내서에서 이 절차를 설명합니다. 터미널의 자격 증명을 애플리케이션에 복사하지 않고 역할을 설정합니다.
인스턴스 프로파일로 접근 권한 부여하기
이 단계에서는 역할의 신뢰 정책과 권한 정책을 생성하고 역할을 인스턴스 프로파일에 추가하여 서버에 연결합니다.
신뢰 정책은 누가 역할을 수임할 수 있는지 정의합니다. EC2 서비스를 신뢰하는 JSON 정책을 생성합니다. 구분자를 따옴표로 감싼 here-document는 JSON을 그대로 유지합니다.
cat > ec2-trust.json <<'JSON'
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"Service": "ec2.amazonaws.com"},
"Action": "sts:AssumeRole"
}]
}
JSON
이 신뢰 정책으로 report-reader 역할을 생성합니다.
aws iam \
create-role \
--role-name report-reader \
--assume-role-policy-document file://ec2-trust.json
권한 정책은 수임한 역할로 어떤 작업을 할 수 있는지 정의합니다. 이 애플리케이션에는 report.csv에 대한 s3:GetObject만 필요합니다. 객체 ARN에는 버킷과 키가 모두 포함됩니다. 이전의 따옴표로 감싼 here-document와 달리 아래의 따옴표 없는 JSON 구분자는 $REPORT_BUCKET을 제공된 버킷 이름으로 확장합니다.
cat > read-report.json <<JSON
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::$REPORT_BUCKET/report.csv"
}]
}
JSON
변수가 확장된 리소스 ARN을 확인합니다.
cat read-report.json
이 인라인 정책을 역할에 추가합니다.
aws iam \
put-role-policy \
--role-name report-reader \
--policy-name ReadReport \
--policy-document file://read-report.json
인스턴스 프로파일은 IAM 역할을 EC2에 전달합니다. CLI를 사용할 때는 역할과 프로파일을 별도로 생성합니다. 알아보기 쉽도록 같은 이름의 프로파일을 생성합니다.
aws iam \
create-instance-profile \
--instance-profile-name report-reader
프로파일에 역할을 추가합니다.
aws iam \
add-role-to-instance-profile \
--instance-profile-name report-reader \
--role-name report-reader
기존 인스턴스에 프로파일을 연결하고 정리 시 사용할 연결 ID를 저장합니다.
ASSOCIATION_ID=$(aws ec2 \
associate-iam-instance-profile \
--instance-id "$INSTANCE_ID" \
--iam-instance-profile Name=report-reader \
--query 'IamInstanceProfileAssociation.AssociationId' \
--output text)
연결 정보를 확인합니다.
aws ec2 \
describe-iam-instance-profile-associations \
--association-ids "$ASSOCIATION_ID" \
--query 'IamInstanceProfileAssociations[].{Instance:InstanceId,State:State,Profile:IamInstanceProfile.Arn}'
associated와 report-reader 프로파일을 확인합니다. AWS View를 새로 고침하고 Read S3 report를 클릭합니다. HTTP 200과 period,total 및 Q1,320이 예상 결과입니다. 애플리케이션은 SDK의 역할 자격 증명을 사용하여 실제 S3 객체를 가져옵니다. 연결이 아직 전파 중이라면 잠시 기다렸다가 요청을 다시 시도합니다.
역할은 버킷 전체나 관리자 접근이 아니라 단일 객체 읽기만 허용합니다. 인스턴스 프로파일 안내서에서 프로파일이 역할을 전달하는 방법과 연결 변경 전파에 시간이 걸릴 수 있는 이유를 설명합니다.
권한 취소 관찰하기
이 단계에서는 역할의 보고서 권한을 제거하고 인가 실패와 애플리케이션 장애를 구분합니다.
직접 생성한 인라인 정책만 제거합니다.
aws iam \
delete-role-policy \
--role-name report-reader \
--policy-name ReadReport
역할에 남아 있는 인라인 정책을 나열합니다.
aws iam \
list-role-policies \
--role-name report-reader
빈 PolicyNames 목록이 예상 결과입니다. 인스턴스 프로파일은 계속 연결되어 있지만 역할은 더 이상 보고서 읽기를 허용하지 않습니다.
AWS View에서 Check application을 클릭하고 HTTP 200을 확인합니다. 서버는 계속 실행 중입니다. 다음으로 Read S3 report를 클릭합니다. HTTP 403과 Access denied가 예상 결과입니다. 권한 변경이 아직 전파되지 않았다면 잠시 기다렸다가 요청을 반복합니다. 정상적인 상태 응답과 S3 거부가 함께 나타나면 중지된 인스턴스나 누락된 애플리케이션이 아니라 인가 문제를 나타냅니다.
SDK는 임시 자격 증명을 캐시할 수 있습니다. 역할 권한을 제거하면 해당 자격 증명으로 허용되는 작업이 달라집니다. 인스턴스 프로파일을 제거해도 이미 발급된 자격 증명이 즉시 취소되는 것은 아닙니다.
인스턴스와 역할 정리하기
이 단계에서는 직접 생성한 연결, 서버, 프로파일 및 역할을 제거합니다.
저장한 연결 ID로 프로파일 연결을 해제합니다.
aws ec2 \
disassociate-iam-instance-profile \
--association-id "$ASSOCIATION_ID"
애플리케이션 인스턴스를 종료합니다.
aws ec2 \
terminate-instances \
--instance-ids "$INSTANCE_ID"
aws ec2 \
wait instance-terminated \
--instance-ids "$INSTANCE_ID"
더 이상 사용하지 않는 인스턴스 프로파일에서 역할을 제거합니다.
aws iam \
remove-role-from-instance-profile \
--instance-profile-name report-reader \
--role-name report-reader
빈 프로파일을 삭제합니다.
aws iam \
delete-instance-profile \
--instance-profile-name report-reader
인라인 정책은 권한 취소 시 이미 제거했습니다. 이제 역할을 삭제합니다.
aws iam \
delete-role \
--role-name report-reader
인스턴스가 종료되었는지 확인합니다.
aws ec2 \
describe-instances \
--instance-ids "$INSTANCE_ID" \
--query 'Reservations[].Instances[].{Instance:InstanceId,State:State.Name}'
지정한 이름의 역할과 프로파일이 없는지 확인합니다.
aws iam \
list-roles \
--query "Roles[?RoleName=='report-reader'].RoleName"
aws iam \
list-instance-profiles \
--query "InstanceProfiles[?InstanceProfileName=='report-reader'].InstanceProfileName"
두 목록 모두 []이어야 합니다. AWS View를 새로 고침하여 서버가 더 이상 실행 중인 대상이 아닌지 확인합니다. 준비된 S3 데이터, 네트워크 및 키 페어는 그대로 유지합니다.
요약
IAM 역할에 EC2 신뢰 관계와 단일 S3 객체 읽기 권한을 생성하고 인스턴스 프로파일을 통해 역할을 전달하여 애플리케이션의 실제 보고서 읽기를 확인했습니다. 다음으로 권한을 취소하고 정상적인 애플리케이션과 S3 접근 거부를 구분했습니다. 마지막으로 인스턴스, 프로파일 및 역할을 제거했습니다.



