Bye AWS, Hello Azure! Azure 인프라 셋팅

주주: 갓생 상장기를 AWS에서 Azure로 옮기면서 잡은 인프라 구조와 그 선택 이유. 그냥 내가 다시 보려고 정리

Jun Noh

드디어, 주주: 갓생 상장기를 스토어에 심사 올렸다.

기획 단계부터 여기까지 참… 오래 걸렸다.

원래대로라면 AWS에 그대로 올렸어야 하는 게 맞다. RDS부터 ALB까지 전부 세팅해놓고 IAM Role까지 다 박아둔 상태였으니까.

근데 도저히… 크레딧이 바닥나고 있는 AWS에 운영 서버를 새로 올릴 엄두가 안 났다.

AWS 크레딧으로 이것저것 도전해봤지만 전부… 그리 마무리가 좋지 못해서. 이번 주주 만큼은 진짜 제대로 올리고 싶었다.

그러다 알게 됐다. MS의 Azure는 비즈니스 인증만 하면 5,000달러 크레딧을 6개월간 지급해주는 Founders Hub 프로그램이 있다는 걸. 바로 신청을 넣었다.

처음 신청은 반려됐다.

사유는 단순했다. 사업자등록증에 박힌 한글 회사명과 신청서에 적은 영문 회사명이 일치하지 않는다는 거였다. 한국 사업자한테는 흔한 일이다. 사업자등록증에 영문명은 따로 안 박혀 있으니까. 근데 MS 검증 시스템 입장에선 그냥 “다른 회사로 보임”이었던 모양이다.

MS 고객센터에 문의를 넣고 영문 회사명 사용에 대한 증빙을 추가로 제출하니, 며칠 뒤에 승인이 떨어졌다.

셋팅해놓고 보니까 살짝 비싸긴 해도 의외로 AWS보다 편한 부분도 있고 쓰기 괜찮아서, 까먹기 전에 한번 정리해두려고 한다.

들어가기 전에 — 이번 인프라 구조와 선택 이유

이번에 잡은 구조는 이렇게 생겼다.

사용자


Front Door Premium       ── 글로벌 edge POP / TLS 종료 / WAF / Bot Protection


Container Apps           ── API 서버 런타임 (autoscaling, revision 기반 무중단 배포)

  ├── PostgreSQL Flexible Server   ── 운영 DB (General Purpose, Zone-redundant HA)
  ├── Storage Account / Blob       ── 유저 업로드 / 정적 자산
  ├── Key Vault                    ── secrets / connection string
  ├── ACR                          ── 컨테이너 이미지 레지스트리
  └── Application Insights         ── logs / metrics / tracing

각 컴포넌트를 왜 골랐는지 정리하면,

  • Front Door Premium — CDN + WAF + Bot Protection이 한 객체에 묶임. WAF 비용이 SKU에 포함이라 rule을 강화해도 청구가 예측 가능. Standard ↔ Premium은 in-place 변경 불가라 처음부터 Premium으로 결정.
  • Container Apps — Fargate처럼 컨테이너만 올리면 되는 serverless 경험인데, KEDA scale rule(HTTP / CPU / cron 등)이 명령 한 줄에 박힌다. 1인 운영에 EKS / AKS는 과함.
  • PostgreSQL Flexible Server — RDS for PostgreSQL과 1:1 매칭. 주주 규모에선 General Purpose tier 한 대면 충분하고, ZRS(Zone-redundant) HA 옵션을 처음부터 켜둠.
  • Storage Account / Blob — 유저 업로드(인증 사진)와 정적 자산을 같은 account 아래 다른 container로 분리. container 단위로 access policy / lifecycle 다르게.
  • Key Vault — AWS의 Secrets Manager + Parameter Store + KMS를 한 객체로 묶어둔 서비스. Container App에서 KV reference로 secret 자동 주입.
  • ACR — ECR과 거의 동일하지만, ACR Cloud Build로 로컬 Docker 없이 amd64 image 빌드가 가능. M1 맥에서 buildx 셋업 안 해도 됨.
  • Application Insights — OpenTelemetry 표준이라 SDK 한 줄로 통합. CloudWatch + X-Ray가 한 곳에 묶인 셈.

선택 기준은 세 가지였다.

  1. 1인이 관리할 수 있는 단순함 — VNet / Private Link 같은 보안 격상은 트래픽이 들어오기 전까지 미룬다.
  2. Managed Identity 우선 — password나 access key를 코드/환경변수로 들고 다니지 않는다.
  3. 각 영역에 가장 가까운 1급 Azure 서비스 — IaaS(VM)로 우회하지 않는다.

명시적으로 빼둔 것들도 짚어둔다.

  • VNet / Private Link — 트래픽 늘어 보안 격상이 필요해질 때까진 public endpoint + RBAC + firewall 조합으로.
  • Azure OpenAI Service — 주주는 LLM 의존 기능이 적어 후속 도입 대상.
  • Azure DevOps / Pipelines — 기존 GitHub Actions를 그대로 쓰고 ACR Cloud Build를 호출하는 식으로.

이제 서비스별로 어떻게 셋팅했고 어디에서 부딪혔는지 정리해보자.

1. Resource Group과 az CLI — AWS와 결이 다른 부분

Resource Group — 이건 솔직히 개좋다.

AWS 쓰면서 답답했던 게 “이 프로젝트 관련 리소스가 뭐뭐 있더라?”를 한눈에 못 본다는 점이었다.

Tag로 묶고, Resource Groups 서비스 켜서 검색하고… 그러고 나서도 “프로젝트 일괄 삭제” 같은 동작은 직접 스크립트를 짜야 했다.

Azure는 이걸 인프라 1급 객체로 풀어낸다.

az group create --name jooju-rg --location koreacentral

모든 Azure 리소스는 반드시 어떤 RG에 속해야 한다. 한 프로젝트의 모든 인프라가 자동으로 한 폴더에 모이는 셈이다.

정리할 땐 이 한 줄.

az group delete --name jooju-rg --yes --no-wait

EC2 / EBS / RDS / IAM 일일이 콘솔 들어가서 “이거 누가 만든 거지?” 검문하던 시절을 생각하면 확실히 편하다.

명명 컨벤션은 처음부터 잡아두는 게 좋다.

  • RG: <AppName>-RG (Pascal-Hyphen)
  • Region: 메인 사용 region 하나로 통일 (예: koreacentral)
  • 리소스: <appname>-<env>-<service> (소문자 + 하이픈)

az CLI는 aws와 비슷하지만 결이 다르다

az login              # 브라우저 OAuth (aws sso login 비슷)
az account list -o table
az account set --subscription "<sub-name-or-id>"

aws --profile이 Azure에선 az account set --subscription. 한 계정에 여러 sub(=AWS의 account 비슷)이 붙을 수 있어서 작업 시작 전에 항상 sub 확인.

함정 하나. Azure docs는 보통 bash 예제로 나오는데, PowerShell에서 그대로 복붙하면 변수 할당 문법 차이로 silently 실패한다. 특히 trailing slash 제거 같은 bash parameter expansion(${VAR%/})은 PowerShell에 없어서, KV 세팅할 때 “Invalid keyVaultUrl” 같은 모호한 에러로 한참 헤맸다.

# bash
KV_URI=$(az keyvault show --name jooju-kv --query properties.vaultUri -o tsv)
KV_URI=${KV_URI%/}
# PowerShell 호환
$KV_URI = az keyvault show --name jooju-kv --query properties.vaultUri -o tsv
$KV_URI = $KV_URI.TrimEnd('/')

OS별 syntax는 시작 전에 한 번 확인하고 들어가는 게 좋다.

그리고 또 하나, Front Door는 az afd (Standard/Premium, 신규)와 az network front-door (Classic, legacy) 두 CLI가 별도다. 신규 운영은 무조건 az afd. 옛날 docs 보고 따라하다 헷갈리지 않게.

2. PostgreSQL Flexible Server — RDS의 Azure 버전

AWS RDS for PostgreSQL과 1:1 매칭되는 게 Azure Database for PostgreSQL — Flexible Server다.

기능은 거의 같다. 자동 백업, patch, monitoring, read replica, parameter tuning. 다른 포인트가 세 개 있다.

Tier 선택 — Burstable은 HA 미지원

RDS의 db.t3.micro 같은 instance type 대신 Azure는 3-tier로 묶어놨다.

Tier용도HA
Burstable (B-series)dev / 저트래픽
General Purpose (D-series)일반 운영✓ Zone-redundant
Memory Optimized (E-series)큰 메모리 read-heavy

처음에 비용 아낀다고 Burstable로 만들었다가, 운영 올리려고 HA 켜려니 안 됐다. Burstable → General Purpose 변경도 케이스에 따라 막히는 경우가 있어서, 운영은 처음부터 General Purpose로 박는 게 안전하다.

--public-access 0.0.0.0은 모든 IP 허용이 아니다

az postgres flexible-server create ... --public-access 0.0.0.0

처음 봤을 땐 의아했다. ”??? 모든 IP 허용?”

실제 의미는 “퍼블릭 endpoint는 만들되, firewall rule은 비워둔다” 였다.

  • public hostname은 만들어지지만,
  • firewall rule을 따로 추가하지 않으면 누구도 접속 불가.
az postgres flexible-server firewall-rule create ... \
  --start-ip-address $MY_IP --end-ip-address $MY_IP

AWS RDS의 Security Group + parameter group을 분리해놓은 디자인이다. 처음엔 헷갈리지만 익숙해지면 깔끔하다.

비밀번호의 @는 host parsing을 깬다

운영 비번에 @, #, $ 같은 특수문자를 그대로 박으면 connection string에서 host parsing이 깨진다.

postgresql://admin:p@ssw0rd@server:5432/db
                  ↑ @가 두 번 → 호스트 파싱 실패

Prisma가 뱉는 에러는 “invalid port number in database URL”. 진짜 invalid port가 아니라, password의 @가 host:port split을 망가뜨려서 5432/db가 port 자리로 밀려난 거다.

URL-encode 하든가, 아예 비번에 안전한 문자만 쓰든가. 나는 후자를 택했다.

3. Storage Account + Blob — S3의 2단계 모델

S3 bucket은 1단계(account → bucket)인데, Azure는 2단계(Storage Account → Container) 다.

AWS S3Azure Blob
Bucket 이름 (전 세계 unique)Storage Account 이름 (전 세계 unique)
ObjectBlob
Pre-signed URLSAS (Shared Access Signature) URL
ACL / Bucket PolicyContainer access level + RBAC

Storage Account 안에 여러 Container(= S3의 bucket-like)를 두는 식.

운영 패턴은 보통 이렇게 묶었다.

  • Account: joojustorage
  • Container 1: uploads (유저 인증 사진)
  • Container 2: assets (정적 자산)
  • Container 3: backups (DB dump)

Storage Account가 redundancy + tier + 네트워크 단위고, Container가 access control + lifecycle 단위라, 같은 redundancy를 쓰는 데이터를 한 account에 묶고 access는 container별로 분리할 수 있다. S3보다 더 세분화된 모델이다.

Public access는 처음부터 차단된다

az storage account create ... --allow-blob-public-access false
az storage container create ... --public-access off

기본은 둘 다 비공개. account와 container 양쪽에서 명시적으로 public 차단을 강제한다.

S3가 historically 실수로 public 됐다가 사고난 케이스가 워낙 많아서, 그 교훈이 디자인에 반영된 듯하다.

Managed Identity로 끝내기

S3 access를 EC2에서 할 때 IAM Role을 EC2에 attach하는 흐름과 같은데, Azure는 SDK 통합이 더 매끄럽다.

# 컴퓨트 만들 때 system identity 자동 발급
az containerapp create ... --system-assigned

PRINCIPAL_ID=$(az containerapp show ... --query identity.principalId -o tsv)

# Storage 권한 부여
az role assignment create --assignee $PRINCIPAL_ID \
  --role "Storage Blob Data Contributor" --scope $STORAGE_ID

서버 코드는 이게 끝.

import { DefaultAzureCredential } from '@azure/identity';
const credential = new DefaultAzureCredential();
// 클라우드 환경: Managed Identity 자동 사용
// 로컬 dev:   az login 토큰 자동 사용

@azure/identity 한 줄이면 클라우드/로컬 둘 다 자동으로 토큰을 resolve 해준다. AWS의 IAM Role + STS AssumeRole + AWS SDK auto-resolve 흐름을 한 객체로 압축한 셈이다.

4. Container Apps — 이번 인프라의 코어 런타임

이번 셋업에서 가장 인상 깊었던 게 Container Apps다.

AWS의 어느 서비스와 1:1 대응이 안 된다. 굳이 비유하면 Fargate + ALB + ECS Service의 묶음, 아니면 App Runner의 enterprise 버전 정도.

내부적으로는 KEDA + AKS 위에서 돌지만, 사용자는 그걸 몰라도 된다. Fargate의 serverless 경험에 EKS의 autoscaling 유연성이 한 객체에 들어있다.

객체 모델

  • Container App Environment — 클러스터 추상화 (logs, networking 공유)
  • Container App — Deployment + Service + HPA 묶음
  • Revision — 특정 image / config의 snapshot. 새 image 배포 시 새 revision 자동 생성
  • Replica — 실제 pod (1~N개)

기본 사용법

az containerapp create \
  --name jooju-api --resource-group jooju-rg \
  --environment jooju-prod-env \
  --image joojuacr.azurecr.io/jooju-api:v1 \
  --target-port 3000 --ingress external \
  --min-replicas 1 --max-replicas 5 \
  --cpu 1.0 --memory 2.0Gi \
  --registry-server joojuacr.azurecr.io --registry-identity system \
  --system-assigned \
  --revisions-mode single \
  --scale-rule-name http-concurrency \
  --scale-rule-type http --scale-rule-http-concurrency 50

핵심 옵션 몇 개만 짚으면,

옵션의미
--target-port 3000컨테이너 안의 listen port
--ingress external외부 traffic 받을지 (internal이면 VNet 안에서만)
--min-replicas 1 --max-replicas 5autoscaling 범위. 0도 가능 (cold start 감수, 비용 0)
--registry-identity systemACR pull 시 password 없이 system identity 사용
--revisions-mode single새 revision 활성화되면 옛 거 자동 deactivate (운영 권장)
--scale-rule-*KEDA scale rule. HTTP concurrency 50 = replica당 동시 50요청 넘으면 scale-out

KEDA scale rule은 HTTP concurrency 외에도 CPU/Memory, Service Bus queue length, Cosmos DB queue, Cron schedule까지 잡힌다. Cron 기반 scale은 Fargate에선 EventBridge + Lambda로 우회하던 건데, 여긴 한 줄로 박을 수 있어서 편하다.

무중단 변경

Container App의 거의 모든 설정은 무중단으로 바꿀 수 있다.

az containerapp update -n jooju-api -g jooju-rg --cpu 2.0 --memory 4.0Gi
az containerapp update -n jooju-api -g jooju-rg --image joojuacr.azurecr.io/jooju-api:v2

새 revision 자동 생성 → traffic shift → 옛 revision deactivate. AWS Fargate도 비슷하지만 KEDA + revision 모델 덕에 rolling deploy가 더 매끄러웠다.

Outbound IP는 고정이 아니다

운영 중에 부딪힌 함정. Container App의 outbound IP는 Container Apps Environment 단위로 발급되고, env 재생성 시 바뀔 수 있다.

az containerapp env show -n jooju-prod-env -g jooju-rg \
  --query "properties.staticIp" -o tsv

PostgreSQL firewall에 specific IP를 화이트리스트 박으려고 했더니 IP가 바뀌어서, 결국 Allow Azure Services rule로 갈아탔다. 트래픽이 늘어 보안 격상이 필요해지면 VNet Integration / Private Link로 옮겨갈 예정.


5. Key Vault — 흩어진 비밀 관리를 한 곳에

AWS는 비밀 관리가 세 곳에 쪼개져 있어서 늘 헷갈렸다.

  • Secrets Manager (KV/value secret + 자동 rotation)
  • Parameter Store (계층적 config)
  • KMS (암호화 키)

Azure의 Key Vault는 이걸 하나로 묶었다. 운영에선 secrets만 써도 충분하다.

az keyvault secret set --vault-name jooju-kv -n DATABASE-URL --value "postgresql://..."
az keyvault secret show --vault-name jooju-kv -n DATABASE-URL --query value -o tsv

RBAC 모드 권장

KV 만들 때 두 모드 중 하나를 골라야 한다.

az keyvault create ... --enable-rbac-authorization true   # RBAC (권장)
# 또는 default 인 Access Policy (legacy)

운영은 RBAC. AWS의 IAM role assignment와 mental model이 같아서 적응하기도 쉽다. Access Policy는 KV만의 별도 모델이라 sub-level RBAC와 일관성이 떨어진다.

Secret 이름은 하이픈만 — 밑줄 X

이걸 모르고 시작했다가 한참 헤맸다.

환경변수: DATABASE_URL  ← 밑줄
KV secret: DATABASE-URL  ← 하이픈

KV secret 이름은 영숫자 + 하이픈만. 밑줄(_)은 못 쓴다. 환경변수와 매핑할 때 자동 변환 로직 한 번 거치는 걸 권장.

Container App에 자동 주입

Container App에서 KV secret을 환경변수로 받는 흐름이 깔끔하다.

# 1. KV reference를 Container App secret으로 등록
az containerapp secret set --name jooju-api --resource-group jooju-rg --secrets \
  database-url="keyvaultref:https://jooju-kv.vault.azure.net/secrets/DATABASE-URL,identityref:system"

# 2. 그 secret을 환경변수로 매핑
az containerapp update --name jooju-api --resource-group jooju-rg \
  --set-env-vars DATABASE_URL=secretref:database-url

장점:

  • Container App의 secret 객체는 KV reference만 들고, 값은 KV에 있다.
  • KV에서 값 변경 시 자동 갱신 (default 24시간 polling).
  • 즉시 갱신이 필요하면 revision restart.

Soft Delete의 양면성

KV는 default로 Soft Delete가 활성화된다. secret delete 해도 진짜 삭제가 아니라 30일간 복구 가능 상태로 남는다.

장점은 실수 방지. 단, 같은 이름으로 다시 set이 안 된다 — deleted 상태로 이름이 점유되어 있어서다.

이거 모르고 잘못 만든 secret을 지우고 다시 만들려다가 “이미 존재함” 에러로 한 시간 정도 헤맸다.

az keyvault secret list-deleted --vault-name jooju-kv          # 일단 확인
az keyvault secret recover --vault-name jooju-kv -n MY-SECRET  # 살리기
# 또는 purge 후 재등록

6. Front Door Premium — CloudFront + WAF + Global Accelerator

Azure Front Door는 AWS의 CloudFront + WAF + Global Accelerator가 하나에 묶인 서비스다.

글로벌 edge POP, TLS 종료, WAF, traffic routing을 한 객체에서 관리한다.

Standard vs Premium — 처음에 잘 골라야 한다

기능StandardPremium
글로벌 edge POP~118개~118개
Custom domain + Managed cert
WAF별도 청구포함
Bot Protection
Private Link to backend

Standard → Premium은 in-place 변경 불가. 새 profile을 만들고 도메인 / cert / route 재셋업, DNS 컷오버까지 다시 해야 한다. 보안 우선이면 처음부터 Premium 박는 걸 추천.

객체 모델

Front Door 객체의미
Profile최상위 (sku 단위)
Endpoint외부 hostname (*.azurefd.net)
Origin Groupbackend pool + health probe
Originindividual backend (Container App 등)
RouteURL pattern → origin group 매핑
Custom Domainapi.example.com
WAF Policy봇/공격 차단 rule

생성 순서는 정해져 있다.

Profile → Endpoint → Origin Group → Origin → Route → Custom Domain → WAF.

순서를 어기면 dependency 에러로 줄줄이 깨진다.

Health probe

az afd origin-group create ... \
  --probe-path /health \
  --probe-protocol Https \
  --probe-request-type GET \
  --probe-interval-in-seconds 30 \
  --sample-size 4 \
  --successful-samples-required 3

읽으면 — “30초마다 GET /health. 최근 4번 중 3번 200이면 healthy”. CloudFront origin failover보다 control이 세밀하다.

Managed Certificate

Custom domain 추가 시 Azure가 자동으로 cert를 발급한다.

az afd custom-domain create ... --certificate-type ManagedCertificate

도메인 소유권 검증(TXT record) → cert 발급 → 글로벌 POP에 propagation까지 한 명령으로 끝난다.

여기서 처음에 헷갈렸던 게, custom domain 상태가 두 단계로 쪼개져 있다는 점이었다.

  • domainValidationState: Approved — 도메인 소유권 검증 완료
  • deploymentStatus: Succeeded — cert가 글로벌 POP에 binding 완료

Approved만 됐다고 동작하는 게 아니다. Deployment가 Succeeded까지 가야 사용자 traffic을 처리할 수 있다. 첫 발급은 보통 5~30분 정도 걸린다.

7. ACR Cloud Build와 Application Insights

ACR Cloud Build — M1에서 amd64 빌드를 한 줄로

ECR은 그냥 registry라 빌드는 별도(CodeBuild 등)였다. ACR은 자체적으로 cloud build를 제공한다.

az acr build --registry joojuacr --image jooju-api:v1 --file Dockerfile --target prod .

이게 꽤 편하다.

  • 로컬 Docker Desktop 필요 X
  • M1/M2 맥에서도 amd64 image 자동 빌드 (buildx 셋업 불필요)
  • .dockerignore 따라 컨텍스트 업로드 → 클라우드 빌드 → registry push 한 번에

CI/CD 파이프라인을 본격적으로 다지기 전 단계의 1인 개발자한테는 꽤 큰 도움이 된다.

ACR pull 권한은 Container App의 system identity에 AcrPull role만 박아주면 password 없이 끝난다.

az role assignment create --assignee $PRINCIPAL_ID --role AcrPull --scope $ACR_ID

Application Insights — CloudWatch + X-Ray의 통합

Application Insights는 AWS의 CloudWatch (logs/metrics) + X-Ray (distributed tracing) 의 통합이다.

OpenTelemetry 표준이라 코드 변경 거의 없이 통합된다. Container App과의 연결은 환경변수 한 줄.

APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=...;IngestionEndpoint=...

Node SDK(@azure/monitor-opentelemetry)가 자동으로 console.log, HTTP request, DB query를 trace로 보내준다. CloudWatch에 Lambda가 자동 통합되는 그 경험과 비슷하다.

운영 시작하면 일단 깔아둘 알람 baseline.

알람Metric임계
Container CPU 과부하UsageNanoCores> 80%
5xx 비율 증가Requests where statusCodeCategory=5xx> 50/5min
DB CPU 과부하cpu_percent> 75%
DB connection 폭증active_connectionstier 한계의 70%

Action Group에 Slack / Teams / 이메일 묶어주면 끝. AWS의 SNS topic과 비슷한 추상이다.

8. 비용 비교 — Azure가 살짝 비싸지만

소규모 운영 1개월 예상 (트래픽 적은 시기 기준):

항목AzureAWS (참고)
Container App (1 vCPU, 2 GiB)$36Fargate $40
PG Flexible Server (D2ds_v5, ZRS HA)$280RDS db.m5.large + Multi-AZ $290
Storage Account$5S3 $5
Front Door Premium$235CloudFront + WAF $20+
ACR Basic$5ECR $0.10 + transfer
Key Vault$1Secrets Manager $5
App Insights (5 GiB ingest)$25CloudWatch $30

겉으로 보면 Azure가 살짝 비싸다.

특히 Front Door Premium $235가 눈에 들어오는데, 이게 WAF 포함 가격이라는 점이 함정 아닌 함정이다. AWS는 CloudFront + WAF가 따로 청구라 트래픽이 적을 땐 차이가 큰데, WAF rule이 늘어나면 비용도 빠르게 따라붙어 결국 비슷해진다.

그리고 Microsoft for Startups Founders Hub의 5,000달러 / 6개월을 고려하면, 이 표 자체가 한동안은 의미가 없어진다.

마치며

AWS에서 다 셋팅해 둔 걸 갈아엎고 Azure로 옮기느라 이틀 가까이 까먹었다.

까놓고 보니까 Azure가 의외로 괜찮은 부분이 많았다.

  • Resource Group의 깔끔함 — 프로젝트 일괄 관리 / 삭제가 한 줄
  • Managed Identity의 직관성 — IAM Role + STS의 흐름을 SDK 한 줄로
  • Container Apps의 단순함 — KEDA + revision 모델 덕에 무중단 배포가 매끄러움
  • Front Door의 통합 관리 — CloudFront + WAF + Cert를 한 객체에서
  • Key Vault의 secrets 통합 — Secrets Manager + Parameter Store + KMS가 한 곳에

AWS 입맛에 익은 사람한텐 처음 1~2일은 헷갈리는 게 정상이다

이번 셋업은 1인이 관리할 수 있는 단순함에 무게를 두고 잡았다.

트래픽이 늘면 VNet Integration / Private Link / Reserved Capacity 같은 격상 옵션을 단계적으로 도입하면 된다.

다음 글에서는 이 인프라 위에 GitHub Actions로 배포 파이프라인을 어떻게 엮었는지, 그리고 운영을 시작하면서 Application Insights에서 본 첫 메트릭들을 정리해볼 생각이다.

마침.

다른 글 보기