CloudTrail + S3 Bucket Policy 순환 의존성 문제
문제 상황#
stacks/audit-security/에서 CloudTrail을 활성화하려고 terraform apply 실행.
에러#
Error: creating CloudTrail Trail (playball-audit-trail): InsufficientS3BucketPolicyException:
Incorrect S3 bucket policy is detected for bucket: playball-audit-logs
원인 분석#
순환 의존성(Circular Dependency):
CloudTrail 생성 → S3 bucket policy에 CloudTrail 쓰기 권한 필요
↕
S3 bucket policy → CloudTrail ARN 참조 필요 (module.cloudtrail.source_arn)
↕
CloudTrail ARN → CloudTrail이 생성되어야 존재
코드에서 dynamic "statement"로 module.cloudtrail.source_arn != null일 때만 policy를 추가하도록 했는데, CloudTrail이 아직 안 만들어졌으니 source_arn = null → dynamic block 스킵 → policy에 CloudTrail 권한 없음 → CloudTrail 생성 실패.
dynamic "statement" {
for_each = module.cloudtrail.source_arn != null ? [1] : [] # ← null이라 빈 리스트
content {
sid = "AWSCloudTrailAclCheck"
...
values = [module.cloudtrail.source_arn] # ← null
}
}
해결#
CloudTrail ARN은 리소스 생성 전에도 형식이 예측 가능하므로, locals에서 미리 구성:
locals {
trail_arn = "arn:aws:cloudtrail:${local.aws_region}:${local.account_id}:trail/${local.project_name}-audit-trail"
}
bucket policy에서 module output 대신 local.trail_arn 사용:
# 수정 후 - dynamic 제거, local ARN 직접 참조
statement {
sid = "AWSCloudTrailAclCheck"
effect = "Allow"
principals {
type = "Service"
identifiers = ["cloudtrail.amazonaws.com"]
}
actions = ["s3:GetBucketAcl"]
resources = [aws_s3_bucket.audit_logs.arn]
condition {
test = "StringEquals"
variable = "aws:SourceArn"
values = [local.trail_arn]
}
}
교훈#
AWS 리소스 중 ARN 형식이 결정적(deterministic)인 것들은 생성 전에 미리 구성할 수 있다:
arn:aws:cloudtrail:{region}:{account}:trail/{name}
arn:aws:s3:::{bucket-name}
arn:aws:iam::{account}:role/{role-name}
이런 경우 module output의 순환 참조를 피하려면 locals에서 ARN을 직접 구성하는 패턴을 쓰면 된다.
추가 이슈: S3 버킷 이름 충돌#
처음에 project_name = "goormgb" → 버킷 goormgb-audit-logs 생성 시도 → BucketAlreadyExists 에러. 메인 계정(497012402578)에서 이미 사용 중인 이름이었음. S3 버킷은 전역 유니크이므로, 계정별로 다른 prefix(playball-)를 사용해야 한다.
goormgb-audit-logs → 메인 계정에서 이미 사용 중
playball-audit-logs → CA 계정용으로 변경
파일#
301-playball-terraform/stacks/audit-security/main.tf301-playball-terraform/modules/cloudtrail/main.tf