기준: SOA-C02 시험 가이드오류 제보
도메인 3(배포·프로비저닝·자동화 18%)과 도메인 4(보안·컴플라이언스 16%)는 얼핏 정반대로 보인다. 하나는 "빠르게 바꾸기", 다른 하나는 "함부로 못 바꾸게 막기". 하지만 두 도메인은 같은 질문의 양면이다 — 변경을 어떻게 안전하게 다룰 것인가. 배포 자동화는 변경을 빠르고 되돌릴 수 있게 만들고, 보안은 그 변경 권한을 최소한으로 가둔다. 빠른 배포 없는 보안은 운영을 마비시키고, 보안 없는 빠른 배포는 사고를 양산한다.
이 글은 두 도메인을 키워드로 훑는 대신, CloudFormation이 왜 "선언적·멱등적"으로 설계됐는지, 배포 정책들이 가용성과 비용 사이에서 어떤 수학적 trade-off를 하는지, Session Manager가 SSH를 대체하는 내부 메커니즘, 그리고 IAM 정책 평가가 어떤 결정 트리를 따르는지를 파고든다.
CloudFormation을 "복습"할 때 스택·템플릿·Change Set을 외우지만, 그 밑에 깔린 더 큰 이야기는 선언형(declarative)이 명령형(imperative)을 이긴 역사다. 이 차이를 잡으면 IaC 전체가 한눈에 정리된다.
명령형 프로비저닝은 "이걸 만들고, 다음에 저걸 연결하고, 그 다음 이 설정을 켜라"처럼 절차를 적는다. 초기 자동화 스크립트(bash, 초기 도구들)가 이 방식이었다. 문제는 두 가지다 — ① 스크립트가 중간에 실패하면 시스템이 어중간한 상태로 남는다(절반만 만들어짐), ② 같은 스크립트를 두 번 돌리면 중복 생성되거나 충돌한다(멱등성 없음).
선언형 프로비저닝은 절차가 아니라 원하는 최종 상태(desired state)를 적는다. "이 VPC, 이 서브넷, 이 EC2가 존재해야 한다"고 선언하면, 도구가 현재 상태와 비교해 차이만큼만 만들거나 고친다. CloudFormation·Terraform·CDK가 모두 이 방식이다. 핵심 이점은 수렴(convergence)이다 — 몇 번을 돌리든, 어느 상태에서 시작하든, 결국 선언한 상태로 수렴한다. 그래서 선언형은 본질적으로 멱등적이고, 실패한 배포를 다시 돌려도 안전하다.
CloudFormation의 자동 롤백도 이 선언형 모델 덕에 가능하다. 스택 생성 중 한 리소스가 실패하면, CloudFormation은 그때까지 만든 것을 모두 되돌려 이전 상태로 수렴시킨다(rollback). 명령형 스크립트라면 "어디까지 만들었는지"를 일일이 추적해 역순으로 지워야 하지만, 선언형은 "이전 선언 상태"라는 명확한 목표가 있으므로 롤백이 깔끔하다.
💡 관련 이론: 선언형 vs 명령형은 프로그래밍 패러다임의 오랜 주제다(SQL이 선언형, C가 명령형인 것과 같은 구분). 인프라에서 선언형이 승리한 결정적 이유는 상태 조정(state reconciliation) 루프 때문이다. Kubernetes의 controller, Terraform의 plan/apply, CloudFormation의 drift detection이 모두 같은 패턴을 쓴다 — "원하는 상태(desired)"와 "실제 상태(actual)"의 차이(diff)를 계산하고, 그 차이를 0으로 만드는 액션만 실행한다. 이 reconciliation 루프는 제어 이론의 피드백 제어와 같은 구조다. Drift Detection이 바로 이 diff 계산을 사람이 볼 수 있게 노출한 기능이다 — 누군가 콘솔에서 손으로 바꿔 actual이 desired에서 벗어나면(drift), 그 차이를 보고한다.
배포 정책 표(All at once / Rolling / Immutable / Blue-Green / Canary)를 외우는 건 쉽다. 어려운 건 시나리오에서 "어느 것이 맞는가"를 고르는 것이고, 그러려면 각 정책이 가용성·롤백 속도·비용이라는 세 축에서 어디에 서 있는지를 이해해야 한다.
핵심 통찰은 이렇다 — 무중단 배포의 비용은 결국 "여분의 용량"이다. 다운타임을 줄이려면 새 버전을 띄울 공간을 따로 마련해야 하고, 그 공간이 비용이다.
| 정책 | 다운타임 | 롤백 속도 | 추가 비용 | 핵심 |
|---|---|---|---|---|
| All at once | 있음 | 느림 | 0 | 개발/비핵심 |
| Rolling | 없음(용량↓) | 느림(재롤링) | 0 | 비용 우선 |
| Rolling + Batch | 없음 | 느림 | 소 | 용량 유지 |
| Immutable | 없음 | 빠름(기존 유지) | 일시 2배 | 안전한 교체 |
| Blue/Green | 없음 | 즉시(전환) | 2배 | 즉시 롤백 필수 |
| Canary | 없음 | 빠름(노출 축소) | 소~중 | 점진 검증 |
Blue/Green의 롤백이 "즉시"인 진짜 이유는 구 버전을 지우지 않고 그대로 두기 때문이다. 전환은 트래픽 라우팅(DNS 레코드 또는 ALB Target Group)만 바꾸는 것이라, 문제가 생기면 라우팅을 되돌리는 한 번의 액션으로 끝난다. 단, DNS 전환을 쓰면 TTL 캐싱 때문에 일부 클라이언트가 한동안 구 버전으로 계속 간다 — 그래서 빠른 전환이 필요하면 DNS보다 ALB Target Group 스왑(즉각 반영)을 쓴다. 또 하나의 함정은 데이터베이스 스키마다. blue와 green이 같은 DB를 공유하면, green용으로 스키마를 바꾼 순간 blue가 깨질 수 있다. 그래서 무중단 배포의 진짜 난이도는 애플리케이션이 아니라 DB 마이그레이션에 있다(backward-compatible 스키마 변경, expand-contract 패턴).
2017년 AWS S3 us-east-1 대규모 장애는 배포·자동화의 위험을 보여준 상징적 사건이다. 한 엔지니어가 청구 시스템의 속도 저하를 디버깅하려고 playbook의 명령으로 일부 서버를 제거하려 했는데, 명령의 입력 파라미터를 잘못 넣어 의도보다 훨씬 많은 서버가 제거됐다. 그 서버들이 S3의 인덱스·배치 서브시스템을 담당하고 있어 연쇄적으로 멈췄고, 복구를 위한 재시작에 수 시간이 걸렸다(이 서브시스템들이 그동안 완전 재시작된 적이 없어 부팅이 예상보다 오래 걸렸다). 교훈은 세 가지였다 — ① 강력한 수동 명령에는 안전장치(한 번에 제거 가능한 최대치 제한)가 필요하다, ② 자동화 도구는 잘못된 입력을 검증해야 한다, ③ 복구 절차(재시작 포함)도 정기적으로 리허설해야 실제로 작동한다. SOA 시험이 "수동 운영 최소화 + 자동화 + 안전장치"를 반복해 강조하는 배경이다.
도메인 3에서 SSM의 7개 컴포넌트를 외우지만, 그중 Session Manager는 내부 동작을 알아야 왜 그렇게 강력한지가 보인다. Session Manager의 핵심은 "인바운드 포트를 하나도 열지 않고" EC2에 셸을 띄운다는 점이다.
전통적 SSH 접속은 22번 포트를 인바운드로 열어야 한다 — 보안 그룹에 22번을 허용하고, 키 페어를 관리하고, 보통 bastion host(점프 서버)를 둔다. 이 모델의 문제는 명확하다. 열린 포트는 공격 표면이고, 키는 분실·유출 위험이며, bastion은 또 하나의 관리 대상이다.
Session Manager는 이 모델을 뒤집는다. EC2 안의 SSM Agent가 SSM 서비스로 아웃바운드 연결을 먼저 맺는다(outbound 443, HTTPS). 운영자가 세션을 시작하면, 트래픽은 이 미리 맺어진 아웃바운드 채널을 타고 흐른다 — 즉 EC2 쪽에는 인바운드 포트가 0개여도 된다. 권한은 키 페어가 아니라 IAM으로 제어하고(누가 어떤 인스턴스에 세션을 열 수 있는가), 모든 세션은 CloudTrail에 기록되며 세션 로그를 S3/CloudWatch Logs로 보낼 수 있다.
이 "아웃바운드만으로 역방향 채널을 만든다"는 패턴은 새로운 게 아니다 — 방화벽 뒤의 머신을 외부에서 제어하는 reverse tunnel의 고전적 기법이다. Session Manager는 이걸 관리형으로, IAM 인증과 감사를 붙여 제공한다. 프라이빗 서브넷의 인스턴스(인터넷 게이트웨이 없음)에서도 VPC Interface Endpoint(PrivateLink)를 통해 SSM에 닿으면 동작한다 — 인터넷 노출 없이 셸을 여는 것이다.
Session Manager의 보안 모델은 제로 트러스트(Zero Trust) 철학의 한 구현이다. 전통적 네트워크 보안은 "내부망은 신뢰, 외부는 차단"이라는 경계(perimeter) 모델이었고, bastion host가 그 경계의 문이었다. 제로 트러스트는 "네트워크 위치로 신뢰하지 않고, 모든 접근을 ID로 인증·인가·기록한다"는 원칙이다. Session Manager가 IP/포트 기반 접근(SSH 22번 + bastion)을 ID 기반 접근(IAM 정책 + CloudTrail 감사)으로 바꾼 것이 정확히 이 전환이다. 시험에서 "SSH 키 관리 부담을 없애고 감사를 강화"가 나오면 거의 항상 Session Manager가 답인 이유다 — 이건 단순 편의가 아니라 보안 패러다임의 이동이다.
도메인 4에서 "SCP → Permission Boundary → Identity → Resource"라는 평가 순서를 외우지만, 정확히 말하면 이건 순서가 아니라 결정 트리(decision tree)다. AWS가 "이 요청을 허용할까?"를 판단하는 알고리즘에는 흔들리지 않는 두 가지 원칙이 있다.
원칙 1 — 기본은 암묵적 거부(implicit deny)다. 아무 정책도 명시적으로 허용하지 않으면 거부된다. 권한은 "안 막혀서 되는 것"이 아니라 "명시적으로 허용돼야 되는 것"이다.
원칙 2 — 명시적 거부(explicit deny)는 그 무엇도 이긴다. 어떤 정책에서든 명시적으로 Deny가 걸리면, 다른 정책 100개가 Allow해도 결과는 거부다. Deny는 절대적 거부권이다.
이 두 원칙 위에서 평가는 여러 정책 유형을 모두 검토한다. SCP(조직 가드레일)·Permission Boundary(IAM 엔티티 권한 상한)·Identity 정책(사용자/역할에 붙은 정책)·Resource 정책(S3 버킷 정책 등)·Session 정책이 모두 입력으로 들어간다. 이들은 AND로 교집합을 이룬다 — SCP가 허용하고 그리고 Boundary가 허용하고 그리고 Identity가 허용해야 비로소 통과한다. 어느 하나라도 빠지면(또는 Deny하면) 막힌다.
요청 평가 결정 트리
─────────────────────────────────
1. 어디서든 명시적 Deny가 있나? ── 예 ──► 거부 (끝)
│ 아니오
▼
2. SCP가 이 액션을 허용하나? ── 아니오 ──► 거부
(조직 멤버 계정만 해당)
│ 예
▼
3. Permission Boundary가 허용하나? ── 아니오 ──► 거부
(Boundary가 설정된 엔티티만)
│ 예
▼
4. Identity 또는 Resource 정책에
명시적 Allow가 있나? ── 아니오 ──► 거부 (암묵적 거부)
│ 예
▼
허용
⚠️ 함정: SCP는 권한을 주지 않는다 — 제한만 한다. SCP에 "S3FullAccess를 Allow"라고 써도, 그 계정의 사용자에게 자동으로 권한이 생기진 않는다. SCP는 "이 계정에서 가능한 권한의 천장(상한)"을 정의할 뿐이고, 실제 권한은 여전히 IAM Identity 정책으로 부여해야 한다. 즉 SCP의 Allow는 "여기까지는 허용해도 된다"는 허가 범위이지 부여가 아니다. 시험에서 "SCP에 Allow를 넣었는데도 권한이 없다"가 나오면, 답은 "SCP는 가드레일(상한)일 뿐 Identity 정책으로 실제 부여가 따로 필요하다"이다. 반대로 SCP에 Deny를 넣으면 그건 강력한 차단이 된다(명시적 Deny가 이기므로).
도메인 4의 비밀 관리에서 Secrets Manager와 Parameter Store SecureString의 선택은 거의 항상 자동 회전(rotation)이라는 한 단어로 갈린다. 둘 다 비밀을 KMS로 암호화해 저장하지만, 설계 목적이 다르다.
Parameter Store는 본래 설정값 저장소다 — 애플리케이션 설정, 환경 변수, 기능 플래그 같은 값을 계층적 경로(/app/prod/db-host)로 관리한다. SecureString 타입으로 비밀도 암호화해 담을 수 있지만, 자동 회전 기능은 없다. 표준 티어는 무료이고, 단순하다.
Secrets Manager는 처음부터 비밀 전용으로 설계됐고, 핵심 차별점이 자동 회전이다. RDS·Redshift·DocumentDB는 내장 회전을 지원하고, 그 외 비밀은 Lambda 회전 함수로 주기적으로 새 비밀을 생성·교체한다. 회전에서 중요한 것은 무중단이다 — 새 비밀을 만들고(create), 대상 시스템에 적용하고(set), 검증하고(test), 활성 버전을 전환(finish)하는 4단계로, 애플리케이션이 끊김 없이 새 비밀로 넘어가게 한다. 또 Cross-Region Replication으로 비밀을 여러 리전에 복제할 수 있다(DR·멀티리전 앱).
| Parameter Store SecureString | Secrets Manager | |
|---|---|---|
| 주 목적 | 설정값 (비밀도 가능) | 비밀 전용 |
| 자동 회전 | 없음 | 있음 (RDS 내장 / Lambda) |
| Cross-Region 복제 | 없음 | 있음 |
| 비용 | 표준 티어 무료 | 비밀당 + API 호출 과금 |
| 선택 기준 | 회전 불필요한 설정·비밀 | DB 패스워드·API 키(회전 필요) |
판단 규칙은 단순하다 — 회전이 필요하면 Secrets Manager, 아니면 Parameter Store. DB 패스워드·API 키처럼 주기적으로 바꿔야 하는 진짜 비밀은 Secrets Manager, 거의 안 바뀌는 설정값은 Parameter Store가 비용 효율적이다.
비밀 회전이 보안에서 중요한 이유는 노출 시간 창(window of exposure)을 줄이기 때문이다. 비밀이 한 번 유출되면, 그 비밀이 유효한 동안 공격자가 그걸 쓸 수 있다. 회전 주기가 30일이면 유출된 비밀의 유효 기간도 최대 30일로 제한된다 — 회전은 "이미 유출됐을지 모르는 비밀"의 피해를 시간으로 가둔다. 더 근본적인 접근은 비밀을 아예 안 쓰는 것이다 — EC2/ECS/Lambda가 IAM Role로 임시 자격증명(STS)을 받아 쓰면, 그 자격증명은 자동으로 짧은 시간(보통 1시간)마다 회전되고 코드에 비밀이 박히지 않는다. 그래서 "DB 패스워드 회전 vs IAM 인증"이 선택지로 나오면, RDS IAM 인증을 쓸 수 있는 상황에서는 비밀 자체를 없애는 IAM 인증이 더 깊은 정답일 수 있다. 회전은 차선, 비밀 제거가 최선이다.
도메인 4의 보안 서비스(GuardDuty/Inspector/Macie/Security Hub/Detective)는 이름만 외우면 시나리오에서 헷갈린다. 각 서비스를 가르는 단 하나의 질문은 "무엇을(어떤 데이터를) 보는가"다.
암기 요령 — GuardDuty는 행위(로그 흐름), Inspector는 취약점(소프트웨어 구멍), Macie는 데이터(S3 내용), Security Hub는 통합(finding 집계), Detective는 조사(맥락 연결). 시나리오에서 "무엇을 보고 싶은가"를 잡으면 답이 갈린다.
GuardDuty의 효용은 EC2 자격증명 탈취 탐지에서 두드러진다. 앞서 본 Capital One 사고처럼, 공격자가 SSRF로 EC2의 IAM 임시 자격증명을 빼내 EC2 밖에서 그 자격증명을 쓰면, GuardDuty의 UnauthorizedAccess:IAMUser/InstanceCredentialExfiltration finding이 발동한다 — 인스턴스에 발급된 자격증명이 그 인스턴스가 아닌 외부 IP에서 사용됐다는 것을 CloudTrail·VPC Flow Logs 상관분석으로 잡아내는 것이다. 이건 Inspector(취약점 스캔)나 Macie(데이터 스캔)로는 절대 못 잡는, 오직 "행위 로그의 흐름"을 보는 GuardDuty만의 영역이다. 각 서비스가 보는 데이터가 곧 탐지 가능 범위를 정의한다는 원칙의 생생한 예다.
도메인 3·4는 "변경을 안전하게 다룬다"는 한 주제의 양면이다 — 자동화로 빠르고 되돌릴 수 있게, 보안으로 최소 권한으로 가둔다.
정리하면 다섯 가지다. ① IaC는 선언형(원하는 상태)이라 멱등적이고 롤백이 깔끔하다 — Drift Detection은 desired와 actual의 diff를 노출한다. ② 무중단 배포의 비용은 결국 여분 용량이다 — Blue/Green은 구 환경을 안 지워 즉시 롤백, 단 DB 스키마와 DNS TTL이 함정. ③ Session Manager는 아웃바운드 443만으로 역방향 채널을 만들어 인바운드 포트 0으로 셸을 연다 — 제로 트러스트의 구현이다. ④ IAM 평가는 결정 트리다 — 명시적 Deny가 모든 걸 이기고, 정책들은 AND 교집합이며, SCP는 부여가 아니라 상한이다. ⑤ 비밀은 회전이 필요하면 Secrets Manager, 아니면 Parameter Store — 더 깊게는 IAM 인증으로 비밀 자체를 없애는 게 최선. 보안 서비스는 "무엇을 보는가"가 각자를 정의한다(GuardDuty=행위, Inspector=취약점, Macie=데이터).
다음 글에선 도메인 5(네트워킹)와 도메인 6(비용·성능)을 같은 깊이로 다시 읽는다 — 패킷이 VPC를 통과하는 경로, NAT와 Endpoint의 비용 구조, 그리고 약정 할인 모델의 수학을 파고든다.
선택지를 클릭하면 정답·해설이 펼쳐집니다.
문제 1
CloudFormation 스택 생성 도중 한 리소스가 실패했다. 명령형 셸 스크립트라면 어중간한 상태로 남았을 텐데, CloudFormation은 깔끔하게 정리됐다. 그 근본 이유는?
문제 2
회사가 새 버전 배포 시 다운타임 0 + 문제 발생 시 즉시 이전 버전으로 복귀를 요구한다. blue/green을 DNS 전환으로 구성했는데, 롤백 후에도 일부 사용자가 한동안 새(문제) 버전으로 계속 간다. 원인과 개선은?
문제 3
보안팀이 EC2 SSH 접속의 키 관리·포트 노출·감사 부담을 모두 없애려 한다. 프라이빗 서브넷(인터넷 게이트웨이 없음) 인스턴스도 대상이다. 가장 적합한 방법과 그 동작 원리는?
문제 4
어떤 계정의 SCP에 s3:* Allow를 명시했는데도 그 계정의 사용자가 S3에 접근하지 못한다. 이유는?
문제 5
RDS DB 마스터 패스워드를 30일마다 무중단으로 자동 교체해야 한다. 가장 적합한 서비스는?
문제 6
공격자가 SSRF로 EC2의 IAM 임시 자격증명을 탈취해 EC2 외부 IP에서 그 자격증명으로 S3에 접근했다. 이 공격을 진행 중에 탐지할 수 있는 서비스는?
문제 7
Elastic Beanstalk 배포에서 "다운타임 0 + 롤백 안전성"을 원하지만 별도 환경(blue/green)을 둘 만큼의 상시 비용은 피하고 싶다. 한 환경 내에서 새 ASG에 전체 새 버전을 띄운 뒤 교체하는 정책은?