애플리케이션에 보고서 접근 권한 부여하기

AWSBeginner
지금 연습하기

소개

실행 중인 애플리케이션이 비공개 보고서를 읽어야 합니다. Terraform 참조로 IAM 역할과 인스턴스 프로파일을 연결하고, 의도한 객체에 접근 권한을 부여한 뒤, 권한 제거 전후에 애플리케이션의 실제 요청을 테스트합니다.

이 실습은 Terraform 참조와 EC2 배포, AWS 역할 신뢰, 인스턴스 프로파일, 범위를 제한한 S3 권한에 대한 지식을 전제로 합니다. 새로운 환경에는 실행 중인 애플리케이션, 해당 네트워크, 비공개 보고서 버킷, 관련 없는 참조 애플리케이션이 제공됩니다. 제공된 데이터와 참조 환경을 온전히 유지해야 합니다.

관련 자격증 시험 항목

자격증 시험 과제 실습 내용
Cloud Practitioner (CLF-C02) Task 2.3 IAM 역할과 최소 권한 객체 접근 권한.
Solutions Architect – Associate (SAA-C03) Task 1.1 범위를 제한한 권한을 사용하는 역할 기반 워크로드 접근.
CloudOps Engineer – Associate (SOA-C03) Task 4.1 기본적인 IAM 역할 및 정책 구현.

실습 개요

개념 개요: EC2 애플리케이션은 인스턴스 프로파일과 IAM 역할로 report.csv를 읽으며 private.csv는 계속 거부됩니다.

실행 중인 애플리케이션에 역할 자격 부여하기

이 단계에서는 EC2 역할과 인스턴스 프로파일을 정의하고, 제공된 애플리케이션에 프로파일을 연결한 뒤, 실제로 사용하는 워크로드 자격을 관찰합니다.

위쪽 AWS View는 Terminal에서 조회하는 것과 같은 리소스를 표시합니다. Request path 선택기로 애플리케이션 상태, 워크로드 자격, 두 비공개 객체 중 하나를 요청할 수 있습니다. Terminal은 준비된 운영자 자격을 사용하며, 애플리케이션은 자체 인스턴스 역할을 사용합니다. 운영자의 조회 성공은 애플리케이션에 권한이 있음을 입증하지 않습니다.

준비된 루트를 확인하고 인스턴스 ID를 기록합니다.

cd /home/labex/project/application-reports
cat terraform.tfvars.json
cat application.tf
terraform state list
INSTANCE_ID=$(terraform output -raw instance_id)
echo "$INSTANCE_ID"
REPORT_BUCKET=$(terraform output -raw report_bucket)
echo "$REPORT_BUCKET"

기존 상태는 애플리케이션 인스턴스를 관리합니다. 네트워크, AMI, 버킷, 참조 애플리케이션은 별도로 제공되었습니다. User Data는 이미 애플리케이션이 준비된 버킷의 report.csv를 가리키도록 설정하지만 액세스 키는 포함하지 않습니다.

AWS View에서 application-server, User · 198.51.100.10, Application · 8081, Health를 선택한 다음 Send request를 클릭하세요. Connected · 200과 Report application이 표시되어야 합니다. Private report를 선택하여 다시 보냅니다. 아직 애플리케이션이 읽을 수 없으므로 Connected · 503과 Application storage unavailable을 보고합니다. HTTP 애플리케이션에는 접근할 수 있지만 워크로드 자격 증명이 없습니다.

IAM 역할의 신뢰 정책은 누가 해당 역할을 수임할 수 있는지 제어합니다. 인스턴스 프로파일은 역할을 EC2에 연결합니다. 둘 중 어느 것도 단독으로 S3 객체 읽기 권한을 부여하지는 않습니다. 두 리소스를 생성합니다.

cat > identity.tf <<'HCL'
resource "aws_iam_role" "reports" {
  name = "tf-report-reader"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = { Service = "ec2.amazonaws.com" }
      Action = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_instance_profile" "reports" {
  name = "tf-report-reader"
  role = aws_iam_role.reports.name
}
HCL
sed -i '/vpc_security_group_ids/a\  iam_instance_profile = aws_iam_instance_profile.reports.name' application.tf
terraform fmt
terraform validate
terraform plan

sed 명령은 기존 보안 그룹 속성 뒤에 인스턴스 프로파일 속성을 삽입합니다. 이 리소스 참조는 실행 중인 인스턴스를 프로파일에 연결하고 프로파일은 역할을 참조합니다. 계획을 검토하세요. 역할과 프로파일을 생성하고 기존 인스턴스 연결을 업데이트하되, 인스턴스를 교체하거나 User Data를 변경해서는 안 됩니다.

적용하고 yes를 입력합니다.

terraform apply

실제 연결과 프로파일을 확인합니다.

aws ec2 \
  describe-iam-instance-profile-associations \
  --filters "Name=instance-id,Values=$INSTANCE_ID" \
  --query 'IamInstanceProfileAssociations[].{Instance:InstanceId,State:State,Profile:IamInstanceProfile.Arn}'
aws iam \
  get-instance-profile \
  --instance-profile-name tf-report-reader \
  --query 'InstanceProfile.{Name:InstanceProfileName,Roles:Roles[].RoleName}'

AWS View에서 application-server의 Workload identity를 선택하여 요청을 보냅니다. Connected · 200과 assumed-role/tf-report-reader/를 포함한 ARN이 표시되어야 합니다. 이는 Terminal 운영자의 자격이 아니라 게스트 내부에서 임시 역할 자격 증명을 사용하는 STS에서 나온 결과입니다.

Private report를 선택하여 다시 보냅니다. Connected · 403과 Access denied가 표시되어야 합니다. 이제 역할 자격은 작동하지만 아직 객체 읽기 권한은 없습니다. 이는 의도한 권한 부여 실패입니다.

의도한 보고서에만 접근 권한 부여하기

이 단계에서는 애플리케이션 역할에 객체 읽기 권한 하나를 부여하고 허용된 보고서와 관련 없는 비공개 객체를 모두 테스트합니다.

역할의 권한 정책은 해당 세션이 무엇을 할 수 있는지 결정합니다. 정확한 report.csv ARN에 s3:GetObject를 허용하는 자격 증명 정책을 사용하세요. 버킷 이름은 제공된 입력값에서, 역할은 리소스 참조에서 가져옵니다. 정적 자격 증명은 User Data에 넣지 않습니다.

cat > permissions.tf <<'HCL'
resource "aws_iam_role_policy" "report" {
  name = "ReadApplicationReport"
  role = aws_iam_role.reports.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Action = ["s3:GetObject"]
      Resource = ["arn:aws:s3:::${var.report_bucket}/report.csv"]
    }]
  })
}
HCL
terraform fmt
terraform validate
terraform plan

계획은 정책 하나를 추가합니다. 애플리케이션을 교체하거나 새 버킷을 생성해서는 안 됩니다. 적용하고 yes를 입력합니다.

terraform apply

AWS View에서 application-server, User, 포트 8081을 선택한 상태로 유지하세요. Private report를 선택하여 요청을 보냅니다. Connected · 200과 다음 보고서가 표시되어야 합니다.

period,total
Q1,320

Unrelated private object를 선택하여 다른 요청을 보냅니다. Connected · 403과 Access denied가 표시되어야 합니다. 애플리케이션은 자신의 보고서를 읽을 수 있지만 private.csv는 권한 범위 밖에 남아 있습니다. 이 403은 연결에 성공한 애플리케이션이 반환한 실제 S3 권한 부여 결과이며 네트워크 연결 실패가 아닙니다.

Workload identity로 돌아가 다시 보냅니다. ARN은 여전히 워크로드 역할을 식별해야 합니다. 수렴을 확인합니다.

terraform plan

No changes.가 표시되어야 합니다. 결과 예시: 애플리케이션이 역할 자격으로 비공개 보고서를 읽습니다. 리소스 ID는 환경마다 다릅니다.

권한 철회 및 실제 효과 테스트하기

이 단계에서는 읽기 정책만 제거하고, 유효한 역할 자격을 가진 실행 중인 애플리케이션이 더 이상 보고서에 접근할 수 없음을 확인합니다.

권한 제거는 프로파일 분리나 인스턴스 중지와 다릅니다. 역할과 프로파일을 유지하고 정책 리소스 구성을 제거한 다음 삭제 계획을 검토합니다.

rm permissions.tf
terraform plan

인스턴스 교체 없이 읽기 정책이 삭제되어야 합니다. 적용하고 yes를 입력합니다.

terraform apply

남은 인라인 정책 이름을 독립적으로 읽습니다.

aws iam \
  list-role-policies \
  --role-name tf-report-reader \
  --query PolicyNames

[]가 표시되어야 합니다. AWS View에서 애플리케이션의 Workload identity 요청을 보냅니다. 여전히 같은 역할 이름으로 Connected · 200을 반환합니다. 그런 다음 Private report와 Unrelated private object 요청을 보냅니다. 둘 다 Connected · 403과 Access denied를 반환해야 합니다. 읽기 거부는 애플리케이션과 역할 연결이 여전히 존재하더라도 권한 제거가 실제 워크로드 요청에 영향을 준다는 것을 입증합니다.

terraform plan

No changes.가 표시되어야 합니다.

관리 대상 리소스 삭제 및 제공된 데이터 보존하기

이 단계에서는 외부 보고서 버킷, 해당 객체, 참조 환경을 보존하면서 관리 중인 인스턴스, 프로파일, 역할을 삭제합니다.

정책은 이미 제거되었습니다. 남은 삭제 범위를 검토합니다.

terraform plan -destroy

애플리케이션 인스턴스, 인스턴스 프로파일, IAM 역할의 세 관리 대상 리소스가 있어야 합니다. 그런 다음 삭제하고 yes를 입력합니다.

terraform destroy

동일한 인스턴스가 실제로 종료되어야 합니다.

aws ec2 \
  describe-instances \
  --instance-ids "$INSTANCE_ID" \
  --query 'Reservations[].Instances[].{ID:InstanceId,State:State.Name}'
terraform state list

terminated가 표시되고 상태에는 관리 중인 리소스가 없어야 합니다. 정확한 이름으로 역할 및 프로파일 목록을 조회합니다. 조회에 성공하여 빈 목록이 나와야 부재를 입증할 수 있으며 인증 실패를 정리 성공으로 취급해서는 안 됩니다.

aws iam list-roles --query "Roles[?RoleName=='tf-report-reader'].RoleName"
aws iam list-instance-profiles --query "InstanceProfiles[?InstanceProfileName=='tf-report-reader'].InstanceProfileName"

둘 다 []를 반환합니다. 버킷은 이 상태의 관리 범위 밖에서 제공되었습니다. Terminal 운영자로 보존된 두 객체를 읽고 바이트를 확인하세요. 이 운영자 읽기는 보존을 확인합니다. 애플리케이션의 제한된 접근은 별도로 해당 역할을 통해 테스트했습니다.

aws s3api get-object --bucket "$REPORT_BUCKET" --key report.csv /tmp/retained-report.csv
cat /tmp/retained-report.csv
aws s3api get-object --bucket "$REPORT_BUCKET" --key private.csv /tmp/retained-private.csv
cat /tmp/retained-private.csv

보고서는 period,total / Q1,320으로 유지되고 관련 없는 객체는 private,retained로 유지됩니다. AWS View에서 reference-server, User, Application · 8081, Health를 선택하여 요청을 보냅니다. Connected · 200과 Reference application이 표시되어야 합니다.

검토할 수 있도록 Terraform 파일을 유지하세요. 이후 일반 계획에서는 남아 있는 구성의 재생성을 제안합니다. 삭제 성공을 위해 해당 구성을 지울 필요는 없습니다.

요약

Terraform 참조로 애플리케이션 인스턴스를 역할에 연결하고, 역할 자격과 객체 권한을 구분하며, 비공개 보고서 읽기 성공과 관련 없는 객체의 거부를 모두 테스트했습니다. 그런 다음 권한을 철회하고 실제 권한 부여 실패를 관찰한 뒤, 제공된 데이터와 참조 애플리케이션을 보존하면서 관리 대상 리소스를 삭제했습니다.