# VM Service Template This repository is a starter template for deploying one or more service VMs in Proxmox using Terraform, then configuring and launching applications with Ansible and Docker Compose. It is designed to work with a shared Terraform module stored in a separate repository. This repo acts as the wrapper/root module and provides the service-specific inputs, deployment workflow, and app stack files. ## What this repo does - Creates one or more Proxmox VMs from a reusable Terraform module. - Uses cloud-init and QEMU guest agent in the template VM. - Writes the VM IP address into Ansible inventory. - Tags VMs with Terraform, Docker, service name, and IP metadata. - Deploys an application stack with Ansible and Docker Compose. ## Repository layout ```text terraform/ Terraform wrapper for the shared Proxmox module. compose/ Docker Compose application files. ansible/ Playbook and role used to configure and deploy the app. .gitea/ Workflow files for apply and deploy. ``` ## Requirements - Terraform installed locally or in CI. - Access to the Proxmox API. - A shared Proxmox VM module in a separate repository. - Ansible installed for application deployment. - Docker and Docker Compose available on the target VM. ## How it works 1. Terraform reads the instance configuration from `terraform.tfvars`. 2. Terraform calls the shared Proxmox module to create the VM. 3. Terraform outputs the VM IP address and tags. 4. The workflow writes the IP into `ansible/inventory/hosts.ini`. 5. Ansible connects to the VM and deploys the Compose stack. ## Single instance Use `instance_mode = "single"` and define one `instance` object. Example: ```hcl instance_mode = "single" instance = { service_name = "grafana" vm_name = "grafana-01" node_name = "pop" app_port = 3000 app_image = "grafana/grafana:latest" vm_tags = ["monitoring"] } ``` ## Multi instance Use `instance_mode = "multi"` and define an `instances` map. Example: ```hcl instance_mode = "multi" instances = { grafana = { service_name = "grafana" vm_name = "grafana-01" node_name = "pop" app_port = 3000 app_image = "grafana/grafana:latest" vm_tags = ["monitoring"] } caddy = { service_name = "caddy" vm_name = "caddy-01" node_name = "pop" app_port = 80 app_image = "caddy:latest" vm_tags = ["proxy"] } } ``` ## Defaults The template supports module defaults for items like: - datastore - BIOS - machine type - SSH key - bridge - CPU, RAM, and disk size Override only what you need in the service repo. ## Running locally ```bash cd terraform cp single.tfvars.example terraform.tfvars terraform init terraform apply ``` After Terraform finishes, run: ```bash cd .. ansible-playbook -i ansible/inventory/hosts.ini ansible/playbooks/deploy.yml ``` ## Workflow trigger This template is intended to be run after the repository is created from it. The usual flow is: - create a new repo from this template, - update the tfvars file, - trigger the workflow manually with `workflow_dispatch`, - or push the first commit to start deployment. ## Notes - The shared Proxmox module should live in a separate repository. - The service repo should contain the wrapper, not the internal Proxmox resource logic. - VM IP tags are generated after Terraform apply. - If the VM disk is resized manually in Proxmox, Terraform may see drift on the next run. ## Example use case This template works well for service VMs such as: - Grafana - Caddy - Jellyfin - Code Server - Monitoring or proxy VMs