A Crossplane composition function for fetching Amazon RDS metrics from AWS CloudWatch and making them available in composition pipelines.
This function retrieves CloudWatch metrics for RDS database instances and writes them to pipeline context or XR status, enabling intelligent scaling decisions and monitoring workflows in Crossplane compositions.
- Dynamic Database Resolution: Supports both static database names and dynamic references to XR fields or pipeline context
- Flexible Metric Selection: Fetch default or custom CloudWatch metrics for RDS instances
- Pipeline Integration: Writes metrics to pipeline context for consumption by subsequent functions (e.g., function-claude for AI-driven scaling)
- Multiple Output Targets: Store metrics in XR status or pipeline context
apiVersion: rdsmetrics.fn.crossplane.io/v1beta1
kind: Input
spec:
# Database identifier (use either databaseName OR databaseNameRef)
databaseName: "my-rds-instance" # Static database name
databaseNameRef: "xr.metadata.name" # Dynamic reference to XR field
# AWS configuration
region: "us-west-2" # AWS region (optional, defaults to us-east-1)
# Metrics configuration
metrics: # List of CloudWatch metrics to fetch (optional)
- "CPUUtilization"
- "DatabaseConnections"
- "FreeableMemory"
- "FreeStorageSpace"
period: 300 # Data granularity in seconds (optional, default: 300)
# Output configuration
target: "context.metricsResult" # Where to store metrics (context.* or status.*)
The function supports dynamic database name resolution using references:
xr.metadata.name
- Use the XR's metadata name (common pattern for database identifiers)xr.spec.database.instanceId
- Reference nested spec fieldsxr.status.database.actualName
- Reference nested status fields
context.databaseName
- Reference pipeline context from previous functions
When no metrics are specified, the function fetches these default CloudWatch metrics:
CPUUtilization
- CPU usage percentageDatabaseConnections
- Number of active connectionsFreeableMemory
- Available memory in bytesFreeStorageSpace
- Available storage in bytesReadIOPS
- Read I/O operations per secondWriteIOPS
- Write I/O operations per secondReadLatency
- Read operation latencyWriteLatency
- Write operation latency
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
spec:
mode: Pipeline
pipeline:
- step: fetch-rds-metrics
functionRef:
name: function-rds-metrics
input:
apiVersion: rdsmetrics.fn.crossplane.io/v1beta1
kind: Input
databaseName: "my-production-db"
region: "us-west-2"
target: "status.metrics"
credentials:
- name: aws-creds
source: Secret
secretRef:
namespace: crossplane-system
name: aws-creds
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
spec:
mode: Pipeline
pipeline:
- step: fetch-rds-metrics
functionRef:
name: function-rds-metrics
input:
apiVersion: rdsmetrics.fn.crossplane.io/v1beta1
kind: Input
databaseNameRef: "xr.metadata.name"
region: "us-west-2"
target: "context.metricsResult"
apiVersion: apiextensions.crossplane.io/v1
kind: Composition
spec:
mode: Pipeline
pipeline:
- step: fetch-metrics
functionRef:
name: function-rds-metrics
input:
apiVersion: rdsmetrics.fn.crossplane.io/v1beta1
kind: Input
databaseNameRef: "xr.metadata.name"
region: "us-west-2"
metrics:
- "CPUUtilization"
- "DatabaseConnections"
- "FreeableMemory"
target: "context.rdsMetrics"
- step: ai-scaling-decision
functionRef:
name: function-claude
input:
apiVersion: claude.fn.crossplane.io/v1beta1
kind: Input
prompt: "Analyze RDS metrics and recommend scaling actions"
contextRef: "rdsMetrics"
target: "status.scalingRecommendation"
The function outputs metrics in this structure:
databaseName: "my-production-db"
region: "us-west-2"
timestamp: "2025-07-27T10:20:56Z"
metrics:
CPUUtilization:
value: 45.2
unit: "Percent"
timestamp: "2025-07-27T10:20:00Z"
DatabaseConnections:
value: 12
unit: "Count"
timestamp: "2025-07-27T10:20:00Z"
FreeableMemory:
value: 1073741824
unit: "Bytes"
timestamp: "2025-07-27T10:20:00Z"
The example/
directory contains several testing scenarios:
crossplane render example/basic-metrics-query/xr.yaml example/basic-metrics-query/composition.yaml example/functions.yaml --function-credentials=example/secrets/aws-creds.yaml
crossplane render example/database-ref-from-xr/xr.yaml example/database-ref-from-xr/composition.yaml example/functions.yaml --function-credentials=example/secrets/aws-creds.yaml --include-context
crossplane render example/custom-metrics-query/xr.yaml example/custom-metrics-query/composition.yaml example/functions.yaml --function-credentials=example/secrets/aws-creds.yaml
The function requires AWS credentials with CloudWatch read permissions. Provide credentials as a Kubernetes secret:
apiVersion: v1
kind: Secret
metadata:
name: aws-creds
namespace: crossplane-system
type: Opaque
data:
credentials: <base64-encoded-aws-credentials-file>
The credentials file should be in AWS CLI format:
[default]
aws_access_key_id = YOUR_ACCESS_KEY
aws_secret_access_key = YOUR_SECRET_KEY
# Run code generation
go generate ./...
# Run tests
go test ./...
# Build the function's runtime image
docker build . --tag=function-rds-metrics
# Build a function package
crossplane xpkg build -f package --embed-runtime-image=function-rds-metrics
For local development, use the Development runtime annotation:
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: function-rds-metrics
annotations:
render.crossplane.io/runtime: Development
Then run the function locally:
go run . --insecure --debug
This function is designed to work in composition pipelines with other functions:
- function-claude: Provides AI-driven analysis of RDS metrics for intelligent scaling decisions
The function implements robust error handling:
- AWS Config Errors: Returns empty metrics but continues pipeline execution
- Missing Database: Fails fast with clear error messages
- CloudWatch API Errors: Logs errors but attempts to continue with available metrics
- Invalid References: Provides detailed error messages for debugging