"AWS 마이그레이션 도구는 이삿짐센터다. Terraform은 집 설계도다. 이사만 하면 되면 이삿짐센터를 불러라. 하지만 이사 후에도 집을 고쳐 살아야 한다면 얘기가 다르다."

🎯 이 글에서 다루는 것
- AWS 마이그레이션 전용 서비스(MGN, DMS 등)의 한계
- 테라폼(Terraform)이란 무엇이고, 왜 이 시점에 배워야 하는가
- 벤더 종속(Vendor Lock-in) 문제와 탈출 전략
- 실제 테라폼 코드 예시로 보는 AWS 인프라 선언
- 마이그레이션 이후의 운영 관점에서 테라폼의 가치
📌 도입 / 배경
AWS 마이그레이션을 앞둔 조직들이 가장 먼저 찾는 것은 AWS Migration Hub, Application Migration Service(MGN), Database Migration Service(DMS) 같은 AWS 전용 마이그레이션 서비스입니다.
충분히 이해할 수 있는 선택입니다. AWS가 직접 만든 도구니까 가장 잘 작동할 것 같고, 공식 문서도 풍부하고, AWS 콘솔에서 바로 클릭 몇 번이면 작동하는 것처럼 보이니까요.
그런데 잠깐, 한 가지 질문을 먼저 해봐야 합니다.
"마이그레이션이 끝난 다음에는 어떻게 할 건가요?"
마이그레이션은 목적지가 아니라 출발점입니다. 온프레미스에서 AWS로 이전하는 그 순간이 끝이 아니라, 이후로도 수년간 AWS 위에서 인프라를 운영하고, 확장하고, 때로는 다른 클라우드로 또 이전해야 할 수도 있습니다.
이 관점에서 보면, 지금 테라폼을 배워야 하는 이유가 분명해집니다.
🔍 AWS 마이그레이션 서비스만으로는 부족한 이유
AWS 전용 서비스가 잘하는 것과 못하는 것
AWS가 제공하는 마이그레이션 도구들은 "이사 트럭"입니다. 짐을 빠르게 새 집으로 옮기는 데 특화되어 있습니다.
| 서비스 | 역할 | 한계 |
| MGN (Application Migration Service) | 서버를 그대로 복제해 EC2로 전환 | 마이그레이션 완료 후 역할 없음 |
| DMS (Database Migration Service) | DB를 AWS RDS/Aurora로 이전 | AWS DB 서비스에 종속 |
| Migration Hub | 마이그레이션 진행 상황 추적 | 모니터링 도구, 인프라 관리 불가 |
| SCT (Schema Conversion Tool) | DB 스키마 변환 | 변환 이후 운영은 별개 문제 |
이 도구들의 공통점은 "일회성"이라는 겁니다. 온프레미스 → AWS 이전이라는 특정 이벤트에 최적화되어 있을 뿐, 이전 이후의 인프라 운영, 변경 관리, 다중 환경(dev/staging/prod) 구성에는 적합하지 않습니다.

🚨 진짜 문제: 클릭으로 만든 인프라는 기록되지 않는다
많은 조직이 AWS 콘솔에서 클릭클릭해서 인프라를 구성합니다. VPC 만들고, 서브넷 만들고, EC2 올리고, RDS 연결하고...
그런데 6개월 뒤, 이런 상황이 옵니다.
- 👨💼 "이 VPC는 왜 이렇게 설정되어 있나요?"
- 😰 "음... 마이그레이션 담당자가 퇴사해서요."
- 👨💼 "똑같은 환경을 스테이징에도 만들 수 있나요?"
- 😰 "...콘솔 보면서 하나하나 다시 만들어야 할 것 같은데요."
- 개발팀: "스테이징 환경을 하나 더 만들어 주세요."
- 보안팀: "어제 누군가가 보안 그룹 규칙을 바꿨는데 누가, 왜 바꿨는지 알 수 없어요."
- 경영진: "비용이 급증했는데 어느 리소스가 문제인지 파악이 안 돼요."
- 재해 복구 담당자: "서울 리전 장애 시 다른 리전에서 동일 환경을 얼마나 빨리 재현할 수 있죠?"
이것이 클릭 기반 인프라 관리의 현실입니다. 재현 불가능, 추적 불가능, 협업 불가능...
🧩 테라폼(Terraform)이란 무엇인가
테라폼은 HashiCorp이 만든 Infrastructure as Code(IaC) 도구입니다. 쉽게 말하면, 인프라를 코드로 선언하는 방법입니다.
"EC2 인스턴스 하나 만들어줘"를 콘솔 클릭 대신 이렇게 씁니다:
# main.tf — EC2 인스턴스 선언
provider "aws" {
region = "ap-northeast-2" # 서울 리전
}
resource "aws_instance" "web_server" {
ami = "ami-0c9c942bd7bf113a2" # Amazon Linux 2023
instance_type = "t3.medium"
tags = {
Name = "web-server"
Environment = "production"
ManagedBy = "terraform"
}
}
이 파일을 Git에 커밋하고, terraform apply를 실행하면 AWS에 EC2가 생성됩니다.
핵심은 이 파일이 남는다는 겁니다. 누가 만들었는지, 어떤 설정인지, 언제 바뀌었는지 — 모든 것이 코드로 기록됩니다.
💡 마이그레이션 시점에 테라폼을 배워야 하는 5가지 이유
1️⃣ 마이그레이션 = 인프라를 처음부터 설계하는 기회
온프레미스에서 AWS로 이전하는 과정은 단순히 서버를 복사하는 게 아닙니다. VPC, 서브넷, 보안 그룹, IAM, 로드밸런서, 데이터베이스... 새로운 인프라를 처음부터 설계하는 기회입니다.
이 시점에 테라폼으로 설계하면, 처음부터 코드로 관리되는 인프라를 갖게 됩니다. 나중에 레거시 콘솔 구성을 코드로 변환하는 수고를 덜 수 있습니다.
2️⃣ 멀티 환경 구성이 복사-붙여넣기 수준으로 쉬워진다
대부분의 조직은 개발(dev), 스테이징(staging), 운영(production) 환경을 별도로 운영합니다. 콘솔로 이걸 각각 구성하면 세 배의 작업이 필요하고, 환경 간 설정 차이가 생기기 쉽습니다.
테라폼은 변수(Variables)와 워크스페이스(Workspace)를 통해 환경별 구성을 깔끔하게 분리합니다:
# variables.tf — 환경별 변수 정의
variable "environment" {
description = "배포 환경 (dev, staging, prod)"
type = string
}
variable "instance_type" {
description = "EC2 인스턴스 타입"
type = string
default = "t3.micro"
}
# terraform.tfvars (운영 환경용)
environment = "prod"
instance_type = "t3.large"
dev 환경과 prod 환경은 변수 값만 다르고, 인프라 구조 자체는 동일한 코드로 관리됩니다. 일관성이 보장됩니다.
3️⃣ 벤더 종속(Vendor Lock-in)을 처음부터 방지한다
AWS 마이그레이션 서비스만 배우면, 여러분의 팀은 AWS 콘솔 조작 능력을 갖게 됩니다. 그런데 만약 3년 뒤 비용 문제로 Azure나 GCP 일부 서비스를 도입하거나, 멀티 클라우드 전략을 검토한다면?
테라폼은 AWS, Azure, GCP, NCP 등 수백 개의 클라우드/서비스를 동일한 문법으로 관리합니다. AWS EC2를 선언하는 방식과 Azure VM을 선언하는 방식의 구조가 같습니다. 배운 사고방식이 그대로 통합니다.
# AWS EC2
resource "aws_instance" "web" { ... }
# Azure VM — 문법 구조가 동일
resource "azurerm_virtual_machine" "web" { ... }
# GCP Compute Engine
resource "google_compute_instance" "web" { ... }
AWS에 종속되지 않는 클라우드 불가지론적(Cloud Agnostic) 역량을 쌓을 수 있습니다.
4️⃣ 변경 이력이 Git에 남아 감사(Audit)와 협업이 가능해진다
보안 규정 준수(컴플라이언스)를 신경 쓰는 조직이라면, 인프라 변경 이력은 필수입니다. "누가, 언제, 무엇을, 왜 바꿨는가"가 추적 가능해야 합니다.
콘솔 클릭은 CloudTrail 로그에 남지만, 이걸 사람이 읽기 좋은 형태로 추적하기는 어렵습니다. 테라폼 코드를 Git으로 관리하면, PR(Pull Request) 기반의 인프라 변경 프로세스가 됩니다.
# 인프라 변경 워크플로우
git checkout -b feature/add-rds-replica
# terraform 코드 수정
git commit -m "feat: RDS 읽기 복제본 추가 (트래픽 분산 목적)"
git push origin feature/add-rds-replica
# PR 생성 → 팀 리뷰 → 승인 → 머지 → terraform apply
이제 인프라 변경도 코드 리뷰의 대상이 됩니다.
5️⃣ 마이그레이션 이후의 운영 자동화를 위한 필수 기반
마이그레이션이 끝나면 진짜 운영이 시작됩니다. 새 서비스 추가, 스케일 업/다운, 재해 복구(DR) 환경 구축, 비용 최적화를 위한 인스턴스 타입 변경...
이 모든 작업이 테라폼으로 관리되는 환경에서는 코드 한 줄 수정 + apply로 끝납니다. 콘솔 기반 환경에서는 수십 번의 클릭과 실수의 위험이 따릅니다.
💻 실습 예시 — 테라폼으로 기본 AWS 네트워크 구성
마이그레이션 시 가장 먼저 필요한 VPC 기본 구성을 테라폼으로 작성해봅니다.
# vpc.tf — 마이그레이션 대상 환경의 네트워크 기반 구성
# VPC 생성
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "migration-vpc"
}
}
# 퍼블릭 서브넷 (웹 서버, ALB용)
resource "aws_subnet" "public" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
map_public_ip_on_launch = true
tags = {
Name = "public-subnet-${count.index + 1}"
Tier = "public"
}
}
# 프라이빗 서브넷 (DB, 백엔드 서버용)
resource "aws_subnet" "private" {
count = 2
vpc_id = aws_vpc.main.id
cidr_block = "10.0.${count.index + 10}.0/24"
availability_zone = data.aws_availability_zones.available.names[count.index]
tags = {
Name = "private-subnet-${count.index + 1}"
Tier = "private"
}
}
# 가용 영역 데이터 소스
data "aws_availability_zones" "available" {
state = "available"
}
이 코드를 실행하면:
- terraform init — 프로바이더 플러그인 다운로드
- terraform plan — 변경 사항 미리 확인 (실제 적용 전 검토)
- terraform apply — 실제 AWS에 인프라 생성
# terraform plan 출력 예시
Plan: 5 to add, 0 to change, 0 to destroy.
# + aws_vpc.main
# + aws_subnet.public[0]
# + aws_subnet.public[1]
# + aws_subnet.private[0]
# + aws_subnet.private[1]
plan 단계에서 무엇이 생성/변경/삭제될지 미리 보여준다는 점이 테라폼의 큰 강점입니다. 콘솔에서는 클릭하고 나서야 결과를 알 수 있습니다.
⚠️ 주의사항 / 흔한 실수
❌ "마이그레이션 끝나고 나서 테라폼 도입하면 되지"
가장 흔한 실수입니다. 콘솔로 구성한 인프라를 나중에 테라폼 코드로 역변환(terraform import)하는 작업은 매우 번거롭고 오류가 많습니다. 처음부터 테라폼으로 구성하는 것이 압도적으로 효율적입니다.
❌ 상태 파일(terraform.tfstate)을 로컬에 보관하기
테라폼은 현재 인프라 상태를 .tfstate 파일에 기록합니다. 이 파일을 로컬에 두면 팀 협업이 불가능하고, 분실 시 큰 문제가 됩니다. S3 + DynamoDB를 이용한 원격 백엔드 설정이 필수입니다.
# backend.tf — 상태 파일을 S3에 저장
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "migration/terraform.tfstate"
region = "ap-northeast-2"
dynamodb_table = "terraform-state-lock" # 동시 수정 방지 락
encrypt = true
}
}
❌ AWS 자격증명을 테라폼 코드에 하드코딩
# 절대 하지 말 것
provider "aws" {
access_key = "AKIAIOSFODNN7EXAMPLE" # ❌ 위험
secret_key = "wJalrXUtnFEMI/K7MDENG" # ❌ 위험
}
AWS CLI 프로파일이나 환경 변수, IAM 역할(Role)을 통해 인증하세요.
✅ 정리 / 마무리
AWS 마이그레이션 서비스(MGN, DMS 등)는 이사 트럭입니다. 짐을 옮기는 데는 유용하지만, 새 집에서의 생활은 다른 역량이 필요합니다.
테라폼은 새 집을 관리하는 방법입니다.
| 비교 항목 | AWS 마이그레이션 서비스만 | 테라폼 기반 접근 |
| 마이그레이션 속도 | 빠름 | 초기 학습 비용 있음 |
| 이후 운영 | 콘솔 클릭 의존 | 코드로 자동화 |
| 환경 재현성 | 불안정 | 완벽 재현 가능 |
| 벤더 종속 | 높음 | 낮음 |
| 감사/추적 | 제한적 | Git 이력으로 완전 추적 |
| 팀 협업 | 어려움 | PR 기반 협업 |
마이그레이션이라는 기회를 단순한 "이사"로 끝내지 마세요. 처음부터 올바른 방식으로 인프라를 코드화하는 출발점으로 삼는다면, 이후의 운영, 보안, 비용 최적화 모두가 훨씬 수월해집니다.
다음 단계 학습 방향:
- Terraform 공식 튜토리얼 (registry.terraform.io)
- AWS Provider 문서 숙지
- Terragrunt로 대규모 모듈 관리
- CI/CD 파이프라인에 terraform plan/apply 통합 (GitHub Actions, GitLab CI)
'클라우드' 카테고리의 다른 글
| 🥊 AWS Image Builder vs Packer — 실무 DevOps 엔지니어라면 뭘 써야 할까? (0) | 2026.03.27 |
|---|---|
| 🏗️ 개발자라면 인프라 배포를 알아야 하는 진짜 이유 — "코드만 잘 짜면 된다"는 착각 (0) | 2026.03.27 |
| 🔑 키 교체(Key Rotation)하면 데이터를 전부 다시 암호화할까? — 클라우드 KMS의 진실 (0) | 2026.03.27 |
| Mac에서 Podman으로 멀티 아키텍처(Intel & ARM) 이미지 한 번에 빌드하기 (0) | 2026.03.18 |
| 🛡️ Docker Swarm에서 --with-registry-auth의 늪 탈출하기: 보안과 효율성 사이의 균형 (0) | 2026.01.09 |