redisctl

The CLI for Redis Cloud and Enterprise

github.com/redis-developer/redisctl

The Problem

No unified CLI for Redis Cloud and Enterprise REST APIs

  • Redis Cloud: No CLI - only web UI or raw API calls
  • Redis Enterprise: rladmin requires cluster-local access
  • DevOps teams: Can't easily automate across both platforms
  • Everyone: Writing fragile bash scripts with curl and jq

The Reality Today

# Typical "automation" script
API_KEY="..."
SECRET="..."

# Create database... hope the JSON is right
curl -s -X POST "https://api.redislabs.com/v1/subscriptions/123/databases" \
  -H "x-api-key: $API_KEY" \
  -H "x-api-secret-key: $SECRET" \
  -H "Content-Type: application/json" \
  -d '{"name": "mydb", "memoryLimitInGb": 1, ...}'

# Poll for completion... forever
while true; do
  STATUS=$(curl -s ... | jq -r '.status')
  if [ "$STATUS" = "active" ]; then break; fi
  sleep 10  # Hope this is enough
done

# Parse response... pray it doesn't change
ENDPOINT=$(curl -s ... | jq -r '.publicEndpoint')
# What if the field is null? What if the API changes?

The Solution

redisctl

First-class CLI for the entire Redis platform

What redisctl Provides

  • Type-safe API clients - no more parsing curl output
  • Async operation handling - no more polling loops
  • Structured output - JSON/YAML for automation
  • Profile management - secure, multi-deployment

Built around four layers of functionality...

Four Layers

  • Profiles - Manage credentials for multiple deployments
  • Raw API - Direct REST access to any endpoint
  • Human Commands - Type-safe, friendly interface
  • Workflows - Multi-step orchestration

Layer 1: Profiles

Manage credentials across environments

# Set up profiles for each environment
redisctl profile set dev --cloud-api-key $DEV_KEY --cloud-secret-key $DEV_SECRET
redisctl profile set staging --cloud-api-key $STG_KEY --cloud-secret-key $STG_SECRET
redisctl profile set prod --cloud-api-key $PROD_KEY --cloud-secret-key $PROD_SECRET

# Set a default
redisctl profile set-default prod

# Switch easily
redisctl --profile dev cloud database list
redisctl --profile prod cloud database list

Profiles: Secure Storage

Keep credentials out of scripts and env vars

# Store credentials in OS keychain (macOS Keychain, Windows Credential Manager)
redisctl profile set prod \
  --cloud-api-key $KEY \
  --cloud-secret-key $SECRET \
  --use-keyring

# Or reference environment variables
redisctl profile set prod \
  --cloud-api-key '${REDIS_CLOUD_API_KEY}' \
  --cloud-secret-key '${REDIS_CLOUD_SECRET_KEY}'

# Credentials never appear in config file
cat ~/.config/redisctl/config.toml
# cloud_api_key = "keyring:prod-api-key"

Layer 2: Raw API

Direct REST access - better than curl

curl

curl -s -X GET \
  "https://api.redislabs.com/v1/subscriptions" \
  -H "x-api-key: $KEY" \
  -H "x-api-secret-key: $SECRET" \
  | jq '.[].name'

redisctl

redisctl api cloud get /subscriptions \
  -q '[].name'

Raw API: Full REST Support

# Any HTTP method
redisctl api cloud get /subscriptions
redisctl api cloud post /subscriptions/123/databases --body '{"name": "test"}'
redisctl api cloud put /subscriptions/123/databases/456 --body '{...}'
redisctl api cloud delete /subscriptions/123/databases/456

# Works for Enterprise too
redisctl api enterprise get /v1/cluster
redisctl api enterprise get /v1/bdbs
redisctl api enterprise post /v1/bdbs --body '{...}'

# JMESPath queries on any response
redisctl api enterprise get /v1/nodes -q '[*].{addr: addr, status: status}'

Layer 3: Human Commands

Day-to-day cluster management and monitoring

# Check cluster health
redisctl enterprise cluster get
redisctl enterprise node list
redisctl enterprise database list

# Monitor performance
redisctl enterprise database stats 1 -o json
redisctl enterprise cluster stats

# Manage databases
redisctl cloud database list --subscription-id 123456
redisctl enterprise database update 1 --memory-size 2147483648

Human Commands: Output Formats

$ redisctl enterprise database list
ID  Name           Memory     Status  Endpoints
1   session-cache  1.0 GB     active  redis-12345.cluster.local:12000
2   user-data      2.0 GB     active  redis-12346.cluster.local:12001
3   analytics      4.0 GB     active  redis-12347.cluster.local:12002
$ redisctl enterprise database list -o json
[{"uid":1,"name":"session-cache","memory_size":1073741824,"status":"active"},
 {"uid":2,"name":"user-data","memory_size":2147483648,"status":"active"}]

Human Commands: JMESPath Queries

Filter, reshape, and transform any JSON output

# Count all subscriptions
$ redisctl cloud subscription list -o json -q 'length(@)'
192

# Get unique cloud providers
$ redisctl cloud subscription list -o json -q '[*].cloudDetails[0].provider | unique(@)'
["AWS", "GCP"]

# Aggregate statistics
$ redisctl cloud subscription list -o json \
  -q '{total: length(@), size_gb: sum([*].cloudDetails[0].totalSizeInGb)}'
{"total": 192, "size_gb": 23.56}

JMESPath: Projections

Reshape data with custom fields

# Extract and reshape subscription details
$ redisctl cloud subscription list -o json \
  -q '[*].{id: id, name: name, provider: cloudDetails[0].provider} | [:3]'
[
  {"id": 2983053, "name": "time-series-demo", "provider": "AWS"},
  {"id": 2988697, "name": "workshop-sub", "provider": "AWS"},
  {"id": 3034552, "name": "test-db", "provider": "GCP"}
]

JMESPath: Pipelines

Chain operations with |

# Get unique regions -> sort -> count
$ redisctl cloud subscription list -o json \
  -q '[*].cloudDetails[0].regions[0].region | unique(@) | sort(@) | length(@)'
7

# Sort by name length (find shortest names)
$ redisctl cloud subscription list -o json \
  -q "[*].{name: name, len: length(name)} | sort_by(@, &len) | [:3]"
[{"len": 5, "name": "bgiri"}, {"len": 6, "name": "abhidb"}, {"len": 6, "name": "CM-rag"}]

JMESPath: String Functions

Transform and filter text

# Convert to uppercase
$ redisctl cloud subscription list -o json -q 'map(&upper(name), [*]) | [:3]'
["XW-TIME-SERIES-DEMO", "GABS-AWS-WORKSHOP-SUB", "BAMOS-TEST"]

# Filter by pattern
$ redisctl cloud subscription list -o json -q "[*].name | [?contains(@, 'demo')] | [:5]"
["xw-time-series-demo", "gabs-redis-streams-demo", "anton-live-demo", ...]

# Replace substrings
$ redisctl cloud subscription list -o json \
  -q "[*].{name: name, modified: replace(name, 'demo', 'DEMO')} | [:2]"
[{"name": "xw-time-series-demo", "modified": "xw-time-series-DEMO"}, ...]

JMESPath: 300+ Functions

Fuzzy Matching

# Find similar names
-q "[*].{name: name, dist: levenshtein(name, 'prod')}"

Math & Stats

# Aggregate stats
-q '{max: max([*].size), avg: avg([*].size)}'

Formatting

# Human-readable bytes
-q '[*].{mem: format_bytes(memory_size)}'

DateTime

# Current timestamp
-q '{checked: now()}'

Type Checking

# Inspect types
-q '[*].{name: name, type: type_of(id)}'

Semver

# Version comparison
-q 'semver_compare(version, `"7.4.0"`)'

Layer 4: Workflows

End-to-end provisioning for Redis Cloud

# Complete subscription setup with database
redisctl cloud workflow subscription-setup \
  --name "production" \
  --provider AWS \
  --region us-east-1 \
  --database-name "cache" \
  --database-memory-gb 2 \
  --high-availability \
  --wait
Looking up payment method...
Creating subscription 'production'...
Waiting for subscription to become active...
Subscription created successfully (ID: 123456)
Database created successfully (ID: 789)

Connection string: redis://redis-12345.c1.us-east-1.ec2.cloud.redislabs.com:12345

Workflows: Enterprise Setup

Initialize and configure clusters

# Initialize a new Enterprise cluster
redisctl enterprise workflow init-cluster \
  --license-file ./license.txt \
  --cluster-name "production"
Uploading license...
Creating cluster 'production'...
Waiting for cluster initialization...
Cluster initialized successfully

Cluster: production
Nodes: 3
Status: active

Workflows: Support Packages

Generate and upload diagnostics in seconds

# Generate, optimize, and upload in one command
redisctl enterprise support-package cluster --optimize --upload
Generating support package...
Optimizing package (removed 847 MB of logs)...
Uploading to Redis Support...

Package: support-package-2024-01-15-cluster.tar.gz
Size: 23 MB (optimized from 870 MB)
Upload: Complete
Case: https://files.redis.com/f/abc123

What used to take 30+ minutes now takes 30 seconds

Using with Docker

No installation required

# Run any command
docker run --rm ghcr.io/redis-developer/redisctl \
  cloud subscription list

# With environment variables
docker run --rm \
  -e REDIS_CLOUD_API_KEY=$KEY \
  -e REDIS_CLOUD_SECRET_KEY=$SECRET \
  ghcr.io/redis-developer/redisctl cloud database list

# Or mount your config
docker run --rm \
  -v ~/.config/redisctl:/root/.config/redisctl \
  ghcr.io/redis-developer/redisctl --profile prod cloud database list

CI/CD Integration

GitHub Actions example

- name: Deploy Redis database
  env:
    REDIS_CLOUD_API_KEY: ${{ secrets.REDIS_CLOUD_API_KEY }}
    REDIS_CLOUD_SECRET_KEY: ${{ secrets.REDIS_CLOUD_SECRET_KEY }}
  run: |
    # Create database and wait for it
    redisctl cloud database create \
      --subscription-id ${{ vars.SUBSCRIPTION_ID }} \
      --name "pr-${{ github.event.number }}" \
      --memory-limit-in-gb 1 \
      --wait -o json > db.json

    # Extract connection info (jq parses the saved JSON file)
    echo "REDIS_URL=$(jq -r '.publicEndpoint' db.json)" >> $GITHUB_ENV

CI/CD: Cleanup

- name: Cleanup PR database
  if: github.event.action == 'closed'
  env:
    REDIS_CLOUD_API_KEY: ${{ secrets.REDIS_CLOUD_API_KEY }}
    REDIS_CLOUD_SECRET_KEY: ${{ secrets.REDIS_CLOUD_SECRET_KEY }}
  run: |
    # Find and delete the PR database
    DB_ID=$(redisctl cloud database list \
      --subscription-id ${{ vars.SUBSCRIPTION_ID }} \
      -q "[?name=='pr-${{ github.event.number }}'].databaseId | [0]" -o json)

    redisctl cloud database delete \
      ${{ vars.SUBSCRIPTION_ID }} $DB_ID --wait

Who Uses redisctl?

Internal Redis teams

Support Engineers

  • Generate support packages instantly
  • Quick cluster diagnostics

Customer Success

  • Health checks during reviews
  • Usage and cost reporting

Solutions Architects

  • Demo environment setup
  • PoC provisioning

Professional Services

  • Migration automation
  • Deployment scripting

Who Uses redisctl?

Customer teams

DevOps / SRE

  • CI/CD database provisioning
  • Infrastructure as Code
  • Disaster recovery automation

Platform Engineers

  • Self-service database portals
  • Cost tracking and chargebacks
  • Multi-environment management

Even CLI-savvy executives: redisctl cloud subscription list -q '[*].{name: name, monthly: price}'

Installation

# Homebrew (macOS/Linux)
brew install redis-developer/homebrew-tap/redisctl

# Cargo (from source)
cargo install redisctl

# With secure credential storage
cargo install redisctl --features secure-storage

# Docker
docker run -it ghcr.io/redis-developer/redisctl --help

# From releases (Linux x86_64)
curl -L https://github.com/redis-developer/redisctl/releases/latest/download/redisctl-x86_64-unknown-linux-gnu.tar.gz | tar xz
./redisctl --help

Get Started

# Install
brew install redis-developer/homebrew-tap/redisctl

# Setup profile
redisctl profile set mycloud --cloud-api-key $KEY --cloud-secret-key $SECRET

# Start using
redisctl cloud subscription list
redisctl cloud database list --subscription-id 123456


github.com/redis-developer/redisctl

Docs: redis-field-engineering.github.io/redisctl-docs