Deprecated Field Migration

This guide helps you migrate from deprecated configuration fields to their current replacements. Deprecated fields continue to work but will be removed in future versions.

Overview

StackGres occasionally deprecates fields when better alternatives are introduced. This ensures:

  • Cleaner API design
  • Better separation of concerns
  • Improved configurability

Recommendation: Migrate to new fields as soon as possible to avoid issues during future upgrades.

Deprecated Fields Reference

Resource Deprecated Field Replacement Removed In
SGCluster spec.pods.disableMetricsExporter spec.configurations.observability.disableMetrics Future
SGCluster spec.initialData.scripts spec.managedSql with SGScript Future
SGCluster spec.initialData.restore.fromBackup.uid spec.initialData.restore.fromBackup.name Future
SGShardedCluster spec.shards spec.workers Future
SGShardedCluster spec.postgresServices.shards spec.postgresServices.workers Future
SGShardedCluster spec.metadata.annotations.shardsPrimariesService spec.metadata.annotations.workersPrimariesService Future
SGShardedCluster spec.metadata.labels.shardsPrimariesService spec.metadata.labels.workersPrimariesService Future

disableMetricsExporter Migration

The spec.pods.disableMetricsExporter field has been moved to the observability configuration section for better organization.

Before (Deprecated)

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: my-cluster
spec:
  instances: 3
  postgres:
    version: '16'
  pods:
    persistentVolume:
      size: '50Gi'
    disableMetricsExporter: true  # DEPRECATED

After (Current)

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: my-cluster
spec:
  instances: 3
  postgres:
    version: '16'
  pods:
    persistentVolume:
      size: '50Gi'
  configurations:
    observability:
      disableMetrics: true  # New location

Migration Steps

  1. Identify clusters using deprecated field:

    kubectl get sgcluster -A -o yaml | grep -B20 "disableMetricsExporter: true"
    
  2. Update cluster spec:

    kubectl edit sgcluster my-cluster
    

    Remove spec.pods.disableMetricsExporter and add spec.configurations.observability.disableMetrics.

  3. Verify configuration:

    kubectl get sgcluster my-cluster -o jsonpath='{.spec.configurations.observability}'
    

Additional Observability Options

The new location provides more observability settings:

configurations:
  observability:
    disableMetrics: true
    prometheusAutobind: false
    receiver: my-otel-receiver  # OpenTelemetry Collector

initialData.scripts Migration

The spec.initialData.scripts field has been replaced by the more powerful managedSql system with SGScript resources.

Before (Deprecated)

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: my-cluster
spec:
  instances: 3
  postgres:
    version: '16'
  pods:
    persistentVolume:
      size: '50Gi'
  initialData:
    scripts:  # DEPRECATED
      - name: create-database
        script: |
                    CREATE DATABASE myapp;
      - name: create-user
        scriptFrom:
          secretKeyRef:
            name: db-credentials
            key: create-user.sql

After (Current)

Step 1: Create an SGScript resource:

apiVersion: stackgres.io/v1
kind: SGScript
metadata:
  name: my-cluster-init
spec:
  scripts:
    - name: create-database
      script: |
                CREATE DATABASE myapp;
    - name: create-user
      scriptFrom:
        secretKeyRef:
          name: db-credentials
          key: create-user.sql

Step 2: Reference the SGScript in the cluster:

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: my-cluster
spec:
  instances: 3
  postgres:
    version: '16'
  pods:
    persistentVolume:
      size: '50Gi'
  managedSql:
    scripts:
      - sgScript: my-cluster-init

Migration Steps

  1. Export existing scripts:

    kubectl get sgcluster my-cluster -o jsonpath='{.spec.initialData.scripts}' > scripts.json
    
  2. Create SGScript resource:

    apiVersion: stackgres.io/v1
    kind: SGScript
    metadata:
      name: my-cluster-init
    spec:
      scripts:
        # Convert your scripts here
    
  3. Apply SGScript:

    kubectl apply -f sgscript.yaml
    
  4. Update cluster to use managedSql:

    kubectl patch sgcluster my-cluster --type=merge -p '
    spec:
      managedSql:
        scripts:
          - sgScript: my-cluster-init
    '
    
  5. Remove deprecated field (after verifying scripts work):

    kubectl patch sgcluster my-cluster --type=json -p '[
      {"op": "remove", "path": "/spec/initialData/scripts"}
    ]'
    

Benefits of managedSql

The new managedSql system provides:

  • Reusability: SGScripts can be shared across clusters
  • Versioning: Scripts can be versioned and re-executed
  • Status tracking: Execution status visible in cluster status
  • Error handling: continueOnSGScriptError and continueOnError options
  • Ordering control: Fine-grained execution order

Script Status Tracking

With managedSql, you can track script execution:

kubectl get sgcluster my-cluster -o jsonpath='{.status.managedSql}' | jq

Example output:

{
  "scripts": [
    {
      "id": 0,
      "startedAt": "2024-01-15T10:00:00Z",
      "completedAt": "2024-01-15T10:00:05Z",
      "scripts": [
        {"id": 0, "version": 1},
        {"id": 1, "version": 1}
      ]
    }
  ]
}

fromBackup.uid Migration

The spec.initialData.restore.fromBackup.uid field is deprecated in favor of name.

Before (Deprecated)

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: restored-cluster
spec:
  initialData:
    restore:
      fromBackup:
        uid: a1b2c3d4-e5f6-7890-abcd-ef1234567890  # DEPRECATED

After (Current)

apiVersion: stackgres.io/v1
kind: SGCluster
metadata:
  name: restored-cluster
spec:
  initialData:
    restore:
      fromBackup:
        name: my-backup  # Use backup name instead

Migration Steps

  1. Find backup name from UID:

    kubectl get sgbackup -A -o custom-columns='NAME:.metadata.name,UID:.metadata.uid'
    
  2. Update cluster spec to use name instead of uid.

SGShardedCluster shards to workers Migration

Since StackGres 1.19.0 the SGShardedCluster CRD version has been bumped to stackgres.io/v1beta1 and the shards concept has been renamed to workers. The following fields have been renamed:

  • spec.shards is now spec.workers
  • spec.postgresServices.shards is now spec.postgresServices.workers
  • spec.metadata.annotations.shardsPrimariesService is now spec.metadata.annotations.workersPrimariesService
  • spec.metadata.labels.shardsPrimariesService is now spec.metadata.labels.workersPrimariesService

The deprecated fields continue to work but will be removed together with the stackgres.io/v1alpha1 version in a future release.

Also, the service exposing the primaries of the workers is now named after the SGShardedCluster name plus the -workers suffix (previously the -shards suffix). The service with the -shards suffix is still created for backward compatibility but applications should migrate their connection configuration to the -workers service.

Before (Deprecated)

apiVersion: stackgres.io/v1alpha1
kind: SGShardedCluster
metadata:
  name: my-sharded-cluster
spec:
  type: citus
  database: mydatabase
  postgres:
    version: '16'
  coordinator:
    instances: 2
    pods:
      persistentVolume:
        size: '10Gi'
  shards:  # DEPRECATED
    clusters: 4
    instancesPerCluster: 2
    pods:
      persistentVolume:
        size: '10Gi'
  postgresServices:
    shards:  # DEPRECATED
      primaries:
        enabled: true
  metadata:
    annotations:
      shardsPrimariesService:  # DEPRECATED
        my-annotation: my-value

After (Current)

apiVersion: stackgres.io/v1beta1
kind: SGShardedCluster
metadata:
  name: my-sharded-cluster
spec:
  type: citus
  database: mydatabase
  postgres:
    version: '16'
  coordinator:
    instances: 2
    pods:
      persistentVolume:
        size: '10Gi'
  workers:  # New name
    clusters: 4
    instancesPerCluster: 2
    pods:
      persistentVolume:
        size: '10Gi'
  postgresServices:
    workers:  # New name
      primaries:
        enabled: true
  metadata:
    annotations:
      workersPrimariesService:  # New name
        my-annotation: my-value

Migration Steps

  1. Identify sharded clusters using deprecated fields:

    kubectl get sgshardedcluster -A -o yaml | grep -E "^\s+(shards|shardsPrimariesService):"
    
  2. Update sharded cluster spec:

    kubectl edit sgshardedcluster my-sharded-cluster
    

    Rename spec.shards to spec.workers, spec.postgresServices.shards to spec.postgresServices.workers and shardsPrimariesService to workersPrimariesService under spec.metadata.annotations and spec.metadata.labels.

  3. Update YAML manifests stored in your GitOps repositories to use apiVersion: stackgres.io/v1beta1 and the new field names.

  4. Update applications connecting to the service with the -shards suffix to use the service with the -workers suffix.

  5. Verify configuration:

    kubectl get sgshardedcluster my-sharded-cluster -o jsonpath='{.spec.workers}'
    

Checking for Deprecated Fields

Audit Script

Check all clusters for deprecated fields:

#!/bin/bash
echo "Checking for deprecated fields..."

for cluster in $(kubectl get sgcluster -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}'); do
  ns=$(echo $cluster | cut -d'/' -f1)
  name=$(echo $cluster | cut -d'/' -f2)

  # Check disableMetricsExporter
  if kubectl get sgcluster -n $ns $name -o jsonpath='{.spec.pods.disableMetricsExporter}' 2>/dev/null | grep -q "true"; then
    echo "[$ns/$name] Uses deprecated: spec.pods.disableMetricsExporter"
  fi

  # Check initialData.scripts
  if kubectl get sgcluster -n $ns $name -o jsonpath='{.spec.initialData.scripts}' 2>/dev/null | grep -q "."; then
    echo "[$ns/$name] Uses deprecated: spec.initialData.scripts"
  fi

  # Check fromBackup.uid
  if kubectl get sgcluster -n $ns $name -o jsonpath='{.spec.initialData.restore.fromBackup.uid}' 2>/dev/null | grep -q "."; then
    echo "[$ns/$name] Uses deprecated: spec.initialData.restore.fromBackup.uid"
  fi
done

for cluster in $(kubectl get sgshardedcluster -A -o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}{"\n"}{end}'); do
  ns=$(echo $cluster | cut -d'/' -f1)
  name=$(echo $cluster | cut -d'/' -f2)

  # Check shards
  if kubectl get sgshardedcluster -n $ns $name -o jsonpath='{.spec.shards}' 2>/dev/null | grep -q "."; then
    echo "[$ns/$name] Uses deprecated: spec.shards"
  fi

  # Check postgresServices.shards
  if kubectl get sgshardedcluster -n $ns $name -o jsonpath='{.spec.postgresServices.shards}' 2>/dev/null | grep -q "."; then
    echo "[$ns/$name] Uses deprecated: spec.postgresServices.shards"
  fi

  # Check shardsPrimariesService
  if kubectl get sgshardedcluster -n $ns $name -o jsonpath='{.spec.metadata.annotations.shardsPrimariesService}{.spec.metadata.labels.shardsPrimariesService}' 2>/dev/null | grep -q "."; then
    echo "[$ns/$name] Uses deprecated: spec.metadata.annotations.shardsPrimariesService or spec.metadata.labels.shardsPrimariesService"
  fi
done

Warnings in Logs

The operator logs warnings when deprecated fields are used:

kubectl logs -n stackgres -l app=stackgres-operator | grep -i deprecated

Best Practices

  1. Test migrations in non-production before applying to production clusters

  2. Keep both fields temporarily during migration if supported

  3. Document changes in your GitOps repositories

  4. Monitor after migration to ensure functionality is preserved

  5. Update automation scripts and Helm values that use deprecated fields