서비스별 IAM 권한 분리와 Terraform 정책 조합
컨테이너 실행 환경의 전환을 검토하면서 기존 IAM 정책도 다시 살펴봤습니다. 서비스마다 필요한 자원이 다른데도 비슷한 정책을 넓게 공유하고 있었습니다. 스토리지를 사용하는 서비스와 메시지를 처리하는 서비스가 같은 권한을 가질 이유는 없었습니다.
공통으로 필요한 부분과 서비스별로 필요한 부분을 나누고, Terraform에서 정책 문서를 조합하도록 바꿨습니다. 권한을 추가할 때도 어떤 서비스의 어떤 작업에 필요한지 구분하려는 변경이었습니다.
실행 권한과 애플리케이션 권한
ECS에서는 컨테이너 실행을 준비하는 task execution role과 애플리케이션이 AWS API를 호출할 때 쓰는 task role을 구분합니다. 이미지를 가져오거나 설정된 로그 드라이버를 실행하는 권한과, 앱이 S3·SQS에 접근하는 권한은 사용 주체가 다릅니다.
Parameter Store나 Secrets Manager도 누가 읽는지에 따라 달라집니다. 태스크 설정으로 값을 주입하는 것과 애플리케이션 코드가 SDK로 직접 조회하는 것을 같은 권한 경로로 생각하면 안 됩니다.
Kubernetes 환경에서는 service account와 IAM 역할을 연결하는 IRSA 같은 방식도 있습니다. 같은 service account를 쓰는 Pod는 연결된 역할을 공유합니다. 어떤 실행 환경이든 정책 내용과 그 정책을 사용하는 역할·워크로드를 함께 확인해야 합니다.
작업과 자원 범위 축소
기존처럼 서비스 이름 접두사에 와일드카드를 붙이고 sqs:*를 허용하면, 메시지 처리에 필요하지 않은 큐 삭제나 전체 메시지 비우기까지 포함될 수 있습니다. 큐에서 메시지를 받아 처리할 때와 보낼 때 필요한 작업을 나누고, 접근 대상도 해당 서비스의 큐로 좁힐 필요가 있었습니다.
S3도 버킷과 객체의 ARN이 다릅니다. 파일을 쓰는 권한과 버킷 목록을 조회하는 권한을 같은 리소스 문자열로 묶으면 의도한 대로 적용되지 않을 수 있습니다.
공통 정책과 개별 정책 조합
Terraform의 aws_iam_policy_document를 사용해 공통 문서를 만들고 source_policy_documents로 가져왔습니다. 다음은 설정을 조회하고 큐에서 메시지를 받는 권한을 조합한 예시입니다. 실제 서비스의 ARN과 정책 전체를 옮긴 코드는 아닙니다.
variable "parameter_arn" {
type = string
}
variable "queue_arn" {
type = string
}
data "aws_iam_policy_document" "read_configuration" {
statement {
sid = "ReadConfiguration"
actions = ["ssm:GetParameter"]
resources = [var.parameter_arn]
}
}
data "aws_iam_policy_document" "export_worker" {
source_policy_documents = [
data.aws_iam_policy_document.read_configuration.json
]
statement {
sid = "ConsumeExportQueue"
actions = [
"sqs:ReceiveMessage",
"sqs:DeleteMessage",
"sqs:ChangeMessageVisibility",
"sqs:GetQueueAttributes"
]
resources = [var.queue_arn]
}
}이 data source는 정책 JSON을 생성합니다. 실제 IAM 정책·역할에 연결하거나 서비스가 그 역할을 사용하도록 만드는 작업은 별도입니다. 암호화된 자원을 사용한다면 KMS 권한과 키 정책 등도 함께 확인해야 합니다.
문서를 조합할 때는 sid의 중복과 재정의 규칙도 봐야 합니다. HCL 문법이 맞는다는 사실만으로 작업 이름·ARN·조건과 실제 접근 권한까지 검증되는 것은 아닙니다.
SNS에서 SQS로 전달하는 권한
SNS가 SQS에 메시지를 보내는 경로에는 큐의 리소스 정책도 필요합니다. 애플리케이션 역할에 메시지 수신 권한을 붙이는 것과는 다른 설정입니다.
다음은 특정 SNS 토픽에서 오는 전송만 허용하는 큐 정책의 예입니다. 앞선 예시의 queue_arn과, 별도로 전달한 정확한 topic_arn을 사용합니다.
variable "topic_arn" {
type = string
}
data "aws_iam_policy_document" "sns_to_queue" {
statement {
sid = "ReceiveFromSelectedTopic"
actions = ["sqs:SendMessage"]
resources = [var.queue_arn]
principals {
type = "Service"
identifiers = ["sns.amazonaws.com"]
}
condition {
test = "ArnEquals"
variable = "aws:SourceArn"
values = [var.topic_arn]
}
}
}ArnEquals로 비교할 값에는 정확한 토픽 ARN을 넣습니다. 이름 패턴을 허용하려면 조건 연산자와 허용 범위를 그 목적에 맞게 따로 검토해야 합니다.
계정이 다르면 토픽의 구독 권한과 구독 확인 등 발행·수신 양쪽의 설정도 봐야 합니다. 위 문서를 만들기만 해서는 큐 정책 적용이나 구독 생성까지 이루어지지 않습니다.
적용 후 접근 확인
정책을 나눈 뒤에는 서비스가 필요한 자원을 사용할 수 있는지 확인해야 합니다. 메시지 수신·삭제·처리 시간 연장처럼 같은 큐를 대상으로 하는 작업도 각각 필요한 권한이 다릅니다.
다른 역할이나 리소스 정책에서 추가 권한을 받고 있는지도 확인할 부분입니다. 정책 파일 하나에서 허용 항목을 지웠다는 이유만으로 실제 접근까지 차단됐다고 볼 수는 없습니다.
공통 정책과 서비스별 정책을 나눈 뒤에는 접근 목적을 확인하기 쉬워졌습니다. 새 자원이나 작업이 추가될 때도 기존 와일드카드를 넓히는 대신, 어느 서비스에 어떤 권한이 필요한지 살펴볼 수 있었습니다.