[IaC] Vagrant로 3-Tier 아키텍처 자동 구성하기
Vagrant를 사용하여 3-Tier 아키텍처(Web-WAS-DB)를 코드로 정의하고 자동으로 프로비저닝하는 Vagrantfile 전체 코드와 상세 설명
🎯 개요
이 문서는 Vagrant를 사용하여 다음 구성을 자동으로 생성하는 코드를 제공합니다:
- Web Server: Nginx (리버스 프록시)
- WAS Server: Tomcat 9 (Java 애플리케이션 서버)
- DB Server: MariaDB (데이터베이스)
관련 실습 포스트: vagrant-3tier-practice
📂 프로젝트 구조
vagrant-3tier/
├── Vagrantfile # VM 정의 및 프로비저닝 스크립트
└── README.md # 사용 방법
📋 전체 Vagrantfile
# -*- mode: ruby -*-
# vi: set ft=ruby :
# Version: 1.1
# Description: 3-Tier Architecture (Web-WAS-DB) with Vagrant
# IP Range: 10.0.0.x
# 순차 실행 보장 (병렬 실행 방지)
ENV['VAGRANT_NO_PARALLEL'] = 'yes'
Vagrant.configure("2") do |config|
# 공통 설정: OS 이미지 (Ubuntu 22.04 LTS)
config.vm.box = "ubuntu/jammy64"
config.vm.box_check_update = false
# ==========================================
# 1. DB Server (Tier 3) - 가장 먼저 생성
# ==========================================
config.vm.define "db" do |db|
db.vm.hostname = "db-server"
db.vm.network "private_network", ip: "10.0.0.30"
db.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
vb.cpus = 1
vb.name = "3tier-db"
end
# DB 설치 및 설정 스크립트
db.vm.provision "shell", inline: <<-SHELL
echo "=========================================="
echo ">>> Starting DB Server Provisioning"
echo "=========================================="
# 패키지 업데이트
apt-get update
# MariaDB 설치
DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server
# 방화벽 비활성화 (개발 환경)
ufw disable
# 외부 접속 허용 (Bind Address 수정)
sed -i 's/127.0.0.1/0.0.0.0/' /etc/mysql/mariadb.conf.d/50-server.cnf
# MariaDB 재시작
systemctl restart mariadb
systemctl enable mariadb
# DB 및 사용자 생성 (WAS에서 접속 가능하도록)
mysql -e "CREATE DATABASE IF NOT EXISTS mydb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -e "CREATE USER IF NOT EXISTS 'appuser'@'%' IDENTIFIED BY 'password';"
mysql -e "GRANT ALL PRIVILEGES ON mydb.* TO 'appuser'@'%';"
mysql -e "FLUSH PRIVILEGES;"
# 샘플 테이블 생성 (테스트용)
mysql mydb -e "CREATE TABLE IF NOT EXISTS test_table (id INT AUTO_INCREMENT PRIMARY KEY, message VARCHAR(255));"
mysql mydb -e "INSERT INTO test_table (message) VALUES ('Hello from DB Server!');"
# 연결 테스트 정보 출력
echo "=========================================="
echo ">>> DB Server Setup Complete"
echo " - IP: 10.0.0.30"
echo " - Port: 3306"
echo " - Database: mydb"
echo " - User: appuser / password"
echo "=========================================="
# MariaDB 상태 확인
systemctl status mariadb --no-pager
SHELL
end
# ==========================================
# 2. WAS Server (Tier 2)
# ==========================================
config.vm.define "was" do |was|
was.vm.hostname = "was-server"
was.vm.network "private_network", ip: "10.0.0.20"
was.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
vb.cpus = 1
vb.name = "3tier-was"
end
# Tomcat 설치 스크립트
was.vm.provision "shell", inline: <<-SHELL
echo "=========================================="
echo ">>> Starting WAS Server Provisioning"
echo "=========================================="
apt-get update
# Java 11 & Tomcat 9 설치
apt-get install -y openjdk-11-jdk tomcat9
# MySQL 클라이언트 설치 (DB 연결 테스트용)
apt-get install -y mysql-client
# 방화벽 비활성화
ufw disable
# Tomcat 시작
systemctl enable tomcat9
systemctl start tomcat9
# DB 연결 대기 (최대 30초)
echo ">>> Waiting for DB Server..."
for i in {1..30}; do
if mysql -h 10.0.0.30 -u appuser -ppassword -e "SELECT 1" &>/dev/null; then
echo ">>> DB Connection Successful!"
break
fi
echo " Retry $i/30..."
sleep 1
done
# DB 테스트
mysql -h 10.0.0.30 -u appuser -ppassword mydb -e "SELECT * FROM test_table;"
echo "=========================================="
echo ">>> WAS Server Setup Complete"
echo " - IP: 10.0.0.20"
echo " - Port: 8080"
echo " - Tomcat: http://10.0.0.20:8080"
echo "=========================================="
systemctl status tomcat9 --no-pager
SHELL
end
# ==========================================
# 3. Web Server (Tier 1)
# ==========================================
config.vm.define "web" do |web|
web.vm.hostname = "web-server"
web.vm.network "private_network", ip: "10.0.0.10"
# 호스트에서 접근 가능하도록 포트 포워딩
web.vm.network "forwarded_port", guest: 80, host: 8080
web.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
vb.cpus = 1
vb.name = "3tier-web"
end
# Nginx 설치 및 리버스 프록시 설정
web.vm.provision "shell", inline: <<-SHELL
echo "=========================================="
echo ">>> Starting Web Server Provisioning"
echo "=========================================="
apt-get update
apt-get install -y nginx curl
# 방화벽 비활성화
ufw disable
# Nginx 설정: 80번 요청을 WAS(10.0.0.20:8080)로 프록시
cat <<EOF > /etc/nginx/sites-available/default
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
location / {
proxy_pass http://10.0.0.20:8080;
proxy_set_header Host \\$host;
proxy_set_header X-Real-IP \\$remote_addr;
proxy_set_header X-Forwarded-For \\$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \\$scheme;
}
# Health check endpoint
location /health {
access_log off;
return 200 "OK\\n";
add_header Content-Type text/plain;
}
}
EOF
# Nginx 재시작
systemctl restart nginx
systemctl enable nginx
# WAS 연결 대기 (최대 30초)
echo ">>> Waiting for WAS Server..."
for i in {1..30}; do
if curl -s http://10.0.0.20:8080 &>/dev/null; then
echo ">>> WAS Connection Successful!"
break
fi
echo " Retry $i/30..."
sleep 1
done
# 최종 연결 테스트
curl -s http://10.0.0.20:8080 > /dev/null && echo ">>> Nginx → WAS: OK"
echo "=========================================="
echo ">>> Web Server Setup Complete"
echo " - IP: 10.0.0.10"
echo " - Port: 80 (forwarded to host:8080)"
echo " - Access: http://localhost:8080"
echo "=========================================="
echo ""
echo "🎉 3-Tier Architecture Setup Complete!"
echo ""
echo "Access Path: Browser → Nginx (Web) → Tomcat (WAS) → MariaDB (DB)"
echo "Test URL: http://localhost:8080"
echo ""
systemctl status nginx --no-pager
SHELL
end
end📖 코드 상세 설명
1. 헤더 및 환경 설정
# -*- mode: ruby -*-
# vi: set ft=ruby :- Vagrantfile은 Ruby 문법 사용
- 에디터에게 Ruby 파일임을 알려주는 힌트
ENV['VAGRANT_NO_PARALLEL'] = 'yes'- 순차 실행 보장: DB → WAS → Web 순서대로 생성
- 병렬 실행 시 WAS가 DB보다 먼저 뜨면 연결 실패 가능
2. 공통 설정
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/jammy64"
config.vm.box_check_update = false| 설정 | 설명 |
|---|---|
Vagrant.configure("2") | Vagrant API 버전 2 사용 |
config.vm.box | 베이스 이미지 (Ubuntu 22.04 LTS) |
config.vm.box_check_update | Box 업데이트 자동 확인 비활성화 |
3. VM 정의 구조
config.vm.define "vm_name" do |vm|
# 호스트명
vm.vm.hostname = "server-name"
# 네트워크 (Private Network, 고정 IP)
vm.vm.network "private_network", ip: "10.0.0.xx"
# 포트 포워딩 (선택사항)
vm.vm.network "forwarded_port", guest: 80, host: 8080
# VirtualBox 설정
vm.vm.provider "virtualbox" do |vb|
vb.memory = "1024" # RAM (MB)
vb.cpus = 1 # CPU 코어 수
vb.name = "vm-name" # VirtualBox GUI 이름
end
# 프로비저닝 스크립트
vm.vm.provision "shell", inline: <<-SHELL
# Shell 명령어들...
SHELL
end4. 네트워크 구성
Private Network
vm.vm.network "private_network", ip: "10.0.0.30"- VirtualBox의 Host-Only 네트워크
- VM 간 통신 가능
- 호스트 PC에서도 접근 가능
Port Forwarding
web.vm.network "forwarded_port", guest: 80, host: 8080- 게스트(VM)의 80번 포트를 호스트의 8080번으로 포워딩
- 호스트에서
http://localhost:8080으로 접근 가능
5. 프로비저닝 스크립트
Shell Script Inline 방식
vm.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y nginx
SHELL주요 프로비저닝 작업
DB Server:
- MariaDB 설치
- 외부 접속 허용 (
bind-address = 0.0.0.0) - DB 및 사용자 생성
- 샘플 데이터 삽입
WAS Server:
- Java 11, Tomcat 9 설치
- MySQL 클라이언트 설치 (테스트용)
- DB 연결 대기 로직 (최대 30초)
Web Server:
- Nginx 설치
- 리버스 프록시 설정 (80 → 8080)
- WAS 연결 대기 로직
🚀 사용 방법
1. 프로젝트 생성
mkdir vagrant-3tier
cd vagrant-3tier
# Vagrantfile 생성 (위 코드 복사)2. VM 생성
# 모든 VM 생성 및 프로비저닝 (5-10분 소요)
vagrant up
# 특정 VM만 생성
vagrant up db
vagrant up was
vagrant up web3. 상태 확인
# VM 상태 확인
vagrant status
# 출력:
# db running (virtualbox)
# was running (virtualbox)
# web running (virtualbox)4. VM 접속
# SSH 접속
vagrant ssh db
vagrant ssh was
vagrant ssh web
# 종료
exit5. VM 제어
# 일시 중지
vagrant halt
# 재시작
vagrant up
# 완전 삭제
vagrant destroy -f
# 특정 VM만 삭제
vagrant destroy db -f6. 재프로비저닝
# VM은 유지하고 프로비저닝 스크립트만 재실행
vagrant provision
# 특정 VM만
vagrant provision was🧪 테스트 방법
1. 웹 브라우저 접근
http://localhost:8080
→ Tomcat 기본 페이지 표시
2. curl 테스트
# 호스트에서
curl http://localhost:8080
# Web VM에서
vagrant ssh web
curl http://10.0.0.20:8080
# Health check
curl http://localhost:8080/health3. DB 연결 확인
vagrant ssh was
# DB 연결 테스트
mysql -h 10.0.0.30 -u appuser -ppassword mydb
# 테이블 확인
SELECT * FROM test_table;
# 출력:
# +----+-----------------------+
# | id | message |
# +----+-----------------------+
# | 1 | Hello from DB Server! |
# +----+-----------------------+🔧 커스터마이징
IP 변경
# 10.0.0.x 대신 192.168.56.x 사용
db.vm.network "private_network", ip: "192.168.56.30"
was.vm.network "private_network", ip: "192.168.56.20"
web.vm.network "private_network", ip: "192.168.56.10"리소스 조정
vb.memory = "2048" # 2GB RAM
vb.cpus = 2 # 2 CPU다른 DB 사용 (PostgreSQL 예시)
db.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y postgresql postgresql-contrib
# PostgreSQL 외부 접속 허용
echo "listen_addresses = '*'" >> /etc/postgresql/14/main/postgresql.conf
echo "host all all 0.0.0.0/0 md5" >> /etc/postgresql/14/main/pg_hba.conf
systemctl restart postgresql
SHELL📊 리소스 사양
| 항목 | DB | WAS | Web | Total |
|---|---|---|---|---|
| 메모리 | 1GB | 1GB | 1GB | 3GB |
| CPU | 1 | 1 | 1 | 3 |
| 디스크 | ~2GB | ~3GB | ~2GB | ~7GB |
권장 호스트 사양:
- RAM: 8GB 이상
- CPU: 4코어 이상
- 디스크: 20GB 여유 공간
📚 참고 자료
🔗 관련 포스트
- 실습 과정: vagrant-3tier-practice
마지막 업데이트: 2025-01-19