Crossplane resources are just Kubernetes Custom Resources (CRs), and Argo CD is designed to manage Kubernetes CRs. So, managing Crossplane resources with Argo CD is as straightforward as managing any other Kubernetes application.

Let’s see it in action.

Imagine you have a Crossplane CompositeResourceDefinition (XRD) that defines a Composite resource called RDSInstance. You want to provision an RDSInstance that represents a PostgreSQL database.

First, your Crossplane installation needs to be configured to talk to your cloud provider (e.g., AWS). This involves creating a ProviderConfig resource.

apiVersion: aws.upbound.io/v1beta1
kind: ProviderConfig
metadata:
  name: default
spec:
  credentials:
    source: Secret
    secretRef:
      namespace: crossplane-system
      name: aws-credentials
      key: credentials

Next, you define the CompositeResourceDefinition (XRD) for your RDSInstance. This tells Crossplane what a RDSInstance is.

apiVersion: apiextensions.crossplane.io/v1
kind: CompositeResourceDefinition
metadata:
  name: rdsinstances.rds.example.com
spec:
  group: rds.example.com
  names:
    kind: RDSInstance
    plural: rdsinstances
  versions:
    - name: v1alpha1
      served: true
      referenceable: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                parameters:
                  type: object
                  properties:
                    storageGB:
                      type: integer
                    instanceClass:
                      type: string
                  required:
                    - storageGB
                    - instanceClass
              required:
                - parameters

Now, you create a CompositeResource (XRs) of type RDSInstance. This is the actual request for a PostgreSQL database.

apiVersion: rds.example.com/v1alpha1
kind: RDSInstance
metadata:
  name: my-postgres-db
spec:
  parameters:
    storageGB: 20
    instanceClass: db.t3.micro

This RDSInstance object is a Kubernetes Custom Resource. Argo CD can track a Git repository containing these YAML manifests.

Here’s a typical Argo CD Application manifest that would point to a Git repository containing the Crossplane CRs (like ProviderConfig, XRD, and the RDSInstance XR):

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: crossplane-resources
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/your-org/your-gitops-repo.git
    path: crossplane/rds-db
    targetRevision: HEAD
  destination:
    server: https://kubernetes.default.svc
    namespace: crossplane-system # Or wherever your Crossplane CRs should live
  syncPolicy:
    automated:
      prune: true
      selfHeal: true

When Argo CD syncs this application, it will apply the ProviderConfig, XRD, and RDSInstance manifests to your Kubernetes cluster. Crossplane, watching for these resources, will then act upon the RDSInstance request. It will consult its CompositeResource definitions and the underlying Managed Resources (like AWS RDS instances) to provision the actual cloud infrastructure.

The magic is that Argo CD doesn’t need to know anything about Crossplane’s internal workings. It just sees a RDSInstance as another CustomResourceDefinition and CustomResource to manage. When you update the RDSInstance YAML in Git (e.g., change storageGB to 30), Argo CD detects the change, syncs it to the cluster, and Crossplane reacts by updating the underlying AWS RDS instance.

The mental model is simple: Git is your source of truth. Argo CD enforces that truth on your cluster. Crossplane translates your abstract, declarative cloud resource definitions into concrete cloud infrastructure.

What most people don’t realize is how deeply integrated Crossplane’s Managed Resources become with the Kubernetes API. When Crossplane provisions an AWS RDS instance, it creates a RDSInstance Managed Resource (e.g., class.aws.upbound.io/RDSInstance.v1alpha1) in your cluster. This is a distinct Kubernetes object that mirrors the state of the actual cloud resource. Argo CD then tracks both your abstract rds.example.com/RDSInstance XR and the concrete class.aws.upbound.io/RDSInstance MR. This two-level abstraction is key to Crossplane’s power.

The next step is to explore how to use Crossplane’s Composition to define the actual cloud provider resources that fulfill your composite resources.

Want structured learning?

Take the full Crossplane course →