Generate and debug kcli YAML plans for deploying virtual machines and network infrastructure.
Install
mkdir -p .claude/skills/kcli-plan-authoring && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/8452" && unzip -o skill.zip -d .claude/skills/kcli-plan-authoring && rm skill.zipInstalls to .claude/skills/kcli-plan-authoring
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Guides creation of kcli plan files for deploying VMs, networks, and infrastructure. Use when writing YAML plans with Jinja2 templating or debugging plan execution issues.Key capabilities
- →Define VM, network, and container resources in YAML
- →Apply Jinja2 templating for infrastructure
- →Override plan parameters at runtime
- →Validate plan syntax and dependencies
- →Execute and update infrastructure plans
How it works
The skill guides the authoring of YAML plans that use Jinja2 templating to define and deploy infrastructure resources via kcli.
Inputs & outputs
When to use kcli-plan-authoring
- →Deploy new virtual machines
- →Define network infrastructure via YAML
- →Debug kcli deployment plans
- →Implement Jinja2 templates for infra
About this skill
kcli Plan Authoring
Plan File Structure
Plans are YAML files with Jinja2 templating. Resources are defined as top-level keys with a type field.
parameters:
param1: value1
param2: value2
resourcename:
type: resourcetype
key1: value1
key2: {{ param1 }}
Resource Types
VM (default if no type specified)
myvm:
image: fedora40
memory: 4096
numcpus: 2
disks:
- size: 20
- size: 10
pool: otherpool
nets:
- name: default
- name: mynet
ip: 192.168.1.10
netmask: 255.255.255.0
gateway: 192.168.1.1
cmds:
- echo hello > /tmp/test
files:
- path: /etc/myconfig
content: |
key=value
Profile
myprofile:
type: profile
image: centos9stream
memory: 2048
numcpus: 2
disks:
- 10
nets:
- default
Network
mynetwork:
type: network
cidr: 192.168.100.0/24
dhcp: true
nat: true
domain: mylab.local
Image
myimage:
type: image
url: https://example.com/image.qcow2
pool: default
Container
mycontainer:
type: container
image: nginx:latest
ports:
- 8080:80
Jinja2 Templating
Parameter Substitution
parameters:
cluster_name: mycluster
worker_count: 3
{{ cluster_name }}-master:
image: rhcos
{% for i in range(worker_count) %}
{{ cluster_name }}-worker-{{ i }}:
image: rhcos
{% endfor %}
Conditionals
parameters:
enable_storage: true
myvm:
image: fedora40
{% if enable_storage %}
disks:
- size: 100
{% endif %}
Custom Filters
kcli provides custom Jinja2 filters in kvirt/jinjafilters/jinjafilters.py:
Path/File Filters:
basename- Get filename from pathdirname- Get directory from pathdiskpath- Convert to /dev/ path if neededexists- Check if file/path existspwd_path- Handle workdir paths in containersreal_path- Get real/absolute pathread_file- Read file contents
String/Data Filters:
none- Return empty string if Nonetype- Return type name (string, int, dict, list)base64- Base64 encode valuecertificate- Wrap in BEGIN/END CERTIFICATE if neededcount- Count occurrences of character
Kubernetes/Cluster Filters:
kubenodes- Generate node names for clusterdefaultnodes- Generate default node listhas_ctlplane- Check if list has ctlplane/master entries
Version/Release Filters:
github_version- Get latest version from GitHub releasesmin_ocp_version- Compare OpenShift versions (minimum)max_ocp_version- Compare OpenShift versions (maximum)
Network Filters:
local_ip- Get local IP for network interfacenetwork_ip- Get IP from network CIDRipv6_wrap- Wrap IPv6 addresses in brackets
Utility Filters:
kcli_info- Get VM info via kcli commandfind_manifests- Find YAML manifests in directorywait_crd- Generate wait script for CRD creationwait_csv- Generate wait script for CSV readinessfilter_bgp_peers- Filter BGP peer list
Standard Jinja2 filters (default, join, upper, lower, etc.) also work
Parameter Files
Create kcli_parameters.yml alongside your plan:
cluster_name: prod
worker_count: 5
memory: 8192
Override at runtime:
kcli create plan -f myplan.yml -P worker_count=10 myplan
Common VM Parameters
| Parameter | Default | Description |
|---|---|---|
numcpus | 2 | Number of CPUs |
memory | 512 | Memory in MB |
pool | default | Storage pool |
image | None | Base image name |
nets | [default] | Network list |
disks | [{size:10}] | Disk list |
cmds | [] | Post-boot commands |
files | [] | Files to inject |
keys | [] | SSH public keys |
start | true | Auto-start VM |
cloudinit | true | Enable cloud-init |
Plan Execution
# Create plan
kcli create plan -f myplan.yml myplanname
# Create with parameter overrides
kcli create plan -f myplan.yml -P memory=4096 -P image=fedora40 myplanname
# List plans
kcli list plan
# Get plan info
kcli info plan myplanname
# Delete plan (and all its resources)
kcli delete plan myplanname
# Update existing plan
kcli update plan -f myplan.yml myplanname
Debugging Plans
- Validate YAML syntax - Use
python -c "import yaml; yaml.safe_load(open('plan.yml'))" - Check Jinja2 rendering - Look for unbalanced
{{}}or{% %} - Run with debug -
kcli -d create plan -f plan.yml test - Check dependencies - Ensure images/networks exist before VMs reference them
Example: Multi-VM Plan
parameters:
domain: lab.local
base_image: centos9stream
labnetwork:
type: network
cidr: 10.0.0.0/24
dhcp: true
domain: {{ domain }}
webserver:
image: {{ base_image }}
memory: 2048
nets:
- labnetwork
cmds:
- dnf -y install nginx
- systemctl enable --now nginx
database:
image: {{ base_image }}
memory: 4096
disks:
- size: 20
- size: 50
nets:
- labnetwork
cmds:
- dnf -y install postgresql-server
- postgresql-setup --initdb
When not to use it
- →Deploying resources without kcli
- →Complex non-YAML infrastructure definitions
Limitations
- →Requires kcli environment
How it compares
It enables dynamic infrastructure generation through templating rather than static configuration files.
Compared to similar skills
kcli-plan-authoring side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| kcli-plan-authoring (this skill) | 0 | 4mo | Review | Advanced |
| iot-engineer | 0 | 4mo | No flags | Advanced |
| azure-mgmt-apicenter-py | 0 | 5mo | Review | Intermediate |
| ansible-fix | 0 | 5mo | Review | Beginner |
Try saying
Example prompts that trigger this skill in your AI assistant.
More by karmab
View all by karmab →You might also like
iot-engineer
Sneha-1608
Use when designing and deploying IoT solutions requiring expertise in device management, edge computing, cloud integration, and handling challenges like massive device scale, complex connectivity scenarios, or real-time data pipelines.
azure-mgmt-apicenter-py
bika11
|
ansible-fix
diegosouzapw
ALWAYS use this skill immediately after running 'ansible-galaxy init' to create a new Ansible role. Also use when the user asks to fix ansible-lint errors or when ansible-lint output shows fixable issues like yaml[comments], schema[meta], meta-incorrect, name[play], or role-name[path] violations.
ops
denniszielke
>
azure-functions
aj-geddes
Create serverless functions on Azure with triggers, bindings, authentication, and monitoring. Use for event-driven computing without managing infrastructure.
ml-pipeline-workflow
wshobson
Build end-to-end MLOps pipelines from data preparation through model training, validation, and production deployment. Use when creating ML pipelines, implementing MLOps practices, or automating model training and deployment workflows.