Skip to main content
Version: v1.2.x

ProjectType

A ProjectType is the platform-engineer-defined infrastructure template for a project. It declares the namespace-scoped Kubernetes resources (the cell namespace itself, NetworkPolicies, ResourceQuotas, baseline RBAC, ImagePullSecrets) that the platform materializes in every environment a project is deployed to, along with the schemas for project-level parameters and per-environment overrides.

Developers reference a ProjectType from Project.spec.type. The Project controller inlines the type's spec into every ProjectRelease it cuts, and each ProjectReleaseBinding renders the inlined templates for its environment.

For the cluster-scoped variant, see ClusterProjectType.

API Version

openchoreo.dev/v1alpha1

Resource Definition

Metadata

ProjectTypes are namespace-scoped resources. Projects in the same namespace reference them by name.

apiVersion: openchoreo.dev/v1alpha1
kind: ProjectType
metadata:
name: <project-type-name>
namespace: <namespace>

Short names: pt, pts

Spec Fields

FieldTypeRequiredDefaultDescription
parametersSchemaSectionNo-Schema for the values project authors supply on Project.spec.parameters
environmentConfigsSchemaSectionNo-Schema for the per-environment values supplied on ProjectReleaseBinding.spec.environmentConfigs
validations[ValidationRule]No-CEL rules evaluated during rendering; all must evaluate to true for rendering to proceed
resources[ResourceTemplate]Yes-Namespace-scoped manifest templates applied to the cell namespace (min: 1). Must include the mandated v1/Namespace entry
note

The rendered output of resources must include a v1/Namespace object whose metadata.name is the literal ${metadata.namespace} placeholder. The check runs against the rendered output, so an includeWhen that suppresses the entry also fails it. A missing namespace surfaces on the binding as Synced=False with reason NamespaceMissing.

SchemaSection

FieldTypeRequiredDescription
openAPIV3SchemaobjectNoSchema in standard OpenAPI V3 / JSON Schema format, with support for defaults, enums, and validation constraints

ValidationRule

FieldTypeRequiredDescription
rulestringYesA CEL expression wrapped in ${...} that must evaluate to true. Has access to the same context as resource templates
messagestringYesError message surfaced when the rule evaluates to false (min: 1)

ResourceTemplate

FieldTypeRequiredDefaultDescription
idstringYes-Unique identifier for this entry within the type (min: 1)
templateobjectYes-The Kubernetes manifest with ${...} CEL expressions evaluated at render time
includeWhenstringNo-Boolean CEL expression wrapped in ${...}; when false, the entry is omitted and any previously applied object is garbage-collected
forEachstringNo-CEL expression wrapped in ${...} yielding a list to iterate over; generates one object per item
varstringNo-Loop variable name for forEach (required when forEach is set)
targetPlanestringNodataplaneTarget plane for the rendered object: dataplane or observabilityplane

Templates have access to ${metadata.*}, ${parameters.*}, ${environmentConfigs.*}, ${environment.*}, ${dataplane.*}, and ${gateway.*}. See the Authoring ProjectTypes guide for the full CEL surface.

Status Fields

ProjectType does not report status fields. Schema validation failures surface on the referencing Project, and rendering or validation failures surface on the ProjectReleaseBinding's status.conditions.

Examples

Minimal ProjectType

The smallest valid ProjectType carries only the mandated cell-namespace entry:

apiVersion: openchoreo.dev/v1alpha1
kind: ProjectType
metadata:
name: minimal
namespace: default
spec:
resources:
- id: cell-namespace
template:
apiVersion: v1
kind: Namespace
metadata:
name: ${metadata.namespace}
labels: ${metadata.labels}

ProjectType With Quotas and Policies

apiVersion: openchoreo.dev/v1alpha1
kind: ProjectType
metadata:
name: quota-managed
namespace: default
spec:
environmentConfigs:
openAPIV3Schema:
type: object
properties:
cpuQuota:
type: string
default: "4"
memoryQuota:
type: string
default: "8Gi"
validations:
- rule: "${environmentConfigs.cpuQuota.matches('^[0-9]+$')}"
message: "cpuQuota must be an integer string"
resources:
- id: cell-namespace
template:
apiVersion: v1
kind: Namespace
metadata:
name: ${metadata.namespace}
labels: ${metadata.labels}
- id: resource-quota
template:
apiVersion: v1
kind: ResourceQuota
metadata:
name: project-quota
namespace: ${metadata.namespace}
labels: ${metadata.labels}
spec:
hard:
limits.cpu: ${environmentConfigs.cpuQuota}
limits.memory: ${environmentConfigs.memoryQuota}
- id: default-deny-egress
template:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-egress
namespace: ${metadata.namespace}
labels: ${metadata.labels}
spec:
podSelector: {}
policyTypes: [Egress]
egress: []

Usage

# List project types in a namespace
kubectl get pt -n default
occ projecttype list

# Inspect a project type
kubectl describe projecttype quota-managed -n default
occ projecttype get quota-managed

# Create or update from a manifest
occ apply -f projecttype.yaml

Best Practices

  1. Always propagate ${metadata.labels} onto every rendered object so data-plane objects carry consistent platform labels
  2. Set metadata.namespace: ${metadata.namespace} on every non-namespace entry so all objects land in the cell namespace
  3. Keep developer-facing choices in parameters and operational per-environment knobs in environmentConfigs
  4. Use validations for cross-field constraints the schema cannot express
  5. Prefer a ClusterProjectType for templates intended to be shared platform-wide