Skip to main content
Version: Develop

Developer How-To Guide

This guide describes how to create and manage AWS RDS resources with Klutch, using workflows that mirror familiar Kubernetes objects (for example, Deployments). It is intended for application developers who need practical, example-driven instructions for provisioning and operating Klutch-backed AWS RDS managed databases.

This guide covers:

  • Provision an Instance — YAML example, required fields, and recommended best practices.
  • Creating a Service Binding — how to create and use bindings and what the generated secret contains.
  • Inject Secret to Applications — how to inject the binding secret into a deployment.
  • Upgrade and Scale — concise guidance for engine upgrades, resource scaling.
  • Configure Parameter Groups — tune PostgreSQL settings using spec.config.parameterGroup.
  • Backup and Restore — manual backups, scheduled backups, and restore workflows.
  • Cleanup - safe deletion

Prerequisites

Before starting, ensure the following:

  • kubectl is installed and configured to access your application cluster.
  • All required Klutch RDS prerequisites have been completed.

Provision an Instance

To provision an AWS RDS service instance, create a Service Instance Claim to your Kubernetes cluster. The following template can be used as a starting point:

apiVersion: rds.aws.anynines.com/v1
kind: <ResourceType>
metadata:
name: my-resource
spec:
serviceVersion: # e.g. "17.5"
plan: # e.g. "single-nano"
info

Both serviceVersion and plan are required fields, and additional optional fields can be used to customize the instance. This guide uses PostgreSQL as the example, which is currently the only supported service; for a full list of optional fields, refer to the PostgreSQL managed database reference.

Below is the PostgreSQL reference example to illustrate the workflows:

cat <<'EOF' > basic-instance-example.yaml
apiVersion: rds.aws.anynines.com/v1
kind: PostgresqlInstance
metadata:
name: example-basic-instance
spec:
serviceVersion: "17.5"
plan: "single-nano"
EOF

Apply the above YAML manifest to create a PostgreSQL instance on AWS:

kubectl apply -f basic-instance-example.yaml

After applying the manifest, please allow some time for the remote resources to be deployed.

Check that the instance was created successfully:

kubectl get postgresqlinstances.rds.aws.anynines.com

Example output:

NAME                     SYNCED   READY   CONNECTION-SECRET     AGE
example-basic-instance True True 10s
info

The CONNECTION-SECRET field will remain empty because Klutch uses Service Bindings to generate connection secrets, rather than relying on Crossplane’s default secret creation mechanism.

If you want to see more details about the resource (e.g. the actual name of instance on AWS) you can use the command below and look for the status field.

kubectl describe postgresqlinstances.rds.aws.anynines.com example-basic-instance

Create a Service Binding

The ServiceBinding Custom Resource provides a way to start using the database. When you create a service binding:

  • A new database user is automatically created.
  • The user credentials and other connection information are stored in a Kubernetes Secret.

Each time a new service binding is created, a new database user is generated and the corresponding connection details are stored in its own secret.

To target a specific service instance, set the spec.instanceRef field in service binding resource manifest.

Optional: If you've followed the example from the previous step, where we created a PostgreSQL Kubernetes Object, you can now proceed to apply the yaml manifest provided in the Example tab below.

  apiVersion: rds.aws.anynines.com/v1
kind: ServiceBinding
metadata:
name: <name>
namespace: <namespace>
spec:
instanceRef: <postgresql-instance-name>
serviceInstanceType: # e.g. postgresql

Deploy the resource:

kubectl apply -f <your-file-name>

Once the ServiceBinding becomes ready (typically within seconds), a secret is automatically created in the same namespace. The secret is named {service-binding-name}-service-binding and contains the database credentials required to access the instance. You can view the credentials by describing the secret using:

kubectl get secret example-basic-instance-sb-service-binding -o yaml

Example output:

apiVersion: v1
data:
username: <base64 encoded value>
password: <base64 encoded value>
dbname: <base64 encoded value>
endpoint: <base64 encoded value>
...

Inject Secret to Application Deployment

After creating the ServiceBinding resource, a secret containing the database connection details is automatically generated. The next step is to reference these secret fields in your application so your application can connect to the database.

An example deployment manifest demonstrating how to use the secret fields as environment variables is shown below:

  apiVersion: apps/v1
kind: Deployment
...
spec:
template:
spec:
containers:
- name: my-app
image: my-app-image
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: <service-binding-name>-service-binding
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: <service-binding-name>-service-binding
key: password
- name: DB_NAME
valueFrom:
secretKeyRef:
name: <service-binding-name>-service-binding
key: dbname
- name: DB_ENDPOINT
valueFrom:
secretKeyRef:
name: <service-binding-name>-service-binding
key: endpoint
...

Upgrade and Scale

Once the database instance is ready, you can update its configuration to upgrade or scale the service. Configuration changes are forward-only: resources can be increased, but not reduced.

You may update different configuration fields independently. For example, you can:

  • upgrade the service plan (e.g., move from a single-instance plan to a clustered plan), and/or
  • increase the allocated storage size.

These changes are not coupled; storage can be increased without changing the plan, and the plan can be changed without modifying storage. The example below demonstrates updating both fields, but other configuration fields can also be updated.

Below is an example showing how to update the plan and increase the allocated storage size:

  apiVersion: rds.aws.anynines.com/v1
kind: PostgresqlInstance
metadata:
name: example-basic-instance
spec:
serviceVersion: "17.5"
plan: "cluster-nano"
config:
compute:
allocatedStorage: 40
replicas:
count: 1

For detailed information on which fields are available to upgrade or scale, see the PostgreSQL managed database reference.

Configure Parameter Groups

You can tune PostgreSQL runtime settings using spec.config.parameterGroup on the PostgresqlInstance resource.

apiVersion: rds.aws.anynines.com/v1
kind: PostgresqlInstance
metadata:
name: <instance-name>
spec:
serviceVersion: "17.5"
plan: "single-small"
config:
parameterGroup:
maxConnections: <integer>
sharedBuffers: <mib>
additionalParameters:
- name: <parameter-name>
value: "<value>"
applyMethod: immediate

Supported typed parameter fields:

FieldDescriptionInput unit / valuesAWS parameter name
maxConnectionsMaximum number of concurrent connectionsinteger, 5-65535max_connections
idleInTransactionSessionTimeoutIdle transaction timeoutmilliseconds, >= 0idle_in_transaction_session_timeout
statementTimeoutStatement execution timeoutmilliseconds, >= 0statement_timeout
sharedBuffersPostgreSQL shared buffersMiB, >= 1shared_buffers
workMemPostgreSQL work memoryMiB, >= 1work_mem
maintenanceWorkMemPostgreSQL maintenance work memoryMiB, >= 1maintenance_work_mem
effectiveCacheSizePlanner cache size estimateMiB, >= 1effective_cache_size
maxWalSendersMaximum WAL sender processesinteger, >= 0max_wal_senders
maxReplicationSlotsMaximum replication slotsinteger, >= 0max_replication_slots
walKeepSizeWAL retained for standbysMB, >= 0wal_keep_size
logConnectionsLog successful connectionsbooleanlog_connections
logDisconnectionsLog disconnected sessionsbooleanlog_disconnections
logMinDurationStatementMinimum duration before statement loggingmilliseconds, >= -1log_min_duration_statement
rdsForceSSLRequire SSL connectionsbooleanrds.force_ssl
rdsLogicalReplicationEnable logical replicationbooleanrds.logical_replication
rdsLogRetentionPeriodRetain PostgreSQL logs in RDSminutes, 1-10080rds.log_retention_period

Notes:

  • additionalParameters is the escape hatch for parameters not exposed as typed fields.
  • Each additionalParameters entry requires name and value, and supports optional applyMethod (immediate or pending-reboot).
  • Memory-related typed fields are entered in MiB and translated to the units expected by AWS.

This table is a quick reference for common parameters. For the canonical schema, complete field set, and validation rules, see PostgreSQL managed database fields.

Backup and Restore

Klutch supports both manual and scheduled backups, and two restore modes (from backup and point-in-time restore).

Create Backups

cat <<'EOF' > backup-claim.yaml
apiVersion: rds.aws.anynines.com/v1
kind: Backup
metadata:
name: example-basic-instance-backup
namespace: default
spec:
instanceRef: example-basic-instance
instanceType: "postgres"
EOF
kubectl apply -f backup-claim.yaml
kubectl get backups.rds.aws.anynines.com -n default

Restore From a Backup

Use one of backupName or backupARN.

note

fromBackup.plan is required for restore-from-backup operations and must be equal to or greater than the plan of the source primary instance.

cat <<'EOF' > restore-from-backup.yaml
apiVersion: rds.aws.anynines.com/v1
kind: Restore
metadata:
name: example-basic-instance-restore
namespace: default
spec:
instanceType: "postgresql"
restoredInstanceName: example-basic-instance-restored
fromBackup:
backupName: example-basic-instance-backup
backupType: "manual"
plan: single-nano
EOF
kubectl apply -f restore-from-backup.yaml
kubectl get restores.rds.aws.anynines.com -n default

Point-In-Time Restore

Use one of latestRestoreTime or restoreTime.

note

For point-in-time restore (PITR), a restore plan is not required.

cat <<'EOF' > restore-pitr.yaml
apiVersion: rds.aws.anynines.com/v1
kind: Restore
metadata:
name: example-basic-instance-pitr
namespace: default
spec:
instanceType: "postgresql"
restoredInstanceName: example-basic-instance-pitr-restored
pointInTime:
instanceRef: example-basic-instance
latestRestoreTime: true
EOF
kubectl apply -f restore-pitr.yaml
kubectl get restores.rds.aws.anynines.com -n default

You can inspect restore status details with:

kubectl get restores.rds.aws.anynines.com <restore-name> -n <namespace> -o yaml

Cleanup

Deleting resources works the same way as with any other Kubernetes object. If you have created both a Service Instance and a Service Binding, you can delete them using the following command:

kubectl delete <resource-type> <resource-name>

It is recommended to delete the resources in the reverse order of creation, first the Service Binding, then the Service Instance.