Skip to content
You are reading dev: the documentation of main. The last release, 0.1.0, predates this site.

Inputs

What a cluster’s configuration holds beyond socle_version and the cloud object. How to write it: Configure a cluster.

{ <module> = { <attribute> = <value> } }, typed any, default {}; only what differs from a default.

Rule
Namessnake_case; the folder, ResourceSet and namespace use kebab-case (external-dns)
Unknown modulerefused at plan: kube: unknown module(s) <name>. Catalog: <every module>.
Unknown attributerefused at plan, with the allowed attributes of every module
Wrong typerefused at plan: each value must have the kind (string, number, bool, list, object) of its default
Module not offered on this cloudrefused at plan: kube: a module is not offered on <cloud>. Cloud-bound modules: …
Secrets in valuesrefused at plan, per module: the chart’s secret-bearing paths. Put them in the Secret named by values_secret
values and a named attribute on the same keyvalues wins

Sources: catalog.tf (the schema), variables.tf (the rules).

Every module but gateway_api and hello also takes values ({}, any chart value, yours winning) and values_secret ("", a Secret in the module’s namespace with a values.yaml key, merged last); not repeated below. An attribute whose default is a block (monitoring.logs…) is merged one level deep: a key written alone keeps its siblings at their default.

ModuleAttributeDefaultMeaning
helloenabledtruepodinfo, as a proof that the pipeline works
helloreplicas1replicas of the podinfo Deployment
hellomessage"hello from socle"the message podinfo serves
gateway_apienabledtruethe Gateway API standard CRDs from upstream, pinned by commit, and Cilium’s cilium class on aws and azure. On gcp GKE owns the CRDs and the class, and the module renders the shared Gateways only. Off orphans the CRDs
gateway_apigatewaystruethe shared Gateways gateway-system/public and private, on aws (once the foundations issued gateway_certificate), azure, and gcp (once they issued the certificate map and the regional certificate, gcp.gateway_certificate)
crossplaneenabledfalseCrossplane and, per cloud, its providers (on aws IAM, EKS and S3; on gcp the Google Cloud ones, as the federated principal the foundations’ gcp.crossplane grants): the tooling each module declares its cloud access through. Off leaves the CRDs and orphans every module role still declared
crossplanepermissions_boundary""aws: the boundary every module role carries; an IAM policy ARN. The aws root wires it from the foundations’ crossplane_permissions_boundary_arn. Refused on gcp
crossplanedns_records_role""gcp: the project custom role Crossplane grants external-dns to write DNS records, on the project (a zone’s own IAM is never honoured); projects/<id>/roles/<role>. The gcp root wires it from the foundations’ dns_records_role. Refused elsewhere
external_dnsenabledfalseDNS records for Services, Ingresses and HTTPRoutes in the cloud’s zone. On aws and gcp with crossplane on, its own access (an IAM role on aws, a binding of the DNS records role on gcp); elsewhere the client brings a credential. The aws and gcp roots turn it on when the foundations’ gateway_certificate is set and Crossplane can give it access
external_dnsdomain_filters[]zones it may write to, as DNS names; at least one when enabled
external_dnspolicy"upsert-only"upsert-only never deletes a record; sync also deletes what it owns
external_dnstxt_owner_idthe cluster namethe owner in the TXT registry, so two clusters never fight over a zone
argocdenabledtrueArgoCD, the client’s GitOps layer
argocdadmin_enabledtruekeep the local admin account; false once SSO exists
argocddomain""the host ArgoCD is served at (configs.cm.url and the HTTPRoute), a lowercase FQDN; empty means no URL and no route
argocdgateway"private"the shared Gateway its HTTPRoute attaches to: private, public, or "" for none
argocdhafalsethe chart’s HA layout: Redis HA, two replicas of server, repo-server and applicationset
argocd_image_updaterenabledfalseArgo CD Image Updater, watching argocd; refused while argocd is off
argocd_image_updaterrepositories[]aws: the ECR repositories of the cluster’s account and region its own read-only role may read, globs allowed, never * alone; needs ecr in aws.crossplane.allowed_services. gcp: LOCATION/REPOSITORY in the cluster’s project, read through roles/artifactregistry.reader on the whole project, which must be in gcp.crossplane.allowed_roles; one registry entry per location named. Both need crossplane on. []: no role, no registry entry
argocd_image_updaterregistries[]the client’s other registries, as Image Updater’s registries.conf writes them, after the socle’s ECR or Artifact Registry entries; credentials a secret:, pullsecret:, env: or ext: reference. config.registries is refused in values
monitoringenabledtruethe victoria-metrics-k8s-stack chart as one release: the operator, VictoriaMetrics, vmagent scraping the cluster, kube-state-metrics, node-exporter, and the parts below
monitoringmetrics{ retention = "15d", storage_size = "20Gi" }VictoriaMetrics single-node. retention: whole hours, days, weeks or years (15d, 4w, 1y), at least a day; storage_size: the claim on the default StorageClass, in Gi or Ti, "" for an emptyDir
monitoringlogs{ enabled = true, retention = "7d", storage_size = "20Gi" }VictoriaLogs single-node, the same shape; off also stops otel_agent
monitoringtraces{ enabled = false, retention = "7d", storage_size = "10Gi" }VictoriaTraces single-node, the same shape. Off: pre-GA, an upgrade may drop stored traces
monitoringgrafana{ enabled = true, domain = "", gateway = "private" }Grafana with the stack’s datasources and dashboards; domain the host it is served at (server.root_url and the HTTPRoute), empty for none; gateway the shared Gateway its HTTPRoute attaches to: private, public, or ""
monitoringalerting{ enabled = false, watchdog = true, receivers = [], route = {}, receivers_secret = "" }vmalert and Alertmanager with kube-prometheus-stack’s rules. receivers and route as Alertmanager writes them, keys only through *_file fields; receivers_secret a Secret in monitoring, mounted under /etc/alertmanager/secrets/; watchdog an always-firing alert to its watchdog-url key. On needs a receiver and, with watchdog, receivers_secret
otel_agentenabledtruethe OpenTelemetry Collector as a DaemonSet: container logs to VictoriaLogs, while monitoring.logs is on
otel_gatewayenabledtruethe OpenTelemetry Collector as a one-replica Deployment: the applications’ OTLP and the Kubernetes events
kedaenabledfalseKEDA, event-driven autoscaling down to zero
kedaservices[]aws and gcp: the services KEDA’s own identity may read — on aws from sqs, cloudwatch, kinesis, dynamodb, each service also in aws.crossplane.allowed_services; on gcp pubsub, read through Cloud Monitoring, roles/monitoring.viewer also in gcp.crossplane.allowed_roles. Needs crossplane on
metrics_serverenabledtruethe metrics.k8s.io API behind kubectl top and HPAs on CPU or memory. aws only
metrics_serverhafalsetwo replicas on two nodes, with a disruption budget
kyvernoenabledfalsethe Kyverno engine, no policy
kyverno_policiesenabledfalsethe socle’s policy set, every policy in Audit; needs kyverno
kyverno_policiesprofile"baseline"baseline, or restricted for baseline plus six
kyverno_policiesenforce[]policies switched to Enforce, each compiled into a native ValidatingAdmissionPolicy; only names this configuration renders
kyverno_policiesallowed_registries[]registries images may come from; empty means no registry policy
external_secretsenabledfalseExternal Secrets Operator
external_secretsprefixes[<cluster_name>]aws with crossplane on: the module’s read-only role reads secret:<prefix>/*, and the ClusterSecretStore secret-manager is created on it. Needs secretsmanager in aws.crossplane.allowed_services. On gcp secrets are named <prefix>_<name>, so a prefix is letters, digits and - (no _, no /). []: no role, no store
reloaderenabledfalseStakater Reloader, opt-in per workload by annotation; reloader.autoReloadAll is refused in values
veleroenabledfalseVelero, backups the applications opt into by label. aws and gcp; needs crossplane on and the bucket’s access in the foundations’ allowlist: s3 in aws.crossplane.allowed_services, roles/storage.objectAdmin in gcp.crossplane.allowed_roles
veleropoliciesseven pairs[{ frequency, retention, schedule }], one Schedule each: hourly 24h and 48h, daily 7d and 30d, weekly 30d and 90d, monthly 90d
veleronode_agenteks_addons.efs_csithe privileged node-agent DaemonSet, which backs EFS volumes up by file system. Refused on gcp: Autopilot forbids its hostPath, and every volume is a PD snapshot

What each module installs and refuses in values: its catalog page.

Three objects, each any, validated like kube; every key optional.

VariableAttributeDefaultWhereMeaning
ciliumenabledtrueaws, azureinstall Cilium, and CoreDNS on aws, before Flux. false is for a cluster that brings its own CNI and DNS; the e2e k3s is the only such cluster
ciliumhubblefalseaws, azureadds Hubble Relay and UI; Hubble in the agent is always on
ciliumgateway_apitrueaws, azureCilium’s Gateway controller and the cilium class
ciliumvalues{}aws, azureany Cilium chart value, merged after the socle’s. Private keys are refused: name a Secret through the chart’s existingSecret fields
corednsvalues{}aws, with Ciliumany CoreDNS chart value, merged after the socle’s. Nothing is refused: the chart takes no secret inline
eks_addonspod_identity_agenttrueawsthe Pod Identity Agent; the two storage drivers need it
eks_addonsebs_csitrueawsthe EBS CSI driver, with its own role
eks_addonsefs_csifalseawsthe EFS CSI driver, with its own role
eks_addonssnapshot_controllertrueawsthe CSI snapshot controller and its CRDs
RefusedWhen
ciliumon gcp and scaleway
corednswhere the socle installs no CoreDNS
eks_addonson every cloud but aws
ebs_csi, efs_csiwith pod_identity_agent = false
in cilium.values (chart 1.20.2)tls.ca.key, hubble.tls.server.key, hubble.relay.tls.client.key, hubble.relay.tls.server.key, hubble.ui.tls.client.key, hubble.metrics.tls.server.key, clustermesh.config.clusters[*].tls.key
  • Not attributes: chart versions, IPAM and routing mode, kube-proxy replacement, operator replicas, resources, the GatewayClass name; all but the chart versions are reachable through values.
  • cluster_network (api_endpoint, service_cidr on aws, pod_cidr on azure) comes from the foundations’ outputs; you never write it. Neither do you write, on gcp, project ({ id, number }, the catalog’s inputs.cluster.projectId and projectNumber), gateway_certificate_map or gateway_regional_certificate: the gcp root wires them.

Generated from opentofu/bootstrap; the roots’ own variables: OpenTofu modules and clusters/gcp.

NameVersion
terraform>= 1.13
aws>= 6.0, < 7.0
helm>= 3.0, < 4.0

No modules.

NameType
aws_eks_addon.ebs_csiresource
aws_eks_addon.efs_csiresource
aws_eks_addon.pod_identity_agentresource
aws_eks_addon.snapshot_controllerresource
aws_iam_role.ebs_csiresource
aws_iam_role.efs_csiresource
aws_iam_role_policy_attachment.ebs_csiresource
aws_iam_role_policy_attachment.efs_csiresource
helm_release.ciliumresource
helm_release.corednsresource
helm_release.instanceresource
helm_release.operatorresource
helm_release.socleresource
helm_release.storage_classresource
aws_caller_identity.currentdata source
NameDescriptionTypeDefaultRequired
cloudWhich cloud this cluster runs on. Selects the artifact's clusters/ overlay and the operator's workload identity wiring. Scaleway has no federation the operator knows, so it runs as a plain kubernetes cluster.stringn/ayes
cluster_nameCluster this socle serves. Stamped on every object the operator creates, and exposed to the catalog as inputs.cluster.name.stringn/ayes
environmentEnvironment this cluster serves. Stamped as a label, exposed as inputs.cluster.environment, and the axis the upgrade rings follow.stringn/ayes
ownerTeam accountable for the cluster. Stamped as a label on every object.stringn/ayes
artifact_pull_secretName of an existing kubernetes.io/dockerconfigjson Secret in flux-system that Flux uses to pull the artifact from a private registry. Empty for a public registry. The Secret is created outside this module — a credential never enters OpenTofu.string""no
artifact_urlOCI repository the socle artifact is pulled from. Override for a mirror; the tag is socle_version.string"oci://ghcr.io/do-now-io/socle/flux-modules"no
ciliumThe socle's Cilium, on the clouds whose foundations create a cluster with
no CNI — aws and azure — as { enabled, hubble, gateway_api }, every key
optional: enabled (true) installs it before Flux; false means the
cluster brings its own CNI and DNS, which only a test double does.
hubble (false) adds Hubble Relay and UI. gateway_api (true) makes
Cilium serve the cilium GatewayClass. values ({}) is any Cilium chart
value, merged over the socle's so the client wins; private keys are
refused there, and the chart's existingSecret fields name a Secret
instead. Refused on gcp and scaleway, where the cloud operates Cilium.
Typed any and validated like kube, so a misspelt key is an error at
plan. Chart versions are pinned in cilium.tf.
any{}no
cluster_networkWhat Cilium needs to know about the cluster, from the foundations'
outputs, never from the client: api_endpoint, the API server as EKS
returns it (https://host) or AKS does (a bare FQDN), for kube-proxy
replacement; service_cidr, the service range, whose .10 is CoreDNS's
address on aws; pod_cidr, Cilium's pool on azure, where the VNet holds
nodes only. Required wherever the socle installs Cilium, ignored
elsewhere.
object({
api_endpoint = string
service_cidr = optional(string)
pod_cidr = optional(string)
})
nullno
corednsThe CoreDNS the socle installs on aws, right after Cilium, as
{ values }: values ({}) is any CoreDNS chart value, merged over the
socle's so the client wins — extra zones, forwarders, plugins. The chart
has no value that takes secret material inline; a Secret is mounted by
name through extraSecrets, or read through env[].valueFrom. Refused
where the socle installs no CoreDNS: every cloud but aws, and aws with
cilium.enabled = false. Chart version pinned in cilium.tf.
any{}no
cosign_identityKeyless identity the artifact's signature must match, as issuer and subject regexes. Defaults to the socle's release workflow on main, so production never consumes a branch build by accident. Override on a dev cluster testing a branch. Null means this default. Verification cannot be disabled.
object({
issuer = string
subject = string
})
{
"issuer": "^https://token\\.actions\\.githubusercontent\\.com$",
"subject": "^https://github\\.com/do-now-io/socle/\\.github/workflows/publish-artifact\\.yaml@refs/heads/main$"
}
no
eks_addonsThe EKS-managed add-ons the socle installs on aws once the nodes run, as
{ pod_identity_agent, ebs_csi, efs_csi, snapshot_controller }, every
key optional:
pod_identity_agent (true) is what hands every Pod Identity association
its credentials — Crossplane's AWS providers included — and flux-operator
waits for it; ebs_csi (true) is the block-storage driver, with its own
role; efs_csi (false) the RWX one, with its own role. Both drivers need
the agent. snapshot_controller (true) is the CSI snapshot controller
and its CRDs, what the velero module's EBS snapshots need. Refused on
every cloud but aws. Versions pinned in eks_addons.tf.
any{}no
flux_componentsFlux controllers to install. The image automation pair is absent by default: the socle's version moves through a reviewed tfvars change, not through a controller rewriting tags.list(string)
[
"source-controller",
"kustomize-controller",
"helm-controller",
"notification-controller"
]
no
flux_versionFlux version the operator installs and keeps converged. 2.x tracks the latest 2 series the operator ships (its embedded distribution, so operator_version bounds it); 2.y.x the latest patch of 2.y; an exact 2.y.z pins it.string"2.x"no
gateway_certificate_arnOn aws, the ACM certificate the shared Gateways' load balancers terminate
TLS with — the foundations' gateway_certificate_arn output, never the
client's. Null or empty on aws means no shared Gateway, and no route
attached to one. Unknown at plan on the apply that issues it, which is
why nothing validates it here. Ignored elsewhere.
stringnullno
gateway_certificate_mapOn gcp, the Certificate Manager map the public shared Gateway's global
load balancer terminates TLS with — the foundations'
gateway_certificate_map output, never the client's. Null or empty on gcp
means no shared Gateway, and no route attached to one. Unknown at plan on
the apply that creates it, which is why nothing validates it here.
Ignored elsewhere.
stringnullno
gateway_regional_certificateOn gcp, the regional Certificate Manager certificate the private shared
Gateway's internal load balancer terminates TLS with — the foundations'
gateway_regional_certificate output, never the client's. Null or empty
on gcp means no shared Gateway either: a private listener without it
would never be programmed. Unknown at plan on the apply that creates it,
which is why nothing validates it here. Ignored elsewhere.
stringnullno
helm_timeout_secondsHow long to wait for each release to become ready. The instance release is the slow one: its health check waits for the operator to converge the controllers.number600no
instance_sizeResource profile the operator applies to the controllers. Empty is the operator's own default; small, medium and large scale requests and limits together.string""no
kubeThe catalog modules this cluster enables and their values, as
{ <module> = { <attribute> = <value> } }. List only what differs from
the catalog's defaults; an absent module is at its default. Module names
are snake_case. Typed any on purpose: a map(any) refuses two modules with
different attributes, and an object type silently drops a misspelt
attribute — the validations below are what makes a typo an error at plan.
The schema is catalog.tf; docs/reference/inputs.md lists it module by module.
any{}no
network_policyLet the operator install network policies isolating the Flux namespace. On by default; Cilium enforces them on every cloud we ship.booltrueno
operator_versionChart version of flux-operator, which is also the operator's own version. Pinned exactly: the operator is pre-1.0 and its minors are not a stable contract.string"0.60.0"no
projectOn gcp, the project the cluster runs in, as { id, number } — the
foundations' project_id and project_number outputs, never the client's.
Exposed to the catalog as inputs.cluster.projectId and projectNumber: a
module's Workload Identity principal names the project number, and the
pool named after the project id. Required on gcp, refused elsewhere.
object({
id = string
number = string
})
nullno
regionRegion the cluster runs in, exposed to the catalog as inputs.cluster.region. Regional cloud APIs need it — on AWS the Pod Identity associations the crossplane module creates. Empty when the caller does not know it; a module that needs it says so.string""no
schedulable_nodesHow many nodes the foundations give the cluster before this module
starts — on aws, the bootstrap node group's size. Everything but Cilium
waits for it: Cilium's DaemonSet is what makes those nodes Ready, so it
is installed beside them, and CoreDNS and the Flux operator, the first
releases that need a scheduled pod, come after. Zero fails the plan with
that reason, instead of Helm waiting helm_timeout_seconds for a node.
Null skips the check, on a cluster whose compute this module cannot see.
numbernullno
socle_versionTag of the socle artifact to pull. Null means this module's own version, so that one bump of the module tag moves module and artifact together. Set it only on a dev cluster testing a branch build, together with cosign_identity.stringnullno
storage_classStorage class for the source-controller's artifact cache. Empty uses the cluster default.string""no
NameDescription
artifactThe socle artifact, as OCI URL and tag.
ciliumWhether this module installed Cilium (aws, azure: the clouds whose foundations create a cluster with no CNI), with the chart versions it pinned. installed is false where the cloud operates Cilium, or when cilium.enabled is false.
cosign_identityKeyless identity the artifact's signature is verified against, on every reconciliation.
eks_addonsThe EKS-managed add-ons this module installed (aws only), each as its pinned version, and for the two storage drivers the ARN of the role their controller runs as. Null for an add-on not installed.
flux_versionFlux version the operator converges the controllers to.
inputsWhat this module ships into the cluster as the ResourceSetInputProvider's defaultValues, after normalisation against the catalog. The catalog's templates read exactly these paths.
namespaceNamespace holding the operator, the Flux controllers and the socle's inputs.
operator_versionVersion of flux-operator installed, which is also its chart version.
socle_versionTag of the socle artifact the cluster pulls.