Ansible 진행을 위한 구현방법 순서
목적: 코드 작성 전에 어떤 순서로 무엇을 결정·구현할지만 정리. 실제 코드는 이 순서를 따라 단계별로 작성.
참조: ansible-implementation-plan.md, pulumi-ansible-step1-step2-plan.md, saas-db-separation-and-scaling-plan.md.
현재 상태 요약
| 항목 | 상태 |
|---|---|
| Playbook | DB 분리형: prego_db_servers(Docker+MariaDB), prego_nodes(Docker+frappe_bench+frappe_site) |
| Roles | docker, mariadb_server, frappe_bench, frappe_site |
| frappe_bench | Docker 기반: frappe/bench 이미지로 컨테이너 기동, 한 번 bench init 실행 |
| frappe_site | frappe_container_name 설정 시 컨테이너 안에서 docker exec로 bench new-site·add-api-key 실행 |
| 구현 완료 | 기획서 §1~2·CI 연동·문서 반영 완료. 로컬 수동 검증·Runbook 체크리스트는 환경에서 실행 후 확인. |
구현방법 순서 (실행 순서대로)
0. 구현 전 준비 (선행 조건)
진입 전에 아래를 정리해 두어야 이후 단계에서 결정이 흔들리지 않는다.
| 순서 | 할 일 | 산출/확인 |
|---|---|---|
| 0.1 | 변수·시크릿 목록 정리: tenant_id, canonical_hostname, db_root_password, ansible_host, ansible_user, ansible_ssh_private_key_file 등. 로컬용 vs CI(GitHub Secrets)용 구분. | 목록 표 또는 체크리스트 |
| 0.2 | 인벤토리 구조 확정: DB 분리형이면 prego_db_servers / prego_nodes 두 그룹, 각각 ansible_host·db_host 등. 단일 서버 실험 시에는 한 호스트를 두 그룹에 모두 넣는 방식 여부 결정. | inventory.example.yml 구조 설명 |
| 0.3 | SSH·DB 비밀값 준비: 로컬용 SSH 키 경로, db_root_password 전달 방식(-e vs Vault). CI용이면 PREGO_SSH_PRIVATE_KEY, PREGO_DB_ROOT_PASSWORD 등 Secret 이름 확정. | 문서화 또는 Secrets 등록 |
1. Frappe/bench 런타임 방식 확정 및 구현
App 서버에서 Frappe bench가 어디서 어떻게 돌아갈지 결정한 뒤, 그에 맞는 role/구성을 만든다.
| 순서 | 할 일 | 산출/확인 |
|---|---|---|
| 1.1 | 방식 선택: (A) Docker 기반 — frappe/bench 등 이미지로 컨테이너 실행, bench 명령은 docker exec로 실행. (B) 네이티브 — 서버에 Python/Node·bench 직접 설치. 기획서 권장은 A. | 결정: A 또는 B |
| 1.2 | (A 선택 시) Frappe bench용 role 추가: 예) roles/frappe_bench. Docker Compose 또는 docker_container로 Frappe bench 이미지 기동, 볼륨·네트워크·서비스 이름 고정. | roles/frappe_bench/ 구조 |
| 1.3 | (A 선택 시) frappe_site 연동 방식 결정: bench 명령을 컨테이너 안에서 실행할지(docker exec + 컨테이너 이름 변수) vs connection: docker로 컨테이너를 호스트처럼 다룰지. 권장: docker exec + frappe_container_name 변수. | frappe_site가 사용할 변수·실행 방식 명세 |
| 1.4 | (B 선택 시) bench 설치용 role 추가: 의존성 설치 → bench init(또는 공식 스크립트) → bench_path·bench_user를 frappe_site와 동일하게 맞춤. | roles/frappe_bench/ 또는 동일 역할 role |
| 1.5 | 멱등성 설계: bench new-site는 creates:로 사이트 디렉터리 지정해 재실행 시 스킵. Docker 재시작 시에도 볼륨에 사이트가 있으면 스킵되도록. | task 설계 원칙 정리 |
2. Playbook·Role 실행 순서 및 변수 연동
런타임이 정해진 뒤, playbook에서 누구를 언제 실행하고 어떤 변수를 넘길지 순서대로 정한다.
| 순서 | 할 일 | 산출/확인 |
|---|---|---|
| 2.1 | Play 실행 순서 확정: (1) prego_db_servers: docker → mariadb_server. (2) prego_nodes: docker → frappe_bench(또는 동일 역할) → frappe_site. | playbook.yml의 play·role 순서 |
| 2.2 | DB 연결 정보 전달 확정: prego_nodes에서 db_host·db_port를 어디서 가져올지 — 인벤토리 vars에 직접 쓰기 vs hostvars[groups['prego_db_servers'][0]].ansible_host 등으로 자동 참조. | 변수 소스 정의 |
| 2.3 | frappe_site에 넘길 변수 정리: tenant_id, canonical_hostname, site_name, db_host, db_port, db_root_password, (Docker 시) frappe_container_name 또는 bench_path·bench_user. | 변수 표 |
| 2.4 | 아티팩트 출력 유지: API 키를 artifacts/tenant_api_key.txt에 쓰는 post_tasks는 그대로 두고, frappe_site에서 설정한 tenant_api_key fact가 이 파일에 반영되는지 흐름 확인. | 데이터 흐름 검증 |
3. 변수·시크릿 정리 및 기본값
구현이 들어가기 전에 어디에 어떤 변수를 둘지 규칙을 정한다.
| 순서 | 할 일 | 산출/확인 |
|---|---|---|
| 3.1 | 필수 변수 목록 고정: tenant_id, db_root_password, (CI 시) ansible_ssh_private_key_file 경로. 선택: canonical_hostname(미전달 시 tenant_id 앞 8자 등 규칙). | group_vars/defaults 또는 문서 표 |
| 3.2 | Role defaults 정리: 각 role의 defaults/main.yml에 노출해도 되는 기본값만 두고, 비밀값은 play·extra vars·Vault로만 전달하도록 원칙 수립. | defaults vs vars 원칙 |
| 3.3 | 시크릿 관리 방식: 로컬은 -e db_root_password=... 또는 ansible-vault; CI는 GitHub Secrets → 워크플로에서만 주입. | README 또는 Runbook에 한 줄씩 명시 |
4. 로컬 수동 검증 절차
코드가 준비되면 로컬에서 끝까지 한 번 수동으로 검증하는 순서를 따른다.
| 순서 | 할 일 | 산출/확인 |
|---|---|---|
| 4.1 | 사전 확인: Pulumi에서 app_server_ip·db_server_ip(또는 단일 server_ip) 확보, SSH 접속 가능 여부 확인. | 접속 테스트 성공 |
| 4.2 | 인벤토리 작성: example 복사 → inventory.yml, IP·db_host 등 치환. | inventory/inventory.yml |
| 4.3 | Playbook 한 번에 실행: ansible-playbook -i inventory/inventory.yml playbook.yml -e tenant_id=... -e db_root_password=... | 전체 playbook 성공 |
| 4.4 | 검증 포인트 확인: Docker 설치 → MariaDB 기동(DB 서버) → Frappe bench 기동(App) → bench new-site → add-api-key → artifacts/tenant_api_key.txt 생성. | 체크리스트 통과 |
| 4.5 | 파이프라인 연동 검증: Prego 레포에서 npx tsx infra/zuplo_sync.ts <tenant_id> --api-key-file artifacts/tenant_api_key.txt 실행해 Zuplo 등록 성공. | Zuplo 연동 확인 |
5. CI(워크플로) 연동
로컬 검증이 끝난 뒤 GitHub Actions에서 동일 playbook이 돌도록 한다.
| 순서 | 할 일 | 산출/확인 |
|---|---|---|
| 5.1 | Ansible 실행 환경 준비: runner에 Ansible 설치(pip/apt/actions). 필요 시 ansible-core 버전 고정. | 워크플로 step 명세 |
| 5.2 | SSH 키 주입: Secret PREGO_SSH_PRIVATE_KEY 내용을 runner 임시 파일로 쓰고, 인벤토리 또는 -e ansible_ssh_private_key_file=...로 경로 전달. | step + 인벤토리/변수 |
| 5.3 | db_root_password 전달: -e db_root_password=${{ secrets.PREGO_DB_ROOT_PASSWORD }} 추가. | 워크플로 수정 |
| 5.4 | 인벤토리 동적 생성: Pulumi 출력(또는 resolve-server)으로 받은 app_server_ip·db_server_ip를 사용해 워크플로 단계에서 inventory 파일 생성 또는 -e로 호스트 지정. | 인벤토리 소스 확정 |
| 5.5 | 아티팩트 전달: Ansible 실행 후 artifacts/tenant_api_key.txt를 다음 단계(zuplo-sync 등)에서 읽을 수 있도록 경로·업로드 여부 확인. | 파이프라인 데이터 흐름 |
6. 문서·Runbook 정리
구현이 안정화된 뒤 재현 가능하도록 문서를 맞춘다.
| 순서 | 할 일 | 산출/확인 |
|---|---|---|
| 6.1 | prego-ansible README: One-off 실행 절차(인벤토리 복사, 필수 변수, 실행 명령), 파이프라인에서의 역할(입력: server_ip·tenant_id, 출력: artifacts/tenant_api_key.txt), Frappe 설치 방식 요약. | README 갱신 |
| 6.2 | provision-tenant-pipeline Runbook: Ansible 단계에서 필요한 Secret(SSH, db_root_password), 실패 시 확인 항목(SSH, bench 로그, DB 연결). | Runbook 보완 |
| 6.3 | 변수·시크릿 표 최종 반영: ansible-implementation-plan의 변수 표와 이 순서서의 결정이 일치하는지 확인. | 문서 간 일관성 |
순서 요약 (한 줄씩)
- 0 — 변수·시크릿·인벤토리 구조·SSH/DB 준비
- 1 — Frappe/bench 방식(A: Docker / B: 네이티브) 확정 → 해당 role 구현·frappe_site 연동
- 2 — Playbook play/role 순서·변수 연동·아티팩트 흐름 확정
- 3 — 변수·시크릿·defaults 정리 및 문서화
- 4 — 로컬에서 인벤토리·playbook·Zuplo sync까지 수동 검증
- 5 — CI에서 Ansible 설치·SSH·db_root_password·인벤토리·아티팩트 연동
- 6 — README·Runbook·변수 표 최종 정리
참조 문서
| 문서 | 내용 |
|---|---|
| ansible-implementation-plan.md | 단계별 상세(1~5단계), 산출물, 체크리스트 |
| pulumi-ansible-step1-step2-plan.md | Pulumi → Ansible 데이터 전달, Ansible 비범위(DNS·Vectorize) |
| saas-db-separation-and-scaling-plan.md | Phase 1 DB 분리, Ansible §5 |
| provision-tenant-pipeline.md | 수동 프로비저닝·워크플로 입력 스펙 |