본문으로 건너뛰기

서버 관리 개요

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 초기 상태 등 공통 요건만 충족하면 가능
AnsibleOS 프로비저닝 + 배포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_serversNginx Proxy Manager (reverse proxy + SSL)1대
app_serversLaravel SaaS 앱N대 (프로젝트별)
db_serversPostgreSQL1~N대
monitoring_serversGrafana LGTM (로그/메트릭)1대
devtools_serverspgAdmin, 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 inventory10대+
3Secret 복잡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 배포

다음 단계

관련 문서