About Conn3x
What is Conn3x?
One tool that creates your servers and configures them, in the same plan. You describe the cloud the way you already do, in HCL with any OpenTofu or Terraform provider, and describe what goes on each server in a circuit: packages, files, services, users and the rest. conn3x plan shows the droplet about to be created next to the exact file changes headed for it, and conn3x apply does both.
It's a single binary, built on OpenTofu, and it reaches your servers over plain SSH.
Why was Conn3x created?
Because creating a server and setting it up are one job that usually takes two tools. Terraform or OpenTofu makes the machine, Ansible configures it, and something in between carries the addresses across: an inventory script, a local-exec, a sleep 60 while SSH comes up. Each tool has its own idea of what's out there, and neither one sees the whole change before it happens.
Conn3x does the whole job with one plan and one state. Why Conn3x tells the longer story.
Who's behind Conn3x?
James Conway started Conn3x and makes the final call while the project is small. Decisions happen in public, in issues, Discussions and pull requests. Anyone who contributes steadily and reviews other people's work can be invited to become a maintainer.
Once there are maintainers from more than one organization, the plan is to move the project, its trademark and its domains to a neutral foundation, so it doesn't depend on any one person or company. GOVERNANCE.md has the details.
Is it free? Could the license change?
It's free, and it's licensed under the Mozilla Public License 2.0, the same license as OpenTofu. That won't change.
There's no CLA and no copyright assignment. Contributors keep the copyright to their work and sign off under the Developer Certificate of Origin, so no single person or company can relicense the project. Sponsors, when there are some, get visibility, not control: nothing is held back from the open source project.
Is Conn3x ready for production?
It's early, and it's honest about it. Conn3x configures Rocky Linux, RHEL, AlmaLinux, Fedora, Debian and Ubuntu, and every change is tested on Rocky Linux 10, Fedora 45, Ubuntu 24.04 and Debian 13. Releases are signed and come with SBOMs.
Until 1.0, read the release notes before you upgrade. Start the way you'd start with any new tool: one server you don't mind touching, with your state backed up. If something doesn't behave, tell us.
Coming from Terraform or OpenTofu
Is Conn3x a fork of OpenTofu?
Yes. Conn3x starts from OpenTofu v1.13.2 and tracks its releases. It adds circuits and the host modules that run them; the planning, state and provider machinery is OpenTofu's. Files that come from OpenTofu keep their original copyright and license headers.
The commands will look familiar: conn3x init, conn3x plan and conn3x apply, where you'd run tofu or terraform.
Will my existing configuration and state work?
Your configuration runs unchanged: the same .tf files, the same providers, the same modules. Conn3x reads and writes OpenTofu state, and OpenTofu reads Terraform state up to the versions it supports. The S3, GCS, azurerm, Kubernetes, Consul, PostgreSQL and HTTP backends are built in.
Back up your state before the first conn3x apply, as you would before any tool change. Use Conn3x with Terraform or OpenTofu configuration walks through it.
Do all the providers work?
Every provider in the OpenTofu Registry works, as it is. Create servers with whichever cloud you already use and hand their addresses to a circuit. Providers lists the usual ones.
How is a circuit different from a provisioner or user_data?
A user_data script or a remote-exec provisioner runs once, when the server is created. The plan doesn't show what it will do, state doesn't record what it did, and nobody hears about it when someone changes the server later.
A circuit reads the server first, shows a diff in the plan, then applies it. What it manages lives in the same state as your resources, so the next plan, and conn3x drift, will tell you when the server no longer matches.
Coming from Ansible
Do I have to rewrite my playbooks?
Not by hand. conn3x convert ansible -i inventory.ini site.yml turns a playbook into circuits: one per play, a step per task, handlers for the restarts your tasks notify, and hosts read from your inventory. Anything it can't translate stays in the output, commented out, with a TODO(convert) line saying why, so nothing is lost.
Migrate from Ansible covers what converts and how to finish the rest.
Why HCL and not YAML?
Because the server config lives next to the infrastructure that creates the server. In HCL a circuit's hosts can be digitalocean_droplet.web.ipv4_address, an expression the plan understands, instead of an address copied into an inventory. Loops, conditions and templates are part of the language, so there's no Jinja inside YAML to keep straight.
What can a circuit manage?
The everyday work: files, templates, and lines or blocks inside them; packages and repositories, services, users and SSH keys, cron jobs and timers, sysctl, mounts, the hostname, time zone and locale, firewalld and ufw, SELinux, downloads, archives, git checkouts, reboots, waits and guarded commands, plus facts about each host to plan with. Every module is in the docs.
Does Conn3x need anything installed on my servers?
No. No Python, no agent. Conn3x connects over SSH, checks the host key every time, and runs ordinary shell commands, as root or through sudo.
Using Conn3x
Which systems does it run on, and which can it configure?
Conn3x runs on Linux and macOS, on amd64 and arm64. It configures Rocky Linux, RHEL, AlmaLinux, Fedora, Debian and Ubuntu servers today. Network devices come next, then Windows.
Can it configure servers it didn't create?
Yes. A circuit's hosts can be plain addresses, such as { web1 = "203.0.113.10" }, so you can point Conn3x at servers you already run. Configure your first real server starts that way.
How does it handle secrets?
Pass a secret in through an ephemeral variable and write it with content_wo or a write-only template. It reaches the server, but never the plan, the state file or a saved plan; state keeps an HMAC instead, so Conn3x can still tell when the file changes. Keep secrets out of state shows it end to end.
Can it reach servers behind a bastion?
Yes. List the hops in jump_hosts, the way you'd pass them to ssh -J, or use the host names you already have in ~/.ssh/config. Reach hosts behind a bastion has the details.
How do I find out when someone changes a server by hand?
Run conn3x drift. It checks both your cloud resources and what's on the servers, and exits 2 when something changed, so a scheduled CI job can alert on it. Catch drift in CI sets one up.
Where can I find circuits other people have written?
On conn3x.org/circuits. Each one goes in with a single module block. Written one worth sharing? Share a circuit explains how to publish it and list it there.
Community
How can I contribute?
Ideas and feedback are the most useful thing right now, and they go in Discussions. If you'd like to write code, issues labelled good first issue and help wanted are ready to pick up: comment on one to claim it. Read CONTRIBUTING.md first. Every commit needs a DCO sign-off (git commit -s).
How do I report a bug or a security problem?
Bugs go in GitHub issues. Security problems should be reported privately, never in a public issue; SECURITY.md explains how.
How do I check that a release is genuine?
Every release ships a checksums.txt signed with cosign by the release workflow, an SBOM for every archive, and GitHub build provenance you can check with gh attestation verify. Install has the commands.
Where can I follow what's happening?
Releases and progress go out on the blog (with an RSS feed) and on X at @conn3xone. Questions and show-and-tell live in Discussions.