본문 바로가기
IT/HomeLabs

[홈랩 IaC 자동화 #7] GitOps — git push 한 번으로 Proxmox VM 자동 생성

by 수누다 2026. 4. 3.

환경 정보

항목 내용
Gitea latest (Docker)
AWX 24.6.1 (K3s + AWX Operator 2.19.1)
Terraform v1.9.x
Provider bpg/proxmox v0.99.0
Proxmox VE 8.x
Gitea 서버 Ubuntu 24.04 (192.168.x.xxx)
AWX 서버 Rocky Linux 9 (192.168.x.xxx)

6편에서 AWX + Terraform 파이프라인을 완성한 상태에서 진행합니다.


이번 편 목표

git push
    ↓ Gitea Webhook
AWX terraform-apply 자동 실행
    ↓ Ansible → terraform apply
Proxmox VM 자동 생성
    ↓
완전 자동화 GitOps 파이프라인 완성!

코드를 수정하고 push하는 것만으로 인프라가 자동으로 바뀐다.


GitOps란?

Git을 단일 진실 공급원(Single Source of Truth)으로 사용해서 인프라를 관리하는 방법이다. 코드 변경 → Git Push → 자동 배포가 핵심이다.

기존 방식: 터미널에서 terraform apply 직접 실행
GitOps:   git push → 자동으로 terraform apply 실행

STEP 1. Gitea 서버 VM 생성

Terraform으로 Gitea 전용 VM을 만든다.

# main.tf locals에 추가
locals {
  vms = {
    "ansible-target-01" = { vmid = 201 }
    "ansible-target-02" = { vmid = 202 }
    "gitea-server"      = { vmid = 203 }
  }
}
terraform apply
terraform output vm_ips
# gitea-server → 192.168.x.xxx

STEP 2. Gitea 설치 (Docker)

# gitea-server SSH 접속
ssh ubuntu@192.168.x.xxx

# Docker 설치
sudo apt update
sudo apt install -y docker.io docker-compose
sudo systemctl enable docker
sudo systemctl start docker

# Gitea 디렉토리 생성
mkdir -p ~/gitea

# docker-compose.yml 작성
cat > ~/gitea/docker-compose.yml << 'EOF'
version: "3"
services:
  gitea:
    image: gitea/gitea:latest
    container_name: gitea
    environment:
      - USER_UID=1000
      - USER_GID=1000
    restart: always
    ports:
      - "3000:3000"
      - "222:22"
    volumes:
      - ./data:/data
EOF

# Gitea 실행
cd ~/gitea
sudo docker-compose up -d

# 상태 확인
sudo docker ps

STEP 3. Gitea 초기 설정

브라우저에서 http://192.168.x.xxx:3000 접속

항목
데이터베이스 유형 SQLite3
사이트 URL http://192.168.x.xxx:3000/
관리자 계정 admin
관리자 비밀번호 특수문자 없는 비밀번호 권장

⚠️ 비밀번호에 ! 같은 특수문자가 있으면 나중에 git remote URL 설정 시 bash 오류가 발생한다. 특수문자 없는 비밀번호를 사용하자.

📸 캡처 타이밍!
→ Gitea 초기 설정 화면
→ 설치 완료 대시보드


STEP 4. Repository 생성 및 코드 Push

Gitea에서 Repository 생성

+ 버튼 → New Repository
이름: homelab-iac
Visibility: Private
Initialize repository: ✅

AWX 서버에서 Git 설정

cd ~/terraform/proxmox-vm

# git 초기화
git init
git config user.email "admin@homelab.local"
git config user.name "admin"

# .gitignore — 민감정보 제외
cat > .gitignore << 'EOF'
.terraform/
terraform.tfstate
terraform.tfstate.backup
*.tfvars
provider.tf
EOF

⚠️ provider.tf에는 Proxmox API Token이 포함되어 있다. 반드시 gitignore에 추가해야 한다!

# 커밋 및 Push
git add .
git commit -m "첫 번째 커밋: Terraform Proxmox VM 자동화"
git remote add origin http://admin:비밀번호@192.168.x.xxx:3000/admin/homelab-iac.git
git push -u origin master

📸 캡처 타이밍!
→ Gitea Repository 파일 목록 화면


STEP 5. AWX SCM 프로젝트 생성

AWX가 Gitea에서 Playbook을 가져오도록 설정한다.

Gitea 자격증명 먼저 등록

Resources → Credentials → Add
항목
Name gitea-credential
Credential Type Source Control
Username admin
Password Gitea 비밀번호

SCM 프로젝트 생성

Resources → Projects → Add
항목
Name homelab-iac-git
Source Control Type Git
Source Control URL http://192.168.x.xxx:3000/admin/homelab-iac.git
소스 제어 참조 master
소스 제어 인증 정보 gitea-credential
Options ✅ 정리 ✅ 삭제

저장 후 🟢 Success 확인

📸 캡처 타이밍!
→ AWX SCM 프로젝트 Success 화면


STEP 6. AWX API Token 발급

Gitea Webhook이 AWX Job을 트리거하려면 인증이 필요하다.

AWX UI → 우측 상단 프로필
→ User Details → Tokens 탭 → Add
항목
Description gitea-webhook
Scope Write

Save → Token 값 메모!


STEP 7. AWX에서 curl로 Job 트리거 테스트

Webhook 설정 전에 API 방식이 동작하는지 먼저 확인한다.

AWX_TOKEN="발급받은Token"
TEMPLATE_ID="12"   # terraform-apply 템플릿 ID

curl -s -X POST \
  http://192.168.x.xxx:30080/api/v2/job_templates/${TEMPLATE_ID}/launch/ \
  -H "Authorization: Bearer ${AWX_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{}'

성공 응답:

{"job": 25, "status": "pending", ...}

AWX Jobs에서 terraform-apply가 실행되면 성공!

⚠️ AWX Webhook 서명 방식 주의: AWX 기본 Webhook(/github/ 엔드포인트)은 HMAC-SHA256 서명 검증을 하는데, Gitea와 호환이 까다롭다. 대신 AWX API Token + /launch/ 엔드포인트 방식이 훨씬 간단하고 안정적이다.


STEP 8. Gitea Webhook 설정

http://192.168.x.xxx:3000/admin/homelab-iac
→ 설정 → Webhooks → Add Webhook → Gitea
항목
Target URL http://192.168.x.xxx:30080/api/v2/job_templates/12/launch/
HTTP Method POST
Content Type application/json
Authorization Header Bearer 발급받은AWXToken
비밀 비워두기
Trigger Push events ✅

저장Test Push Event 클릭

📸 캡처 타이밍!
→ Gitea Webhook 설정 화면


STEP 9. git push로 최종 확인

# AWX 서버에서
cd ~/terraform/proxmox-vm

# 코드 수정
echo "# GitOps 테스트 $(date)" >> main.tf

# commit & push
git add .
git commit -m "GitOps 테스트 - 자동 배포"
git push origin master

결과

Gitea 커밋 기록:
admin pushed to master at admin/homelab-iac
"GitOps 테스트 - 자동 배포"
AWX Jobs:
25 — terraform-apply  ✅ 성공

git push 한 번으로 Proxmox VM이 자동으로 만들어진다! 🎉

📸 캡처 타이밍!

1. Gitea 커밋 기록 화면
2. AWX Jobs terraform-apply 자동 실행 성공 화면
3. Proxmox UI — VM 자동 생성 확인

트러블슈팅

AWX Webhook 403 Forbidden

원인: AWX /github/ 엔드포인트는 HMAC-SHA256 서명 검증 필요

해결: /launch/ 엔드포인트 + AWX API Token 방식 사용

# 잘못된 방식
Target URL: http://AWX/api/v2/job_templates/12/github/

# 올바른 방식
Target URL: http://AWX/api/v2/job_templates/12/launch/
Authorization Header: Bearer AWX_TOKEN

git push 시 bash: !비밀번호: event not found

원인: 비밀번호에 ! 포함 시 bash 히스토리 확장 오류

해결: Gitea 비밀번호를 특수문자 없는 것으로 변경


known_hosts 충돌 (REMOTE HOST IDENTIFICATION HAS CHANGED)

원인: 같은 IP로 다른 VM을 재생성했을 때 호스트 키 변경

해결:

ssh-keygen -R 192.168.x.xxx
ssh ubuntu@192.168.x.xxx

전체 GitOps 파이프라인 완성

개발자 (AWX 서버)
    ↓ git push
Gitea (192.168.x.xxx:3000)
    ↓ Webhook (API Token 인증)
AWX (192.168.x.xxx:30080)
    ↓ terraform-apply Job 자동 실행
Ansible → terraform init → terraform apply
    ↓
Proxmox VM 자동 생성
    ↓ cloud-init
SSH 키 + qemu-guest-agent 자동 설치
    ↓
인프라 자동화 완성! 🎉

마무리

드디어 7편까지 완성했다. git push 한 번으로 VM이 자동으로 만들어지는 걸 보니 꽤 뿌듯하다.

AWX 기본 Webhook 방식(/github/ 엔드포인트)은 HMAC 서명 검증 때문에 Gitea와 연동이 까다로웠다. 삽질을 좀 하다가 AWX API Token + /launch/ 엔드포인트 방식으로 바꾸니 깔끔하게 해결됐다. 복잡한 서명 계산 없이 Bearer Token 하나로 끝나서 훨씬 단순하다.

이번 시리즈 전체를 돌아보면:

1편: AWX 설치
2편: Playbook 실행
3편: 스케줄러 + 텔레그램 알림
4편: Terraform VM 자동화
5편: Terraform + Ansible 연동
6편: AWX + Terraform 파이프라인
7편: GitOps 완성

7편에 걸쳐 홈랩 IaC 자동화의 전체 스택을 직접 구축했다. 다음엔 GitHub Actions나 ArgoCD 같은 도구로 더 고도화할 수 있겠지만, 이 정도면 홈랩에서 쓰기엔 충분하다.


참고 링크


메타 설명 (검색 노출용)

Gitea + AWX Webhook으로 git push 시 Proxmox VM이 자동 생성되는 GitOps 파이프라인 구축 방법. AWX Webhook 403 오류 해결, API Token 방식 Webhook 설정 포함.