Skip to main content

Configuration Reference

AADApplication

FieldTypeDefaultDescription
principalIDstring

ACMECredentials

ACMECredentials carries the DNS-provider secrets the cert-manager ClusterIssuer's DNS-01 solver authenticates with. Only needed when cluster.acmeDNS01 is set.

FieldTypeDefaultDescription
cloudflareApiTokenstringCloudflareAPIToken is a Cloudflare API token with Zone:Read +
DNS:Edit on the zones the solver manages (the TXT challenge
records). Sealed into the cert-manager/cloudflare-api-token
Secret the ClusterIssuer references.

ACMEDNS01Config

ACMEDNS01Config selects and scopes the ClusterIssuer's DNS-01 solver. Only Cloudflare is wired today (the chart's solver list also knows route53; extend Provider's oneof when kubeaid-cli grows the matching credential plumbing).

FieldTypeDefaultDescription
providerstringcloudflare
dnsZones[]stringDNSZones limits which zones this solver answers challenges
for (cert-manager's selector.dnsZones). Empty matches every
DNS-01 order — fine when this is the only solver.

AMIConfig

FieldTypeDefaultDescription
idstring

APIServerConfig

REFER : https://github.com/kubernetes-sigs/cluster-api/blob/main/controlplane/kubeadm/config/crd/bases/controlplane.cluster.x-k8s.io_kubeadmcontrolplanes.yaml.

NOTE : Generally, refer to the KubeadmControlPlane CRD instead of the corresponding GoLang source types linked below. There are some configuration options which appear in the corresponding GoLang source type, but not in the CRD. If you set those fields, then they get removed by the Kubeadm control-plane provider. This causes the capi-cluster ArgoCD App to always be in an OutOfSync state, resulting to KubeAid CLI not making any progress!

FieldTypeDefaultDescription
extraArgsmap[string]string{}
extraVolumes[]HostPathMountConfig[]
files[]FileConfig[]

AWSAutoScalableNodeGroup

FieldTypeDefaultDescription
amiAMIConfig
instanceTypestring
rootVolumeSizeuint32
sshKeyNamestring
namestringNodegroup name.
labelsmap[string]string[]Labels that you want to be propagated to each node in the nodegroup.

Each label should meet one of the following criterias to propagate to each of the nodes :

1. Has node-role.kubernetes.io as prefix.
2. Belongs to node-restriction.kubernetes.io domain.
3. Belongs to node.cluster.x-k8s.io domain.

REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine.
taints[]k8s.io/api/core/v1.Taint[]Taints that you want to be propagated to each node in the nodegroup.
minSizeuintMinimum number of replicas in the nodegroup.
maxSizeuintMaximum number of replicas in the nodegroup.

AWSConfig

FieldTypeDefaultDescription
regionstring
sshKeyNamestring
vpcIDstring
bastionEnabledboolTrue
controlPlaneAWSControlPlane
nodeGroups[]AWSAutoScalableNodeGroup

AWSControlPlane

FieldTypeDefaultDescription
loadBalancerSchemestringinternet-facing
replicasuint32
instanceTypestring
amiAMIConfig

AWSCredentials

FieldTypeDefaultDescription
accessKeyIDstring
secretAccessKeystring
sessionTokenstring

ArgoCDConfig

FieldTypeDefaultDescription
deployKeysDeployKeysConfig

AutoScalableNodeGroup

FieldTypeDefaultDescription
minSizeuintMinimum number of replicas in the nodegroup.
maxSizeuintMaximum number of replicas in the nodegroup.
namestringNodegroup name.
labelsmap[string]string[]Labels that you want to be propagated to each node in the nodegroup.

Each label should meet one of the following criterias to propagate to each of the nodes :

1. Has node-role.kubernetes.io as prefix.
2. Belongs to node-restriction.kubernetes.io domain.
3. Belongs to node.cluster.x-k8s.io domain.

REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine.
taints[]k8s.io/api/core/v1.Taint[]Taints that you want to be propagated to each node in the nodegroup.

AzureAutoScalableNodeGroup

FieldTypeDefaultDescription
vmSizestring
diskSizeGBuint32
minSizeuintMinimum number of replicas in the nodegroup.
maxSizeuintMaximum number of replicas in the nodegroup.
namestringNodegroup name.
labelsmap[string]string[]Labels that you want to be propagated to each node in the nodegroup.

Each label should meet one of the following criterias to propagate to each of the nodes :

1. Has node-role.kubernetes.io as prefix.
2. Belongs to node-restriction.kubernetes.io domain.
3. Belongs to node.cluster.x-k8s.io domain.

REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine.
taints[]k8s.io/api/core/v1.Taint[]Taints that you want to be propagated to each node in the nodegroup.

AzureConfig

FieldTypeDefaultDescription
tenantIDstring
subscriptionIDstring
aadApplicationAADApplication
locationstring
storageAccountstring
workloadIdentityWorkloadIdentity
sshPublicKeystring
canonicalUbuntuImageCanonicalUbuntuImage
controlPlaneAzureControlPlane
nodeGroups[]AzureAutoScalableNodeGroup

AzureControlPlane

FieldTypeDefaultDescription
loadBalancerTypestringPublic
diskSizeGBuint32
vmSizestring
replicasuint32

AzureCredentials

FieldTypeDefaultDescription
clientIDstring
clientSecretstring

BareMetalConfig

FieldTypeDefaultDescription
sshBareMetalSSHConfig
kubeletBareMetalKubeletConfigKubelet tuning applied to every host (control-plane and workers).
controlPlaneBareMetalControlPlane
nodeGroups[]BareMetalNodeGroup

BareMetalControlPlane

FieldTypeDefaultDescription
endpointBareMetalControlPlaneEndpoint
hosts[]BareMetalHost

BareMetalControlPlaneEndpoint

FieldTypeDefaultDescription
hoststring
portuint6443

BareMetalHost

FieldTypeDefaultDescription
publicAddressstring
privateAddressstring
sshBareMetalSSHConfig

BareMetalKubeletConfig

BareMetalKubeletConfig mirrors KubeOne's per-host KubeletConfig. REFER : https://docs.kubermatic.com/kubeone/v1.13/references/kubeone-cluster-v1beta2/#kubeletconfig

FieldTypeDefaultDescription
systemReserved,omitemptymap[string]string
kubeReserved,omitemptymap[string]string
evictionHard,omitemptymap[string]string
maxPods,omitemptyint32

BareMetalNodeGroup

FieldTypeDefaultDescription
hosts[]BareMetalHost
namestringNodegroup name.
labelsmap[string]string[]Labels that you want to be propagated to each node in the nodegroup.

Each label should meet one of the following criterias to propagate to each of the nodes :

1. Has node-role.kubernetes.io as prefix.
2. Belongs to node-restriction.kubernetes.io domain.
3. Belongs to node.cluster.x-k8s.io domain.

REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine.
taints[]k8s.io/api/core/v1.Taint[]Taints that you want to be propagated to each node in the nodegroup.

BareMetalSSHConfig

FieldTypeDefaultDescription
portuint22
privateKeyFilePathstringPrivateKeyFilePath is the on-disk SSH private key
kubeaid-cli reads to derive PublicKey + Fingerprint and
(for cloud-side SSH connections like the Hetzner NAT
gateway setup) to authenticate the SSH session. Required
when UseSSHAgent is false; ignored when UseSSHAgent is
true (the agent owns the private key — yubikey case —
so there's nothing on disk to point at). Cross-field
validation in pkg/config/parser/validate.go enforces
"exactly one is set".
useSSHAgentboolUseSSHAgent flips the SSH key sourcing from "read a file
from PrivateKeyFilePath" to "dial $SSH_AUTH_SOCK and ask
the agent for its loaded identities". The first identity
supplies PublicKey + Fingerprint; the SSH client (kubeone)
signs through the agent socket so yubikey-resident
private keys never need to be exported.

CanonicalUbuntuImage

FieldTypeDefaultDescription
offerstring
skustring

CloudConfig

FieldTypeDefaultDescription
awsAWSConfig
azureAzureConfig
hetznerHetznerConfig
bare-metalBareMetalConfig
localLocalConfig
disasterRecoveryDisasterRecoveryConfig

ClusterConfig

FieldTypeDefaultDescription
typestringworkload
namestringName of the Kubernetes cluster.

We don't allow using dots in the cluster name, since it can cause issues with tools like
ClusterAPI and Cilium : which use the cluster name to generate other configurations.
k8sVersionstringKubernetes version (>= 1.30.0).
enableAuditLoggingboolTrueWhether you would like to enable Kubernetes Audit Logging out of the box.
Suitable Kubernetes API configurations will be done for you automatically. And they can be
changed using the apiSever struct field.
acmeEmailstringACMEEmail is the contact email used to register with the ACME
CA (Let's Encrypt) when cert-manager's ClusterIssuer is
rendered. Required when cluster.keycloak.mode=managed (the
keycloakx and netbird-mgmt Ingresses both need TLS certs);
optional otherwise. Used as Issuer.spec.acme.email.
acmeDNS01ACMEDNS01ConfigACMEDNS01 switches the rendered ClusterIssuer's solver from
the HTTP-01 default to DNS-01. Required for the split-horizon
mesh pattern: NetBird-exposed services use real public DNS
names (e.g. argocd.staging.acme.com) that only resolve inside
the mesh — Let's Encrypt can never reach them over HTTP, but
proves ownership via a TXT record on the public zone instead.
Requires cluster.acmeEmail plus the provider credential in
secrets.yaml (acme.cloudflareApiToken).
apiServerAPIServerConfigConfiguration options for the Kubernetes API server.
lockdownboolLockdown pre-answers the end-of-bootstrap Host Firewall (CCNP)
step. nil = ask interactively (legacy behavior); true = apply
without prompting (CI-safe); false = skip the step.
keycloakKeycloakConfigKeycloak declares the Keycloak instance a VPN cluster hosts as
NetBird's SSO IdP. Required on cluster.type=vpn (mode=managed →
kubeaid-cli installs it; mode=external → operator runs it
elsewhere). Not supported on workload clusters — access there is
via the NetBird mesh (cluster.netbird.dns), so a keycloak block
on a workload cluster is rejected.
netbirdNetBirdConfigNetBird declares the NetBird Management instance this VPN
cluster hosts. Only meaningful when cluster.type=vpn AND
cluster.keycloak.mode=managed. NetBird Mgmt's OIDC client
is created in the same Keycloak realm; its public DNS is
used for the redirect URI and audience claim.
additionalUsers[]UserConfigOther than the root user, addtional users that you would like to be created in each node.
NOTE : Currently, we can't register additional SSH key-pairs against the root user.
argoCDArgoCDConfigArgoCD specific details.

DeployKeysConfig

FieldTypeDefaultDescription
kubeaidSSHKeyPairConfig
kubeaidConfigSSHKeyPairConfig

DisasterRecoveryConfig

FieldTypeDefaultDescription
veleroBackupsBucketNamestring
sealedSecretsBackupsBucketNamestring

FileConfig

REFER : "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1".File.

FieldTypeDefaultDescription
pathstring
contentstring

FirewallConfig

FirewallConfig drives the Cilium host-firewall policy rendered by kubeaid-cli for Hetzner bare-metal clusters. The resulting CiliumClusterwideNetworkPolicy selects every node and locks down the public NIC via eBPF host-endpoint rules. See docs/hetzner-bare-metal-network-surface.md.

FieldTypeDefaultDescription
enabledboolEnabled gates whether kubeaid-cli renders the Cilium host-firewall
CiliumClusterwideNetworkPolicy at all. Defaults to true; set false to
opt out — e.g. a separate upstream L3 firewall appliance already fronts
the cluster. A pointer so an explicit "enabled: false" is distinguishable
from unset and honoured.
allowSshFrom[]stringAllowSSHFrom restricts inbound SSH (22/tcp) on every bare-metal node to
these sources. Rendered as a fromCIDR rule in the CCNP. Empty (the
default) allows SSH from anywhere — matching the bare-metal posture where
nodes are not NetBird peers and have no mesh fallback path. Each entry is
an IPv4 address or CIDR (e.g. "203.0.113.4" or "203.0.113.0/24"); a bare
address is treated as /32.
allowPublic[]FirewallPortAllowPublic is a legacy field from the (removed) Hetzner Robot firewall.
It is parsed and validated but NOT rendered into the Cilium host-firewall
policy — parser.validateHetznerConfig only logs a warning when it is set.
The policy's world-facing ports come from hostNetworkPolicy.publicPorts
(chart default [80, 443]); 6443 is never world-public — it is a separate
rule restricted to hostNetworkPolicy.apiserverSourceCIDRs (the node IPs).
To open extra ports to the world, add them to hostNetworkPolicy.publicPorts
in the cilium chart values overlay, not here.

FirewallPort

FirewallPort is one {port, protocol} entry in FirewallConfig.AllowPublic.

FieldTypeDefaultDescription
portstringPort is a single port ("25") or an inclusive range ("30000-32767").
protocolstringProtocol is "tcp", "udp", or omitted for any protocol.

ForksConfig

KubeAid and KubeAid Config repository specific details. We require the KubeAid and KubeAid Config repositories to be hosted in the same Git server.

FieldTypeDefaultDescription
kubeaidKubeAidForkConfigKubeAid repository specific details.
kubeaidConfigKubeaidConfigForkConfigKubeAid Config repository specific details.

GeneralConfig

Non secret configuration options.

FieldTypeDefaultDescription
gitGitConfigGit server specific details.
forkURLsForksConfigKubeAid and KubeAid Config repository specific details.
The KubeAid and KubeAid Config repositories must be hosted in the same Git server.
clusterClusterConfigKubernetes specific details.
cloudCloudConfigCloud provider specific details.
kubePrometheusKubePrometheusConfigKube Prometheus installation specific details.
kubeaidStoragectlKubeaidStoragectlConfigKubeaidStoragectl pins the kubeaid-storagectl release tag
used by the bare-metal preKubeadm script when carving the
ZFS pool and Ceph partition. Leave nil (block omitted) to
fall back to the kubeaid-cli binary's own release version,
which is the right default for most operators — every node
downloads the storagectl that ships with the kubeaid-cli
release that bootstrapped it. Set explicitly to override:

- to pin against a tag newer/older than kubeaid-cli for
testing a fix or rolling back, or
- to point at an unreleased dev build when running a
go run ./cmd/kubeaid-cli development bootstrap (the
CLI's KubeaidCLIVersion is empty there and the chart
would otherwise fall through to latest, which 404s if
no release has been published yet).
obmondoObmondoConfigObmondo customer specific details.

GitConfig

Git specific details, used by KubeAid CLI, to clone repositories from and push changes to the Git server. We enforce the user to use SSH, for authenticating to the Git server.

FieldTypeDefaultDescription
caBundlePathstring
sshUsernamestringgitSSH username.
knownHosts[]stringAdditional SSH known hosts.
Merged with known hosts of common Git repo hosting providers (like Azure DevOps, GitLab etc.)
privateKeyFilePathstringPrivateKeyFilePath is the on-disk SSH private key
kubeaid-cli reads to derive PublicKey + Fingerprint and
(for cloud-side SSH connections like the Hetzner NAT
gateway setup) to authenticate the SSH session. Required
when UseSSHAgent is false; ignored when UseSSHAgent is
true (the agent owns the private key — yubikey case —
so there's nothing on disk to point at). Cross-field
validation in pkg/config/parser/validate.go enforces
"exactly one is set".
useSSHAgentboolUseSSHAgent flips the SSH key sourcing from "read a file
from PrivateKeyFilePath" to "dial $SSH_AUTH_SOCK and ask
the agent for its loaded identities". The first identity
supplies PublicKey + Fingerprint; the SSH client (kubeone)
signs through the agent socket so yubikey-resident
private keys never need to be exported.

HCloudAutoScalableNodeGroup

Details about (autoscalable) node-groups in HCloud.

FieldTypeDefaultDescription
machineTypestringHCloud machine type.
You can browse all available HCloud machine types here : https://hetzner.com/cloud.
minSizeuintMinimum number of replicas in the nodegroup.
maxSizeuintMaximum number of replicas in the nodegroup.
namestringNodegroup name.
labelsmap[string]string[]Labels that you want to be propagated to each node in the nodegroup.

Each label should meet one of the following criterias to propagate to each of the nodes :

1. Has node-role.kubernetes.io as prefix.
2. Belongs to node-restriction.kubernetes.io domain.
3. Belongs to node.cluster.x-k8s.io domain.

REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine.
taints[]k8s.io/api/core/v1.Taint[]Taints that you want to be propagated to each node in the nodegroup.

HCloudConfig

FieldTypeDefaultDescription
zonestring
imageNamestringubuntu-26.04
natGatewayServerTypestringcpx22NATGatewayServerType is the HCloud server type for the NAT gateway
that fronts the private network during bootstrap. cpx22 is a small,
cost-optimised x86 box — ample for NAT. Override it if cpx22 is out
of stock / not offered in your locations, or you need more throughput
(hcloud server-type list shows what's available).
hetznerNetworkHetznerNetworkConfigHetzner Network specific details.

HCloudControlPlane

FieldTypeDefaultDescription
machineTypestring
replicasuint
loadBalancerHCloudControlPlaneLoadBalancer

HCloudControlPlaneLoadBalancer

FieldTypeDefaultDescription
enabledbool
regionstring
endpointstringEndpoint is the FQDN clients use to reach kube-apiserver
(CAPI's controlPlaneEndpoint.host, kubeadm cert SAN,
kubeconfig server URL). Optional: when omitted, the LB
private IP is used as the control-plane endpoint directly
(no public interface, no DNS wait). When set, the LB gets
a public interface during bootstrap and kubeaid-cli waits
for the operator's DNS A-record to land before continuing.
DNS resolution is the operator's responsibility.

HCloudVPNClusterConfig

FieldTypeDefaultDescription
namestring

HetznerBareMetalConfig

FieldTypeDefaultDescription
wipeDisksboolfalse
installImageInstallImageConfig
firewallFirewallConfigFirewall configures the Cilium host-firewall policy (CiliumClusterwideNetworkPolicy)
that locks down each bare-metal node's public NIC. Enabled controls whether
kubeaid-cli renders the policy at all; AllowSSHFrom feeds the per-CIDR SSH ingress
rule. See docs/hetzner-bare-metal-network-surface.md.
zfsZFSConfigZFS specific configuration.
Every node runs a ZFS pool, named primary. We carve out storage for container images, pod
logs and pod ephemeral volumes from that ZFS pool, as required.
The ZFS pool has RAIDZ-1 enabled, which means it can survive single disk failure.
vSwitchVSwitchConfigDetails about the VSwitch which'll be used to connect the Hetzner Bare Metal servers with
the Hetzner Network.

HetznerBareMetalControlPlane

FieldTypeDefaultDescription
endpointHetznerBareMetalControlPlaneEndpoint
bareMetalHosts[]HetznerBareMetalHost
zfsZFSConfigZFS pool size on each control-plane node. See ZFSConfig.Size for sizing rules.

HetznerBareMetalControlPlaneEndpoint

FieldTypeDefaultDescription
isFailoverIPbool
hoststring

HetznerBareMetalHost

FieldTypeDefaultDescription
serverIDstring
privateIPstring

HetznerBareMetalNodeGroup

FieldTypeDefaultDescription
bareMetalHosts[]HetznerBareMetalHost
zfsZFSConfigZFS specific configuration.
Every node runs a ZFS pool, named primary. We carve out storage for container images, pod
logs and pod ephemeral volumes from that ZFS pool, as required.
The ZFS pool has RAIDZ-1 enabled, which means it can survive single disk failure.
namestringNodegroup name.
labelsmap[string]string[]Labels that you want to be propagated to each node in the nodegroup.

Each label should meet one of the following criterias to propagate to each of the nodes :

1. Has node-role.kubernetes.io as prefix.
2. Belongs to node-restriction.kubernetes.io domain.
3. Belongs to node.cluster.x-k8s.io domain.

REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine.
taints[]k8s.io/api/core/v1.Taint[]Taints that you want to be propagated to each node in the nodegroup.

HetznerConfig

FieldTypeDefaultDescription
modestringhcloudThe Hetzner mode to use :

(1) hcloud : Both the control-plane and the nodegroups will be in HCloud.

(2) bare-metal : Both the control-plane and the nodegroups will be in Hetzner Bare Metal.

(3) hybrid : The control-plane will be in HCloud, and each node-group can be either in
HCloud or Hetzner Bare Metal.
hcloudVPNClusterHCloudVPNClusterConfigDetails about the VPN cluster you have in HCloud.
sshKeyPairHetznerSSHKeyPairDetails about the SSH keypair which will be used to SSH into the HCloud or / and Hetzner
Bare Metal server.
KubeAid CLI will create the corresponding HCloud or / and Hetzner Bare Metal SSH keypairs,
if it / they doesn't already exist.
hcloudHCloudConfigHCloud specific details.
bareMetalHetznerBareMetalConfigHetzner bare-metal specific details.
controlPlaneHetznerControlPlaneControl-plane specific details.
nodeGroupsHetznerNodeGroupsDetails about the node-groups.

HetznerControlPlane

FieldTypeDefaultDescription
hcloudHCloudControlPlane
bareMetalHetznerBareMetalControlPlane
regions[]stringRegions is the list of Hetzner regions (lower-case IDs: "fsn1", "hel1", "ash", ...)
the CAPH chart constrains control-plane placement to. At least one is required.
extraCertSANs,omitempty[]stringExtraCertSANs are additional DNS names added to the apiserver's
TLS cert SAN list, on every Hetzner mode (hcloud, bare-metal,
hybrid). The chart merges these with endpoint.host into kubeadm's
apiServer.certSANs. Use for any additional hostnames clients reach
the apiserver under.

HetznerCredentials

FieldTypeDefaultDescription
apiTokenstringAPIToken is the HCloud Cloud-API token. Required for every Hetzner mode.
robotHetznerRobotCredentials

HetznerNetworkConfig

FieldTypeDefaultDescription
cidrstring
hcloudServersSubnetCIDRstring

HetznerNodeGroups

Details about node-groups in Hetzner.

FieldTypeDefaultDescription
hcloud[]HCloudAutoScalableNodeGroupDetails about node-groups in HCloud.
bareMetal[]HetznerBareMetalNodeGroupDetails about node-groups in Hetzner Bare Metal.

HetznerRobotCredentials

FieldTypeDefaultDescription
userstring
passwordstring

HetznerSSHKeyPair

FieldTypeDefaultDescription
namestring
privateKeyFilePathstringPrivateKeyFilePath is the on-disk SSH private key
kubeaid-cli reads to derive PublicKey + Fingerprint and
(for cloud-side SSH connections like the Hetzner NAT
gateway setup) to authenticate the SSH session. Required
when UseSSHAgent is false; ignored when UseSSHAgent is
true (the agent owns the private key — yubikey case —
so there's nothing on disk to point at). Cross-field
validation in pkg/config/parser/validate.go enforces
"exactly one is set".
useSSHAgentboolUseSSHAgent flips the SSH key sourcing from "read a file
from PrivateKeyFilePath" to "dial $SSH_AUTH_SOCK and ask
the agent for its loaded identities". The first identity
supplies PublicKey + Fingerprint; the SSH client (kubeone)
signs through the agent socket so yubikey-resident
private keys never need to be exported.

HostPathMountConfig

REFER : "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1".HostPathMount

FieldTypeDefaultDescription
namestring
hostPathstring
mountPathstring
pathTypek8s.io/api/core/v1.HostPathType
readOnlybooltrueWhether the mount should be read-only.

InstallImageConfig

FieldTypeDefaultDescription
imagePathstring/root/.oldroot/nfs/images/Ubuntu-2604-resolute-amd64-base.tar.zst
vg0VG0Config

KeycloakConfig

KeycloakConfig declares the Keycloak instance a VPN cluster hosts as NetBird's SSO IdP. The parser derives the Realm from DNS when unset and validates the combination against cluster.type. The admin password is generated by kubeaid-cli at bootstrap and never lives in this struct or in secrets.yaml; only Mode/DNS/Realm are user-facing.

FieldTypeDefaultDescription
modestringMode is "managed" (kubeaid-cli installs Keycloak via the
keycloakx Helm chart on this cluster — VPN clusters only)
or "external" (Keycloak is already running elsewhere;
supply DNS only). Workload clusters must use external.
dnsstringDNS is the public hostname Keycloak is reachable at, e.g.
"keycloak.vpn.acme.com". Required. Used to derive the OIDC
issuer URL the apiserver and kubelogin trust, and (when
Realm is unset) to default the realm name.
realmstringRealm is the Keycloak realm name. Optional — when empty,
kubeaid-cli derives it from DNS via
golang.org/x/net/publicsuffix.EffectiveTLDPlusOne and the
first dot-separated segment of the result. Examples:
keycloak.vpn.acme.com → "acme"
keycloak.foo.co.uk → "foo"
Set this explicitly to override the derivation.

KeycloakCredentials

KeycloakCredentials carries Keycloak-related secrets — admin credentials and OIDC client secrets the operator either supplies (external mode) or kubeaid-cli auto-generates and persists into secrets.yaml (managed mode, via FillMissingSecrets).

All fields are persisted in secrets.yaml so SealedSecret renders are byte-stable across re-runs — the alternative (read-or-generate from the in-cluster Secret) caused the re-encryption noise that produced spurious PRs on every run.

FieldTypeDefaultDescription
adminPasswordstringAdminPassword is templated into the keycloak-admin
SealedSecret's KEYCLOAK_PASSWORD key. Required when
cluster.keycloak.mode is "managed"; ignored otherwise.
FillMissingSecrets generates a value here on first run if
the field is empty.
netBirdBackendClientSecretstringNetBirdBackendClientSecret is the confidential-client
secret for the netbird-backend OIDC client. In external
mode the operator creates the client in their Keycloak
and supplies the resulting secret here. In managed mode
FillMissingSecrets generates it, the realm reconciler
creates the Keycloak client with this exact value, and
the netbird SealedSecret is templated with the same
value — single source of truth either way.

KubeAidForkConfig

KubeAid repository specific details.

FieldTypeDefaultDescription
urlstringKubeAid repository SSH URL.
versionstringKubeAid git ref (tag / branch / commit).

KubePrometheusConfig

FieldTypeDefaultDescription
versionstring
grafanaURLstring

KubeaidConfigForkConfig

KubeAid Config repository specific details.

FieldTypeDefaultDescription
urlstringKubeAid Config repository SSH URL.
directorystringName of the directory inside your KubeAid Config repository's k8s folder, where the KubeAid
Config files for this cluster will be contained.

When not specified, the directory name will default to the cluster name.

So, suppose your cluster name is 'staging'. Then, the directory name will default to
'staging'. Or you can customize it to something like 'staging.qa'.

KubeaidStoragectlConfig

KubeaidStoragectlConfig pins the kubeaid-storagectl release. See GeneralConfig.KubeaidStoragectl for when to set it.

FieldTypeDefaultDescription
versionstringVersion is the GitHub release tag of kubeaid-storagectl —
rendered into the chart as global.kubeaidStoragectl.version
and used to build the releases/download/<version>/ URL the
node's preKubeadm wget hits. Empty string is treated as "not
set" and falls back to kubeaid-cli's own version, same as
omitting the parent block.

LocalConfig

Local specific.

FieldTypeDefaultDescription

NetBirdClusterProxyConfig

NetBirdClusterProxyConfig configures the netbird-operator kube-apiserver proxy (netbird-operator.clusterProxy in the chart values). The proxy registers under cluster.name (netbird kubernetes write-kubeconfig ).

FieldTypeDefaultDescription
enabledboolEnabled toggles the cluster proxy.
rbac[]NetBirdClusterProxyRBACConfigRBAC binds NetBird groups to cluster roles via the proxy's
identity impersonation.

NetBirdClusterProxyRBACConfig

NetBirdClusterProxyRBACConfig binds one NetBird group to one ClusterRole through the cluster proxy.

FieldTypeDefaultDescription
groupstring
clusterRolestring

NetBirdConfig

NetBirdConfig describes this cluster's relationship to the NetBird mesh. It is valid for both cluster.type=vpn (which hosts NetBird Mgmt) and cluster.type=workload (which only joins the mesh): dns/stun/turn are meaningful only on the VPN host, while dnsZone applies to any cluster on the mesh. cluster.type is the gate.

FieldTypeDefaultDescription
dnsstringDNS is the public hostname NetBird Management is reachable at,
e.g. "netbird.vpn.acme.com". Required only for cluster.type=vpn
(enforced in parser/keycloak.go); unused on workload clusters.
dnsZonestringDNSZone is the mesh DNS domain peers resolve under — NetBird
Mgmt's --dns-domain, e.g. "mesh.acme.com". Operator-supplied, no
default. Required for cluster.type=vpn and for workload clusters
that join a mesh; absent on workload clusters that don't. Used to
create the DNS zone on NetBird, to drive --dns-domain on VPN
clusters, and to add the kubernetes. apiserver cert SAN.
stunDNSstringStunDNS is the public hostname Coturn answers STUN queries
on, e.g. "stun.vpn.acme.com". Optional: kubeaid-cli derives
it as "stun." where base is DNS with the leading
"netbird." stripped (so netbird.vpn.acme.com → stun.vpn.acme.com).
Override only when STUN is exposed on a non-standard FQDN.
turnDNSstringTurnDNS is the public hostname Coturn answers TURN queries
on, e.g. "turn.vpn.acme.com". Optional: derived as
"turn." by the same logic as StunDNS.
turnUserstringnetbirdTurnUser is the static username Coturn / NetBird Mgmt agree
on for TURN authentication. The matching password is
generated and persisted in the Secret. Optional, defaults
to "netbird".
clusterProxyNetBirdClusterProxyConfigClusterProxy configures the netbird-operator's kube-apiserver
proxy (operator >= 0.7.0): a mesh peer that proxies kubectl to
the in-cluster apiserver, impersonating the caller's NetBird
identity. Omit the block to leave it disabled.
groups[]stringGroups are extra NetBird groups this cluster OWNS (chart: groups), beyond
the derived k8s- and k8s--access. Declare a group from ONE
cluster only — a duplicate wedges that operator on HTTP 409.

NetBirdCredentials

NetBirdCredentials carries the random secrets NetBird's in-cluster components need at startup. All fields are auto-generated by FillMissingSecrets when blank. Persisted in secrets.yaml for re-run stability — same rationale as KeycloakCredentials.

FieldTypeDefaultDescription
datastoreEncryptionKeystringDatastoreEncryptionKey is the AES key NetBird Mgmt uses
to encrypt its data store. base64(32 random bytes); the
chart base64-decodes it back to 32 raw bytes for
AES-256.
relayPasswordstringRelayPassword is the shared secret between NetBird Mgmt
and the in-cluster Relay deployment. Alphanumeric so it
flows cleanly through Helm values + envFrom.
turnPasswordstringTurnPassword is the credential the NetBird agents use to
authenticate with Coturn (TURN server). Same value is
templated into both the netbird Secret (Mgmt-side) and
the netbird-turn-credentials Secret (Coturn-side) — the
two MUST match or relayed TURN auth fails.
apiKeystringAPIKey is a NetBird Management service-user access token
(nbp_…) the netbird-operator authenticates to the Mgmt
API with — minting setup keys for routing peers, managing
groups / networks / policies. Created manually in the
NetBird dashboard: Team → Service Users → create →
generate access token (a service user, not a personal
PAT, so it survives offboarding). NOT auto-generated by
FillMissingSecrets — only the Mgmt dashboard can mint it.
Rendered into the netbird/netbird-mgmt-api-key
SealedSecret whose NB_API_KEY the operator Deployment
reads (the chart's default secret ref). When blank,
the SealedSecret is skipped and bootstrap pauses at
netbird.AwaitOperatorToken with instructions instead.

NodeGroup

FieldTypeDefaultDescription
namestringNodegroup name.
labelsmap[string]string[]Labels that you want to be propagated to each node in the nodegroup.

Each label should meet one of the following criterias to propagate to each of the nodes :

1. Has node-role.kubernetes.io as prefix.
2. Belongs to node-restriction.kubernetes.io domain.
3. Belongs to node.cluster.x-k8s.io domain.

REFER : https://cluster-api.sigs.k8s.io/developer/architecture/controllers/metadata-propagation#machine.
taints[]k8s.io/api/core/v1.Taint[]Taints that you want to be propagated to each node in the nodegroup.

ObmondoConfig

FieldTypeDefaultDescription
customerIDstring
monitoringbool
certPathstringPath to the mTLS client cert issued by Obmondo. Required when
Monitoring is true — kubeaid-agent uses it to authenticate to the
Obmondo API, and kube-prometheus's Alertmanager uses it to push
alerts to Obmondo's alert-receiver endpoint.
keyPathstringPath to the private key paired with CertPath. Required when
Monitoring is true.

OpenIDProviderSSHKeyPairConfig

FieldTypeDefaultDescription
publicKeyFilePathstring
privateKeyFilePathstringPrivateKeyFilePath is the on-disk SSH private key
kubeaid-cli reads to derive PublicKey + Fingerprint and
(for cloud-side SSH connections like the Hetzner NAT
gateway setup) to authenticate the SSH session. Required
when UseSSHAgent is false; ignored when UseSSHAgent is
true (the agent owns the private key — yubikey case —
so there's nothing on disk to point at). Cross-field
validation in pkg/config/parser/validate.go enforces
"exactly one is set".
useSSHAgentboolUseSSHAgent flips the SSH key sourcing from "read a file
from PrivateKeyFilePath" to "dial $SSH_AUTH_SOCK and ask
the agent for its loaded identities". The first identity
supplies PublicKey + Fingerprint; the SSH client (kubeone)
signs through the agent socket so yubikey-resident
private keys never need to be exported.

SSHKeyPairConfig

FieldTypeDefaultDescription
privateKeyFilePathstringPrivateKeyFilePath is the on-disk SSH private key
kubeaid-cli reads to derive PublicKey + Fingerprint and
(for cloud-side SSH connections like the Hetzner NAT
gateway setup) to authenticate the SSH session. Required
when UseSSHAgent is false; ignored when UseSSHAgent is
true (the agent owns the private key — yubikey case —
so there's nothing on disk to point at). Cross-field
validation in pkg/config/parser/validate.go enforces
"exactly one is set".
useSSHAgentboolUseSSHAgent flips the SSH key sourcing from "read a file
from PrivateKeyFilePath" to "dial $SSH_AUTH_SOCK and ask
the agent for its loaded identities". The first identity
supplies PublicKey + Fingerprint; the SSH client (kubeone)
signs through the agent socket so yubikey-resident
private keys never need to be exported.

SecretsConfig

FieldTypeDefaultDescription
awsAWSCredentials
azureAzureCredentials
hetznerHetznerCredentials
keycloakKeycloakCredentials
netbirdNetBirdCredentials
acmeACMECredentials

UserConfig

FieldTypeDefaultDescription
namestring
sshPublicKeystring

VG0Config

FieldTypeDefaultDescription
sizeint80
rootVolumeSizeint50

VSwitchConfig

FieldTypeDefaultDescription
vlanIDintVLANID is the Hetzner vSwitch VLAN ID. Hetzner's webservice only
accepts 4000-4091 (inclusive) — matches
pkg/config/validate.{Min,Max}HetznerVLANID, enforced again here
(not just at prompt time) so a config from outside the prompt
(hand-written, or rendered by the Obmondo API) still fails fast
instead of erroring against Hetzner's API mid-bootstrap.
namestring
subnetCIDRBlockstringSubnetCIDRBlock is the vSwitch subnet attached to the Hetzner Network.
The IP written here doubles as the subnet's gateway (net.ParseCIDR's
first return), so "10.0.1.0/24" yields gateway 10.0.1.0 — write the IP
you want as the gateway, not just any address in the range.

WorkloadIdentity

FieldTypeDefaultDescription
openIDProviderSSHKeyPairOpenIDProviderSSHKeyPairConfig

ZFSConfig

FieldTypeDefaultDescription
sizeint220ZFS pool size (in GB), on each node in the corresponding node-group.
Must be >= 200 GB : reserving 100 GB for container images, 50 GB for pod logs and 50 GB for
pod ephemeral volumes.
On top of that, if you want x GB of node-local storage for your workloads (like Redis),
the ZFS pool size will be (200 + 2x) GB, keeping in mind that RAIDZ-1 is enabled.