2026.04.13 - [프로젝트/OpenCSP] - [OpenCSP] Index - Provisioning Flow
[OpenCSP] Index - Provisioning Flow
2026.03.23 - [프로젝트/OpenCSP] - API 요청으로 Terraform CR 생성하기 2026.03.25 - [프로젝트/OpenCSP] - API 요청으로 PVE VM 생성하기 2026.03.26 - [프로젝트/OpenCSP] - OpenCSP Console로 VM 생성해보기 2026.03.28 - [프로젝
miiml.tistory.com
이전 글에서 API로 직접 Terraform CR을 생성해봤다.
그리고 snippets 파일을 SSH가 아닌 PVE API를 사용한 전달로 변경하는 게 나을 거 같다고 생각했어서 모듈을 해당 방식으로 수정했다.
먼저 기존 모듈을 사용해서 구성해둔 인프라에는 영향을 주지 않기 위해 모듈에 버전 tag랑 release note를 남겨줬고,
Core에서 해당 태그의 코드를 사용하도록 지정해줬다. (관련 커밋 : https://github.com/h001-lab/OpenCSP-modules/commit/17f4a557571bfc9b737d47631eadd00e11709ecc)
모듈 수정 후 테스트 해보면서 PVE에서 API로 snippets 파일 업로드를 지원하지 않는다는걸 알게됐는데 (2019년 관련 이슈만 있고 아직 개발진행 안됐다고 함, 현재는 iso랑 vztmpl만 지원)
생각해보니까 처음 모듈을 구성할 때 SSH로 했던 이유가 이거였는데 다른 작업들을 하다보니 까먹고 한번 더 개발해버렸다.
(그래도 덕분에 모듈에 버저닝이 추가됐으니까 장기적으로는 이득..)
아무튼 위에 작업들을 하면서 몇 가지 정리해두고 싶은게 생겨서 2번 글을 따로 작성했다.
SSH 방식에서 Terraform 컨테이너에 SSH key와 API 크레덴셜을 전달해야하니까 기존 Tofu-controller Secret에 해당 내용을 추가해준 부분, provision(wrapper) 디렉토리 구조 수정, 테라폼 모듈 버저닝, Release Note 반 자동화 같은 내용들인데
일단 여기선 2번째 까지만 적어두고 나머진 나중에 정리해봐야겠다.
먼저 ssh 키 새로 생성해서 host에 등록해주고
# 키 생성
ssh-keygen -t ed25519 -f ~/.ssh/pve-tofu -C "tofu-controller" -N ""
# host에 키 등록
ssh-copy-id -i ~/.ssh/pve-tofu.pub root@{pve ip}
위에 생성한 pve-tofu 내용을 기존 secret.yaml에 등록해주면 된다. (sops로 암호화도 해줌)
---
apiVersion: v1
kind: Secret
metadata:
name: pve-ssh-key
namespace: flux-system
type: Opaque
stringData:
id_rsa: |
-----BEGIN OPENSSH PRIVATE KEY-----
~/.ssh/pve-tofu 내용 붙여넣기
-----END OPENSSH PRIVATE KEY-----
참고로 기존 secret에도 ssh 관련 값이 있으니까 거기도 맞춰주야 됨.
저 키를 컨테이너에 마운트 해주는건 Terraform CR이 해준다.
secret 잘 생성 되었으면 아래처럼 curl을 보내볼 수 있다.
curl -v -k -X POST \
"${PVE_K3S_API_SERVER}/apis/infra.contrib.fluxcd.io/v1alpha2/namespaces/flux-system/terraforms" \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"apiVersion": "infra.contrib.fluxcd.io/v1alpha2",
"kind": "Terraform",
"metadata": {
"name": "test-vm-provision",
"namespace": "flux-system",
"annotations": {
"kustomize.toolkit.fluxcd.io/prune": "disabled"
}
},
"spec": {
"path": "./bootstrap/terraform/provisions/proxmox-vm",
"interval": "10m",
"approvePlan": "auto",
"destroyResourcesOnDeletion": true,
"sourceRef": {
"kind": "GitRepository",
"name": "flux-system",
"namespace": "flux-system"
},
"runnerPodTemplate": {
"spec": {
"volumes": [{
"name": "ssh-key",
"secret": {
"secretName": "pve-ssh-key",
"defaultMode": 292
}
}],
"volumeMounts": [{
"name": "ssh-key",
"mountPath": "/home/runner/.ssh",
"readOnly": true
}]
}
},
"varsFrom": [
{"kind": "Secret", "name": "terraform-secrets"}
],
"vars": [
{"name": "vm_name", "value": "test-vm3"},
{"name": "vm_id", "value": 7003},
{"name": "cores", "value": 1},
{"name": "memory", "value": 2048},
{"name": "disk_size", "value": "50G"},
{"name": "vm_ip", "value": "{IP}/24"},
{"name": "vm_gw", "value": "{GW}"},
{"name": "vm_network_bridge", "value": "vmbr0"},
{"name": "target_node", "value": "pve"},
{"name": "template_name", "value": "ubuntu-2404-template"},
{"name": "storage_pool", "value": "local-lvm"},
{"name": "snippet_storage_pool", "value": "local"}
]
}
}'
몇가지 옵션들 설명해보면
"annotations": {
"kustomize.toolkit.fluxcd.io/prune": "disabled"
}
이건 fluxcd의 prune 옵션인데, 이거 활성화시키고 git에 코드가 없으면(flux가 관리하지 않는 리소스면) 계속 제거해주는 옵션이다.
클러스터 관리 면에선 켜주는게 좋지만 CR을 BE가 생성해야 해서 꺼줬다.
"destroyResourcesOnDeletion": true,
이건 리소스가 삭제될 때 destory를 진행할지에 대한 옵션이고, 이게 켜져있으면 Terraform CR이 제거될 때 생성된 리소스가 같이 제거됨.
"path": "./bootstrap/terraform/provisions/proxmox-vm",
"sourceRef": {
"kind": "GitRepository",
"name": "flux-system",
"namespace": "flux-system"
},
이 부분이 2번째 항목인데 기존에 tofu-controller가 참조하기 위해 modules/.../provision 으로 만들었던 wrapper를 core로 옮겨줬다. 이렇게 하면 GitRepository CR을 별도로 추가할 필요없고, 모듈에 두는거 보다 Core에 두는게 운영 관점에서 더 맞다.
"runnerPodTemplate": {
"spec": {
"volumes": [{
"name": "ssh-key",
"secret": {
"secretName": "pve-ssh-key",
"defaultMode": 292
}
}],
"volumeMounts": [{
"name": "ssh-key",
"mountPath": "/home/runner/.ssh",
"readOnly": true
}]
}
},
runnerPodTemplate 부분이 위에서 생성한 ssh 키를 컨테이너에 마운트 시켜주는 부분이고, 권한을 292(read)로 줘서 PVE 접근용 ssh 키를 읽을 수 있게 해줌
참고로 아래 명령어로 필드 구조를 알 수 있다.
kubectl explain terraform.spec.runnerPodTemplate.spec
실행하면 아래처럼 Apply가 성공하고 VM도 생성된걸 볼 수 있음


삭제도 잘 된다. (근데 참고로 finalizer를 먼저 제거하면 CR은 잘 지워지지만 VM 리소스가 제거 되지 않는다.)
curl -k -X DELETE \
"${PVE_K3S_API_SERVER}/apis/infra.contrib.fluxcd.io/v1alpha2/namespaces/flux-system/terraforms/test-vm-provision" \
-H "Authorization: Bearer ${TOKEN}"
| Ansible Semaphore로 VM post-provisioning하기 (0) | 2026.04.03 |
|---|---|
| OpenCSP Console로 VM 생성해보기 (0) | 2026.03.28 |
| API 요청으로 Terraform CR 생성하기 (0) | 2026.03.23 |
| k3s에 zitadel 올려보기 (0) | 2026.03.21 |
| k3s에 Teleport 올리고 리소스 연결하기 (0) | 2026.03.20 |