
AWS vs GCP vs Azure: 3대 클라우드 선택 기준
처음엔 다 비슷해 보였는데, 실제로 써보니 각각 강점이 완전히 달랐다. 스타트업 관점에서 클라우드 선택 기준을 정리했다.

처음엔 다 비슷해 보였는데, 실제로 써보니 각각 강점이 완전히 달랐다. 스타트업 관점에서 클라우드 선택 기준을 정리했다.
왜 CPU는 빠른데 컴퓨터는 느릴까? 80년 전 고안된 폰 노이만 구조의 혁명적인 아이디어와, 그것이 남긴 치명적인 병목현상에 대해 정리했습니다.

내 서버가 왜 이렇게 작고 강력한지 이해하려면, 집채만 했던 1세대 컴퓨터를 봐야 합니다. 하드웨어의 다이어트 역사와 클라우드 비용 절약의 비밀을 파헤칩니다.

서버를 끄지 않고 배포하는 법. 롤링, 카나리, 블루-그린의 차이점과 실제 구축 전략. DB 마이그레이션의 난제(팽창-수축 패턴)와 AWS CodeDeploy 활용법까지 심층 분석합니다.

ChatGPT는 질문에 답하지만, AI Agent는 스스로 계획하고 도구를 사용해 작업을 완료한다. 이 차이가 왜 중요한지 정리했다.

첫 프로젝트를 시작할 때, 클라우드 선택은 별로 중요하지 않아 보였다. EC2든 Compute Engine이든 Virtual Machine이든, 어차피 서버 하나 띄우는 건데 뭐가 다르겠어? AWS가 가장 크니까 AWS 쓰면 되겠지.
그런데 각 클라우드의 특징을 비교해보니, 완전히 달랐다. 마치 같은 '자동차'라도 스포츠카, SUV, 세단이 완전히 다른 것처럼, 각 클라우드는 전혀 다른 철학으로 만들어져 있었다.
AWS는 서비스가 많은 만큼 청구서가 복잡하고, GCP는 혁신적이지만 서비스가 deprecated되는 경우가 있으며, Azure는 기업 고객 중심이라 문서 구조가 스타트업 개발자에게는 낯설다는 이야기를 많이 접했다.
결국 이해했다. 클라우드 선택은 단순히 "어디가 더 좋아?" 문제가 아니라, "우리 상황에 무엇이 맞아?" 문제라는 것을.
AWS는 마치 백화점 같다. 없는 게 없다. 200개가 넘는 서비스가 있고, 매년 수천 개의 새로운 기능이 추가된다.
처음 AWS를 쓸 때 느낀 건 "아, 이건 검색하면 다 나오네"였다. 어떤 에러를 만나든 Stack Overflow에 답이 있고, 어떤 유즈케이스든 이미 누군가 블로그에 정리해뒀다.
// AWS SDK는 정말 모든 서비스에 대한 클라이언트가 있다
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { DynamoDBClient, PutItemCommand } from "@aws-sdk/client-dynamodb";
import { SQSClient, SendMessageCommand } from "@aws-sdk/client-sqs";
import { LambdaClient, InvokeCommand } from "@aws-sdk/client-lambda";
// 거의 모든 것을 AWS 안에서 해결할 수 있다
const s3 = new S3Client({ region: "ap-northeast-2" });
await s3.send(new PutObjectCommand({
Bucket: "my-bucket",
Key: "uploads/image.jpg",
Body: fileBuffer
}));
이게 주는 안정감은 엄청났다. 어떤 기능이 필요해도 "AWS에는 있겠지" 하는 확신이 있었다.
문제는 가격이었다. AWS 청구서는 마치 미로 같다. EC2 요금, EBS 요금, 데이터 전송 요금, NAT Gateway 요금... 항목이 수십 개다.
# AWS 청구서 예시 (소규모 서비스 기준, 월 $300~400대 나올 수 있음)
# EC2 인스턴스: ~$52
# EBS 볼륨: ~$18
# 데이터 전송 (아웃바운드): ~$127 ← 이게 제일 비쌌다
# NAT Gateway: ~$45
# RDS: ~$63
# S3: ~$12
# CloudWatch Logs: ~$8
# 기타: ~$22
# 결국 핵심은: 데이터 전송비를 조심해라
와닿았다. AWS는 "들어오기는 쉽지만 최적화하기는 어렵다"는 것을.
GCP는 완전히 다른 느낌이었다. 마치 Google이 "우리가 쓰던 도구를 너희도 써봐"라고 준 것 같았다.
GCP를 선택한 가장 큰 이유는 BigQuery였다. 데이터 분석이 정말 쉬웠다.
-- 수십억 건의 로그를 몇 초만에 분석
SELECT
user_id,
COUNT(*) as events,
APPROX_QUANTILES(session_duration, 100)[OFFSET(50)] as median_duration
FROM `project.dataset.events`
WHERE DATE(timestamp) >= DATE_SUB(CURRENT_DATE(), INTERVAL 30 DAY)
GROUP BY user_id
HAVING events > 10
ORDER BY events DESC
LIMIT 1000;
-- 이게 3초 만에 돌아간다. 테라바이트 데이터도.
AWS Athena나 Redshift도 있지만, BigQuery의 속도와 편의성은 차원이 달랐다. 특히 가격 모델이 단순했다: 스캔한 데이터 용량만큼만 내면 됐다.
Firebase를 쓰고 있다면 GCP는 자연스러운 선택이었다.
// Firebase + GCP Cloud Functions 조합
import * as functions from "firebase-functions";
import { BigQuery } from "@google-cloud/bigquery";
export const onUserSignup = functions.auth.user().onCreate(async (user) => {
// Firebase Authentication 이벤트를 BigQuery에 바로 저장
const bigquery = new BigQuery();
await bigquery.dataset("analytics").table("user_signups").insert([{
user_id: user.uid,
email: user.email,
created_at: new Date().toISOString()
}]);
});
// Firebase, Cloud Functions, BigQuery가 한 생태계 안에서 움직인다
문제는 Google의 "서비스 종료" 문화였다. Google Cloud IoT Core가 갑자기 종료 공지가 났고, 우리는 급하게 마이그레이션해야 했다.
결국 이거였다. GCP는 "최신 기술과 혁신"을 원하는 팀에게 좋지만, 장기 안정성이 필요하면 조금 불안하다.
Azure는 처음엔 이해하기 어려웠다. AWS나 GCP에 익숙한 개발자 입장에서, Azure의 용어나 구조는 낯설었다.
하지만 B2B 고객을 상대하면서 Azure의 가치를 이해했다. 특히 Active Directory 통합은 엔터프라이즈 환경에서 필수였다.
// Azure AD를 통한 SSO
import { DefaultAzureCredential } from "@azure/identity";
import { SecretClient } from "@azure/keyvault-secrets";
// 회사 AD 계정으로 자동 인증
const credential = new DefaultAzureCredential();
const client = new SecretClient(
"https://my-vault.vault.azure.net",
credential
);
// 기업 고객 입장에서는 이게 엄청 편하다
// 기존 AD 계정 그대로 클라우드 리소스에 접근
대기업 고객이 "우리는 Azure만 쓰는데, Azure로 배포 가능해?"라고 물어봤을 때, Azure를 지원하는 게 계약 조건이 됐다.
.NET으로 개발한다면 Azure는 당연한 선택이었다.
// Azure Functions with C#
[FunctionName("ProcessOrder")]
public static async Task Run(
[QueueTrigger("orders")] Order order,
[Table("Orders")] IAsyncCollector<OrderEntity> orderTable,
[SendGrid] IAsyncCollector<SendGridMessage> messages,
ILogger log)
{
// Queue, Table Storage, SendGrid가 모두 바인딩으로 연결
await orderTable.AddAsync(new OrderEntity(order));
await messages.AddAsync(CreateConfirmationEmail(order));
}
Visual Studio에서 F5 누르면 로컬 디버깅도 되고, 배포도 클릭 한 번이었다.
| 서비스 | AWS | GCP | Azure |
|---|---|---|---|
| VM | EC2 | Compute Engine | Virtual Machines |
| Serverless | Lambda | Cloud Functions | Functions |
| Container | ECS/EKS | GKE | AKS |
| 타입 | AWS | GCP | Azure |
|---|---|---|---|
| 관계형 | RDS | Cloud SQL | Database for MySQL/PostgreSQL |
| NoSQL | DynamoDB | Firestore | Cosmos DB |
| 분석 | Redshift | BigQuery | Synapse |
// 세 클라우드 모두 비슷하지만 DX가 다르다
// AWS Lambda - 가장 성숙함
export const handler = async (event: APIGatewayEvent) => {
return { statusCode: 200, body: JSON.stringify({ ok: true }) };
};
// GCP Cloud Functions - 가장 간결함
export const hello = (req: Request, res: Response) => {
res.json({ ok: true });
};
// Azure Functions - .NET 개발자에게 최고
[FunctionName("Hello")]
public static IActionResult Run([HttpTrigger] HttpRequest req) {
return new OkObjectResult(new { ok = true });
}
승자: AWS (생태계), GCP (단순함), Azure (.NET 환경)
AWS Free Tier: 12개월 제한 + 영구 무료
GCP Free Tier: Always Free + $300 크레딧 (90일)
Azure Free Tier: $200 크레딧 (30일) + 12개월 무료 + 영구 무료
이게 진짜 중요했다. 초기 스타트업이라면 크레딧 프로그램을 꼭 활용해야 한다.
우리는 GCP 크레딧 $5,000로 1년을 버텼다.
가장 무서운 건 벤더 락인이었다. 한 번 선택하면 옮기기 어렵다.
진짜 중요한 건 추상화 레이어를 두는 것이었다.
// 나쁜 예: 클라우드 SDK에 직접 의존
import { S3Client } from "@aws-sdk/client-s3";
export async function uploadFile(file: Buffer) {
const s3 = new S3Client({ region: "us-east-1" });
await s3.send(new PutObjectCommand({ /* ... */ }));
}
// 좋은 예: 추상화 레이어
interface StorageService {
upload(key: string, data: Buffer): Promise<void>;
download(key: string): Promise<Buffer>;
}
class S3Storage implements StorageService {
async upload(key: string, data: Buffer) { /* AWS 구현 */ }
async download(key: string) { /* AWS 구현 */ }
}
class GCSStorage implements StorageService {
async upload(key: string, data: Buffer) { /* GCP 구현 */ }
async download(key: string) { /* GCP 구현 */ }
}
// 앱 코드는 StorageService 인터페이스에만 의존
export function createStorage(): StorageService {
return process.env.CLOUD === "aws"
? new S3Storage()
: new GCSStorage();
}
이렇게 하면 나중에 클라우드를 바꿔도 핵심 로직은 그대로 유지된다.
솔직히 요즘은 "3대 클라우드"만이 선택지가 아니다. 특히 웹 애플리케이션이라면 Vercel이나 Cloudflare가 더 나을 수 있다.
// Vercel Edge Functions - 전 세계 엣지에서 실행
export const config = { runtime: "edge" };
export default async function handler(req: Request) {
// 지연시간이 거의 없다 - 사용자 위치에서 가장 가까운 엣지에서 실행
return new Response(JSON.stringify({ ok: true }), {
headers: { "content-type": "application/json" }
});
}
Next.js를 쓴다면 Vercel이 압도적으로 편했다. 배포는 git push가 전부고, 성능 최적화는 자동이었다.
Cloudflare Workers는 진짜 빨랐다. 전 세계 300개 이상 도시에서 5ms 이내 응답이 가능했다.
// Cloudflare Workers
export default {
async fetch(request: Request): Promise<Response> {
// 이게 전 세계 어디서든 5ms 안에 응답한다
const url = new URL(request.url);
return new Response(`Hello from ${request.cf?.colo}`);
}
}
가격도 매력적이었다. Workers는 10만 요청/일까지 무료였다.
우리는 결국 하이브리드로 갔다: 프론트엔드는 Vercel, 백엔드 API는 GCP, 데이터 분석은 BigQuery.
지금까지의 경험을 정리하면, 이런 프레임워크로 선택할 수 있다.
우리 팀이 이미 잘 아는 클라우드가 있나?
└─ YES → 그거 써라. 학습 비용이 가장 크다.
└─ NO → 2단계로
데이터 분석이 핵심인가?
└─ YES → GCP (BigQuery)
.NET을 쓰나? 또는 B2B 고객이 많나?
└─ YES → Azure
Kubernetes를 쓰나?
└─ YES → GCP (GKE)
엔터프라이즈 고객 대응이 중요한가?
└─ YES → AWS (생태계가 가장 크다)
Next.js 웹앱이 전부인가?
└─ YES → Vercel
글로벌 API + 초저지연이 필요한가?
└─ YES → Cloudflare Workers
초기 스타트업 ($1k/월 미만)
└─ GCP/Vercel/Cloudflare (Free Tier가 관대함)
중소 규모 ($1k-10k/월)
└─ GCP 또는 AWS (최적화에 투자할 시간이 있으면 AWS)
대규모 ($10k+/월)
└─ AWS (협상 여지가 크고, Enterprise Support가 가치있음)
5년 후에도 이 서비스가 있을까?
└─ AWS > Azure > GCP (안정성 순)
글로벌 확장이 필요한가?
└─ GCP/Cloudflare (전 세계 인프라가 균등함)
멀티 클라우드 전략이 필요한가?
└─ Terraform + 추상화 레이어 필수
각 클라우드의 특징을 비교해본 결과, 이렇게 정리됐다.
AWS를 선택해라:
GCP를 선택해라:
Azure를 선택해라:
Vercel/Cloudflare를 선택해라:
가장 중요한 깨달음은 이거였다: "최고의 클라우드"는 없다. 우리 팀과 제품에 맞는 클라우드가 있을 뿐이다.
처음엔 AWS가 가장 크니까 AWS를 선택했다. 하지만 지금은 프론트엔드는 Vercel, 백엔드는 GCP, 데이터는 BigQuery, CDN은 Cloudflare를 쓴다. 멀티 클라우드가 복잡해 보이지만, 각 영역에서 최적의 도구를 쓰는 게 결국 더 단순했다.
클라우드 선택으로 고민 중이라면, 일단 작게 시작해라. Free Tier로 프로토타입을 만들어보고, 직접 경험하는 게 백 번의 비교 글보다 낫다.