Infrastructure Automation
A GitOps control plane for OpenTofu: Git-synced Projects and Stacks, a plan-then-approve-then-apply workflow, and an encrypted secrets vault.
Infrastructure Automation provisions and configures real infrastructure from code you keep in Git: OpenTofu for provisioning, Ansible for configuration management. It's available on the Enterprise plan, given the blast radius of a feature that can create, destroy, and reconfigure real infrastructure.
What it does
- Projects: the top-level container, pointed at a Git repository (branch), with an optional credential for private repos. A Project holds one or more Stacks, each a subdirectory of either OpenTofu (
.tf/.tofu) code or an Ansible playbook and inventory. - Vaults & Secrets: every Project can hold multiple named vaults. A secret's value is encrypted (AES-256-GCM) the moment you save it, and is never returned by any API call again, not even to you. Saving a new value for the same name creates a new version rather than overwriting the old one, so history is preserved. A dedicated
ssh_keysecret type holds the private key Ansible uses to connect to target hosts. - Variables: non-secret key/value pairs, either project-wide or scoped to a specific stack. For an OpenTofu stack, variables and secrets are injected as
TF_VAR_<name>environment variables. For an Ansible stack, they're passed as--extra-vars. Both are matched by name, so there's no separate mapping step to configure. - Runs: an OpenTofu stack is acted on via plan, apply, destroy, or refresh. An Ansible stack is acted on via check (a
--check --diffdry run) or run (the real playbook execution). Every run streams its live output to a log viewer on the run's own page. - Targets: a Stack can optionally be linked, for display purposes, to a cluster or host you already monitor elsewhere in KubeWatch, so its dashboard page shows what it manages at a glance. This link is purely informational. What actually decides what a Stack provisions or connects to is its own OpenTofu provider configuration or Ansible inventory.
The plan-then-approve-then-apply workflow
This is the one guardrail that can't be turned off, and it applies the same way to both engines: applying a real change always requires a specific, already-succeeded dry-run on the same stack that a human has explicitly approved. There's no way to skip straight to a real change nobody has reviewed. For OpenTofu, apply and destroy each require an approved plan run on the same stack. Destroy specifically requires a plan_destroy run (a plan that shows what would be deleted), since an ordinary plan run can never authorize a destroy. For Ansible, run requires an approved check run (Ansible's own --check --diff dry run) on the same stack.
In practice: click Run plan (or Run destroy plan for OpenTofu, Run check for Ansible), wait for it to succeed, review its output in the log viewer, then click Approve. Only then does Apply, Destroy, or Run appear, and only on that specific dry-run, pre-filled with the right reference, never asking you to type a run ID by hand. Destroying anything additionally requires typing the stack's name to confirm, since it's the one action here that can't be undone.
Access control
Every Project has its own membership list, independent of your organization's broader role assignments. Being a member of the org does not automatically grant access to a Project's Stacks, Vaults, or secrets. Three roles, each a strict superset of the one below it:
- Viewer: see everything, run nothing.
- Operator: create/run Stacks, manage Vaults and Variables, approve plans.
- Admin: everything Operator can do, plus manage Project settings and membership. Every Project always keeps at least one Admin, so removing the last one, or demoting them, is blocked.
Every mutation (creating a Stack, saving a secret, approving a plan, running a destroy) is written to the same append-only audit trail every other privileged action in this platform uses.
Private repositories
A Project can attach a Git credential from its own Vaults (an api_token secret, used as an HTTPS access token) under its Edit panel. Once attached, every clone for that Project's Stacks authenticates with it automatically. Only HTTPS token auth is supported. SSH-based Git authentication isn't.
Blueprint gallery
A Stack doesn't have to start from code already sitting in your repo. The blueprint gallery, opened from a Project's Stacks tab, is a catalog of 50 built-in starter templates across provisioning, Kubernetes, databases, messaging, networking, security, observability, and CI/CD, split evenly between OpenTofu and Ansible. Each entry shows its description, suggested variables (with sensible defaults for ordinary config, and clearly flagged names you should add as Vault secrets for anything sensitive), and the exact file content it would create.
Picking one and clicking Use this blueprint does more than the rest of this feature ever does elsewhere: it creates the Stack, then pushes the blueprint's files as a new commit directly to your Project's own Git repository. Every other action here only ever reads your repo, cloning it to plan, apply, check, or run. This is the one path that writes to it, authored under a generic automation identity rather than a real person's. Because of that, it needs a Git credential with push access attached to the Project, not just the read access cloning already required. Attaching a read-only token works for everything else in this feature but will fail here with a clear error telling you to grant it more.
What it doesn't do yet
- SSH-based Git authentication isn't supported, only HTTPS with an optional token credential. (This is separate from the
ssh_keysecret type above, which is for Ansible's connection to its target hosts, not for cloning the Project's own repo.) - Custom, org-authored blueprints aren't supported yet: the gallery is currently the 50 built-in templates only, not a place to save your own Stack as a reusable one.