What are Managed Resources in Crossplane?
Quick Answer
Managed Resources are Crossplane's representation of individual cloud infrastructure resources as Kubernetes custom resources. Each Managed Resource maps one-to-one to an external cloud resource like an S3 bucket, an RDS database, or a GCP Cloud SQL instance, and the Crossplane controller continuously reconciles its desired state with the actual state in the cloud.
Detailed Answer
Think of a Managed Resource like a reservation card at a restaurant. You fill out the card with your preferences: table for four, by the window, at 7 PM. You hand the card to the host (Kubernetes API server), and the host passes it to the restaurant manager (Crossplane controller) who actually arranges the table. If someone moves your table, the manager notices and puts it back. The card is your declaration of what you want, and the manager ensures reality matches.
A Managed Resource (MR) is the most granular unit of infrastructure in Crossplane. Each MR corresponds to exactly one external resource in a cloud provider. An S3 Bucket MR maps to one S3 bucket in AWS, an RDS Instance MR maps to one RDS database instance, a CloudSQL Instance MR maps to one Cloud SQL database in GCP. When you create a Managed Resource by applying its YAML manifest, the Crossplane provider controller calls the cloud API to create the corresponding resource. The MR's status section is then updated with the external resource's actual attributes, such as its ARN, endpoint URL, and current state. For example, when the payments-api team creates an RDS Instance MR, the status will eventually show the database endpoint that the application can connect to.
The spec of a Managed Resource is divided into two main sections. The forProvider section contains the configuration that gets sent to the cloud API, things like region, instance class, storage size, and engine version. The providerConfigRef section tells the controller which ProviderConfig to use for authentication, allowing different MRs to target different cloud accounts. There is also a deletionPolicy field that controls what happens when you delete the MR from Kubernetes. Setting it to Delete means the external resource is destroyed when the MR is deleted, which is the default. Setting it to Orphan means the external resource is left untouched in the cloud even after the MR is removed from the cluster, which is useful during migrations or when you want to decommission the Crossplane management of a resource without destroying the actual infrastructure that the order-processing-service depends on.
Crossplane continuously reconciles each Managed Resource with its external counterpart. The controller checks the external resource's state at regular intervals, typically every few minutes, and compares it against the desired state in the MR's spec. If there is drift, for example if someone manually changed the instance class of the user-auth-service database through the AWS console, Crossplane detects this and reverts the change to match the spec. This drift detection and correction is one of the most powerful features of Crossplane, as it ensures that infrastructure configuration defined in Git remains the source of truth even when humans or other tools make ad-hoc changes.
Managed Resources also support cross-resource references through the ref and selector patterns. For instance, an RDS Instance can reference a SubnetGroup and SecurityGroup by name, and Crossplane resolves these references to the actual cloud resource IDs before making the API call. This is analogous to how Kubernetes Services reference Pods through label selectors. For the checkout-service team provisioning a full database stack, they create a SubnetGroup MR, a SecurityGroup MR, and an Instance MR that references the other two. Crossplane handles the dependency ordering automatically, creating the subnet group and security group before attempting to create the database instance.