TL;DR:
OpenTofu evaluates all .tf files in the same directory into a single configuration.
It is recommended to split up the infrastructure configuration into different files for readability.
Kubestack aims to follow popular OpenTofu conventions.
So teams familiar with OpenTofu should feel right at home.
And so should AI coding agents: the predictable layout means an agent that has learned the Kubestack skill finds every platform component where the conventions put it, in every session and every repository.
Files and directories in the root of the Kubestack repository fall into two categories:
.user/
Kubestack provides container images to be used during bootstrapping and for disaster recovery locally.
The .user directory is used to persist the HOME directory between containers.
It is excluded from Git using the .gitignore file in the repository.
manifests/
The manifests directory can be used to store custom Kubernetes manifests in YAML format that may be integrated using the custom-manifest module.
Dockerfile
The Dockerfile specifies the version of the Kubestack container image to use. You can use the Dockerfile to add additional binaries to Kubestack images. Or customize the environment and configuration of the upstream image.
state.tf
This file defines the configuration for the OpenTofu remote state. OpenTofu stores state about your infrastructure. It uses this state to map the real world resources to your configuration, keep track of metadata and to improve performance.
When using OpenTofu as a team and in a CI/CD pipeline it is important to store state centrally and ensure only one change is applied at any given time. This is achieved by using remote state with state locking.
Remote state backends are not Kubestack specific. You can use any backend OpenTofu supports. Please refer to the OpenTofu documentation for backends. The tutorial defaults to using your chosen cloud provider's object storage as the OpenTofu remote state store.
versions.tf and .terraform.lock.hcl
The versions file is used to set the required OpenTofu version and specify required OpenTofu providers.
A tofu init will determine module and provider versions to use, based on the required versions from the root and all child modules.
The resulting provider versions are locked using the OpenTofu lock file.
This ensures subsequent OpenTofu runs use the same provider versions.
Kubestack supports managing multiple clusters, even in different regions and from different cloud providers, in a single repository. In addition, Kubestack supports provisioning platform features on top of these clusters. This means there will be one cluster module and one binding file per platform feature per desired cluster. To organize this, Kubestack recommends a convention to prefix these cluster specific OpenTofu files with the module name.
The following files prefix example_ as a placeholder for the module name in a real configuration.
example_cluster.tf
Use a file per desired cluster by calling a cluster module and passing the respective configuration.
In a multi-cluster configuration you'd have multiple *_cluster.tf files.
Modules are self-contained packages of reusable OpenTofu configurations.
example_providers.tf
Providers extend OpenTofu to support additional APIs. In Kubestack's case, the main providers used are the provider for your chosen cloud. And the Kubestack maintained Kustomization provider. The cloud API credentials, are read from the environment automatically. Some cloud providers require per provider configuration. But to deploy Kubernetes resources onto the correct cluster, each cluster has a specific Kustomization provider. These provider configurations are defined in the per cluster providers file.
example_feature_<feature_name>.tf
The platform feature bindings, that use the cluster specific Kustomization provider configuration are also recommended to be stored in individual files.
.├── Dockerfile├── .gitignore├── example_cluster.tf├── example_feature_nginx.tf├── example_feature_prometheus.tf├── example_providers.tf├── manifests/├── modules/│ └── nginx/├── README.md├── .terraform.lock.hcl├── .user/└── versions.tf