Kubernetes CustomResourceDefinition (CRD) is a Kubernetes API extension that lets you add your own resource types to a cluster. In practical terms, a CRD lets teams manage domain-specific objects, such as databases, certificates, cloud resources, backups, or application environments, using the same Kubernetes API patterns they already use for Pods, Services, and Deployments.
A CRD adds a new resource kind to the Kubernetes API. Once installed, users can create, read, update, delete, and watch that custom resource with tools such as kubectl, GitOps controllers, CI/CD pipelines, and Kubernetes clients.
For example, after installing a CRD for a managed database, you might create a resource like:
apiVersion: database.example.com/v1
kind: PostgresInstance
metadata:
name: orders-db
spec:
version: "15"
storageGB: 100
replicas: 2
Kubernetes stores this object in its API server, validates it against the CRD schema, and makes it available for controllers to act on.
A CRD defines the shape and behavior of a custom Kubernetes resource. It tells the Kubernetes API server:
database.example.com.v1alpha1, v1beta1, or v1.PostgresInstance.postgresinstances.spec and other fields.A CRD alone usually defines the API, but it does not perform actions by itself. For automation, you normally pair it with a controller or operator. The controller watches custom resources and reconciles the real system to match the desired state in the resource’s spec.
Most useful CRD-based systems follow the Kubernetes controller pattern:
spec with the actual state.status.For example, a Certificate custom resource might cause a controller to request a TLS certificate, store it in a Secret, renew it before expiry, and update status fields when issuance succeeds or fails.
CRDs are common in production Kubernetes platforms because they let teams model higher-level workflows as Kubernetes resources.
Application, Environment, or Database while platform teams handle the underlying implementation.kubectl, RBAC, admission control, audit logs, and GitOps tools with custom resources.CRDs are powerful, but they add operational responsibility. A poorly designed CRD can become hard to support across teams and cluster upgrades.
A CRD defines a new type of Kubernetes resource. A custom resource is an instance of that type.
For example:
PostgresInstance as an API type is defined by a CRD.orders-db as a specific database request is a custom resource.This is similar to the difference between a class definition and an object instance in programming, but in Kubernetes API terms.
Built-in resources, such as Pods, Services, Deployments, ConfigMaps, and Secrets, ship with Kubernetes. CRDs are added after the cluster is running.
Both can use the Kubernetes API, metadata, labels, annotations, RBAC, and watch behavior. The main difference is ownership: Kubernetes core components manage built-in resources, while custom controllers usually manage CRD-backed resources.
Say your platform team wants developers to request cloud databases without opening tickets or learning every cloud provider setting. The team can define a Database CRD with fields such as:
engine: PostgreSQL or MySQLversion: Database versionstorageGB: Requested storagebackupRetentionDays: Backup policyenvironment: dev, staging, or productionA developer commits a Database custom resource to Git. A GitOps controller applies it to the cluster. A platform controller provisions the database, creates credentials, stores connection data in a Secret, and updates the resource status.
This pattern is common with tools that manage infrastructure through Kubernetes APIs. Crossplane, for example, uses CRDs to represent cloud resources and compositions. You can see the pattern in a more complete workflow that deploys a Kubernetes app and AWS resource using Crossplane.
CRDs often sit at the boundary between application delivery and infrastructure management. Teams may install CRDs using Helm, Kustomize, GitOps, or Terraform, then manage custom resources through the same pipeline.
If your team already manages Kubernetes objects through Terraform, CRDs can become part of that workflow too. For a related approach, see how to deploy Kubernetes resources using Terraform.
A Kubernetes CRD extends the Kubernetes API with your own resource types. It is the foundation for operators, platform APIs, GitOps abstractions, and Kubernetes-based infrastructure management. Use CRDs when you want a declarative, Kubernetes-native way to manage something beyond the built-in resource types, and pair them with well-designed controllers, validation, RBAC, and upgrade planning.