서버 관리 개요
multi-saas-kit은 클라우드 서버를 코드로 관리(IaC) 하는 표준 체계를 제공합니다. Ansible로 OS 프로비저닝/소프트웨어 배포를, Tailscale로 서버 간 보안 네트워크를 구성합니다. IaaS 제공자는 선택 가능 — Vultr, DigitalOcean, Linode, Hetzner, AWS EC2 등 Ubuntu LTS를 제공하는 어떤 클라우드도 동일한 방식으로 동작합니다.
이 가이드의 예시에서 Vultr가 등장한다면, 그것은 하나의 참고 예시일 뿐입니다. 각 운영자가 선호하는 IaaS로 자유롭게 교체할 수 있으며, Ansible 코드는 수정 없이 재사용됩니다. 변경되는 것은 inventory/hosts.ini의 IP와 초기 VM 생성 단계뿐입니다.
이 체계의 의사결정 과정과 대안 비교는 ADR-018 Ansible 기반 서버 프로비저닝 채택을 참조하세요.
왜 이 조합인가
| 도구 | 역할 | 선택 이유 |
|---|---|---|
| IaaS 제공자 | VM 인프라 | 운영자 선호 (Vultr, DigitalOcean, Linode, Hetzner, AWS EC2 등). API·cloud-init·root-only 초기 상태 등 공통 요건만 충족하면 가능 |
| Ansible | OS 프로비저닝 + 배포 | Agentless(SSH만), 선언적, 멱 등성, 5~100대 스윗스팟, IaaS 중립 |
| Tailscale | 서버 간 사내망 | 제로 설정 VPN, ACL 기반 권한, 방화벽 대체 |
| Docker Compose | 애플리케이션 레이어 | 기존 생태계와 호환, 앱 배포 단위 |
아키텍처 한눈에
┌──────────────────────────────────────────────────────────────┐
│ 로컬 Control Node (운영자 PC 또는 CI) │
│ workspace/_infra/ansible/ │
│ ├── inventory/ # 서버 목록 │
│ ├── roles/ # 역할별 설정 │
│ ├── playbooks/ # 실행 시나리오 │
│ └── vault/ # 암호화된 Secret │
└──────────────────┬───────────────────────────────────────────┘
│ SSH (Tailscale)
▼
┌──────────────────────────────────────────────────────────────┐
│ IaaS 서버들 (Tailscale Mesh 100.64.0.0/10) │
│ │
│ NPM 서버 ─▶ App 서버 1 ─▶ DB 서버 │
│ │ App 서버 2 │
│ └─▶ DevTools (pgAdmin, RedisInsight, Grafana) │
│ │
│ 모든 서버: Docker + Tailscale + node_exporter + promtail │
└──────────────────────────────────────────────────────────────┘
설계 원칙
| 원칙 | 의미 |
|---|---|
| 선언적 | "이 상태여야 한다"만 기술 — 절차 X, 결과 O |
| 멱등성 | 같은 Playbook을 반복 실행해도 결과 동일 |
| 최소 권한 | root 직접 로그인 차단, deploy 유저 + sudo |
| 비밀 분리 | Secret은 ansible-vault로 암호화 저장 |
| 역할 분리 | 공통부(common) + 역할별(role) 조합 |
| 점진 도입 | 5대 → Ansible 단독 / 10대+ → Terraform 추가 |
서버 역할 분류
Ansible inventory는 그룹 단위로 서버를 분류합니다.
| 그룹 | 역할 | 예시 서버 |
|---|---|---|
npm_servers | Nginx Proxy Manager (reverse proxy + SSL) | 1대 |
app_servers | Laravel SaaS 앱 | N대 (프로젝 트별) |
db_servers | PostgreSQL | 1~N대 |
monitoring_servers | Grafana LGTM (로그/메트릭) | 1대 |
devtools_servers | pgAdmin, RedisInsight 등 | 1대 |
공통 그룹 all — 모든 서버에 기본 role 적용: common / user / hardening / tailscale / docker / node_exporter / promtail
단계별 도입 로드맵
| Phase | 시기 | 도입 범위 | 서버 수 |
|---|---|---|---|
| 1 | 지금 | Ansible 단독 (정적 inventory), 기본 role 3~5개 | 5대 |
| 2 | 향후 | + Terraform (IaaS별 provider), dynamic inventory | 10대+ |
| 3 | Secret 복잡 | SOPS + age 마이그레이션 검토 | — |
| 4 | 팀 규모↑ | CI에서 Playbook 실행 (GitHub Actions), 승인 워크플로 | 50대+ |
지금 권장: Phase 1만 시작. Terraform은 VM이 자주 생성/파괴될 때 가치 — 초기엔 각 IaaS의 대시보드 UI로도 충분.
저장소 구조 (멀티 계정 Overlay)
multi-saas-kit은 공통 코드와 계정(tenant)별 데이터를 폴더 수준으로 분리합니다. 스타터킷을 구매한 개발사는 자사 서버 + 자기 고객사 서버까지 한 저장소로 관리할 수 있습니다(MSP 패턴).
workspace/_infra/
├── ansible/ ← 스타터킷 공통 (판매 대상)
│ ├── ansible.cfg # account-aware (환경변수 override)
│ ├── playbooks/{bootstrap,site}.yml
│ ├── roles/{common,user,hardening,tailscale,docker, …}
│ └── docs/ # 내부 세부 가이드
│
├── ansible-accounts/ ← 계정 루트
│ ├── _example/ ← 템플릿 (판매 포함)
│ ├── self/ ← 자사 계정 (gitignore)
│ ├── customer-a/ ← 고객사 A (gitignore)
│ └── customer-b/ ← 고객사 B (gitignore)
│
└── scripts/
└── ansible-account.sh ← 계정 선택 실행 wrapper
계정 격리 장치 3가지
| 장치 | 효과 |
|---|---|
계정별 .vault-pass 분리 | 다른 계정의 secret을 실수로 복호화 불가 |
ANSIBLE_INVENTORY 강제 주입 | ansible all -m ... 명령도 해당 계정 서버만 대상 |
| 계정 폴더 존재 검증 | 오타(예: customer-A vs customer-a) 즉시 에러 |
실행 예시
cd workspace/_infra
# 자사 서버
scripts/ansible-account.sh self site
# 고객사 서버
scripts/ansible-account.sh customer-a bootstrap --limit npm-01
scripts/ansible-account.sh customer-b site --tags hardening --check --diff
설계 배경: ADR-020 멀티 계정 Overlay
네트워크 설계
Public → Tailscale → Private 3단 구조
Public Internet
│ *.codebase.how (DNS: Cloudflare)
▼
NPM 서버 (80/443 only)
│ SSL 종료 + reverse proxy
▼
Tailscale Mesh (100.64.0.0/10)
├─ App 서버들
├─ DB 서버
└─ DevTools 어드민
방화벽 정책
| 포트 | 외부 공개 | Tailscale 내부 |
|---|---|---|
| 22 (SSH) | ❌ | ✅ Tailscale IP로만 |
| 80 (HTTP) | NPM만 ✅ | — |
| 443 (HTTPS) | NPM만 ✅ | — |
| 앱/DB/Redis | ❌ | ✅ 내부만 |
주요 자동화 범위
Ansible이 담당하는 작업:
| 범주 | 작업 |
|---|---|
| OS 기본 | hostname, timezone, apt update, 필수 패키지 |
| 계정 | deploy 유저 생성, SSH 키 주입, sudo NOPASSWD |
| 보안 | SSH hardening, UFW 규칙, fail2ban, unattended-upgrades |
| 네트워크 | Tailscale 가입 + ACL 태그 |
| 컨테이너 | Docker Engine + Compose v2 설치 |
| 관측 | node_exporter + promtail 설치·설정 |
| 앱 배포 | git clone + docker compose up -d + 환경변수 주입 |
| 역할별 | NPM / Laravel / PostgreSQL / Grafana LGTM 배포 |
다음 단계
- 서버 프로비저닝 가이드 — 임의 IaaS 서버 생성부터 Ansible bootstrap까지
- 일상 운영 시나리오 — 서버 추가/패치/장애 복구