A Kubernetes controller that automatically manages Apache Guacamole connections from declarative YAML configuration. It bridges the gap between GitOps workflows and Guacamole by providing:
- Declarative connections -- Define SSH, RDP, VNC, and Telnet connections in a simple YAML file
- Connection groups -- Connections are automatically organized into Guacamole folders
- Reconciliation loop -- Continuously syncs state, creating new connections, updating changed ones, and removing orphans
- Safe naming convention -- All managed connections are prefixed with
[managed]so manually-created connections are never touched
The reconciler runs as a single-replica Deployment inside your cluster. Every reconciliation cycle (default: 5 minutes) it:
- Connects to the Guacamole REST API using local database credentials
- Lists all existing connections and filters to those with the
[managed]prefix - Fetches parameters for each managed connection
- Loads desired state from the mounted ConfigMap (
/config/connections.yaml) - Creates, updates, or deletes connections to match the desired state
- Creates connection groups (folders) automatically as needed
helm install guacamole-reconciler ./charts/guacamole-reconciler \
--namespace guacamole \
--set guacUrl=http://guacamole:8080 \
--set credentials.existingSecret=my-guac-secretThe existing secret must contain username and password keys:
apiVersion: v1
kind: Secret
metadata:
name: my-guac-secret
type: Opaque
stringData:
username: guacadmin
password: guacadminBuild and push the container image:
docker build -t your-registry/guacamole-reconciler:latest .
docker push your-registry/guacamole-reconciler:latestThen set image.repository, image.tag, and image.useCustomImage: true in the Helm values.
Apply the raw Kubernetes manifests directly -- see the charts/guacamole-reconciler/templates/ directory for reference.
| Variable | Default | Description |
|---|---|---|
GUAC_URL |
(required) | Guacamole web URL (e.g., http://guacamole:8080) |
GUAC_USERNAME |
(required) | Guacamole admin username |
GUAC_PASSWORD |
(required) | Guacamole admin password |
GUAC_VERIFY_SSL |
true |
Verify SSL certificates |
RESYNC_INTERVAL |
300 |
Seconds between reconciliation cycles |
LOG_LEVEL |
INFO |
Log level (DEBUG, INFO, WARNING, ERROR) |
See charts/guacamole-reconciler/values.yaml for all available options.
Key values:
guacUrl: "http://guacamole:8080"
guacVerifySsl: "true"
resyncInterval: "300"
logLevel: "INFO"
credentials:
existingSecret: "my-guac-secret" # recommended
# OR inline (not recommended for production):
# username: "guacadmin"
# password: "changeme"
staticConnections:
enabled: true
connections:
- name: My Server
protocol: ssh
group: Servers
parameters:
hostname: "192.168.1.10"
port: "22"
username: "admin"Define connections in a YAML file mounted at /config/connections.yaml:
connections:
- name: Core Router
protocol: ssh
group: Network
parameters:
hostname: "192.168.1.1"
port: "22"
username: "admin"
- name: Windows Server
protocol: rdp
group: Servers
parameters:
hostname: "192.168.1.50"
port: "3389"
username: "Administrator"
security: "nla"
ignore-cert: "true"
- name: VNC Host
protocol: vnc
group: Infrastructure
parameters:
hostname: "192.168.1.100"
port: "5900"
- name: Network Switch
protocol: telnet
group: Network
parameters:
hostname: "192.168.1.2"
port: "23"
username: "admin"| Field | Required | Description |
|---|---|---|
name |
Yes | Display name (becomes [managed] {name} in Guacamole) |
protocol |
Yes | Connection protocol: ssh, rdp, vnc, telnet |
group |
No | Connection group (folder) name; created automatically if missing |
parameters |
Yes | Protocol-specific parameters passed directly to Guacamole |
SSH: hostname, port, username, password, private-key
RDP: hostname, port, username, password, domain, security, ignore-cert, width, height, color-depth, resize-method
VNC: hostname, port, password
Telnet: hostname, port, username, password
All parameter values must be strings. The reconciler passes them directly to the Guacamole API without transformation.
All reconciler-managed connections are prefixed with [managed] in Guacamole:
- YAML
name: Core Routerbecomes[managed] Core Routerin Guacamole - Only connections with the
[managed]prefix are managed by the reconciler - Manually-created connections (without the prefix) are never modified or deleted
The reconciler authenticates via the Guacamole REST API using local database credentials. This works even when OpenID/SSO is configured alongside database auth, because Guacamole loads both authentication providers simultaneously.
It is recommended to create a dedicated service account user in Guacamole for the reconciler, with permissions to manage connections and connection groups.
This chart works well with ArgoCD using a multi-source Application:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: guacamole-reconciler
namespace: argocd
spec:
project: default
sources:
- repoURL: https://github.com/moellere/guacamole-reconciler.git
targetRevision: HEAD
path: charts/guacamole-reconciler
helm:
releaseName: guacamole-reconciler
valueFiles:
- $values/path/to/values.yaml
- repoURL: git@github.com:your-org/your-argocd-repo.git
targetRevision: HEAD
ref: values
destination:
server: https://kubernetes.default.svc
namespace: guacamole
syncPolicy:
automated:
prune: true
selfHeal: trueMIT