보안 거버넌스 — Organizations · SCP · 계정 감시
단일 계정에서 멀티 어카운트로 넘어가는 시점과 방법. AWS Organizations로 계정을 OU로 묶는 구조, SCP로 조직 차원 가드레일을 거는 법(Terraform 예시), Control Tower 랜딩 존, GuardDuty · Security Hub · Config · Inspector를 위임 관리자에서 조직 전체에 켜는 법, IAM Identity Center SSO 연결, 그리고 한 계정 → N 계정 마이그레이션 패턴까지 정리합니다.
28장에서 VPC를 여러 개로 나누는 멘탈 모델을 잡으면서, 진짜 격리는 계정 분리가 더 강하다는 이야기를 했습니다. 이 챕터는 그 다음 단계입니다 — 언제 계정을 나누고, 나눈 계정들을 어떻게 한 조직으로 묶어 통제하는가입니다.
2장 IAM이 한 계정 안에서 누가 무엇을 할 수 있는지를 다뤘다면, 이 챕터는 계정 자체를 여러 개 두고 조직 차원에서 경계를 긋는 거버넌스를 다룹니다. 본 책은 단일 계정에서 OU로 나누는 데까지를 중심으로 하고, 대규모 멀티 어카운트 운영은 개요로 짚습니다.
단일 계정의 한계 — 언제 나누나 #
1~4부는 단일 계정을 가정했습니다. 작은 팀, 한두 개 서비스라면 그것으로 충분합니다. 다음 신호가 보이면 계정을 나눌 때입니다.
- 폭발 반경 — dev의 실수가 prod 리소스를 건드릴 수 있는 구조. 계정을 나누면 권한 경계가 계정 경계와 일치합니다.
- 청구 가시성 — 어느 팀 / 환경이 얼마를 쓰는지 한 계정 안에서는 태그로만 갈라야 합니다. 계정을 나누면 청구서가 자연히 분리됩니다.
- 규제 / 감사 — 특정 워크로드를 격리된 계정에 둬야 하는 컴플라이언스 요구.
- 권한 한계 — IAM 정책만으로는 “이 환경에서는 아예 이 리전 / 이 서비스를 못 쓰게” 같은 조직 차원의 금지를 깔끔히 표현하기 어렵습니다.
AWS Organizations — 계정을 묶다 #
AWS Organizations는 여러 계정을 하나의 조직으로 묶는 도구입니다.
- 관리 계정(management account) — 조직을 만든 최상위 계정. 청구 통합과 조직 관리만 하고, 워크로드는 올리지 않습니다.
- 멤버 계정 — 조직에 속한 나머지 계정들(prod / staging / dev / sandbox 등).
- OU(Organizational Unit) — 계정을 묶는 폴더. 보통 환경(Prod OU / Non-Prod OU)이나 팀 기준으로 나눕니다.
- 통합 청구(Consolidated Billing) — 모든 계정의 청구가 관리 계정으로 모이고, 볼륨 할인과 Savings Plan을 조직 전체가 공유합니다.
Root
├── 관리 계정 (청구 · 조직 관리)
├── Security OU
│ ├── 로그 아카이브 계정
│ └── 보안 감사 계정
├── Prod OU
│ └── prod 계정
└── Non-Prod OU
├── staging 계정
└── dev 계정Terraform으로는 조직 · OU · 계정을 코드로 선언합니다. 관리 계정에서 실행합니다.
resource "aws_organizations_organization" "org" {
feature_set = "ALL" # SCP 등 모든 기능 활성화
# 조직 단위로 켜 둘 서비스의 위임을 허용
aws_service_access_principals = [
"guardduty.amazonaws.com",
"securityhub.amazonaws.com",
"config.amazonaws.com",
"sso.amazonaws.com",
]
}
resource "aws_organizations_organizational_unit" "prod" {
name = "Prod"
parent_id = aws_organizations_organization.org.roots[0].id
}
resource "aws_organizations_organizational_unit" "nonprod" {
name = "Non-Prod"
parent_id = aws_organizations_organization.org.roots[0].id
}
resource "aws_organizations_account" "prod" {
name = "myapp-prod"
email = "aws+prod@example.com" # 계정마다 유일한 이메일
parent_id = aws_organizations_organizational_unit.prod.id
}SCP — 조직 차원의 가드레일 #
**SCP(Service Control Policy)**는 OU나 계정에 거는 권한의 상한선입니다. IAM과의 차이가 핵심입니다.
| IAM 정책 | SCP | |
|---|---|---|
| 적용 대상 | 계정 안의 사용자 / 역할 | OU / 계정 전체 |
| 역할 | 권한을 부여 | 권한의 상한을 정함(부여는 못 함) |
| 효과 | 허용한 것만 가능 | SCP가 막으면 계정 안에서 IAM으로 허용해도 불가 |
즉 SCP는 “이 OU의 어떤 계정도 이건 못 한다"는 가드레일입니다. 실제 권한 = (SCP가 허용) ∩ (IAM이 허용)의 교집합입니다. SCP가 막은 것은 그 계정의 루트 사용자조차 못 합니다.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "DenyOutsideApproved",
"Effect": "Deny",
"NotAction": ["iam:*", "organizations:*", "route53:*", "cloudfront:*"],
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": ["ap-northeast-2", "us-east-1"]
}
}
}]
}이 SCP가 걸린 OU의 계정은 서울과 버지니아 외 리전에 리소스를 만들 수 없습니다. 글로벌 서비스(IAM · Route 53 · CloudFront 등)는 NotAction으로 예외를 둬야 잠기지 않습니다. 또 하나 자주 거는 가드레일은 감사 로그 보호입니다.
{
"Version": "2012-10-17",
"Statement": [{
"Sid": "ProtectAudit",
"Effect": "Deny",
"Action": [
"cloudtrail:StopLogging",
"cloudtrail:DeleteTrail",
"config:DeleteConfigurationRecorder",
"config:StopConfigurationRecorder"
],
"Resource": "*"
}]
}Terraform으로 SCP를 만들어 OU에 붙입니다.
resource "aws_organizations_policy" "region_lock" {
name = "region-lock"
type = "SERVICE_CONTROL_POLICY"
content = file("${path.module}/scp/region-lock.json")
}
resource "aws_organizations_policy_attachment" "region_lock_prod" {
policy_id = aws_organizations_policy.region_lock.id
target_id = aws_organizations_organizational_unit.prod.id
}자주 쓰는 가드레일 묶음: ① 루트 사용자의 위험 작업 금지, ② 승인된 리전 외 사용 금지, ③ CloudTrail / Config 비활성화 금지, ④ 특정 고비용 서비스의 무단 사용 금지.
Control Tower — 랜딩 존 자동화 #
Organizations + SCP + 로그 계정 + 기본 가드레일을 손으로 다 세우는 것은 번거롭습니다. Control Tower는 이 초기 구성(랜딩 존)을 자동으로 깔아 줍니다.
- OU 구조(보통 Security · Sandbox), 로그 아카이브 / 감사 계정, 권장 SCP 가드레일(필수/강력 권장/선택)을 한 번에 설정합니다.
- Account Factory로 새 계정을 표준 형태(네트워크 · 가드레일 · SSO 포함)로 찍어냅니다.
- 작은 조직이 멀티 어카운트로 처음 넘어갈 때 출발점으로 적합합니다.
본 책에서는 Control Tower의 존재와 역할까지만 짚습니다. 한 계정에서 시작해 OU 두세 개로 나누는 단계라면 Organizations + 직접 만든 SCP 몇 개로 충분하고, 계정이 빠르게 늘어나는 조직에서 Control Tower가 값을 합니다.
계정 전체를 감시 — GuardDuty · Security Hub · Config · Inspector #
계정을 나눴다면 조직 전체를 한눈에 감시하는 도구가 필요합니다. 네 가지가 짝을 이룹니다.
| 서비스 | 역할 |
|---|---|
| GuardDuty | 위협 탐지. CloudTrail / VPC Flow Log / DNS 로그를 분석해 이상 행위(권한 탈취, 암호화폐 채굴 등)를 알림 |
| Security Hub | 보안 상태 통합 대시보드. 여러 계정 · 여러 검사 결과를 한곳에 모으고 표준(CIS, AWS FSBP) 대비 점수화 |
| Config | 리소스 구성 추적. “이 보안 그룹이 0.0.0.0/0을 열었는가” 같은 규칙 위반을 기록하고 자동 교정 |
| Inspector | 취약점 스캔. EC2 / ECR 이미지 / Lambda의 알려진 취약점(CVE)을 자동 점검 |
운영의 핵심은 이들을 계정마다 따로 켜지 않고, 위임 관리자 계정(보통 Security OU의 감사 계정)에서 조직 전체에 한 번에 켜는 것입니다. 그러면 새로 만든 계정도 자동 등록 됩니다.
# 관리 계정에서: 감사 계정을 GuardDuty 위임 관리자로 지정
resource "aws_guardduty_organization_admin_account" "this" {
admin_account_id = aws_organizations_account.audit.id
}
# 감사 계정(provider alias)에서: 신규 계정 자동 활성화
resource "aws_guardduty_organization_configuration" "this" {
provider = aws.audit
detector_id = aws_guardduty_detector.audit.id
auto_enable_organization_members = "ALL" # 기존 + 미래 계정 전부
}GuardDuty의 위협 알림(findings)은 19장 EventBridge / SQS / SNS의 EventBridge 규칙으로 받아 SNS → 슬랙 / 이메일로 보냅니다. Config 규칙 위반은 자동 교정(remediation)으로 잇습니다.
resource "aws_cloudwatch_event_rule" "gd" {
name = "guardduty-findings"
event_pattern = jsonencode({ source = ["aws.guardduty"], "detail-type" = ["GuardDuty Finding"] })
}
resource "aws_cloudwatch_event_target" "gd_sns" {
rule = aws_cloudwatch_event_rule.gd.name
arn = aws_sns_topic.security_alerts.arn
}IAM Identity Center — 계정을 넘나드는 권한 #
계정이 여러 개가 되면 계정마다 IAM 사용자를 만드는 것은 관리가 불가능합니다. **IAM Identity Center(구 AWS SSO)**로 한 번 로그인해 여러 계정의 역할을 골라 쓰게 합니다(5장).
- Permission Set = 여러 계정에 공통으로 배포하는 역할 템플릿(예:
AdminAccess,ReadOnly,Developer). - 사용자/그룹을 (계정, Permission Set) 조합에 배정하면, 그 계정에 해당 역할이 자동 생성됩니다.
resource "aws_ssoadmin_permission_set" "developer" {
instance_arn = local.sso_instance_arn
name = "Developer"
session_duration = "PT8H"
}
resource "aws_ssoadmin_account_assignment" "dev_to_prod" {
instance_arn = local.sso_instance_arn
permission_set_arn = aws_ssoadmin_permission_set.developer.arn
principal_id = local.dev_group_id
principal_type = "GROUP"
target_id = aws_organizations_account.prod.id
target_type = "AWS_ACCOUNT"
}한 계정 → N 계정 마이그레이션 패턴 #
이미 단일 계정에서 운영 중이라면, 멀티 어카운트로 넘어가는 현실적인 순서는 다음과 같습니다.
- Organizations 생성 — 새 관리 계정을 만들고 현재 계정을 멤버로 초대합니다. 관리 계정에는 워크로드를 두지 않는 것이 원칙입니다(권한이 가장 강하므로 공격 표면을 최소화).
- 로그 / 감사 계정 분리 — CloudTrail 조직 추적과 로그 아카이브 S3를 전용 계정으로 모읍니다. 이 계정은 SCP로 가장 강하게 보호합니다.
- 환경 계정 분리 — dev / staging / prod를 계정으로 나눕니다. 리소스 이전은 한 번에 하지 않고 새 워크로드부터 새 계정에 올립니다.
- SCP 가드레일 적용 — 리전 제한, 루트 보호, 감사 로그 보호부터 겁니다.
- 계정 간 연결 — VPC는 28장의 Transit Gateway로, 권한은 IAM Identity Center의 SSO로 잇습니다.
멀티 어카운트는 비가역적이지 않지만 이전 비용이 큽니다. 새 계정은 새 워크로드부터 채우고, 기존 단일 계정은 천천히 비워 갑니다. 6부 캡스톤은 단일 계정을 가정하지만, 그 인프라가 Terraform으로 코드화되어 있으면 새 계정으로 옮기는 것도 “다른 계정 provider로 apply"에 가까워집니다.
연습문제 #
- 본인 조직(또는 가상의 조직)을 Root → OU → 계정 구조로 그려 보세요. 최소한 관리 계정 · 로그 계정 · prod · dev를 어떤 OU에 배치할지 정하고, 각 경계가 §“단일 계정의 한계"의 어느 문제를 푸는지 한 줄씩 연결해 두세요.
- “모든 계정에서 ap-northeast-2와 us-east-1 외 리전 사용 금지"를 IAM 정책으로 거는 것과 SCP로 거는 것의 차이를 설명하고, 왜 글로벌 서비스를
NotAction으로 예외 처리해야 하는지를 §“SCP — 조직 차원의 가드레일"의 JSON을 근거로 적어 보세요. - 새 멤버 계정을 추가했을 때 GuardDuty가 자동으로 켜지게 하려면 어느 설정이 필요한지 §“계정 전체를 감시"의 Terraform에서 찾아 적고, 그 알림이 19장의 어느 서비스를 거쳐 담당자에게 닿는지 한 흐름으로 그려 보세요.
한 줄 요약: 폭발 반경 · 청구 가시성 · 규제 · 권한 한계의 신호가 보이면 단일 계정을 멀티 어카운트로 나눈다. AWS Organizations가 계정을 OU로 묶어 청구를 통합하고, SCP는 IAM과 달리 OU/계정 전체에 권한의 상한(가드레일)을 거는 deny 경계이며 실제 권한은 SCP ∩ IAM의 교집합이다(루트도 SCP를 못 넘는다). 글로벌 서비스는 NotAction으로 예외를 둔다. Control Tower는 랜딩 존을 자동화하고, GuardDuty · Security Hub · Config · Inspector는 위임 관리자 계정에서
auto_enable_organization_members로 조직 전체(미래 계정 포함)에 켠다. 계정 간 권한은 IAM Identity Center의 Permission Set로, 네트워크는 Transit Gateway로 잇고, 마이그레이션은 새 워크로드를 새 계정에 올리는 방식으로 점진 진행한다.
다음 챕터 #
다음 30장 재해 복구·백업에서는 한 리전 / 한 AZ가 무너졌을 때 데이터와 서비스를 어떻게 되살리는지를 다룹니다. RDS PITR · S3 버전 관리 / 복제 · AWS Backup으로 백업을 잡고, Pilot Light · Warm Standby · Multi-Site의 리전 간 DR 패턴을 RTO / RPO 기준으로 고르는 법을 정리합니다.