Skip to content
The last release, 0.1.0, predates this site: this is the documentation of main.

Configure a cluster

A cluster is one main.tf, in a directory of its own, that calls the socle’s root for its cloud.

Before you start: your cloud’s prerequisites are met. AWS is the only cloud with a root today.

clusters/
dev/main.tf
prod/main.tf

Each has its own state key, so a plan on dev never touches prod. Commit the .terraform.lock.hcl tofu init writes next to it.

clusters/prod/main.tf
terraform {
backend "s3" {
bucket = "acme-tofu-state"
key = "socle/aws/acme-prod.tfstate"
region = "eu-west-3"
use_lockfile = true
}
}
locals {
socle_version = "0.1.0" # x-release-please-version
}
module "socle" {
source = "oci://ghcr.io/do-now-io/socle/opentofu-modules//opentofu/clusters/aws?tag=${local.socle_version}"
socle_version = local.socle_version
aws = {
region = "eu-west-3"
cluster_name = "acme-prod"
owner = "platform"
environment = "prod"
kubernetes_version = "1.34"
availability_zones = ["eu-west-3a", "eu-west-3b", "eu-west-3c"]
cluster_endpoint_public_access_cidrs = ["203.0.113.0/24"]
gateway_certificate = { domain = "acme.example" }
}
kube = {
argocd = { domain = "argocd.acme.example" }
kyverno = { enabled = true }
}
}
BlockWhat it holds
socle_versionA released version, never latest or main; the only line an upgrade touches, source included.
awsThe foundations’ variables. Keys without a default, kubernetes_version among them, are required. Every option: prod.tfvars.example, written as tfvars; the same keys go in the module block.
kubeOnly what differs from the catalog’s defaults, in snake_case. Defaults: Inputs; modules: catalog.

Every module with a chart takes values, any value of its chart. Yours win over the socle’s defaults and over the module’s named attributes:

kube = {
argocd = {
domain = "argocd.acme.example"
values = {
configs = {
cm = { "accounts.alice" = "apiKey, login" }
rbac = { "policy.csv" = "g, alice, role:admin" }
}
}
values_secret = "argocd-values"
}
}

values lands in the OpenTofu state, so secrets are refused there at plan. Put them in a Secret with a values.yaml key, in the module’s namespace, and name it in values_secret:

Terminal window
kubectl -n argocd create secret generic argocd-values --from-file=values.yaml
kubectl -n argocd label secret argocd-values reconcile.fluxcd.io/watch=Enabled

The Secret is merged last and optional; the label applies a change at once. OpenTofu never reads it.

4. Adjust what precedes Flux, if you need to

Section titled “4. Adjust what precedes Flux, if you need to”

On aws the root also takes cilium, coredns and eks_addons, every key optional (Inputs), beside aws and kube in the module block:

cilium = { hubble = true }
coredns = { values = { replicaCount = 3 } }
eks_addons = { efs_csi = true }

Leave cilium.enabled at true on a real EKS: the cluster has no other network.

Terminal window
cd clusters/prod
tofu init
tofu plan
tofu apply

A misspelt name, a wrong type, a module not offered on your cloud or a secret in values fails the plan (Troubleshooting). A green apply is not convergence: check kubectl -n flux-system get resourceset socle-root (Enable a module).