# The OxygenFlow OpenTofu image A root file system for deploy jobs (oxygenflow#56): - Debian bookworm, slim, with CA certificates. - OpenTofu 1.13.1, checked against its published SHA-256. - A provider mirror in `/opt/tofu/mirror`: `hashicorp/google` 8.7.0, `hashicorp/google-beta` 8.7.0 (Firebase) and `cloudflare/cloudflare` 5.28.0, checked by `tofu providers mirror` against the registry's signed checksums when the image is built. - `/etc/tofu/cli.tfrc` (set by `TF_CLI_CONFIG_FILE`) installs providers from the mirror only. - TFLint 0.64.0 and its Google ruleset 0.40.0, each checked against its release's SHA-256, the ruleset in `/opt/tflint/plugins` (`TFLINT_PLUGIN_DIR`): a repository's `.tflint.hcl` enables it with `plugin "google" { enabled = true version = "0.40.0" source = "github.com/terraform-linters/tflint-ruleset-google" }`, and linting needs no `tflint --init`. So `tofu init`, `fmt` and `validate` need no network; `plan` and `apply` reach the cloud's APIs through allow-listed egress (#55). The guest's environment is the pipeline's, so a job sets `TF_CLI_CONFIG_FILE` itself (below). ## Building and importing ``` images/tofu/build.sh /path/to/oxygenflow-tofu.tar scp /path/to/oxygenflow-tofu.tar claude@earth:/home/claude/flow/dl/ ssh claude@earth 'cd ~/flow && FLOW_HOME=~/flow bin/flow rootfs import dl/oxygenflow-tofu.tar' ``` Pin the printed hash in the pipelines that use it, and push it to the hub (`flow rootfs push HASH`) so every runner can fetch it. A provider version in a pipeline's lock file must be in the mirror: bump `mirror.tf`, rebuild and re-pin when a lock file changes. ## Using it ```kdl sandbox "tofu" { runtime "microvm" rootfs "cas://blob/" memory-limit "2GiB" cpu-limit 2 network "isolated" env { TF_CLI_CONFIG_FILE "/etc/tofu/cli.tfrc" TF_IN_AUTOMATION "1" TFLINT_PLUGIN_DIR "/opt/tflint/plugins" } } ```