ElastiCache
Protocol: Query (XML) for management API + Redis RESP protocol for data plane
Management Endpoint: POST http://localhost:4566/
Data Endpoint: localhost:<proxy-port> (TCP)
Floci manages real Valkey/Redis Docker containers and proxies TCP connections to them. This means any Redis client works — including IAM authentication.
Supported Management Actions
| Action | Description |
|---|---|
ValidateIamAuthToken |
Validate an IAM auth token (data-plane auth) |
CreateReplicationGroup |
Start a new Redis/Valkey cluster; AtRestEncryptionEnabled, KmsKeyId (resolved to the key ARN), SnapshotRetentionLimit, SnapshotWindow and Tags are kept and returned, with the group ARN |
DescribeReplicationGroups |
List clusters and their connection info |
ModifyReplicationGroup |
Modify SnapshotRetentionLimit and SnapshotWindow, and the associated user groups |
DeleteReplicationGroup |
Stop and remove a cluster |
CreateUser |
Create an ElastiCache IAM user |
DescribeUsers |
List ElastiCache users |
ModifyUser |
Update user access strings |
DeleteUser |
Remove an ElastiCache user |
CreateCacheCluster |
- |
DescribeCacheClusters |
- |
DeleteCacheCluster |
- |
CreateCacheSubnetGroup |
Create a cache subnet group |
DescribeCacheSubnetGroups |
List cache subnet groups |
ModifyCacheSubnetGroup |
Replace a group's description or subnets |
DeleteCacheSubnetGroup |
Delete a cache subnet group |
CreateCacheParameterGroup |
Create a cache parameter group |
DescribeCacheParameterGroups |
List parameter groups, including the AWS defaults |
ModifyCacheParameterGroup |
Set parameters on a group |
DescribeCacheParameters |
List the parameters set on a group |
DeleteCacheParameterGroup |
Delete a cache parameter group |
ListTagsForResource |
Tags on a parameter group ARN |
Cluster Mode
CreateReplicationGroup provisions a real sharded Valkey cluster when the request asks for one:
NumNodeGroups greater than 1, a default.*.cluster.on parameter group, a custom parameter group
with cluster-enabled set to yes, or ClusterMode=enabled.
Floci starts one --cluster-enabled container per node — NumNodeGroups × (1 + ReplicasPerNodeGroup)
in total — forms the cluster (config epochs, MEET, slot assignment, replica attachment), and fronts
each node with its own auth-proxy port from the proxy port range. Nodes announce Floci's configured
hostname as their preferred endpoint (cluster-announce-hostname with
cluster-preferred-endpoint-type hostname, plus cluster-announce-client-ipv4/
cluster-announce-port), so CLUSTER SLOTS, CLUSTER SHARDS and MOVED/ASK redirects hand
clients the same name the ConfigurationEndpoint reports, while the cluster bus keeps using the
container network. Any cluster-aware Redis/Valkey client works against the reported
ConfigurationEndpoint.
Because clients must resolve the announced name to follow redirects, a FLOCI_HOSTNAME that only
resolves inside Floci's Docker network (such as the Compose service name floci) breaks
cluster-aware clients connecting from outside it. Set
FLOCI_SERVICES_ELASTICACHE_CLUSTER_ANNOUNCE_HOSTNAME to a universally resolvable name in that
case — the shipped docker-compose.yml uses localhost.floci.io, which public DNS resolves to
127.0.0.1 on the host (reaching the published proxy ports) while the Compose network alias and
Floci's embedded DNS resolve it to the Floci container from inside Docker. Cluster-mode groups
then announce that name and report it as their ConfigurationEndpoint.
With persistent, hybrid or wal storage, cluster-mode groups are re-provisioned from their
persisted topology on startup: containers are restarted, the cluster is re-formed (caches restart
empty, as on any Floci restart) and each node's proxy port is re-reserved. Ports are re-reserved
and groups marked creating before Floci reports ready; the container restarts and cluster
formation run in the background so a slow Docker daemon cannot delay readiness, and each group
flips to available once its data plane is back. A group whose data plane cannot be brought back
is reported with status create-failed instead of available, and its member clusters answer
DescribeCacheClusters with restore-failed (CacheClusterStatus has no create-failed value).
DescribeReplicationGroups reports the topology honestly: ClusterEnabled, one NodeGroup per
shard with its Slots, NodeGroupMembers, and MemberClusters. Each member also answers
DescribeCacheClusters (as on AWS), which is what terraform-provider-aws reads node type, engine
version and port from.
Cluster mode requires a Valkey 8.1+ image (the default valkey/valkey:8 qualifies) for
cluster-announce-client-ipv4 support. Each node consumes one port from the proxy range, so size
FLOCI_SERVICES_ELASTICACHE_PROXY_BASE_PORT/_MAX_PORT to the number of nodes you need.
aws elasticache create-replication-group \
--replication-group-id my-sharded-cache \
--replication-group-description "Sharded dev cache" \
--engine valkey \
--cache-parameter-group-name default.valkey8.cluster.on \
--num-node-groups 2 \
--replicas-per-node-group 1 \
--endpoint-url $AWS_ENDPOINT_URL
aws elasticache describe-replication-groups \
--replication-group-id my-sharded-cache \
--query 'ReplicationGroups[0].ConfigurationEndpoint' \
--endpoint-url $AWS_ENDPOINT_URL
redis-cli -c -h localhost -p <configuration-endpoint-port> set mykey "hello"
Cache Subnet Groups
A subnet group's VPC and each subnet's availability zone are read from the subnets themselves, as AWS reads them, so the subnets have to exist in the emulator's EC2 first. Subnets that are unknown, or that span more than one VPC, are refused the way AWS refuses them.
Cache Parameter Groups
The default.* groups AWS publishes are listed for every family it supports, and cannot be modified
or deleted — AWS refuses those by the identifier rule, since a name it accepts cannot contain a dot.
floci does not carry AWS's per-family catalogue of parameter names, which runs to dozens per family.
It therefore stores whatever parameters a caller sets and reports them with source user, rather
than rejecting names a partial catalogue happens to be missing, which would refuse configurations
AWS accepts. DescribeCacheParameters returns those parameters; a request for system or
engine-default parameters returns none, and listings are unpaged.
A replication group that names a parameter group is refused with CacheParameterGroupNotFound when
no such group exists, and a parameter group still referenced by a replication group cannot be
deleted: DeleteCacheParameterGroup answers InvalidCacheParameterGroupState until that
replication group is gone. The reference counts from the moment CreateReplicationGroup accepts
the name, not from when the group is stored, so a delete that lands while that create is still
provisioning its container is refused too.
Configuration
| Variable | Default | Description |
|---|---|---|
FLOCI_SERVICES_ELASTICACHE_ENABLED |
true |
Enable or disable the service |
FLOCI_SERVICES_ELASTICACHE_PROXY_BASE_PORT |
6379 |
First host port in the ElastiCache proxy range |
FLOCI_SERVICES_ELASTICACHE_PROXY_MAX_PORT |
6399 |
Last host port in the ElastiCache proxy range |
FLOCI_SERVICES_ELASTICACHE_DEFAULT_IMAGE |
valkey/valkey:8 |
Docker image for Redis/Valkey containers |
Docker Compose
ElastiCache requires the Docker socket and port range exposure. For private registry authentication and other Docker settings see Docker Configuration.
services:
floci:
image: floci/floci:latest
ports:
- "4566:4566"
- "6379-6399:6379-6399" # ElastiCache proxy ports
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
FLOCI_SERVICES_DOCKER_NETWORK: my-project_default
Examples
export AWS_ENDPOINT_URL=http://localhost:4566
# Create a replication group (starts a Valkey container)
aws elasticache create-replication-group \
--replication-group-id my-cache \
--replication-group-description "Dev cache" \
--endpoint-url $AWS_ENDPOINT_URL
# Get the connection port
PORT=$(aws elasticache describe-replication-groups \
--replication-group-id my-cache \
--query 'ReplicationGroups[0].NodeGroups[0].PrimaryEndpoint.Port' \
--output text \
--endpoint-url $AWS_ENDPOINT_URL)
# Connect with redis-cli
redis-cli -h localhost -p $PORT ping
# Use from your application
redis-cli -h localhost -p $PORT set mykey "hello"
redis-cli -h localhost -p $PORT get mykey
# Delete the cluster
aws elasticache delete-replication-group \
--replication-group-id my-cache \
--endpoint-url $AWS_ENDPOINT_URL
IAM Authentication
Floci supports ElastiCache IAM auth token validation. Create a user with access strings and validate tokens the same way real ElastiCache RBAC works.