Deployment
Container Image
The provider image is built as a multi-stage Docker image (Go builder + distroless runtime) and pushed to GHCR:
ghcr.io/stuttgart-things/provider-vspherevm:<version>
ghcr.io/stuttgart-things/provider-vspherevm:latest
Each GitHub release publishes a semver-tagged image.
Dockerfile location: cluster/images/provider-vspherevm/Dockerfile
Crossplane xpkg
The Crossplane package (xpkg) embeds the runtime image, CRDs, and package metadata:
ghcr.io/stuttgart-things/provider-vspherevm-xpkg:<version>
ghcr.io/stuttgart-things/provider-vspherevm-xpkg:latest
Build the xpkg locally:
crossplane xpkg build \
--package-root=package \
--embed-runtime-image=ghcr.io/stuttgart-things/provider-vspherevm:<version> \
-o provider-vspherevm.xpkg
Install via Crossplane
apiVersion: pkg.crossplane.io/v1
kind: Provider
metadata:
name: provider-vspherevm
spec:
package: ghcr.io/stuttgart-things/provider-vspherevm-xpkg:v0.1.0 # or :latest
Verify
# Check the provider is installed and healthy
kubectl get providers provider-vspherevm
# Check all 11 CRDs were installed
kubectl get crds | grep vspherevm
# Check VirtualMachine resources
kubectl get virtualmachine
ProviderConfig Setup
Create the vSphere credentials Secret and ProviderConfig:
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Secret
metadata:
name: vsphere-credentials
namespace: crossplane-system
stringData:
credentials: |
{
"user": "administrator@vsphere.local",
"password": "your-password",
"server": "vcenter.example.com",
"allow_unverified_ssl": "true"
}
---
apiVersion: vspherevm.stuttgart-things.com/v1beta1
kind: ProviderConfig
metadata:
name: default
spec:
credentials:
source: Secret
secretRef:
name: vsphere-credentials
namespace: crossplane-system
key: credentials
EOF
The credentials are extracted as JSON and mapped to Terraform provider arguments in internal/clients/vsphere.go:
ps.Configuration = map[string]any{
"user": creds["user"],
"password": creds["password"],
"vsphere_server": creds["server"],
"allow_unverified_ssl": creds["allow_unverified_ssl"],
}
Local Development
# Init build submodule (first time)
make submodules
# Install CRDs and start the provider locally
kubectl apply -R -f package/crds
go run cmd/provider/main.go \
--debug \
--terraform-version=1.5.7 \
--terraform-provider-source=vmware/vsphere \
--terraform-provider-version=2.15.0
Provider Flags
| Flag | Default | Description |
|---|---|---|
--debug / -d |
false |
Enable debug logging |
--leader-election / -l |
false |
Enable leader election for HA |
--poll |
10m |
How often to check each resource for drift |
--max-reconcile-rate |
10 |
Max reconciliations per second |
--terraform-version |
(required) | Terraform CLI version |
--terraform-provider-source |
(required) | TF provider source (vmware/vsphere) |
--terraform-provider-version |
(required) | TF provider version (2.15.0) |