ELASTICACHE REDIS → STACKIT VALKEY · TUTORIAL
ElastiCache Redis to STACKIT Valkey: a worked example
STACKIT Key Value Store is Valkey, and the run's report quotes the Valkey project's statement that it is compatible with Redis OSS 7.2 and earlier, so existing clients keep working in the common case. What changes is everything around the engine: access control, sizing, the endpoint and the credential. This tutorial runs StackToIT on a small session-cache estate and follows the result to the key copy.
The input: a two-node Redis 7.1 group
A demo estate written for this page: a replication group of two cache.m6g.large nodes with automatic failover, encryption in transit and at rest, an AUTH token, a seven-day snapshot retention and a parameter group with an LRU eviction policy. Left: the parameter group and the group, as they stand in the file. Right: the Valkey Terraform the run wrote, without its review comments.
resource "aws_elasticache_parameter_group" "sessions" {
name = "sessions-redis7"
family = "redis7"
parameter {
name = "maxmemory-policy"
value = "allkeys-lru"
}
}
resource "aws_elasticache_replication_group" "sessions" {
replication_group_id = "sessions"
description = "Session store for the web tier"
engine = "redis"
engine_version = "7.1"
node_type = "cache.m6g.large"
num_cache_clusters = 2
automatic_failover_enabled = true
multi_az_enabled = true
port = 6379
subnet_group_name = aws_elasticache_subnet_group.sessions.name
security_group_ids = [aws_security_group.cache.id]
parameter_group_name = aws_elasticache_parameter_group.sessions.name
at_rest_encryption_enabled = true
transit_encryption_enabled = true
auth_token = var.cache_auth_token
snapshot_retention_limit = 7
snapshot_window = "02:00-03:00"
}resource "stackit_valkey_instance" "sessions" {
project_id = var.project_id
name = "sessions"
plan_name = var.sessions_plan_name
version = var.sessions_version
parameters = {
sgw_acl = join(",", var.sessions_allowed_cidrs)
}
}
resource "stackit_valkey_credential" "sessions" {
project_id = var.project_id
instance_id = stackit_valkey_instance.sessions.instance_id
}What the run reports
The summary for the demo estate, as printed by stacktoit assess . <output folder> --offline --no-validate (console.txt; --no-validate is why the OpenTofu check of the source did not run). Seven resources were scanned. Five became migration units, all RECONFIGURE; the subnet group and the parameter group fold into the cache unit and need no resource of their own.
Source: input
Source files: 1
Resources scanned: 7
support resources: 2 (+0 Terraform helpers, out of scope; 2 + 0 = the 2 support nodes of summary.support.nodes in assessment.json)
Migration units: 5 (5 instances)
Unit dependencies: 6
Source checks: Built-in source checks found inputs the package does not hold — OpenTofu validation of the source was not run
Source inputs: missing required input ×1 (1 stops nothing) (summary.source_inputs)
Source completeness: VARIABLE_UNRESOLVED — 1 root variable(s) have no default and no value (cache_auth_token): what reads them is unknown until a run supplies them (-var-file, -var or TF_VAR_*; give a variable file with --var-file)
STACKIT mapping
────────────────────────────────────────────
DIRECT 0
RECONFIGURE 5 ██████████████████████████████ 100%
REPLATFORM 0
CONTAINERIZE 0
REDESIGN 0
MANUAL_REVIEW 0
BLOCKED 0 (the mapping class BLOCKED, not the execution blockers, which Migration readiness counts)What the draft carries and what it does not
| ElastiCache setting | In the Valkey draft | What you do |
|---|---|---|
| engine redis, engine_version 7.1 | Valkey, version set by a variable; the catalogue offers major version 8 | Choose the version; moving from 7.1 is an engine upgrade and the report says so |
| node_type cache.m6g.large, two nodes | A plan name, default a replica plan; the plan defines nodes and replicas | Confirm the size derived from the source; the decision stays open until you answer it |
| subnet group, security group | Not carried: the instance has no subnet or security group attribute | List the client CIDRs in the access list variable; the list has no default |
| port 6379 | Not carried: the port comes with the credential | Switch the clients to the host and port the credential returns |
| auth_token | A Valkey credential generated by STACKIT, exposed as a sensitive output | Read it after the apply and hand it to every client before the cutover |
| transit encryption on | TLS is enforced by the service | Check that every client driver is configured for TLS (rediss:// or a TLS option) |
| at-rest encryption on | Reported as unknown: no attribute and no statement found for the service | Ask STACKIT before you rely on it for a requirement |
| parameter group, maxmemory-policy | Not translated; selected settings live under the instance parameters | Map the settings your application needs |
| snapshot_window 02:00-03:00, retention 7 | Not carried; the snapshot time is a parameter of the instance | Decide the snapshot schedule |
The key copy plan
The run writes a data move runbook next to the Terraform (terraform/handover/cache-sessions/data-move.md) and the steps into the execution plan. StackToIT moves no data. These are the steps of the one method it keeps open, a copy by a client you run.
Preflight
Read-only checks from the move host: engine version, key counts, memory use, whether SCAN, DUMP and PTTL work with the credential you will copy with, whether the clients use TLS. The service key of the target is not an administrator, so do not expect CONFIG, ACL or MODULE to work.
Rehearsal
Copy a sample into a scratch instance of the same plan and version, note keys per second and the keys RESTORE refuses, run the application tests against it, then delete the scratch instance.
Write freeze
List who writes, record every client's connection settings, stop the writers. The source stays untouched, so the way back needs nothing on it.
Final sync
Iterate the keys with SCAN, read each with DUMP and PTTL, write it with RESTORE and its remaining time to live. The plan avoids the KEYS and MIGRATE commands on purpose: STACKIT's own migration tutorial pipes KEYS into MIGRATE, which needs a direct connection from the source to the target backend host.
Reconcile and cleanup
Compare key counts and sorted key lists with the writers stopped, run one real read of the application, record GO or NO-GO, then remove the move host from the access list and delete the working files.
The reconcile check, verbatim
The first check after the transfer (key-counts). The client asks for the password interactively, so it never appears on the command line. Replace the placeholders with the endpoints of your source and of the credential.
valkey-cli -h <source-host> -p <source-port> --tls --askpass DBSIZE
valkey-cli -h <source-host> -p <source-port> --tls --askpass INFO keyspace
valkey-cli -h <target-host> -p <target-port> --tls --sni <target-host> --user <target-user> --askpass DBSIZE
valkey-cli -h <target-host> -p <target-port> --tls --sni <target-host> --user <target-user> --askpass INFO keyspaceThe four ways to move the data, and what the plan says of each
| Method | State in the plan | Why |
|---|---|---|
| Export and import with the engine clients | Candidate, not chosen | Needs a write freeze as long as the copy and the comparison; the plan has not run RESTORE against a Key Value Store |
| Snapshot restore (ElastiCache export to S3, load into Valkey) | Refused by the plan | AWS can export a backup to an S3 bucket as .rdb files, but no STACKIT page or API read documents loading such a file into a Key Value Store |
| Online replication from the source | Refused by the plan | No STACKIT page or API read documents attaching an instance as a replica of an external primary; the plan records that the source side does not offer it either |
| A tool of your own | Customer owned | The plan states no duration or freeze window; it keeps the freeze, reconcile and rollback steps |
What to change before you apply
Four values and decisions stand between the draft and an apply in the demo run.
Client CIDRs
Fill the access list variable. Without a list STACKIT applies its default access list, which admits the addresses of every STACKIT customer.
Public endpoint
The instance has its own endpoint outside your project network. The draft accepts a public endpoint limited by the CIDR list; redesign it if clients must not reach it from outside.
Version and plan
Set the Valkey version and confirm or change the plan name. Pick a replica plan if the source fails over by itself.
Can the cache start empty?
If the owner of the application says the keys can be rebuilt, skip the copy and answer the data movement decision with your own tool.
Questions teams ask
Do our Redis clients need code changes?
Usually only configuration: host, port, TLS and the credential. STACKIT states that Key Value Store is compatible with existing Redis setups, and the report limits its own claim to Redis OSS 7.2 and earlier, without Redis modules or later features.
Can I restore my ElastiCache backup into Valkey?
AWS can export a backup to S3 as .rdb files, but the plan refuses the method because no STACKIT documentation read describes loading such a file. A Valkey server you run yourself can read an RDB file, which is a variant the plan does not write as steps.
Why is there no network placement for the instance?
The Valkey instance has no network attribute, so the draft cannot place it in a drafted network. Access is controlled by the CIDR access list, which is why the exposure decision exists.
What if a session sits idle for an hour?
The plan lists as a risk that exposed STACKIT data services drop an idle connection after 60 minutes. Make the copy client reconnect.
Sources
Your next move: STACKIT.
Tell us about your estate. We show you what StackToIT delivers for it: target architecture, Terraform artifacts and a structured migration plan.