TM Taeyang Moon
Demo · 아키텍처 해설

거버넌스 면역 스토리지 — Private Endpoint

거버넌스가 스토리지 공개 접근을 잠가도 자동화 잡이 계속 동작하게

Private EndpointVNet 주입형 Container AppsPrivate DNSVNet PeeringManaged Identity(키리스)거버넌스 공존
🔗
라이브 사이트moontaeyang.com
사이트 열기 →

이 문서는 "클라우드 거버넌스 정책이 내 스토리지를 자동으로 잠가버려도, 자동화 잡이 계속 동작하게 만드는 법" 을 하나의 Azure 아키텍처 사례로 보고, 어떤 서비스를 어떻게 조합했는지, 왜 그렇게 설계했는지를 직접 구축하려는 엔지니어 관점에서 설명합니다. (기준일: 2026-06-16 · 리전: East US 2 · 대상: moontaeyang.com의 두 디지스트 에이전트)

🎯 이 데모가 보여주는 것: 많은 대기업/규제 환경에는 중앙 거버넌스 자동화가 돌면서 "스토리지 공개 접근 차단(publicNetworkAccess=Disabled)" 같은 보안 베이스라인을 사람 몰래 주기적으로 강제합니다. 우리가 직접 켜 놔도 몇 분~하루 만에 다시 꺼집니다. 이 환경에서 공개 접근에 의존하던 자동화 잡은 어느 날 갑자기 깨집니다. 해법은 싸우는 게 아니라 사설 경로(Private Endpoint)로 우회하는 것 — 정책과 공존하면서도 잡은 끊기지 않게 만드는 설계입니다.


한눈에 보기

핵심 키워드: Private Endpoint · VNet 주입형 Container Apps · Private DNS · VNet Peering · Managed Identity(키리스) · 정책과의 공존


비즈니스 관점 — 왜 중요한가


아키텍처

  [공개 사용자]                         ※ 스토리지 공개 접근(pna)이 꺼져도 영향 없음
      │ HTTPS
      ▼
  Azure Static Web Apps  ──  moontaeyang.com  (engit-daily · azure-daily 섹션)
      ▲                                   공개 서빙은 SWA가 전담
      │ swa deploy(아웃바운드)
      │
  ┌─────────────────────────── rg-english-daily ───────────────────────────┐
  │  VNet 10.60.0.0/16                                                       │
  │   ├ snet-aca /23 (위임: Microsoft.App/environments)                      │
  │   │    └ Container Apps Env (VNet 주입형, 워크로드 프로파일)              │
  │   │         └ engitdaily-job ── UAMI(키리스) ──┐                          │
  │   └ snet-pe /24                                 │ blob R/W                │
  │        └ Private Endpoint(blob) 10.60.2.4 ◀─────┘                         │
  │             │ 사설 통로                                                   │
  │             ▼                                                             │
  │        Storage engitdailyst…  (pna=Disabled 여도 PE는 통과)               │
  │   Private DNS: privatelink.blob.core.windows.net                         │
  │        engitdailyst… → 10.60.2.4   (+ azwhatsnewst… → 10.61.2.4 교차등록) │
  └──────────────────────────────┬──────────────────────────────────────────┘
                                  │  VNet Peering (양방향 Connected)
  ┌──────────────────────────────┴──── rg-azwhatsnew ───────────────────────┐
  │  VNet 10.61.0.0/16  (snet-aca /23, snet-pe /24)                          │
  │    Container Apps Env(VNet 주입형) └ azwhatsnew-job ─ UAMI ─ PE 10.61.2.4 │
  │    Storage azwhatsnewst…   ·   Private DNS(상동, engit 레코드도 교차등록)  │
  └─────────────────────────────────────────────────────────────────────────┘

  거버넌스(MCAPSGov-AutomationApp): 두 스토리지의 pna를 주기적으로 Disabled로 강제 → 그래도 잡은 PE로 동작

구성 요소와 설계 결정

1) Container Apps 환경을 "VNet 주입형"으로 — 재생성이 불가피한 이유

2) Storage Private Endpoint(blob) + Private DNS

3) 교차 의존성 — 이 데모의 가장 중요한 교훈

4) 공개 서빙은 SWA가 분리 — 창고를 잠가도 손님은 무관


검증 (실제로 잠그고 돌려봄)

두 스토리지를 모두 publicNetworkAccess=Disabled + defaultAction=Deny잠근 상태에서 양쪽 잡 실행:

확인 항목 결과
engit 잡 / azwn 잡 둘 다 Succeeded
자기 blob 쓰기 Blob 업로드 완료 …
교차 미러(상대 창고 읽기) 섹션 미러링 engit-daily:4 / azure-daily:8 ✅ (PE 경유)
인증 오류 0건
라이브 사이트 moontaeyang.com /·/engit-daily/·/azure-daily/ 모두 200
알림 텔레그램 200

정책이 공개를 잠근 steady-state에서도 자동화가 끊기지 않음을 실측으로 확인.


비용 / 트레이드오프

항목
Private Endpoint 2개 ≈ 월 $15 + 데이터 처리 소액
Private DNS / VNet / Peering 사실상 무료(동일 리전 peering, 소액 쿼리)
환경 재생성 일회성 노력(다운타임은 cron 사이 짧게)

직접 만들 때 체크리스트

  1. 스토리지가 데이터플레인(잡 R/W) 용인지, 공개 서빙용인지 분리한다(서빙은 SWA/CDN로).
  2. 잡을 VNet 주입형 Container Apps 환경에 올린다(기존 환경은 재생성 필요, 잡 environmentId 불변).
  3. UAMI를 재사용해 키리스 + 역할 재부여 최소화.
  4. 스토리지에 PE(blob) + privatelink.blob.core.windows.net Private DNS.
  5. 여러 잡이 서로의 스토리지를 읽는다면VNet Peering + 각 zone에 모든 스토리지 A레코드 교차 등록.
  6. 배포 스크립트의 데이터플레인 호출(--static-website 등)은 pna=Disabled 내성 처리.
  7. 실제로 잠그고(--public-network-access Disabled) 잡을 돌려 steady-state를 검증한다.

참고 코드 / 위치

← 데모 목록학습 포털 홈