Skip to content
Service Type Definitions

Service Type Definitions

This enhancement defines standardized schemas for DCM service types to enable cross-platform portability.

Summary

This ADR defines provider-agnostic schemas for DCM service types. These schemas enable Service Providers to provision six core service types — virtual machines, containers, databases, Kubernetes clusters, standalone storage, and network services — across different infrastructure platforms without vendor lock-in. The key principle is portability first: schemas contain only minimal fields common across all implementations, with platform-specific configuration delegated to provider_hints.

Motivation

Define a generic schema structure that ensures portability across infrastructure platforms while allowing extensibility for platform-specific optimizations without breaking compatibility.

Goals

  • Define a generic schema that works for any service_type, ensure portability, and allows extensibility without schema changes.
  • Define an initial set of six primary service types applying this pattern:
    • VM
      Virtual machines with compute, storage, and OS specifications
    • Container
      Containerized workloads running on any container platform
    • Kubernetes Cluster
      Kubernetes Container Platform of any distribution (Kubernetes, OpenShift, EKS, AWS, GKE, etc.)
    • Database
      Database services with various engines (PostgreSQL, MySQL, etc.)
    • Storage
      Standalone persistent volumes decoupled from compute service types
    • Network
      Standalone network interfaces for exposing workloads

Non-Goals

  • Allow runtime editability through API operations so administrators can create and modify templates without code changes
  • Tooling to validate Service Provider compliance with catalog schemas (conformance test suites, reference implementations, automated validation frameworks)
  • Migration strategies for breaking schema changes
  • Provider-specific implementation details (each provider handles translation independently)
  • Additional service types beyond VMs, containers, databases, Kubernetes clusters, standalone storage and networking interfaces (deferred to future phases)
  • Standalone storage volumes are supported via the storage service type; disk size on VMs and ephemeral allocation on containers remain bundled with compute where applicable.
  • Multiple service type schema versions. Initial release supports only the current schema version; service type versioning deferred to future phases.

Proposal

Implementation Details/Notes/Constraints

All schemas use OpenAPI 3.1.0 to leverage JSON Schema features like contains for array validation.

Generic Service

All service schemas share common fields defined once in common.yaml

Schema Structure

FieldRequiredTypeDescriptionReadOnly
service_typeYesstringService type identifier (vm, container, database, cluster, storage, network)No
metadataYesMetadataService identification and labelsNo
provider_hintsNoProviderHintsPlatform-specific configurationNo
idNostringUnique identifier for the resourceYes
statusNostringCurrent state of the resourceYes
pathNostringResource path or locationYes
status_messageNostringMessage providing details about the current statusYes
create_timeNodate-timeTimestamp when the resource was createdYes
update_timeNodate-timeTimestamp when the resource was last updatedYes

Metadata Object

FieldRequiredTypeDescription
nameYesstringUnique service name identifier
labelsNomap[string]stringKey-value pairs for tagging and organization (e.g., environment: production, owner: platform-team)

ProviderHints Object

FieldRequiredTypeDescription
<provider-name>Nomap[string]anyProvider-specific configuration keyed by provider identifier (e.g., kubevirt, vmware, openstack)

provider_hints is key to portability: providers use hints they recognize and ignore the rest. This means catalog offering using only common fields (vcpu, memory, guest_os) can be provisioned by any compatible provider. The provider_hints section allows adding platform-specific optimizations: providers use hints they recognize and silently ignore the rest, so the same catalog item remains portable across platforms.

Specific services

Any service_type can be defined by inheriting from common.yaml and adding type-specific fields. For the first milestone, DCM will support the following service_types:

  • Virtual Machine
    Virtual machines with CPU, memory, storage, and OS specifications
  • Container
    Fields common to Kubernetes, Docker, Podman, Openshift, CRI-O, containerd
  • Cluster
    Fields common to Kubernetes, OpenShift, EKS, GKE, AKS, and other distributions
  • Database
    Fields common across all database types (SQL, NoSQL, search, time-series, etc.)
  • Storage
    Standalone persistent volumes (capacity, access mode) independent of compute
  • Network
    Standalone network interfaces for exposing workloads

Virtual Machine

The following sections detail the VM schema architecture.

    flowchart TD
    SC[(Service Catalog)]
    API[Service Provider API]

    subgraph SP [Service Provider]
        direction LR
        KV[KubeVirt]
        VW[VMware]
        OS[OpenStack]
        AWS[AWS EC2]
    end

    Note_Reg

    Note_Trans@{ shape: card, label: "Each provider translates
the catalog item to its
native resource format" }

    SC --> API
    API --> SP

    Note_Reg -.- SP
    Note_Trans -.-> KV
    Note_Trans -.-> VW
    Note_Trans -.-> OS
    Note_Trans -.-> AWS
  

Schema

For easier review, the schema is accessible here vmspec.yaml.
Plus common fields: service_type, metadata, provider_hints

FieldRequiredTypeDescription
vcpuYesVcpuVirtual CPU configuration
memoryYesMemoryMemory configuration
storageYesStorageStorage configuration
guest_osYesGuestOSOperating system specification
accessNoAccessVM access configuration

VM vcpu Object

FieldRequiredTypeDescription
countYesintegerNumber of virtual CPUs

VM memory Object

FieldRequiredTypeDescription
sizeYesstringMemory size with unit (e.g., 8GB, 16GB)

VM storage Object

FieldRequiredTypeDescription
disksYesarray[Disk]List of disks; must include one named boot

Disk names must be unique within the VM.

VM disk Object

FieldRequiredTypeDescription
nameYesstringDisk identifier; root volume must be named boot
capacityYesstringDisk capacity with unit (e.g., 100GB, 2TB)

VM guest_os Object

FieldRequiredTypeDescription
typeYesstringOS identifier (e.g., rhel-9, ubuntu-22.04, windows-server-2022)

VM access Object

FieldRequiredTypeDescription
ssh_public_keyNostringSSH public key for VM access

Containers

The following sections detail the Container schema architecture.

Schema

For easier review, the schema is accessible here containerspec.yaml.
Plus common fields: service_type, metadata, provider_hints

FieldRequiredTypeDescription
imageYesImageContainer image specification
resourcesYesResourcesCPU and memory limits
processNoProcessProcess configuration
networkNoNetworkNetwork configuration

Container image Object

FieldRequiredTypeDescription
referenceYesstringContainer image reference (e.g., quay.io/myapp:v1.2, docker.io/nginx:latest)

Container resources Object

FieldRequiredTypeDescription
cpuYesCpuCPU resource constraints
memoryYesMemoryMemory resource constraints

Container resources.cpu Object

FieldRequiredTypeDescription
minYesintegerMinimum guaranteed CPU cores
maxYesintegerMaximum allowed CPU cores

Container resources.memory Object

FieldRequiredTypeDescription
minYesstringMinimum guaranteed memory with unit (e.g., 1GB, 2GB)
maxYesstringMaximum allowed memory with unit (e.g., 2GB, 4GB)

Container process Object

FieldRequiredTypeDescription
commandNoarray[string]Entrypoint override
argsNoarray[string]Arguments to the entrypoint
envNoarray[EnvVar]Environment variables

Container env Object

FieldRequiredTypeDescription
nameYesstringEnvironment variable name
valueYesstringEnvironment variable value

Container network Object

FieldRequiredTypeDescription
portsYesarray[Port]Ports to expose

Container port Object

FieldRequiredTypeDescription
container_portYesintegerPort number to expose (e.g., 8080, 443)
visibilityYesstringPort visibility: none, internal, or external

The visibility field controls how the port is exposed by the Service Provider:

  • none — the port is not exposed via any networking abstraction (no Service created for this port)
  • internal — the port is exposed within the cluster (e.g., ClusterIP Service in Kubernetes)
  • external — the port is exposed externally (e.g., LoadBalancer or NodePort Service in Kubernetes)

Database

The following sections detail the Database schema architecture.

Schema

For easier review, the schema is accessible here databasespec.yaml.
Plus common fields: service_type, metadata, provider_hints

FieldRequiredTypeDescription
engineYesstringDatabase engine type (e.g., postgresql, mysql, mariadb)
versionYesstringEngine version (e.g., 15, 8.11, 8.0)
resourcesYesResourcesCompute and storage resources
replicasNointegerNumber of replicas to create (default 1)
networkNoNetworkNetwork configuration

Database resources Object

FieldRequiredTypeDescription
cpuYesCpuCPU resource constraints
memoryYesMemoryMemory resource constrains
storageYesstringStorage size with unit (e.g., 100GB, 2TB)

Note: The resources are per replica, not per database instance

Database resources.cpu Object

FieldRequiredTypeDescription
minYesstringMinimum guaranteed CPU cores with or without unit (e.g. 500m, 1)
maxYesstringMaximum allowed CPU cores with or without unit (e.g. 500m, 1)

Database resources.memory Object

FieldRequiredTypeDescription
minYesstringMinimum guaranteed memory with unit (e.g., 1GB, 2GB)
maxYesstringMaximum allowed memory with unit (e.g, 2GB, 4GB)

Database network Object

FieldRequiredTypeDescription
portNointegerPort for the database to listen on
visibilityNostringDatabase visibility: internal, external

The visibility field controls how the database’s port is exposed by the Service Provider:

  • internal - the port is exposed within the Service Provider’s platform (For Kubernetes, creates only a Service resource of ClusterIP type)
  • external - the port is exposed externally (For Kubernetes, creates a Service resource of LoadBalancer or NodePort type)

Kubernetes Cluster

The cluster schema works across all Kubernetes distributions: OpenShift, EKS, GKE, AKS, etc.

Schema

For easier review, the schema is available here: clusterspec.yaml.
Plus common fields: service_type, metadata, provider_hints

FieldRequiredTypeDescription
versionYesstringKubernetes version (e.g., 1.29, 1.30)
nodesYesNodesNode pool configuration

Cluster nodes Object

FieldRequiredTypeDescription
control_planeYesControlPlaneControl plane node configuration
workerYesWorkerWorker node configuration

Cluster control_plane Object

FieldRequiredTypeDescription
countYesintegerNumber of control plane nodes (1, 3, or 5)
cpuYesintegerNumber of CPUs per node
memoryYesstringMemory per node with unit (e.g., 16GB, 32GB)
storageYesstringStorage per node with unit (e.g., 120GB, 500GB)

Cluster worker Object

FieldRequiredTypeDescription
countYesintegerNumber of worker nodes
cpuYesintegerNumber of CPUs per node
memoryYesstringMemory per node with unit (e.g., 8GB, 16GB)
storageYesstringStorage per node with unit (e.g., 120GB, 500GB)

Storage

The following sections detail the Storage schema architecture for standalone persistent volumes. See k8s-storage-sp for the Kubernetes reference Service Provider implementation.

Schema

Plus common fields: service_type, metadata, provider_hints

FieldRequiredTypeDescription
capacityYesstringVolume size with unit (e.g., 100Gi, 1TB)

Storage provider_hints (kubernetes)

Platform-specific PVC settings may be supplied under provider_hints.kubernetes:

FieldRequiredTypeDescription
storage_classNostringKubernetes StorageClass name
volume_modeNostringFilesystem (default) or Block
access_modeNostringPVC access mode: ReadWriteOnce (default), ReadOnlyMany, ReadWriteMany

When access_mode is omitted, the Service Provider applies a platform default (typically ReadWriteOnce for block storage).

Note: access_mode is Kubernetes-specific because it controls both attachment scope (single node vs. multiple nodes vs. single pod) and permissions (read-write vs. read-only) at PVC creation time. Other storage platforms handle attachment and permissions differently (e.g., AWS EBS sets multi-attach capability via volume type; GCP Persistent Disk sets mode at attach time). The CatalogItem admin configures this field based on the backend capabilities (e.g., Ceph RBD only supports ReadWriteOnce; CephFS only supports ReadWriteMany).

Network

The network schema defines load balancing and service discovery resources for providing network access to workloads. Unlike managing networking as part of compute resources, this service type treats network services as first-class resources.

When to Use Standalone Network

The network service type creates network resources independently from workloads.

Use standalone network when:

  • Exposing existing workloads that were created without network configuration
  • Managing network lifecycle independently from workload lifecycle
  • Creating endpoints for manually-managed pods or external resources

Use visibility field when:

  • Creating a new workload that needs immediate network exposure
  • Network resource should be tied to workload lifecycle (created/deleted together)
FieldRequiredTypeDescription
portsYesarray[Port]Ports to expose
routingLevelNostringWhether traffic is handled at the transport level (TCP/UDP) or application level (HTTP/HTTPS)

Network port Object

FieldRequiredTypeDescription
nameNo*stringPort name. *Required when using providerHints.kubernetes.nodePorts. Must be DNS-compatible (RFC 1035). Pattern: ^[a-z0-9]([-a-z0-9]*[a-z0-9])?$
protocolNostringProtocol (TCP, UDP, SCTP). Default: TCP
portYesintegerService port (1-65535)
targetPortYesintegerTarget pod port (1-65535)

Note: When using providerHints.kubernetes.nodePorts, all ports must have unique name fields. The keys in nodePorts must match these port names.

routingLevel

Specifies whether traffic is handled at the transport level (TCP/UDP) or the application level (HTTP/HTTPS). When omitted, creates a basic service without external routing infrastructure.

  • Default: omitted (no external routing)
  • Values:
    • network: Transport-level traffic handling (TCP/UDP)
    • application: Application-level traffic handling (HTTP/HTTPS) with routing capabilities
    • omitted: Basic service without external routing

Kubernetes Provider Hints

The Kubernetes Network Service Provider uses the following fields in providerHints.kubernetes:

FieldRequiredTypeDescription
selectorNomap[string]stringLabel selector to match target pods
clusterIPNostringSpecific cluster IP allocation or “None” for headless
nodePortsNomap[string]intMap of port names to NodePort values (30000-32767). The Kubernetes Service type is inferred from the combination of routingLevel and nodePorts presence. See Service Type Inference.

Schema Compatibility

DCM supports only the current API version for each service type. Service Providers must implement the latest schema definitions. Support for multiple service type versions is planned for future releases.

Implementation History

Drawbacks

Alternatives

Comprehensive schemas with all platform features

Description: We considered including all possible fields (CPU topology, security contexts, HA configuration, etc.) in the core schema.

Why rejected: Not all fields exist on all platforms. This would force providers to handle features they don’t support, or force users to understand which fields work where. Portability would be compromised.

Virtual Machine Alternatives

Pure OVF XML Format

Description: We considered using OVF XML directly as our catalog format. This would provide perfect alignment with the standard but creates practical problems. OVF XML is verbose with complex nested structures, XML namespaces, and numeric resource type codes (3 for CPU, 4 for memory).

Pros: Perfect standard compliance, well-understood by virtualization teams

Cons: XML complexity, poor API ergonomics, includes packaging concepts irrelevant to catalog specs

TOSCA Cloud Orchestration

Description: TOSCA (Topology and Orchestration Specification for Cloud Applications) is an OASIS standard designed specifically for cloud resource orchestration. It provides a comprehensive model with node templates, capabilities, requirements, and relationship definitions. While powerful, TOSCA introduces significant complexity with its topology-based approach. For a catalog specification that describes individual resource templates, TOSCA’s relationship modeling and orchestration features are overkill.

Pros: Purpose-built for cloud, handles complex deployments

Cons: Steep learning curve, heavyweight for simple resource specs, less tooling ecosystem

Custom Schema from Scratch

Description: We could design a completely custom schema without reference to existing standards, optimizing purely for our immediate needs. This provides maximum flexibility and simplicity initially but loses the benefit of industry knowledge embedded in standards like OVF. Provider translation becomes harder because engineers must learn our invented vocabulary rather than mapping to familiar concepts they already know from OVF, OpenStack, or other systems.

Pros: Perfect fit for current needs, no standard overhead

Cons: Reinventing solved problems, harder provider adoption, no external validation

OpenStack-Style Flavors

Description: OpenStack’s approach separates compute templates (flavors) from images. Users select a flavor (m1.small, m1.medium) and an image separately. While simple, this creates a two-level hierarchy that feels unnatural for a general catalog system. It also doesn’t handle the full richness of VM configuration, storage configuration, and network interfaces. Initialization is handled separately rather than as part of a cohesive specification.

Pros: Simple flavor model, proven in OpenStack

Cons: Limited to compute specs, doesn’t handle full VM configuration, creates artificial separation

Container Alternatives

Kubernetes Pod Specification

Description: Using Kubernetes Pod/Deployment YAML directly as the catalog format would provide immediate familiarity for Kubernetes users but creates vendor lock-in.

Pros: Familiar to Kubernetes users, rich feature set, comprehensive documentation, established ecosystem

Cons: Kubernetes-specific (incompatible with Docker/Podman standalone), includes orchestration concepts unnecessary for resource specifications, ties catalog to Kubernetes API versions, prevents portability to non-Kubernetes platforms

Compose Specification

Description: The Compose Specification provides a YAML format for defining multi-container applications, now an open specification supported by Docker, Podman, and other runtimes.

Pros: Simple and approachable, widely known format, open specification, good for multi-container applications

Cons: Designed for application composition not individual resource specifications, doesn’t map cleanly to single-container catalog items, less granular than OCI for runtime configuration, focuses on orchestration rather than resource provisioning

Containerfile Build Instructions

Description: Define containers through Dockerfile/Containerfile rather than runtime specifications.

Pros: Reproducible builds, version control friendly, defines complete container image

Cons: Build-time specification not runtime specification, requires build infrastructure in catalog system, doesn’t address runtime configuration (resources, networking, security), mixes build concerns with deployment concerns

Custom Schema

Description: Design a container schema without reference to existing standards like OCI, optimizing purely for DCM’s immediate needs.

Pros: Optimized for DCM requirements, simpler for current use cases, no standard overhead

Cons: Reinventing problems OCI already solved, harder provider adoption (engineers learn new vocabulary instead of familiar OCI concepts), no external validation, loses portability benefits, incompatible with existing container tooling

Database Alternatives

Single Cloud Provider Model

Description: Using AWS RDS, Azure Database, or Google Cloud SQL specification directly as the catalog format.

Pros: Complete feature coverage, well-documented, proven in production

Cons: Vendor lock-in, cloud-specific terminology and features, doesn’t work with on-premise or Kubernetes-based databases, prevents multi-cloud portability

Kubernetes Operator CRD

Description: Using a specific Kubernetes database operator CRD (CloudNativePG, Percona) as the standard.

Pros: Kubernetes-native, rich feature set, battle-tested

Cons: Kubernetes-specific, incompatible with cloud DBaaS providers, ties catalog to specific operator versions, doesn’t support VM-based database deployments

SQL Standard Only

Description: Focus purely on SQL standards (ANSI SQL, SQL:2016) for database specifications.

Pros: Well-established standard, vendor-neutral

Cons: Only covers query language not provisioning/infrastructure, no coverage for NoSQL databases, doesn’t address compute/storage/backup configuration, mixes application concerns with infrastructure.

Custom Schema

Description: Design database schema without reference to existing patterns.

Pros: Optimized for DCM needs, simpler initially

Cons: Reinventing patterns cloud providers and operators already solved, harder adoption, no external validation, incompatible with existing tooling and knowledge

Kubernetes Cluster Alternatives

Full install-config.yaml

Description: Using OpenShift’s complete install-config.yaml format as the catalog schema.

Pros: Comprehensive coverage of all OpenShift deployment options, official Red Hat format, well-documented

Cons: Platform-specific sections create complexity, includes infrastructure credentials and bootstrapping details inappropriate for catalog specifications, ties catalog to OpenShift installer API versions, verbose for users who just want node sizing

Cluster API (CAPI) Specification

Description: Adopting Kubernetes Cluster API CRDs as the standard for all cluster provisioning.

Pros: Kubernetes community standard, cloud-agnostic, supports multiple platforms

Cons: Still maturing as a standard, OpenShift has its own established patterns, CAPI abstractions don’t always align with OpenShift’s architecture, requires CAPI operator infrastructure

Managed OpenShift Service APIs

Description: Using cloud provider managed OpenShift APIs (ROSA for AWS, ARO for Azure) as the specification format.

Pros: Native to cloud providers, optimized for managed OpenShift services

Cons: Cloud-specific, incompatible with on-premise and self-managed OpenShift deployments, each provider has different API structure, doesn’t work with standard OpenShift IPI/UPI installations, prevents portability to vSphere or bare metal

Custom Cluster Schema

Description: Design a cluster schema without reference to existing standards or patterns.

Pros: Optimized for DCM requirements, simpler for current use cases

Cons: Ignores established OpenShift configuration patterns, harder for users familiar with install-config.yaml, no validation against industry knowledge, incompatible with existing automation and tooling

Infrastructure Needed

TBD