Search code examples
amazon-web-servicesserverlessamazon-elasticachelettucevalkey

Java Springboot application not able to connect to AWS Elasticache Valkey Cache (Serverless)


Trying to connect to AWS Elasticache (valkey engine: serverless: version 8.0) from my Java springboot application. JDK 17 & springboot version 3.2.5.

Using Lettuce client to connect to Valkey cache (https://docs.aws.amazon.com/pdfs/AmazonElastiCache/latest/dg/redis-ug.pdf#BestPractices.Clients-lettuce)

Below is the code snippet I am using, which fails at line "client.connect()"

 public void readLettuceCacheAuth() {
        try {
            AWSCredentialsProvider awsCredentialsProvider = new DefaultAWSCredentialsProviderChain();
            IAMAuthTokenRequest iamAuthTokenRequest = new IAMAuthTokenRequest("iam-user-valkey-01", "my-cache", "us-east-1", true);
            String iamAuthToken = iamAuthTokenRequest.toSignedRequestUri(awsCredentialsProvider.getCredentials());
            log.info("iamAuthToken: " + iamAuthToken);
            RedisURI redisURI = RedisURI.builder()
                    .withHost(VALKEY_CACHE_HOST)
                    .withPort(VALKEY_CACHE_PORT)
                    .withSsl(true)
                    .withAuthentication("iam-user-valkey-01", iamAuthToken)
                    .build();
            RedisClient client = RedisClient.create(redisURI);
            log.info("client => " + client);
            StatefulRedisConnection<String, String> connection = client.connect();   <== exception at this line
            log.info("connection => " + connection);
            RedisStringCommands<String, String> syncCommands = connection.sync();
            syncCommands.set("key", "value");
            String value = syncCommands.get("key");
        } catch (Exception e) {
            log.error("Lettuce error: " + e);
        }
    }

Below are the logs,

iamAuthToken: my-cache/?Action=connect&User=iam-user-valkey-01&ResourceType=ServerlessCache&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEOv%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDmFwLXNvdXRoZWFzdC0yIkcwRQIhAO9SJdccIXP2Y2VDj0WxEqdCLQDLMUTbH8IRnbAS11QmAiAOjS

client => io.lettuce.core.RedisClient@504021e

Lettuce error: io.lettuce.core.RedisConnectionException: Unable to connect to my-cache-fpheum.serverless.apse2.cache.amazonaws.com/<unresolved>:6379
  1. Both Cache, Springboot application are in same VPC.

  2. Updated Cache's security group inbound rules to allow java application on port 6379.

Can someone please help what is going wrong here?


Solution

  • I got it working after correcting below:

    1. Adding below policies to the ecs task role
            AllowElasticacheConnect: new iam.PolicyDocument({
                statements: [
                  new iam.PolicyStatement({
                    actions: ['elasticache:Connect'],
                    effect: iam.Effect.ALLOW,
                    resources: [
                      `arn:aws:elasticache:ap-southeast-2:${this.account}:serverlesscache:my-cache`,
                      `arn:aws:elasticache:ap-southeast-2:${this.account}:user:iam-user-valkey-01`,
                    ]
                  }),
                ],
            })
    
    1. Update security group of valkey cache and add inbound rules to allow java app