Feasibility assessment: fly.io provider
Bottom line: technically possible to wire in, but fly.io is a poor fit for what machine does. Roughly half of the CloudProvider interface has no native fly.io equivalent, and the tool's core workflow — boot an OS image, inject SSH keys, run a cloud-init script, point a DNS record at the VM's IP — doesn't map onto fly.io's model.
One premise worth correcting first: fly.io isn't a bare-metal provider. They run their own bare metal, but what they sell is Firecracker microVMs ("Machines") that boot from Docker/OCI container images (e.g. registry-1.docker.io/library/ubuntu:latest), not full OS images. That difference drives most of the friction below.
What maps cleanly
- API mechanics: a simple REST API (
POST /v1/apps/{app}/machines, plus get/list/delete/start/stop) withAuthorization: Bearertoken auth. No SDK needed — plainrequestswould do, so no new dependency risk for the Python ≥3.8 / shiv build. create_vm/get_vm/destroy_vm/list_vms— all have direct endpoints.tagsmaps to machinemetadata,regionmaps to fly regions,sizemaps toguestconfig (cpu_kind,cpus,memory_mb).validate_region/validate_image— straightforward.
What breaks
- cloud-init /
user_data— not supported at all. Machines boot a container entrypoint, not a cloud-init-enabled OS. The closest emulation is thefilesconfig (write files into the machine) plus a customentrypoint, but that's a different contract than the cloud.init scripts this tool is built around. This is the biggest blocker since cloud-init specification is one of your three stated core features. - SSH keys — fly.io has no SSH key resource. Access is via
fly ssh consoleover their WireGuard mesh with their own agent (hallpass); to get real sshd with your keys, you'd have to bake sshd and the public key into the container image.get_ssh_key/list_ssh_keysand thessh_key_namesargument tocreate_vmcan't be implemented natively. - Public IPs — allocated per app, not per machine, and they're anycast addresses (shared IPv4 by default; dedicated IPv4 costs extra and is still app-scoped). Machines themselves only have private 6PN IPv6 addresses.
VM.ip_address— which the DNS workflow presumably feeds — has no clean per-VM answer. - DNS — fly.io offers no DNS hosting or record-management API (only
.fly.devsubdomains and certificate management for custom domains).create_dns_record,delete_dns_record,get_dns_records, andlist_domains— four of the ten abstract methods — would have to be stubbed out or delegated to another provider. - App container concept — every machine must live inside a "Fly App" (which is also the unit of IP allocation and internal DNS), so the provider would need an app-management strategy (one app per VM vs. one shared app) that has no analogue in the current abstraction.
Verdict
If the goal is "manage fly.io machines from this CLI," a provider could be written in a day or two using the four VM CRUD methods and stubs elsewhere — similar in spirit to how GCP presumably omits some pieces. But users would get machines they can't cloud-init, can't ssh into with their configured keys, and can't point DNS at a per-machine IP. I'd recommend against adding it unless you're willing to reframe fly.io support as a container-deployment mode rather than a VM provider. If you want a provider with a similar "modern API, runs its own hardware" flavor that does fit the abstraction (real VMs, cloud-init, SSH keys, per-VM IPs), Hetzner Cloud or Linode would slot into the existing interface almost 1:1.
Sources: Machines API index, Machines resource, Networking services