Skip to main content
The cpln convert command transforms Kubernetes manifests into Control Plane resources, enabling seamless migration from Kubernetes environments.

When to use this

Kubernetes migration

Migrate existing K8s workloads, secrets, and storage to Control Plane

Reuse existing manifests

Leverage your existing Kubernetes YAML files without rewriting them

Preview conversions

See how K8s resources translate to Control Plane before applying

CI/CD integration

Convert and apply K8s manifests in automated pipelines

Supported resources

Workload conversions

How workload type is determined

The converter analyzes your Kubernetes spec to automatically select the appropriate Control Plane workload type:
Job and CronJob resources always become cron workloads.
  • CronJobs preserve their schedule from spec.schedule
  • Jobs use a default schedule of * * * * * (every minute)
The workload becomes stateful if any container mounts a volumeset (from PersistentVolumeClaim or volumeClaimTemplates).Stateful takes precedence over standard when both conditions are met.
All non-cron workloads start as standard. The type remains standard unless a stateful condition is detected. Conditions that explicitly confirm standard:
  • A container has no ports or more than one port
  • A container uses gRPC health probes (liveness or readiness)
  • The workload has rollout options (from K8s strategy, updateStrategy, minReadySeconds, or podManagementPolicy)

Secret and config conversions

Storage conversions

Domain conversions

How secrets are converted

Kubernetes Secrets are converted based on their type field:
ConfigMaps are always converted to dictionary secrets, with all key-value pairs preserved. If a secret has both data and stringData fields, it is always converted to dictionary with both merged.

How volumesets are configured

PersistentVolumeClaims are converted to volumesets with these settings: High-performance SSD detection: If the StorageClass parameters contain any of these values, the volumeset uses high-throughput-ssd:
  • AWS: io1, io2
  • GCP: pd-extreme
  • Azure: UltraSSD_LRS
  • VMware: thick
  • Other: fast, persistent_1

How domains are converted

Kubernetes Ingresses are converted to Control Plane Domains. The converter maps Ingress rules (host + paths) to domain routes, resolving backend Services to workloads.

Field mapping

Path type handling

Service-to-workload resolution

The converter resolves each Ingress backend to a Control Plane workload through the following steps:
1

Find the Service

The converter locates the Kubernetes Service referenced by the Ingress backend’s service.name.
2

Match the workload

The Service’s selector labels are matched against workload pod template labels to find the target workload.
3

Resolve the port

The Service port’s targetPort is resolved to the actual container port:
  • Numeric targetPort — used directly as the container port
  • Named targetPort — resolved by matching the port name in the container spec
  • No targetPort — falls back to the Service port number

Domain defaults

All converted domains use these fixed settings:

Wildcard and apex domain merging

When an Ingress contains rules for both example.com and *.example.com, the converter merges them into a single domain named example.com with acceptAllSubdomains: true. Routes from both rules are combined and deduplicated.
Domains with acceptAllSubdomains enabled require a Dedicated Load Balancer on the target GVC.

GVC context

If a --gvc is provided, workload links use it directly (e.g., //gvc/my-gvc/workload/api). Otherwise, the converter inserts a {{GVC}} placeholder that you must replace before applying.

Auto-generated resources

When workloads reference secrets (via environment variables or volume mounts), the converter automatically creates:
  1. Identity - Named identity-{workload-name}, linked to the workload
  2. Policy - Named policy-{workload-name}, granting reveal permission on referenced secrets
This ensures workloads can access their secrets without manual policy configuration.

Firewall and public exposure

The converter analyzes your Kubernetes Services and Ingresses to determine if a workload should be publicly accessible:
All workloads have external outbound traffic allowed by default (0.0.0.0/0).

Informational resources

These Kubernetes resources are not directly converted but inform the conversion:

Basic usage

This outputs the converted Control Plane resources to stdout.

Options

How port protocol is inferred

When you don’t specify --protocol, the converter automatically infers the protocol for each container port using a multi-level strategy (in priority order):
1

Service appProtocol (highest priority)

If a Kubernetes Service explicitly declares appProtocol on a port that targets this container, that protocol is used.
2

Service port name prefix

The converter checks if any Service port targeting this container has a name with a protocol prefix.
3

Container port name prefix

The container’s own port name is checked for protocol prefixes.
4

Health probe type

If the port has a liveness or readiness probe, the probe type determines the protocol:
  • grpc probe → gRPC
  • httpGet probe → HTTP
  • tcpSocket probe → TCP
5

Well-known port number (lowest priority)

Common port numbers are mapped to their typical protocols. See the tables below.

Recognized protocol prefixes

Port names starting with these prefixes are automatically mapped:

Well-known port mappings

These port numbers are automatically assigned protocols when no other signal is available:
If no protocol can be inferred, the converter defaults to tcp.

Example conversion

1

Create a Kubernetes manifest

Create a file named k8s.yaml:
k8s.yaml
2

Convert the manifest

3

Apply the converted resources

Convert and apply in one command:
Or pipe the conversion output:

More conversion examples

A simple Deployment with one HTTP port becomes standard (the default type):
k8s-deployment.yaml
Converts to a standard workload (the default type for all non-cron, non-stateful workloads).

Override protocol inference

To bypass automatic protocol inference and set a specific protocol for all ports, use the --protocol flag:

Verbose mode

Use --verbose to see which K8s properties were converted and which were ignored:
Ignored properties are highlighted in yellow and marked with (ignored).

Delete converted resources

To remove resources that were applied from a K8s manifest:

Troubleshooting

Some Kubernetes resources don’t have direct Control Plane equivalents. Use --verbose to see which properties are ignored during conversion.
ConfigMaps are converted to dictionary secrets. Reference them in your workload using environment variables or volume mounts pointing to the secret.
HorizontalPodAutoscaler settings inform the workload’s autoscaling configuration. Check the converted workload’s defaultOptions.autoscaling section.
Services are used to inform port mappings but don’t create standalone resources. Ports are configured directly on the workload’s container spec.
PersistentVolumeClaims are converted to volumesets. Ensure the PVC is referenced by a StatefulSet’s volumeClaimTemplates for proper conversion.
Ingress conversion requires the referenced Services and their matching workloads (Deployments, StatefulSets, etc.) to be present in the same file. The converter uses the Service selector to find the target workload by matching pod template labels.
Ingress backend Services must have a selector defined so the converter can resolve which workload the Service targets. Services without selectors (e.g., ExternalName services) are not supported for domain conversion.

Next steps

Apply YAML Manifests

Learn more about applying resources

Delete Resources

Remove resources from Control Plane

Workload Reference

Understand workload configuration

Convert Command Reference

Convert command reference