Conn3x v0.6.5: circuits that share a host get along

Open source · Built on OpenTofu

Provision it. Configure it.
One plan.

Today that's Terraform, Ansible, and a drawer of glue scripts holding them together. Conn3x does both jobs: one binary, one plan, one state, for your cloud and every server it creates.

brew install conn3xorg/tap/conn3x
  • DigitalOcean
  • AWS
  • Hetzner Cloud
  • Google Cloud
  • Azure
  • Akamai (Linode)
  • Vultr
  • Scaleway
  • Oracle Cloud
  • Proxmox VE
  • Rocky Linux
  • RHEL
  • AlmaLinux
  • Fedora
  • Debian
  • Ubuntu

01 One plan

One plan for the cloud and the servers in it. Point a circuit at a resource and the plan shows the server about to be created next to every package, file and service headed for it.

Reads before it writes

Every step reads the server first, so the plan shows the exact change, not a guess.

Waits for SSH

A new server's steps wait until it answers. No sleep 60.

One state

The droplet and everything on it live in the same state file.

One conn3x apply creates two droplets, waits for SSH on each, installs nginx, writes its config and starts it on both, then reports 8 resources added.conn3x applydroplet.web["web1"]+ createdweb1ssh okssh …package nginxfile nginx.confservice nginxdroplet.web["web2"]+ createdweb2ssh okssh …package nginxfile nginx.confservice nginxApply complete · 8 added

02 Drift

Hear about the 3 a.m. fix at breakfast. conn3x drift checks the cloud and the servers, and fails the job when either has moved.

  1. conn3x applyServers match the code.
  2. A hand edit on web1worker_connections, 1024 to 4096.
  3. Nightly conn3x driftFinds it, exits 2, the job fails.
  4. conn3x applyPut back. Or keep it, in code.
web1:/etc/nginx/nginx.conf
user nginx;
worker_processes auto;
events {
  worker_connections 10244096;
}
nightly drift · GitHub Actionspassingexit code 2
$ conn3x drift
Drift found in 1 resource.
 
Hosts
  ~ conn3x_file.web__nginx_conf["web1"]  changed
$ conn3x apply
conn3x_file.web__nginx_conf["web1"]: Modifying...
conn3x_file.web__nginx_conf["web1"]: Modifications complete after 1s

03 Bring your playbooks

Your playbooks come with you. The converter rewrites each task it can prove, and marks the rest with the reason. Nothing gets guessed.

site.yml
- name: Install nginx
  ansible.builtin.dnf:
    name: nginx
    state: present
- name: Start nginx
  ansible.builtin.service:
    name: nginx
    state: started
    enabled: true
- name: Install tools
  ansible.builtin.package:
    name: "{{ item }}"
  loop: [git, jq]
- name: Open the status port
  ansible.posix.firewalld:
    port: "{{ status_port }}/tcp"
    state: enabled
  when: ansible_os_family == "RedHat"
web.circuit.hcl
step "install_nginx" {
  package {
    name = "nginx"
  }
}
step "start_nginx" {
  service {
    name    = "nginx"
    state   = "started"
    enabled = true
  }
}
step "install_tools" {
  for_each = ["git", "jq"]
  package {
    name = item.value
  }
}
# TODO(convert): Task "Open the status port"
# uses when, which the converter can't
# translate yet.
#   - name: Open the status port
#     when: ansible_os_family == "RedHat"

Servers still need packages, files and services. What's changing is that one plan can see all of it.

How it fits together

Your HCL configuration and circuits go into Conn3x, which has an OpenTofu core and a circuit engine. The core talks to cloud APIs through providers, the engine talks to hosts over SSH, and both write to one state file.main.tfweb.circuit.hclCONN3XOpenTofu coregraph · plan · providersCircuit engineread · diff · applyprovidersSSHCloud APIsany providerYour serversweb1 · web2One statecloud and hosts together

Your configuration and your circuits are one HCL project. Conn3x plans the cloud through OpenTofu's providers and the servers over SSH, and records both in one state file.

How a step runs

1 · Read

What's on web1 now?

/etc/nginx/nginx.conf
worker_connections 4096;

2 · Diff

What would change, shown in the plan.

~ conn3x_file.web__nginx_conf["web1"]
-   worker_connections 4096;
+   worker_connections 1024;

3 · Apply

Only after you approve the plan.

Modifications complete after 1s
notify → handler.reload_nginx

Every step reads the server first, so the plan shows the exact change, not a guess. Nothing on the server changes until you apply, and a step that already matches does nothing.

Built on OpenTofu

Conn3x adds

  • Circuits
  • 29 host modules
  • SSH with host-key checks
  • conn3x drift
  • conn3x convert ansible

OpenTofu v1.13

  • Plan and apply
  • State and backends
  • Providers
  • Modules
  • HCL

Conn3x starts from OpenTofu and tracks its releases, so your providers, modules and state come with you. Files from OpenTofu keep their original licence headers.

04 Everyday work

Everything a server needs. Linux first: every change is tested on Rocky Linux 10, Fedora 45, Ubuntu 24.04 and Debian 13.

Every module in the docs →

05 Circuits

Don't write the nginx setup again. Borrow a circuit with one module block, or share your own on the directory.

Browse every circuit →

06 Compare

Two tools, or one. The same job, with one less handoff.

AspectTerraform or OpenTofu, plus AnsibleConn3x
To installTwo tools, and Python on the controller and every hostOne binary
StateTerraform state for the cloud, none for the hostsOne state for both
Seeing host changesA separate --check --diff runIn the same plan as the cloud
Cloud addresses in host configInventory scripts or pluginsAn expression
Finding drift on hostsRun the playbook in check modeconn3x drift, both layers

07 Open source

Built with the people who use it. Every fix from outside the project ships with the name of whoever wrote it, right there in the release notes.

MPL-2.0, no CLA, and no feature held back for sponsors. Meet the people building it, or start with the contributing guide.

From the blog.

All posts
  1. Conn3x v0.6.5: circuits that share a host get alongPackage steps from two circuits now wait for each other's locks, ufw rules applied together all stick, and sysctl and file steps work on minimal images. Six fixes, three of them from contributors.
  2. The first five contributorsWithin hours of the first release, people started opening pull requests against Conn3x. Here's who they were, what they fixed, and what you can expect if you're next.
  3. GitHub Universe, and the place Conn3x livesGitHub Universe runs today and tomorrow in San Francisco. A note on why Conn3x is built entirely in the open on GitHub, and an open door for whoever wants to build it with us.

Fifteen minutes to your
first circuit.

All you need is one Linux server you can reach over SSH. No server handy? Try it on a throwaway container, in about five.