kcli drives a dozen virtualization providers through one command set
Management tool for virtualization and kubernetes platforms
At a glance
- What is it?
- kcli is a Python management tool that deploys and manages virtual machines across libvirt, KubeVirt, oVirt, OpenStack, vSphere, AWS, Azure, GCP, IBM Cloud and Hetzner Cloud, with YAML plan files as the unit of work. It is a one-person project with Apache-2.0 licensing, an active push history and no tagged releases.
- Who is it for?
- Adopt kcli when your team runs virtual machines across several clouds or hypervisors and wants the same plan files, profiles and cloud image handling everywhere instead of a different client per provider. Skip it when you need the deep corners of one provider's own tooling, since kcli normalises the common operations and leaves provider specific features behind.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 4 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
One command set over ten virtualization providers
The stated purpose of kcli is to interact with existing virtualization providers and to easily deploy and customize VMs from cloud images. The provider list in the readme is long: libvirt, KubeVirt, oVirt, OpenStack, VMware vSphere, AWS, Azure, GCP, IBM cloud and Hcloud.
What that buys you is a single vocabulary. You list, inspect, connect to, start, stop, delete and open console sessions on virtual machines regardless of where they run, and you add or remove disks and network interfaces with the same commands. On a team that has a lab on a hypervisor and production on a public cloud, that consistency is the actual product.
The tool also reaches beyond the hypervisor. The readme lists DNS handling for the machines, automatic subscription of RHEL virtual machines, sharing of private keys between machines, and configuration injection through cloud-init or Ignition, with the equivalent mechanism in cloud providers. A push button notification arrives when a deployment finishes, and there is a web interface as an alternative to the command line.
The unit of work is a YAML plan file. You declare virtual machines, containers, networks and Ansible playbooks in one file with a simple syntax, customise a deployment with parameters and Jinja templating, and adjust virtual machines from a plan so their memory, CPU, flavour, disks and interfaces match what the plan says.
Profiles and products sit above the plan file
Two reuse mechanisms sit on top of the raw plan. Profiles let you launch virtual machines with the same hardware characteristics, which is how you keep a lab fleet consistent without repeating disk and interface definitions in every file.
Products are the wider mechanism, and the readme describes them as entire products for which plans were already created for you. You can share a plan or use existing ones from a GitHub repository as products, and the plans that ship with the project cover Kubernetes, OpenShift, OpenStack, oVirt and KubeVirt. So a cluster deployment that would be several hundred lines of YAML for one provider becomes a product someone else already wrote.
Plans can also be launched from an URL, which means a plan can live in a shared repository and be referenced rather than copied into a local tree.
The trade-off is that the plan schema becomes a contract. The readme does not publish a schema version or a compatibility statement for plan files, and there are no GitHub releases in this repository, so a plan written for one version of kcli has no documented guarantee against a later version. That is the single most important thing to test in your own environment before you build a fleet on top of it.
Installing from the repository script and launching a first VM
The quick start is one command, piping the install script from the repository into a shell:
curl -s https://raw.githubusercontent.com/karmab/kcli/main/install.sh | bashPiping a remote script straight into bash is convenient and is the sort of thing worth thinking about for a machine with production credentials, so an alternative is to read install.sh first and run it from a local copy. The repository also ships a Fedora Copr build, so a distribution package exists for those who prefer one.
The first deployment sequence in the readme is four commands:
kcli create vm -i centos8stream myvm
kcli list vm
# wait 5-10 seconds for vm to grab an ip
kcli ssh myvmand the cleanup is a fifth:
kcli delete vmThe comment between the list and the ssh is the part worth noticing, because it describes real behaviour rather than a slogan. A freshly created machine needs a few seconds before it has an address, so the tool lists before it connects and the reader is told to wait. The image reference uses the -i flag with a distribution name, and the readme notes that existing cloud images for each distribution are used, so you are not expected to supply an image file.
Provider dependencies are split into optional extras
The packaging in setup.py shows how the project is structured for different environments. There is a base install list, and then one extra per provider:
INSTALL = ['argcomplete', 'PyYAML', 'prettytable', 'jinja2', 'libvirt-python>=2.0.0']
AWS = ['boto3']The base list is small and sensible: argcomplete for shell completion, PyYAML and Jinja2 for the plan format and templating, prettytable for the tabular list output, and libvirt-python.
That last entry is the one to look at. The libvirt bindings sit in the mandatory install list rather than in an extra, so a machine that only ever talks to AWS or GCP still installs the Python bindings for the local hypervisor. The rest of the provider libraries are properly optional, with boto3 for AWS, azure-mgmt-compute and the other Azure packages, google-api-python-client and google-cloud-compute for GCP, the OpenStack clients, ovirt-engine-sdk-python, proxmoxer, pyvmomi for vSphere, the IBM Cloud packages including ibm_vpc, and hcloud. An extras list combines all of them.
The version field in setup.py reads 99.0, which is a deliberate placeholder rather than a release number. There are no GitHub releases in the repository either, so the version you install is the version in the source you fetched, and pinning a specific commit is the only way to make a deployment reproducible.
What kcli does not cover that a provider client would
The honest limitation is depth. A provider's own client exposes its full API surface, including the administrative corners that kcli has no reason to model. kcli standardises the operations that matter across a fleet, and it is a Python library with a CLI on top, so anything it does not wrap is simply out of reach.
There is a second constraint that follows from the plan file design. Because the plan is the unit of work, workflows that are inherently stateful or interactive, a live migration between providers, for instance, or a provider-specific billing operation, do not fit the model well. The readme lists the platform-specific extra topics in the repository, spanning AWS, Azure, GCP, Hetzner Cloud, IBM Cloud, k3s, kubeadm, kubevirt, microshift, OpenShift, oVirt, Proxmox, rke2 and vSphere, which tells you the breadth the author intends to cover rather than the depth in any one of them.
Third, the installation method. The quick start pipes a script from the main branch into a shell, so a network-dependent install is the documented path and no checksum or signature is mentioned for it. For a workstation that is acceptable. For a pipeline, a distribution package or a pinned checkout is the safer route, and the Copr build shows the project supports that path.
Documentation lives on Read the Docs, the code on one branch
The project points to a documentation site at kcli.readthedocs.io, with the homepage recorded as the Read the Docs English site, and the repository carries a .readthedocs.yml alongside a docs/ directory. The documentation, not the readme, is where the plan file syntax is defined, which is what you need before writing anything beyond a single machine.
The repository layout also tells you what kind of tool this is. Alongside the source there are extras/, a kvirt/ directory for the KubeVirt provider, a samples/ directory with all_parameters.yml, config.yml and profiles.yml as examples of the plan and profile format, a tests/ directory, a skills/ directory, and packaging files for both RPM and a broader spec. The samples are the fastest way to see the shape of a plan file, and the profiles sample shows how hardware is shared between machines.
The project also carries a Code of Conduct, a Contributing guide and CI badges pointing at a GitHub Actions workflow and a Fedora Copr build, so changes are checked automatically and packages are built for Fedora users.
Support is offered through a GitHub issue and two Slack channels, one on the Kubernetes Slack instance and a dedicated kcli channel.
Apache-2.0 licensing and a single maintainer
The licence is Apache License 2.0, spelled out in full in the readme, with the copyright held by Karim Boumedhel for 2017 to 2025. It is a permissive grant with attribution and an explicit patent clause, and it puts no copyleft obligation on the projects that use it. The setup.py metadata records the licence as ASL.
The single maintainer is the more significant fact for an adopter. Every provider integration, the plan schema and the release cadence depend on one person, and the readme carries a personal sign off. There is no governance file and no maintainer list beyond the contributor graph linked from the readme.
The activity level is good. The last push was on 2026-10-19 and the repository is not archived, so the code is being worked on regularly even without tagged releases. What you give up by not having releases is the ability to say which version a plan file was written against, which is exactly the information a fleet deployment needs. The practical mitigation is to pin a commit and keep your plans in your own repository, where you control their history.
Editorial conclusion
Adopt kcli when your team runs virtual machines across several clouds or hypervisors and wants the same plan files, profiles and cloud image handling everywhere instead of a different client per provider. Skip it when you need the deep corners of one provider's own tooling, since kcli normalises the common operations and leaves provider specific features behind. Before committing, read the documentation at kcli.readthedocs.io, try the install script from the repository and not from a third party mirror, and check whether the base install pulling in libvirt-python suits a machine that only ever touches cloud providers.
Frequently asked questions
What is kcli and which virtualization platforms does it support?
kcli is a Python management tool for virtualization and Kubernetes platforms. It interacts with libvirt, KubeVirt, oVirt, OpenStack, VMware vSphere, AWS, Azure, GCP, IBM cloud and Hcloud, deploying and customizing VMs from cloud images.
How do I install kcli?
The quick start pipes the repository install script into bash with curl -s https://raw.githubusercontent.com/karmab/kcli/main/install.sh | bash. A Fedora Copr package is also built for the project, and the source can be installed from a checkout.
What are kcli plan files?
A plan file is a YAML file that declares objects such as VMs, containers, networks and Ansible playbooks in one file. Deployments are customised with parameters and Jinja templating, and sample plans, profiles and a configuration example live in the samples/ directory.
Does kcli need a dependency for every cloud provider?
No, the provider libraries are optional extras. The base install is argcomplete, PyYAML, prettytable, jinja2 and libvirt-python, while boto3, the Azure packages, the Google client libraries, the OpenStack clients, proxmoxer, pyvmomi, the IBM Cloud packages and hcloud are extras that can be installed as needed.
How do I connect to a virtual machine created with kcli?
After kcli create vm and kcli list vm, the readme notes that you should wait 5 to 10 seconds for the machine to get an IP address, and then use kcli ssh myvm. Deleting the machine is done with kcli delete vm.
Is kcli still maintained and how is it released?
The repository is not archived and the last push was on 2026-10-19, but it has no GitHub releases and the version field in setup.py reads 99.0 as a placeholder. The licence is Apache License 2.0, copyright Karim Boumedhel, and support is offered through a GitHub issue and two Slack channels.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/karmab-kcli)Was this useful?