Files
N8N/README.md
2026-05-20 22:26:32 +00:00

3.5 KiB

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

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:

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:

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

cd terraform
cp single.tfvars.example terraform.tfvars
terraform init
terraform apply

After Terraform finishes, run:

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