본문 바로가기
클라우드

☁️ AWS 마이그레이션할 때 왜 AWS 콘솔 말고 테라폼을 배워야 하나?

by gasbugs 2026. 3. 27.

"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"
}

 

이 코드를 실행하면:

  1. terraform init — 프로바이더 플러그인 다운로드
  2. terraform plan — 변경 사항 미리 확인 (실제 적용 전 검토)
  3. 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)