Files
homelab-infrastructure-as-code/proxmox-infra/CLAUDE.md
T
kasun 57dc56c690
Deploy Proxmox Infra / Pulumi Preview (push) Has been skipped
Deploy Proxmox Infra / Pulumi Deploy (push) Failing after 55s
Initial Pulumi proxmox-infra setup with Gitea Actions
2026-05-27 20:26:52 +02:00

2.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Project Overview

This is a Pulumi TypeScript project (proxmox-infra) for provisioning VMs and LXC containers in Proxmox using the @muhlba91/pulumi-proxmoxve provider. The stack name is dev.

Common Commands

# Install dependencies
npm install

# Preview infrastructure changes
pulumi preview

# Sync Pulumi state with actual Proxmox state (run before up if resources were changed manually)
pulumi refresh --yes

# Deploy infrastructure
pulumi refresh --yes && pulumi up --yes

# Destroy infrastructure
pulumi destroy

# View current stack outputs
pulumi stack output

# View stack config
pulumi config

Architecture

  • Entry point: index.ts — all Pulumi resources are declared here
  • Provider: @muhlba91/pulumi-proxmoxve v8.x — community Proxmox provider (not an official Pulumi provider)
  • Stack: dev — configured in Pulumi.dev.yaml
  • Runtime: Node.js with npm, TypeScript compiled to bin/ (excluded from git)

CI/CD (Gitea Actions)

Workflow file: ../.gitea/workflows/deploy-proxmox-infra.yaml

  • Pull requestpulumi preview (no changes deployed)
  • Push to mainpulumi refresh then pulumi up

Secrets required in Gitea (Settings → Actions → Secrets):

  • PULUMI_BACKEND_URL — PostgreSQL connection string for the self-hosted state backend
  • PULUMI_CONFIG_PASSPHRASE — passphrase used to decrypt secrets in Pulumi.dev.yaml
  • PULUMI_DEV_YAML — base64-encoded content of Pulumi.dev.yaml (auto-synced by pre-push hook)

Local Setup (one-time)

  1. Copy .env.local.example to .env.local and fill in your Gitea API URL and token
  2. Register the git hook so it runs automatically on push:
    git config core.hooksPath .githooks
    
  3. Generate a Gitea personal access token at: Gitea → Settings → Applications → Access Tokens (needs read/write Actions Secrets permission)

After this, every git push automatically encodes Pulumi.dev.yaml and updates the PULUMI_DEV_YAML Gitea secret.

Key Notes

  • Credentials for both Proxmox nodes are stored as encrypted secrets in Pulumi.dev.yaml and decrypted at runtime using PULUMI_CONFIG_PASSPHRASE. Do not pass Proxmox credentials via environment variables — the code uses config.requireSecret().
  • There are two Proxmox providers: pveProvider (main node pve) and pveBckpProvider (backup node pve-bckp). Always pass the correct provider when adding resources.
  • Pulumi.dev.yaml contains the encryption salt — never delete it or secrets become unrecoverable.
  • If a Proxmox resource was changed outside of Pulumi, run pulumi refresh before pulumi up to avoid state drift conflicts.
  • TypeScript is compiled with strict mode, nodenext module resolution, and noImplicitReturns — all functions must have explicit return types when TypeScript cannot infer them.