Crossplane can provision AWS RDS instances using its managed resources, abstracting away direct AWS API calls and enabling GitOps workflows.
Let’s see this in action. Imagine we want to provision a PostgreSQL RDS instance. Here’s a simplified RDSInstance custom resource definition (CRD) that Crossplane understands:
apiVersion: rds.aws.upbound.io/v1beta1
kind: RDSInstance
metadata:
name: my-postgres-db
spec:
region: us-east-1
engine: postgres
engineVersion: "13.4"
instanceClass: db.t3.micro
allocatedStorage: 20
username: adminuser
# Password management is crucial, often handled via a Kubernetes Secret
masterPasswordSecretRef:
name: rds-master-password
namespace: default
# Network configuration (VPC, Subnet Groups) is also essential
# ...
When you apply this YAML to your Kubernetes cluster where Crossplane is installed, Crossplane’s AWS provider observes this RDSInstance resource. It then translates this desired state into the corresponding AWS API calls to create an RDS instance with the specified parameters.
The problem Crossplane solves here is the management of cloud infrastructure as code, directly from Kubernetes. Instead of using Terraform, CloudFormation, or the AWS console, you declare your RDS instance as a Kubernetes object. Crossplane’s role is to reconcile the state of this Kubernetes object with the actual state of the AWS resource. If the RDSInstance object in Kubernetes says instanceClass: db.t3.micro, Crossplane ensures that the corresponding AWS RDS instance has that db.t3.micro instance class. If someone manually changes the instance class in the AWS console, Crossplane will detect the drift and revert it back to db.t3.micro to match the desired state in Kubernetes.
Internally, Crossplane uses a provider (in this case, the AWS provider) to communicate with the cloud API. The AWS provider for Crossplane knows how to translate the fields in the RDSInstance CRD into the parameters for the AWS RDS CreateDBInstance API call. It also watches for changes to the actual RDS instance in AWS and updates the RDSInstance Kubernetes object’s status accordingly. This reconciliation loop is the heart of Crossplane’s infrastructure management.
The exact levers you control are the fields within the spec of the RDSInstance CRD. You define the region, engine (e.g., postgres, mysql, sqlserver), engineVersion, instanceClass (e.g., db.t3.micro, db.r5.large), allocatedStorage in GiB, username, and crucially, how the masterPassword is handled. For production, you’d also configure vpcSecurityGroupIDs, dbSubnetGroupName, publiclyAccessible, backupRetentionPeriod, and skipFinalSnapshot. These map directly to AWS RDS configuration options, allowing fine-grained control through Kubernetes YAML.
A common point of confusion is how Crossplane handles secrets like database passwords. You don’t put the password directly in the RDSInstance CRD. Instead, you create a Kubernetes Secret object containing the password and then reference that Secret using masterPasswordSecretRef. Crossplane then reads the password from the Secret and passes it to the AWS API when creating the RDS instance. This leverages Kubernetes’ built-in secret management for sensitive data.
The next concept you’ll likely encounter is managing network resources like VPCs, subnets, and security groups, which are prerequisites for a functional RDS instance and can also be provisioned by Crossplane.