[Azure] SQL Server VM 구축부터 Azure SQL Database 마이그레이션까지

감자·2026년 5월 6일

microsoft_dataschool

목록 보기
27/28
post-thumbnail

본 포스팅에서는 Azure 환경에서 Linux/Windows VM 기반의 SQL Server(IaaS)를 구축하고, 이를 Azure SQL Database(PaaS)로 마이그레이션한 뒤 웹 앱(Flask)의 연동을 전환하는 전체 과정을 실습함.

📌 시스템 아키텍처 흐름

Part 1: IaaS 구성                    Part 2: PaaS 마이그레이션
─────────────────                    ──────────────────────────
┌──────────────┐                     ┌─────────────────────────┐
│  로컬 PC     │                     │  Azure SQL Database     │
│  SSMS ───────┼──── 1433 ──┐        │  (S0 / 10 DTU)          │
│  브라우저 ───┼──── 5000   │        │  CarMarket DB           │
└──────────────┘       │    │        └────────────┬────────────┘
│    │                 │                              │
▼    ▼                 │ Part 3: 앱 전환              │
┌──────────────┐       │                              │
│  Azure VM    │  ← DMS/sqlcmd ───────────────────────┘
│  Ubuntu 24.04│
│  SQL Server  │
│  Flask App   │
└──────────────┘

시스템 흐름: 데이터 수집 → 전처리/벡터화 → Cosmos DB 저장 → 사용자 쿼리 → 챗봇(RAG) 응답
핵심 기술: Azure Cosmos DB, Azure OpenAI, Gradio, Azure Functions


Part 1. Linux VM + SQL Server 설치 (외부 SSMS 접근)

1.1 자동 설치 (권장)

환경변수를 미리 설정하여 대화형 입력을 줄이고 터미널(Mac/Linux/WSL)에서 한 줄로 스크립트를 실행함.

1.1-1 WSL 설치

  • 관련 문서: WSL 설치 (Microsoft Learn)
  • Ubuntu 자격 증명:
    • ID: ****
    • Password: ****

1.1-2 Azure CLI 설치 및 bash 스크립트 실행

# Azure CLI 설치 (Windows)
winget install -e --id Microsoft.AzureCLI
# 환경변수 설정 및 스크립트 실행
export RG=3dt026-rg-carmarket-lab
export LOC=koreacentral
export SA_PASSWORD='CarMarket@2026'

bash "/mnt/z/microsoft/강의자료/애저VM을 활용한 SQL서버 운영및관리/scripts/01-setup-vm-sqlserver.sh"

💡 bash 스크립트 수행 작업 내역
1. Azure CLI 로그인 확인 및 SSH 키 검증
2. Resource Group 및 Ubuntu 24.04 VM (B2s) 생성
3. NSG(네트워크 보안 그룹)에서 22(SSH), 1433(SQL), 5000(Flask) 포트 오픈
4. SQL Server 2025 Developer Edition 설치
5. 0.0.0.0 바인딩 (외부 SSMS 접근 허용)
6. CarMarket DB 스키마 생성 및 시드 데이터 5건 입력
7. Flask 앱 배포 및 systemd 서비스 등록

🚨 트러블슈팅: 스크립트 실행 오류 시 해결 방안
Windows 환경에서 문제가 발생할 경우 PowerShell 7을 이용한 스크립트 실행을 권장함.

# (1) PowerShell 7 설치
winget install --id Microsoft.PowerShell --source winget

# (2) 새로 설치된 PowerShell 7(pwsh) 실행 후 실행 정책 변경
pwsh
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass

# (3) PowerShell용 스크립트 실행
cd "Z:\microsoft\강의자료\애저VM을 활용한 SQL서버 운영및관리\scripts"
.\01-setup-vm-sqlserver.ps1

# (4) 필요시 az CLI 설치 후 3번 다시 실행
winget install --id Microsoft.AzureCLI --source winget
  • 생성된 서버 정보 (예시):
    • 서버 이름: ****
    • 패스워드: ****

1.2 SSMS로 VM SQL Server 접속

스크립트 완료 후 출력된 연결 정보를 바탕으로 로컬 SSMS에서 접속함.

항목값
서버 유형데이터베이스 엔진
서버 이름20.200.136.216,1433 (본인의 VM IP 입력)
인증SQL Server 인증
로그인**
암호****

1.3 데이터 확인 (SSMS 쿼리 실행)

SSMS에 접속하여 시딩된 데이터를 확인함.

USE CarMarket;
GO

-- 1. 테이블 목록 확인
SELECT TABLE_NAME, TABLE_TYPE
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE';

-- 2. 차량 매물 확인
SELECT c.Brand, c.Model, c.Year,
  FORMAT(c.Price, 'N0') AS Price,
  FORMAT(c.Mileage, 'N0') AS Mileage,
  u.Name AS Seller
FROM Cars c
JOIN Users u ON c.SellerId = u.UserId
ORDER BY c.Price DESC;

-- 3. 인덱스 확인
SELECT i.name AS IndexName,
  t.name AS TableName,
  COL_NAME(ic.object_id, ic.column_id) AS ColumnName
FROM sys.indexes i
JOIN sys.tables t ON i.object_id = t.object_id
JOIN sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
WHERE i.name LIKE 'IX_%';

1.4 웹 앱 연동 확인

브라우저에서 http://<VM_PUBLIC_IP>:5000/ 에 접속하여 CarMarket 웹 UI가 표시되는지 확인. 터미널에서 API 테스트도 진행함.

# 환경 변수 로드
source ~/.carmarket-env

# 헬스체크
curl http://$PUBIP:5000/health

# 차량 목록 조회
curl http://$PUBIP:5000/api/cars

# 브랜드 필터 적용 조회
curl "http://$PUBIP:5000/api/cars?brand=BMW"

1.5 보안 참고사항

학습 편의를 위해 1433 포트를 외부에 직접 오픈했으나, 프로덕션 환경에서는 절대 금지해야 함. 실무 권장 방법:

  • SSH 터널링: ssh -L 1433:localhost:1433 azureuser@<PUBIP> 연결 후 SSMS 접속
  • VPN Gateway 또는 Azure Bastion 사용
  • Private Endpoint 적용

Part 2. Azure SQL Database 마이그레이션

2.1 마이그레이션 전략 이해

방식적합한 경우다운타임
sqlcmd 직접 (본 실습)소규모 DB, 학습용짧음 (분 단위)
bacpac export/import중소규모, 일회성 마이그레이션중간 (DB 크기에 비례)
Azure DMS (온라인)대규모, 프로덕션최소화 (거의 없음)

본 실습은 sqlcmd 직접 방식을 기본으로 하며, 선택적으로 Azure DMS 리소스를 생성함.

2.2 자동 마이그레이션 실행

. C:\Users\jaeky\.carmarket-env.ps1
.\02-migrate-to-azure-sql 1.ps1

💡 스크립트 수행 내역:
1. Azure SQL Server(논리 서버) 및 Database(S0) 생성
2. 방화벽 규칙 설정 (VM IP, 로컬 IP, Azure 서비스 허용)
3. VM SQL Server에서 스키마 및 데이터를 SQL 스크립트로 추출
4. Azure SQL Database에 스키마/시드 데이터 적용
5. Azure DMS 리소스 생성 (선택)
6. 소스 ↔ 대상 데이터 일치 검증

(마이그레이션 오류 발생 시 롤백 및 재진행 명령어)

.\99-cleanup.ps1
& ".\01-setup-vm-sqlserver 2.ps1"
. C:\Users\jaeky\.carmarket-env.ps1
& ".\02-migrate-to-azure-sql 2.ps1"

2.3 SSMS로 Azure SQL Database 접속

항목값
서버 이름sql-carmarket-vcoaq.database.windows.net
인증SQL Server 인증
로그인sqladmin
암호****

2.4 마이그레이션 검증 (SSMS)

-- 1. 테이블 구조 비교
SELECT TABLE_NAME,
  (SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS c
   WHERE c.TABLE_NAME = t.TABLE_NAME) AS ColumnCount
FROM INFORMATION_SCHEMA.TABLES t
WHERE TABLE_TYPE = 'BASE TABLE'
ORDER BY TABLE_NAME;

-- 2. 행 수 비교 (소스와 동일해야 함)
SELECT 'Users' AS TableName, COUNT(*) AS RowCount FROM Users
UNION ALL
SELECT 'Cars', COUNT(*) FROM Cars
UNION ALL
SELECT 'Inquiries', COUNT(*) FROM Inquiries;

-- 3. 데이터 내용 확인
SELECT c.Brand, c.Model, c.Year,
  FORMAT(c.Price, 'N0') AS Price,
  u.Name AS Seller
FROM Cars c
JOIN Users u ON c.SellerId = u.UserId
ORDER BY c.Price DESC;

-- 4. Azure SQL 특유 정보 확인
SELECT @@VERSION AS SQLVersion,
  DB_NAME() AS DatabaseName,
  DATABASEPROPERTYEX(DB_NAME(), 'Edition') AS Edition,
  DATABASEPROPERTYEX(DB_NAME(), 'ServiceObjective') AS ServiceTier;

2.5 VM SQL Server vs Azure SQL Database 비교

항목VM SQL Server (IaaS)Azure SQL Database (PaaS)
@@VERSIONSQL Server 2025 CU…Microsoft SQL Azure…
EditionDeveloperSQL Azure
서버 관리사용자 관리 (패치, 백업, HA)Microsoft 관리 (자동)
sys.databasesmaster, CarMarket 등 전체 표시CarMarket만 표시
SQL Agent사용 가능없음 (Elastic Jobs로 대체)
가격 모델VM 시간 과금DTU/vCore 과금
백업수동 구성자동 (7~35일 보존)
고가용성수동 Always On 구성기본 내장 (99.99% SLA)

Part 3. Flask 앱 연결 전환

3.1 앱 전환 실행

로컬에서 제공된 쉘 스크립트(03-switch-app-to-azure-sql.sh 또는 .ps1)를 실행하거나, VM 내부에 SSH로 접속하여 수동으로 수정함.

# VM 내부 수동 전환 방법
ssh azureuser@20.41.98.214  # 본인 VM IP로 변경

cd ~/sqlvm_usedcar/app

# 1. 현재 DB_USER 확인
grep 'DB_USER' app.py

# 2. app.py 수정 (환경변수에서 읽도록 변경)
sed -i 's/DB_USER = "sa"/DB_USER = os.environ.get("DB_USER", "sa")/' app.py

# 3. .env 확인 및 추가
cat .env
grep -q 'DB_USER' .env || echo 'DB_USER=sqladmin' >> .env

# 4. 서비스 재시작 및 헬스체크 확인
sudo systemctl restart carmarket
curl -s http://localhost:5000/health

3.2 전환 후 검증

# 헬스체크 (db: connected 확인)
curl http://$PUBIP:5000/health

# 차량 목록 (Azure SQL에서 조회)
curl http://$PUBIP:5000/api/cars

# 매물 등록 테스트 (Azure SQL에 INSERT)
curl -X POST http://$PUBIP:5000/api/cars \
-H "Content-Type: application/json" \
-d '{"seller_id":1,"brand":"기아","model":"카니발","year":2023,"price":38000000,"mileage":10000}'

3.3 롤백 (VM SQL Server로 복귀)

연결에 문제가 발생할 경우 백업된 환경설정 파일을 복원하여 VM으로 즉시 롤백 가능함.

ssh azureuser@$PUBIP
cp ~/sqlvm_usedcar/app/.env.vm-backup ~/sqlvm_usedcar/app/.env
sudo systemctl restart carmarket

🧹 리소스 정리 및 파일 구조

비용 발생을 막기 위해 실습 종료 후 반드시 리소스를 정리함.

source ~/.carmarket-env

# 방법 1: VM만 중지 (데이터 유지, 비용 중단)
bash scripts/99-cleanup.sh

# 방법 2: 전체 삭제 (복구 불가)
bash scripts/99-cleanup.sh --delete

📂 파일 구조

migration-lab/
├── Migration_Lab_Guide.md            ← 이 문서
└── scripts/
    ├── 01-setup-vm-sqlserver.sh      ← VM + SQL Server 생성 및 세팅
    ├── 02-migrate-to-azure-sql.sh    ← Azure SQL DB로 데이터 마이그레이션
    ├── 03-switch-app-to-azure-sql.sh ← Flask 앱 DB 연결 전환
    └── 99-cleanup.sh                 ← 리소스 정리

🛠️ 트러블슈팅 (Troubleshooting)

1. SSMS에서 VM SQL Server 접속 실패

# NSG 1433 포트 오픈 확인
az network nsg rule list -g $RG --nsg-name <NSG_NAME> -o table

# SQL Server 바인딩 포트 확인 (0.0.0.0인지 검증)
ssh azureuser@$PUBIP "sudo ss -tlnp | grep 1433"

# 바인딩 문제 수정 및 재시작
sudo /opt/mssql/bin/mssql-conf set network.ipaddress 0.0.0.0 && sudo systemctl restart mssql-server

(주의: SSMS 연결 시 "서버 인증서 신뢰" 옵션 체크 필수)

2. Azure SQL Database 방화벽 오류
에러: Client with IP address 'x.x.x.x' is not allowed...

# 해결: 클라이언트 IP 허용 추가
az sql server firewall-rule create \
-g $RG -s $SQL_SERVER_NAME \
-n AllowMyNewIP \
--start-ip-address <YOUR_IP> --end-ip-address <YOUR_IP>

3. Flask 앱 Azure SQL 연결 실패

# .env 설정 확인
ssh azureuser@$PUBIP "cat ~/sqlvm_usedcar/app/.env"

# VM에서 Azure SQL 연결 테스트
sqlcmd -S $SQL_FQDN -U $SQL_ADMIN -P "$SQL_ADMIN_PASSWORD" -d CarMarket -Q "SELECT 1"

# ODBC Driver 존재 확인
odbcinst -q -d

4. DMS 마이그레이션 실패

  • VM의 1433 포트가 NSG에서 열려있는지 확인
  • SQL Server가 0.0.0.0으로 바인딩되어 있는지 확인
  • DMS 리소스가 동일한 리전에 있는지 확인

💡 추가 실습: Windows 기반 Azure VM에 SQL Server 프로비저닝

1단계: Azure Virtual Machine 배포

  1. 웹 브라우저에서 [https://portal.azure.com](https://portal.azure.com)에 접속 및 로그인.
  2. 검색창에 Azure SQL 입력 후 서비스 선택.
  3. [+ 만들기] 버튼 클릭.
  4. SQL 가상 머신 항목에서 free SQL Server 라이선스: Windows Server 2022 기반 SQL Server 2022 Developer 옵션을 선택 후 [만들기] 클릭.
  5. 가상 머신 만들기 설정 (기본값 외 아래 내용 변경):
    • 구독/리소스 그룹: 본인 환경에 맞게 지정
    • 가상 머신 이름: AzureSQLServerVM
    • 지역: 리소스 그룹과 동일 혹은 가까운 지역
    • 크기: Standard_D2s_v5 (2 vCPU, 8GiB)
    • 관리자 계정: 3dt026 / 암호: 3dt026@sqlvm (메모 필수)
    • 인바운드 포트: RDP (3389) 허용
    • Windows Server 라이선스: 예
  6. 디스크 / 네트워킹 / 관리 / 고급 탭을 검토 (관리 탭의 자동 종료 사용 안 함 확인).
  7. [SQL Server 설정] 탭에서 스토리지 구성 확인 (데이터-프리미엄 디스크 읽기 캐시, 로그-프리미엄 디스크 캐시 없음, TempDB-로컬 SSD D:\).
  8. [검토 + 만들기] 클릭 후 유효성 검사가 통과되면 [만들기] 클릭 (약 5~10분 소요).
  9. 배포 완료 후 [리소스로 이동] 클릭.

✅ Azure Cloud Shell에서 계정 정보 확인

az account show --output table

# 출력 결과 (예시)
EnvironmentName    HomeTenantId                          IsDefault    Name                        State    TenantId
AzureCloud         5fb256f0-fbf2-40d2-81d5-bac1b32c419d  True         대한상공회의소 Data School  Enabled  5fb256f0-fbf2-40d2-81d5-bac1b32c419d

2단계: VM 접속 및 SQL Server 연결

  1. VM 개요 페이지에서 [연결] 탭 클릭 후 RDP 선택.
  2. [RDP 파일 다운로드] 버튼 클릭 후 다운로드된 .rdp 파일 실행.
    (포트 필수 조건 오류 시 NSG에서 3389 인바운드 허용 확인)
  3. 보안 경고 창에서 [연결] 클릭. 설정한 자격 증명(3dt026 / 3dt026@sqlvm) 입력 후 인증서 경고에서 [예] 클릭.
  4. Windows 데스크톱 접속 후, 검색 아이콘에서 SSMS(Microsoft SQL Server Management Studio) 검색 및 실행.
  5. 서버에 연결 대화 상자에서 인증을 Windows 인증으로 확인, 서버 인증서 신뢰(Trust server certificate) 옵션 체크 후 [연결] 클릭.
  6. 개체 탐색기에서 서버 정상 연결을 확인한 뒤 SSMS 종료.
  7. 원격 데스크톱 세션 로그아웃 또는 닫기.

🧹 Windows VM 정리 단계
사용하지 않을 때는 VM을 중지(할당 취소)하여 비용 발생을 방지하거나, 리소스 그룹 단위로 완전 삭제를 권장함.</VM_PUBLIC_IP>

profile
제 별명이 감자입니다

0개의 댓글