Infrastructure Controllers
Infrastructure controllers provision the cloud resources your application needs in the customer’s environment: a Kubernetes cluster, a database, object storage, networks and IAM roles. The deployment controllers deploy applications, while the infrastructure controllers create and reconcile what those applications run on.
An infrastructure controller is not a new kind of deployment target. It is a container image that you release as a regular Distr application, with a Docker Compose file or a Helm chart. The Docker controller runs it on a VM, or the Kubernetes controller runs it in an existing cluster. Versions, entitlements, secrets, logs, health and updates work exactly as they do for every other application.
The infrastructure controllers are open source and available in the distr-infrastructure-controllers repository.
| Controller | Manages | Image |
|---|---|---|
| OpenTofu controller | Infrastructure described by an OpenTofu or Terraform config | ghcr.io/distr-sh/distr-infrastructure-controllers/opentofu-controller |
Use cases
Section titled “Use cases”- Bring Your Own Cloud (BYOC): the OpenTofu controller creates the cluster and the resources your product needs in the customer’s cloud account, and the Kubernetes controller deploys your application into that cluster.
- Terraform use cases: provision a managed database, a bucket or DNS records next to an application the customer runs, with the same versioned configuration for every customer and a view in Distr of which version each customer runs and whether its last run succeeded.
OpenTofu controller
Section titled “OpenTofu controller”The OpenTofu controller runs an OpenTofu configuration baked into its image and keeps the state in a persistent volume. OpenTofu is the open source fork of Terraform, so existing Terraform configurations and providers work without changes.
On start, the controller copies the configuration into its data volume, next to the state.
It then plans and applies the configuration every RECONCILE_INTERVAL and logs each step, so the deployment logs in Distr show what is created, changed or destroyed and why:
INFO run #1 started {"operation": "apply", "mode": "auto", "version": "0.2.0"}INFO plan: update aws_s3_object.versionINFO plan: 0 to add, 1 to change, 0 to destroyINFO upgrading the infrastructure from version 0.1.0 to 0.2.0INFO aws_s3_object.version: modification complete after 0s [id=version.json]INFO apply complete: 0 added, 1 changed, 0 destroyedINFO run #1 finished in 3.7s: the infrastructure is up to dateThe controller tells an upgrade, a new configuration, changed variables and drift apart, and says which one caused a change.
Its /readyz endpoint reports whether the last run succeeded, so a failed run shows up in Distr as an unhealthy deployment and can trigger an alert.
Ship your infrastructure with the OpenTofu controller
Section titled “Ship your infrastructure with the OpenTofu controller”-
Write an OpenTofu configuration with an empty
backend "local" {}block and keep the.terraform.lock.hclthattofu initwrites. The controller installs exactly the providers locked in it. -
Build an image on top of the OpenTofu controller that copies the configuration to
/module, and push it to the Distr registry or any other registry:FROM ghcr.io/distr-sh/distr-infrastructure-controllers/opentofu-controller:0.2.0ARG VERSIONENV APP_VERSION=${VERSION}COPY . /module/Build it with
--build-arg VERSION=1.0.0to set the version of the infrastructure, which OpenTofu receives asvar.app_version. -
Create an application in Distr whose Compose file or Helm chart runs that image with a persistent volume at
/data. Every example in the repository contains both. -
Deploy it to a deployment target in the customer’s environment. Pass the cloud credentials as secrets and the variables of your configuration as
TF_VAR_<name>. -
To change the infrastructure, release a new image version and update the deployment. Distr rolls it out like any other application update.
Examples
Section titled “Examples”Every directory in examples/opentofu/ is a complete infrastructure application with a Dockerfile, a Compose file with its environment template and a Helm chart. Copy one to start your own.
| Example | Provisions |
|---|---|
hello-world | Nothing real: random names, a password and a fake provisioning delay |
azure-static-website | A public Azure Storage website showing the deployed version |
aws-eks | An EKS cluster, a PostgreSQL database and a bucket in one zone |
Configuration
Section titled “Configuration”The most important environment variables of the OpenTofu controller are listed below. The repository README documents all of them.
| Variable | Default | Description |
|---|---|---|
INSTANCE_NAME | required | Name of the installation, passed to OpenTofu as var.instance_name |
APPLY_MODE | auto | auto applies every plan, plan only logs it for review |
RECONCILE_INTERVAL | 15m | Time between two runs |
STATE_ENCRYPTION_PASSPHRASE | Encrypts the state and the plans, at least 16 characters | |
DESTROY_CONFIRM | Set to INSTANCE_NAME to destroy all infrastructure, also in plan mode | |
PROVIDER_MIRROR | OCI repository prefix to install providers from, for installations that can’t reach the registry | |
TF_VAR_<name> | Variables of the OpenTofu configuration |