본문 바로가기
MegazoneCloud
← 전체 글
AWS

AWS 계정이 조직을 이전하기 전 확인해야 하는 것 — Account Assessment for AWS Organizations 활용기

들어가며

최근 win-back 건이 늘면서, 관리 계정(Payer) 이관 사례도 함께 증가하고 있습니다. SA로서 이런 프로젝트를 맡으면, 고객사의 요건은 대체로 다음과 같습니다.

  • “관리 계정(Payer)을 다른 곳으로 이관해야 합니다.”
  • “이 계정들을 다른 Organization으로 옮겨주세요.”

AWS Organizations로 수십 개 계정을 운영하는 고객사일수록 이런 요청의 무게는 더 커집니다.

단순히 “계정 몇 개 옮기는 것”처럼 보이지만, 실제로는 조직 전체에 흩어진 정책 의존성과의 싸움입니다. 계정이 기존 조직을 떠나는 순간, 그 계정을 신뢰하던 정책이나 그 조직 ID를 조건으로 걸어둔 정책이 한꺼번에 무효가 되면서, 거기에 의존하던 기능이 중지될 수 있습니다. 문제는 “어떤 의존성이, 몇 개나 무효가 되는지”를 이전 전에 알아내는 것입니다.

이 글은 실제 Payer 이관 프로젝트에서 Account Assessment for AWS Organizations(이하 Account Assessment)를 어떻게 활용했는지 정리한 것입니다. 솔루션 소개 자체보다, 왜 이 도구가 필요했고 그 결과를 어떻게 “판단”으로 바꿨는지에 초점을 둡니다.


1. 고객의 요건

한 고객사례를 요약하면 다음과 같습니다.

  • AWS Control Tower 기반 조직, 멤버 계정 약 27개
  • 멀티 리전 운영 (실사용 리전 7개)
  • 관리 계정(Payer)을 **A 사업자 → B 사업자(MZC)**로 교체하면서, 기존 조직의 전 계정을 신규 조직으로 그대로 이관(lift & shift)
  • 전환 기준일(D-Day) 하루에 Payer가 바뀌므로, 그 전에 무효가 될 의존성을 모두 식별하고 조치해야 함

여기서 핵심 리스크는 두 가지였습니다.

(1) 조직 ID 조건에 묶인 정책 리소스 정책이나 신뢰 정책에 aws:PrincipalOrgID, aws:SourceOrgId 같은 조건이 걸려 있으면, 계정이 신규 조직으로 넘어가는 순간 조직 ID가 바뀌면서 조건이 더 이상 맞지 않게 되고, 그 즉시 접근이 거부됩니다.

(2) 특정 계정 ID를 신뢰/참조하는 정책 구 관리 계정, 구 Audit 계정, 구 Log-Archive 계정의 ID를 신뢰하거나 참조하는 IAM 역할·리소스 정책이 조직 전반에 퍼져 있었습니다.

이 둘을 사람이 손으로 전수 조사하는 것은 사실상 불가능합니다. 계정 수십 개 × 리전 × 서비스(S3, KMS, SQS, SNS, ECR, Lambda, …) 조합을 전수조사해야 하기 때문입니다.

실제로 이 프로젝트 초기에는 수동으로 “공유 성격이 강한 계정 4개”만 먼저 조사했는데, 리소스 정책 기준 20여 건밖에 찾지 못했습니다. 워크로드 계정과 IAM 정책은 통째로 빠져 있었습니다. 이 한계가 Account Assessment를 도입한 직접적인 이유였습니다.


2. Account Assessment for AWS Organizations 란

AWS가 공식 제공하는 솔루션(Guidance)으로, 조직 전체 계정을 한 번에 스캔해서 정책·신뢰 관계·활성화된 서비스를 들여다볼 수 있게 해줍니다. AWS 공식 문서가 꼽는 대표 유스케이스가 이번 고객사례와 정확히 겹칩니다. (아래 내용은 공식 문서를 요약했습니다.)

  • 관리 계정 변경(Management account change): 새 계정을 관리 계정으로 만들고 기존 관리 계정을 멤버로 내릴 때, 기존 관리 계정의 정책 가시성을 확보
  • 인수·합병(Mergers or acquisitions): 운영 워크로드를 유지한 채 계정을 조직/OU 간 이동
  • 보안 감사(Security audits): 계정·정책·신뢰 관계·활성 서비스 파악
  • 중앙 Policy Explorer: 조직 전체 정책에서 action·resource·condition 등을 검색·필터·다운로드

출처: Use cases – Account Assessment for AWS Organizations (내용 요약)

세 가지 스캔

이 솔루션이 제공하는 스캔은 크게 세 종류입니다.

스캔무엇을 조회하나
Policy Explorer조직 전 계정의 Identity 기반 / 리소스 기반 / SCP 정책을 검색 (이번 사례의 핵심)
Delegated Admin서비스별 위임 관리자 계정 조회
Trusted Access조직에서 신뢰 액세스가 활성화된 서비스 조회

이번 프로젝트에서 주력으로 사용한 것은 Policy Explorer입니다. “구 조직 ID / 구 관리·Audit·Log-Archive 계정 ID”를 조직 전체 정책에서 전수 검색하는 용도로 적합했습니다.

지원 서비스 (리소스 기반 정책)

Account Assessment는 30종 이상의 서비스 정책을 스캔합니다. 이번 사례에서 실제로 검출된 서비스가 전부 지원 목록에 있었습니다: S3, KMS, SQS, SNS, ECR, CodeArtifact, Lambda, RAM, VPC Endpoint, EventBridge 등. (전체 목록은 공식 Features and benefits 참조)


3. 어떻게 구성되나 (아키텍처)

Account Assessment는 3개의 CloudFormation 스택으로 배포되며, 역할 분담이 명확합니다. (아래는 공식 아키텍처 문서를 요약한 것입니다. 각 스택을 어느 계정에 올리는지는 뒤의 “배포 구성”에서 다룹니다.)

스택역할
Hub웹 UI, API, 스캔 오케스트레이션, 결과 저장(DynamoDB)
SpokeHub가 Assume 할 수 있는 실행 역할 제공 (실제 스캔이 여기서 실행됨)
OrgManagementDelegated Admin / Trusted Access 스캔용 역할 제공

동작 흐름은 아래 아키텍처 다이어그램의 번호와 함께 보면 이해가 빠릅니다. (다이어그램은 AWS 공식 문서 기준)

#구성요소동작
1CloudFront사용자가 웹 UI에 접속
2S3웹 UI 정적 파일을 호스팅
3Cognito로그인·인증 (액세스 토큰 발급)
4WAFAPI 앞단에서 접근 IP 제한·웹 공격 차단
5API GatewayAPI 요청 수신
6Cognito (authorizer)들어오는 요청의 토큰 검증
7Lambda요청을 담당 Lambda로 라우팅·처리
8DynamoDB조회 요청 시 저장된 스캔 결과를 로드
9Lambda → OrgManagementDelegated Admin·Trusted Access 스캔 시, 관리 계정의 역할을 Assume해 Organizations API 호출
10EventBridgePolicy 스캔을 하루 1회 스케줄로 트리거
11Step FunctionsPolicy 스캔 작업을 오케스트레이션
12Lambda계정별로 Spoke 역할 Assume 가능 여부 확인
13Lambda → Spoke각 계정에서 계정×서비스×리전 단위로 정책 수집
14→ DynamoDB수집한 정책을 저장 (이후 Policy Explorer에서 조회)

크게 보면 ① 웹 UI·인증(1~8), ② 온디맨드 스캔(9), ③ 하루 1회 자동 Policy 스캔(10~14) 

배포 구성 — 어느 스택을 어디에

여기서 한 가지 짚어둘 점은, **”3개 템플릿을 전부 관리 계정(Payer)에 올리는 것이 아니다”**라는 것입니다. 스택마다 작업하는 계정과 배포 방식이 다릅니다. 특히 혼동하기 쉬운 부분이 Spoke인데, StackSet 자체는 관리 계정에서 생성하고, 그 StackSet이 각 멤버 계정에 리소스(스택 인스턴스)를 생성하는 구조입니다. 즉 “StackSet을 생성하는 곳”과 “리소스가 생성되는 곳”이 다릅니다.

배포 자체는 복잡하지 않습니다. 공식 문서(AWS CloudFormation templates)에 3종의 템플릿이 제공되며, 각 템플릿을 해당 계정의 CloudFormation 콘솔에서 **”템플릿 파일 업로드”**로 올려 배포하면 됩니다.

  • account-assessment-for-aws-organizations-hub.template — Hub
  • account-assessment-for-aws-organizations-spoke.template — Spoke
  • account-assessment-for-aws-organizations-org-management.template — OrgManagement

이때 Hub와 OrgManagement는 일반 Stack으로, Spoke만 StackSet으로 배포한다는 점만 기억하면 됩니다.

상세 절차는 공식 문서로 갈음하고, 전체 그림만 정리하면 다음과 같습니다.

스택배포 방식생성하는 계정실제 리소스가 생성되는 곳
OrgManagement일반 Stack (1회)관리 계정(Payer)관리 계정(Payer)
Hub일반 Stack (1회)중앙 계정 1개 (Payer일 필요 없음, 임의의 멤버 계정 가능)그 계정
SpokeStackSet (1회 생성 → 다계정 배포)관리 계정(Payer)에서 StackSet 생성스캔 대상 모든 멤버 계정 (원하면 Hub 계정 포함)

배포 순서는 다음과 같습니다. 순서가 중요합니다 — Hub를 가장 먼저 배포해야 합니다.

  1. 중앙 멤버 계정에서 Hub 스택 생성 — 웹 UI·API·스캔 엔진과 함께, 뒤 단계에서 신뢰 주체(Principal)가 되는 역할({네임스페이스}-{리전}-TrustedAccess 등)이 이 계정에 생성됩니다.
  2. 관리 계정(Payer)에서 OrgManagement 스택 생성 — Hub가 Organizations 데이터(계정 목록·위임 관리자·신뢰 액세스)를 읽을 IAM 역할을 생성합니다. 이 역할의 신뢰 정책이 1단계에서 만든 Hub 역할을 Principal로 참조하므로, Hub가 먼저 존재해야 합니다.
  3. 관리 계정(Payer)에서 Spoke StackSet 생성 — StackSet 자체는 관리 계정에서 관리되고, 이 StackSet이 스캔 대상 각 멤버 계정에 “Hub가 Assume할 실행 역할”을 생성합니다.

⚠️ 배포 순서가 중요: OrgManagement를 Hub보다 먼저 배포하면 Invalid principal in policy 오류로 실패합니다. OrgManagement 역할이 아직 존재하지 않는 Hub 역할을 Principal로 참조하기 때문입니다. IAM은 신뢰 정책의 Principal 역할이 실제로 존재할 때만 검증을 통과시키므로, 반드시 Hub → OrgManagement 순서로 배포하세요.

핵심은 Spoke만 StackSet이라는 점, 그리고 StackSet은 관리 계정(Payer)에서 생성하지만 실제 역할 리소스는 각 멤버 계정에 생성된다는 점입니다. 스캔 대상 계정이 많으므로 하나씩 올리는 대신 조직 전체(또는 특정 OU)에 일괄 배포합니다. 이를 위해 관리 계정에서 CloudFormation StackSets의 신뢰 액세스(서비스 관리형 StackSet)가 활성화되어 있어야 합니다.

Spoke StackSet을 배포할 때 두 가지만 더 기억하면 됩니다.

  • 리전은 1개만 지정합니다. Spoke가 만드는 것은 IAM 역할(글로벌 리소스)이므로 여러 리전을 선택하면 두 번째 리전부터 “역할이 이미 존재함” 충돌로 실패합니다. Hub와 같은 리전 하나만 고르면 됩니다. (실제 정책 스캔은 Hub가 이 역할로 전 리전을 순회하므로, Spoke 스택 자체는 한 리전이면 충분합니다.)
  • 관리 계정(Payer)에는 Spoke가 자동 배포되지 않습니다. 서비스 관리형 StackSet은 관리 계정을 자동 배포 대상에서 제외하는 것이 AWS의 기본 동작입니다. 따라서 관리 계정은 Spoke 역할이 생기지 않아 Policy Explorer 스캔에서 빠질 수 있습니다. 관리 계정의 정책까지 봐야 한다면 OrgManagement 역할로 조회되는 범위를 확인하거나 별도로 처리해야 합니다. (조직 구조를 모르면 “관리 계정만 왜 안 잡히지?”로 헤매기 쉬운 지점입니다.)

네임스페이스 — 세 스택을 묶는 공통 키

세 스택은 배포 시 지정하는 네임스페이스(접두사) 를 기준으로 서로 연동됩니다. Hub가 각 계정의 Spoke 역할을 Assume할 때 이 네임스페이스로 역할 이름을 조합해 찾기 때문에, Hub와 Spoke에 동일한 네임스페이스를 지정해야 서로를 인식합니다. 네임스페이스가 어긋나면 역할 이름이 맞지 않아 스캔이 실패합니다.

생성되는 리소스 이름은 대략 다음과 같은 형태입니다. (네임스페이스 mzc 예시)

mzc-ap-northeast-2-AccountAssessment-Spoke-ExecutionRole

주의: 네임스페이스는 짧게 잡으세요. 위처럼 네임스페이스 뒤에 리전·고정 접미사가 붙어 이름이 조합되는데, IAM 역할 이름은 최대 64자입니다. 네임스페이스를 길게 주면 이 한도를 넘겨 StackSet 배포가 실패할 수 있습니다. 태그나 스택 이름도 같은 네임스페이스를 공유하므로, 처음부터 2~4자 정도의 짧은 값으로 정하는 것이 안전합니다.

Hub 배포 시 짚어둘 파라미터

Hub 스택 배포 시 입력값이 여러 개지만, 대부분 기본값으로 두어도 됩니다. 주의가 필요한 것만 추리면 다음과 같습니다. (나머지는 공식 문서 참고)

  • Namespace — 앞서 설명한 공통 접두사. 짧게, 그리고 Spoke·OrgManagement에 같은 값으로.
  • Web UI Login User Email — 초기 관리자 계정이 이 이메일로 생성되고 임시 비밀번호가 메일로 발송됩니다. 반드시 수신 가능한 주소를 넣으세요.
  • CIDR ranges — 웹 UI·API에 접근을 허용할 IP 대역입니다. 전체 개방(0.0.0.0/1,128.0.0.0/1)도 가능하지만, Hub는 전 계정 정책을 읽는 민감한 콘솔이므로 접속할 IP를 /32로 좁혀 지정하는 것을 권장합니다.
  • Org Management Account ID — 조직 관리 계정(Payer)의 계정 ID. 뒤에서 OrgManagement 스택을 올릴 그 계정입니다.

Hub를 어느 계정에 올릴 것인가는 두 가지 기준으로 판단했습니다.

  • 보안 민감도 (공식 권고): Hub 계정은 전 계정의 리소스 이름·정책·버킷명·시크릿명까지 읽을 수 있습니다. 따라서 Hub는 스캔 대상 중 가장 민감한 계정만큼 엄격하게 보호해야 합니다.
  • 비용 귀속 (실무 고려): Hub는 CloudFront·API Gateway·Cognito·Lambda·DynamoDB 등 웹 애플리케이션 리소스가 상주하며 요금이 발생합니다. 따라서 그 비용이 붙어도 무방한 계정을 고르는 것이 현실적입니다.

실제 프로젝트에서는 위 기준을 종합해, 관리 계정(Payer)이 아니라 Shared 성격의 공용 계정에 Hub를 배포했습니다. 관리 편의성과 비용 귀속이 명확하다는 점이 결정적이었습니다.

Spoke 역할이 가지는 권한 — 읽기 전용

보안 검토 관점에서 한 가지 안심할 수 있는 점은, 각 계정에 배포되는 Spoke 역할의 권한이 전부 조회(Get/List/Describe) 전용이라는 것입니다.

s3:GetBucketPolicy, kms:GetKeyPolicy, iam:ListRolePolicies, ram:GetResourcePolicies처럼 정책을 읽기만 할 뿐, 리소스를 변경·삭제하는 권한은 없습니다. 조직 전체에 역할을 심는 작업인 만큼, 배포 전 이 권한 범위를 직접 확인해두면 내부 보안 리뷰를 통과하기 수월합니다.


4. 활용 방안

본문의 핵심 내용입니다. 솔루션은 “매칭되는 정책 목록”까지 제공하지만, 그것을 ‘사전에 조치할 것 / 사후에 조치할 것’으로 바꾸는 판단은 엔지니어의 판단 영역입니다.

4-0. 이번 케이스의 핵심은 Policy Explorer

웹 UI에 로그인하면 왼쪽 메뉴에 세 가지 스캔이 있지만, Payer 이관에서 실제로 쓰는 것은 Policy Explorer 하나입니다. 이관 시 무효가 될 의존성(조직 ID 조건, 레거시 계정 참조)은 전부 정책 안에 있고, 그 정책을 조직 전 계정에서 전수로 뽑아주는 것이 Policy Explorer이기 때문입니다. 이 글의 4-1 이후 내용도 전부 Policy Explorer 결과를 다룹니다.

Policy 스캔은 버튼으로 돌리는 것이 아니라, 하루 한 번 스케줄로 자동 실행된다는 점만 알고 있으면 됩니다. 그래서 배포 직후에는 Job History가 비어 있는 것이 정상이고, 다음 스케줄 시각이 지나면 결과가 채워집니다. (Job History에서 Started by가 event-rule로 표시되면 스케줄이 자동 실행한 것입니다.)

나머지 두 스캔은 보조 수단으로, 이번 케이스에서는 참고용입니다.

  • Delegated Admin Accounts — 서비스별 위임 관리자 계정을 보여줍니다. 화면의 Start Scan으로 즉시 실행됩니다.
  • Trusted Access — 조직에서 신뢰 액세스가 활성화된 서비스를 보여줍니다. 역시 Start Scan으로 실행됩니다.

보조 화면을 볼 때 한 가지만 유의하면 됩니다. 행이 “계정 단위”가 아니라 (계정 × 서비스) 조합 단위입니다. 그래서 한 계정이 여러 서비스의 위임 관리자이면 같은 계정이 여러 행으로 반복됩니다. (예: Audit 계정이 Config와 Resource Explorer의 위임 관리자이면 두 줄 — 중복이 아니라 정상입니다.) 또한 전체 계정 목록이 아니라 위임 관리자로 지정된 계정만 보인다는 점도 함께 기억하세요.

4-1. 스캔 실행

Policy Explorer는 정책 유형(Identity / Resource / SCP)을 고르고, Action·Resource·Condition 필드로 검색하는 구조입니다. 이번에는 다음을 검색 대상으로 삼았습니다.

  • Condition 필드에 구 조직 ID → aws:PrincipalOrgID / aws:SourceOrgId 조건이 걸린 정책 (유형 ①)
  • Resource 필드에 구 관리·Audit·Log-Archive 계정 ID → 해당 계정을 참조·신뢰하는 정책 (유형 ②)

4-2. 결과 조회와 정리

스캔 결과, 전체 정책 아이템 중 위 4개 대상에 매칭된 항목이 수백 건 나왔습니다. 결과를 조회하는 방법은 두 가지입니다.

방법 1. 웹 콘솔(Policy Explorer)에서 필터링

가장 손쉬운 방법입니다. 검색을 실행하면 매칭된 정책이 AccountId / Resource / Action / Effect 컬럼의 리스트로 나오고, 각 행의 View Policy로 정책 원문(JSON)을 바로 확인할 수 있습니다. 우상단 Download Results로 결과를 CSV로 내려받는 것도 가능합니다. 빠르게 훑어보거나 특정 조건 몇 개만 확인할 때 적합합니다.

방법 2. DynamoDB에서 직접 조회

이 솔루션은 스캔 결과를 DynamoDB 테이블에 저장합니다. 이번처럼 “구 조직 ID, 구 관리·Audit·Log-Archive 계정 ID 네 가지를 한꺼번에 걸러서, 리소스 단위로 중복을 제거하고, 관리 주체(커스텀 vs CT·솔루션 자동생성)로 분류”하는 식의 대량·복합 가공은 콘솔 필터만으로는 한계가 있습니다. 그래서 Hub 계정의 DynamoDB 테이블을 직접 조회해 전체 데이터를 추출한 뒤 가공했습니다.

  • raw 데이터: statement 단위 전체 (보관용)
  • 정리 데이터: 리소스 단위로 중복 제거 + 관리 주체 컬럼 추가 → 실제 조치 대상만 추림

요약하면, 빠른 확인은 콘솔, 전수 분석·분류는 DynamoDB 직접 조회입니다. 수백 건 규모를 체계적으로 분류해야 한다면 후자가 거의 필수입니다.

여기서 첫 번째 교훈입니다. “매칭 건수 = 조치 대상”이 아닙니다. 매칭의 상당수는 Control Tower나 솔루션이 자동 생성한 리소스(신규 환경에서 자동으로 재생성됨)였고, 실제 조치가 필요한 것은 커스텀 리소스였습니다. 이 분류만으로도 조치 범위가 절반 이하로 줄었습니다.

4-2-1. 스캔으로 드러난 의존성 — 실제 예시

Policy Explorer가 집어낸 정책이 실제로 어떻게 생겼는지 보면 이해가 빠릅니다. 아래 예시는 실제 스캔 결과를 마스킹한 것으로, 이관 시 거동이 다른 두 유형을 대표합니다. (계정 ID·조직 ID는 모두 가상 값)

유형 ①: 조직 ID 조건 — 이관 순간 무효가 되는 정책

백업 점검용 역할의 신뢰 정책이 aws:PrincipalOrgID로 구 조직 ID를 조건에 걸고 있었습니다. 조직에 속한 주체라면 Assume를 허용하되, 그 범위를 조직 ID 조건으로 제한하는 전형적인 패턴입니다. 계정이 신규 조직으로 이동하면 조직 ID가 바뀌어 이 조건이 더 이상 맞지 않게 되고, 해당 역할의 AssumeRole이 즉시 거부됩니다. → 사전 조치 대상

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "*" },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": { "aws:PrincipalOrgID": "o-xxxxxxxxxx" }
      }
    }
  ]
}

같은 유형이 S3 로그 수집 버킷에서도 나왔습니다. 중앙 로그 버킷 정책이 aws:SourceOrgID(구 조직 ID) 조건으로 조직 내 계정의 로그 전송을 허용하고 있어, 이관 순간 VPC/ELB/Flow Log 전송이 거부됩니다.

{
  "Effect": "Allow",
  "Principal": { "Service": "delivery.logs.amazonaws.com" },
  "Action": "s3:PutObject",
  "Resource": "arn:aws:s3:::apne2-prd-example-elb-access-log-bucket/*",
  "Condition": {
    "StringEquals": { "aws:SourceOrgID": "o-xxxxxxxxxx" }
  }
}

조치 방법: 조건을 삭제하지 않고 신규 조직 ID를 배열로 함께 추가(["o-xxxxxxxxxx", "o-yyyyyyyyyy"])해두면, 이관 전에 미리 반영해도 기존 동작이 유지됩니다. 안정화 후 구 값을 제거합니다.

유형 ②: 계정 ID 참조 — 이관해도 끊기지 않는 정책

반면 아래 역할은 구 Audit 계정 ID를 Principal로 직접 신뢰합니다. 계정 ID는 조직을 옮겨도 바뀌지 않으므로 이관 직후에도 그대로 동작합니다. 다만 신규 환경에서 Audit 계정의 역할이 바뀌므로, 재구성 시점에 맞춰 사후에 정리하면 됩니다. → 사후 조치 대상

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": { "AWS": "arn:aws:iam::333333333333:role/ProwlerCodeBuildRole" },
      "Action": "sts:AssumeRole"
    }
  ]
}

이처럼 같은 “매칭”이라도 조건에 조직 ID가 걸렸는지, 계정 ID를 참조하는지에 따라 조치 시점이 완전히 갈립니다. 이 구분이 다음 단계의 핵심입니다.

4-3. 의존성 해석 — 결과를 “판단”으로 바꾸기

매칭된 정책을 **”그 의존성이 무효가 되면 무엇이 중지되는가”**로 재분류했습니다. 이것이 조치 시점(사전/사후)을 가르는 핵심이었습니다.

판단축은 의존 방식이었습니다.

의존 방식이전 순간 거동조치 시점
조직 ID 조건 (aws:PrincipalOrgID / aws:SourceOrgId)조직이 바뀌는 순간 조건이 맞지 않게 되어 접근이 즉시 거부됨사전 필수
특정 계정 ID 참조/신뢰계정 ID는 불변 → 이전해도 그대로 동작사후 (신규 환경 재구성으로 해결)

그리고 “중지되는 대상”을 세 축으로 나눴습니다.

축중지되는 것원칙
워크로드 서비스운영 트래픽·배포·계정 간 통신·DNS사전 필수
로그 저장Flow Log·ELB 로그·보안 버스 전송조직 ID 조건이면 사전, 계정 ID 참조면 사후
보안 조치보안 점검·알림·스캔 자동화대부분 사후 (탐지 자체는 유지되므로)

예를 들면 다음과 같습니다.

  • ECR golden image, CodeArtifact, 빌드용 S3 (조직 ID 조건) → 이전 직후 첫 배포에서 이미지 pull 실패로 직결 → 사전 필수. 네트워크는 대부분 챙기지만 이쪽이 가장 놓치기 쉬운 지점이었습니다.
  • RAM 공유(TGW, Route53 Profile 등) → 이전 순간 계정 간 통신·DNS 해석 단절 → 사전 필수 (계정 ID 기반 공유 사본 생성)
  • 중앙 로그 수집 버킷 (조직 ID 조건) → 이전 순간 로그 전송이 거부됨 → 사전 조치가 무해하므로 함께 처리
  • 보안 점검/알림/Prowler/SIEM → 계정 ID 참조라 그대로 동작하고, 신규 Audit/Log-Archive에 재구성 예정 → 사후

핵심 원칙: 조직 ID 조건은 **”삭제하지 않고 신규 값을 추가”**해두면 이전 전에 미리 반영해도 기존 동작이 깨지지 않습니다. (예: ["구 Org", "신규 Org"] 병행) → 사전에 안전하게 선반영하고, 안정화 후 구 값을 제거합니다.

4-4. 교차검증

처음에 수동으로 찾았던 20여 건이 Account Assessment 결과에 전부 포함되는지 대조했습니다. 전부 재확인되었고, 거기에 더해 수동으로는 놓쳤던 IAM 정책·워크로드 계정·SIEM 인프라까지 드러났습니다. 이를 통해 ① 솔루션 결과의 신뢰성과 ② 수동 조사의 범위 한계를 동시에 확인할 수 있었습니다.


5. 활용 팁 / 주의사항

실전에서 유용했던 포인트들입니다.

  • 스캔이 “부분 실패”로 끝나는 것은 대부분 정상입니다. Job 상태가 SUCCEEDED_WITH_FAILED_TASKS로 표시되어 당황하기 쉬운데, Job 상세의 실패 내역을 열어보면 대부분 Error가 "Service is not available in {리전}." — 즉 미사용·미지원 리전에 그 서비스 자체가 없어서 난 무해한 실패입니다. 권한 거부(AccessDenied)가 아니므로, 실사용 리전 기준으로 AccessDenied가 0건인지만 확인하면 데이터는 신뢰할 수 있습니다.
  • 자동 생성 리소스와 커스텀 리소스를 먼저 구분하세요. CT baseline, SSO 예약 역할 등은 신규 환경에서 재생성되므로 조치 대상이 아닙니다. 이 분류가 작업량을 크게 줄여줍니다.
  • “매칭 = 조치”가 아닙니다. 매칭을 의존 방식(조직 ID vs 계정 ID) × 멈추는 대상(서비스/로그/보안)으로 재분류하는 것이 실제 작업의 대부분입니다.
  • 스캔은 시점 스냅샷입니다. 이전 전후로 재스캔해서 잔존 리소스(예: 자동 삭제되지 않는 역할)를 확인하는 것이 좋습니다.
  • Hub 계정 보안을 처음부터 엄격히 관리하세요. 전 계정 정책을 읽는 계정입니다.

마치며

Account Assessment for AWS Organizations는 “조직 전체 정책에 대한 전수 가시성”을 제공합니다. 다만 그 결과는 출발점이지 결론이 아닙니다. 매칭 목록을 ‘어떤 의존성이 언제 무효가 되어 무엇을 멈추게 하는가’로 해석하고 사전/사후 조치로 설계하는 것이 실제 가치였습니다.

다음과 같은 상황이라면 도입을 적극 권합니다.

  • 관리 계정(Payer) 교체
  • 조직 간 계정 대량 이관 (M&A, MSP 이관)
  • 조직 ID 조건·레거시 계정 참조 정리
  • 조직 전반 보안 감사

참고 링크

본 글의 공식 문서 인용은 라이선스 준수를 위해 요약·재구성한 것입니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다