콘솔로 만든 IAM을 Terraform 밑으로 옮기기

<aside>

🎯 목표 설정

지금까지 팀 근두운의 AWS 콘솔에는 IAM 사용자 8명, 그룹 3개(WHS4_Attack, WHS4_Infra, WHS4_SIEM_Detect)가 직접 생성되어 있었다. 반면 identity 모듈에는 이미 이 리소스를 코드로 관리할 수 있는 Terraform 구조가 짜여 있었지만 실제 AWS 상태와는 연결되지 않은 채였다.

이번 작업의 목표는 콘솔로 만든 기존 IAM 리소스를 Terraform state로 편입시켜서, 앞으로의 계정/그룹/권한 변경도 코드 리뷰(PR)를 거치게 만드는 것이다.

</aside>

기존 코드 구조 파악

identity 폴더는 외부 모듈 없이 리소스를 직접 정의하고 있었고, 사용자·그룹 명단은 members.yaml/groups.yaml이라는 YAML 파일에서 읽어와 for_each로 동적 생성하는 구조였다.

# groups.tf (요약)
resource "aws_iam_group" "managed" {
  for_each = yamldecode(file("${path.module}/groups.yaml"))
  name     = each.key
}

resource "aws_iam_group_policy_attachment" "managed" {
  for_each = local.group_policy_pairs
  group    = each.value.group
  policy_arn = each.value.policy_arn
}
# users.tf (요약)
resource "aws_iam_user" "member" {
  for_each              = yamldecode(file("${path.module}/members.yaml"))
  name                  = each.key
  permissions_boundary  = var.permissions_boundary_arn
}

resource "aws_iam_user_group_membership" "member" {
  for_each = ...
  user     = each.key
  groups   = each.value.groups
}

문제는 members.yaml, groups.yaml 두 파일이 전부 빈 템플릿 상태였다는 것이다. 코드는 준비되어 있었지만, 실제로 무엇을 관리할지는 아무것도 채워지지 않은 채였다.

마이그레이션 과정

1. 실제 AWS 상태 조회

AWS CLI로 그룹 목록, 그룹별 소속 사용자, 그룹별 부착 정책을 전부 조회했다.

aws iam list-groups
aws iam get-group --group-name WHS4_Infra
aws iam list-attached-group-policies --group-name WHS4_Infra

2. YAML 초안 작성

조회 결과를 바탕으로 groups.yaml, members.yaml을 채웠다.

# groups.yaml (일부)
WHS4_Infra:
  policy_arns:
    - "arn:aws:iam::aws:policy/IAMFullAccess"
    - "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess"
    - "arn:aws:iam::aws:policy/AmazonS3FullAccess"
    - "arn:aws:iam::aws:policy/AWSCloudTrail_FullAccess"
    - "arn:aws:iam::446413909569:policy/WHS4_SelfAccountManagement"
# members.yaml (일부)
hyeri:
  groups: ["WHS4_Infra", "WHS4_SIEM_Detect"]
junhwan:
  groups: ["WHS4_Infra"]

3. terraform import

resource "aws_iam_group_policy_attachment" "managed" {
  for_each = {
    "WHS4_Infra|arn:aws:iam::aws:policy/IAMFullAccess" = {
      group      = "WHS4_Infra"
      policy_arn = "arn:aws:iam::aws:policy/IAMFullAccess"
    }
  }

  group      = each.value.group
  policy_arn = each.value.policy_arn
}

for_each 구문을 이용해 그룹 3개, 사용자 8명, 그룹-정책 attachment 21개, 사용자-그룹 멤버십 8개까지 총 40개 리소스를 import했다.