You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用go-redis通过IAM认证连接AWS ElastiCache Redis?

使用go-redis实现AWS ElastiCache Redis的IAM认证连接

要替换原有的密码认证为IAM认证,核心是通过AWS SDK生成临时认证Token,将其作为Redis客户端的密码使用。以下是具体实现步骤:

前提条件

  • ElastiCache Redis集群已开启IAM认证
  • 你的IAM实体(用户/角色)拥有elasticache:Connect权限(需指定对应集群的ARN)
  • 使用AWS SDK for Go v2(v1已停止维护)

1. 安装依赖

需要安装go-redis(推荐v8或v9版本)及AWS SDK v2相关包:

go get github.com/go-redis/redis/v8
# 或使用v9版本:go get github.com/redis/go-redis/v9
go get github.com/aws/aws-sdk-go-v2/aws
go get github.com/aws/aws-sdk-go-v2/config
go get github.com/aws/aws-sdk-go-v2/service/elasticacheauth

2. 基础实现(单次生成Token)

该示例生成一次IAM认证Token,用于建立Redis连接:

import (
    "context"
    "log"

    "github.com/go-redis/redis/v8"
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/elasticacheauth"
)

func pingRedisWithIAM() {
    ctx := context.Background()

    // 加载AWS配置,自动读取环境变量、本地凭证文件或实例角色
    cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("your-aws-region"))
    if err != nil {
        log.Fatalf("加载AWS配置失败: %v", err)
    }

    // 创建ElastiCache认证客户端
    authClient := elasticacheauth.NewFromConfig(cfg)

    // 生成IAM认证Token,用户名可填任意非空字符串(IAM认证会忽略该值,仅满足格式要求)
    tokenOutput, err := authClient.GenerateAuthToken(ctx, &elasticacheauth.GenerateAuthTokenInput{
        UserName:           aws.String("iam-auth-user"),
        ReplicationGroupId: aws.String("your-elasticache-cluster-id"),
    })
    if err != nil {
        log.Fatalf("生成IAM认证Token失败: %v", err)
    }

    // 初始化Redis客户端,用生成的Token作为密码
    cli := redis.NewClient(&redis.Options{
        Addr:     "redis-address:6379", // 替换为你的ElastiCache地址及端口
        Password: *tokenOutput.AuthenticationToken,
        DB:       0,
    })

    _, err = cli.Ping(ctx).Result()
    if err != nil {
        log.Fatalf("Redis连接失败: %v", err)
        return
    }
    log.Println("已通过IAM认证成功连接ElastiCache Redis")
}

3. 进阶实现(自动刷新Token)

IAM认证Token有效期为15分钟,需定期刷新避免连接失效。以下是自动刷新Token的实现:

import (
    "context"
    "log"
    "time"

    "github.com/redis/go-redis/v9" // 使用v9版本更方便处理动态密码
    "github.com/aws/aws-sdk-go-v2/aws"
    "github.com/aws/aws-sdk-go-v2/config"
    "github.com/aws/aws-sdk-go-v2/service/elasticacheauth"
)

// 生成IAM认证Token的工具函数
func generateIAMToken(ctx context.Context, cfg aws.Config, clusterID string) (string, error) {
    authClient := elasticacheauth.NewFromConfig(cfg)
    tokenOutput, err := authClient.GenerateAuthToken(ctx, &elasticacheauth.GenerateAuthTokenInput{
        UserName:           aws.String("iam-auth-user"),
        ReplicationGroupId: aws.String(clusterID),
    })
    if err != nil {
        return "", err
    }
    return *tokenOutput.AuthenticationToken, nil
}

// 创建带Token自动刷新的Redis客户端
func createIAMRedisClient() *redis.Client {
    ctx := context.Background()
    clusterID := "your-elasticache-cluster-id"
    redisAddr := "redis-address:6379"
    awsRegion := "your-aws-region"

    // 加载AWS配置
    cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion(awsRegion))
    if err != nil {
        log.Fatalf("加载AWS配置失败: %v", err)
    }

    // 初始生成Token
    initialToken, err := generateIAMToken(ctx, cfg, clusterID)
    if err != nil {
        log.Fatalf("生成初始Token失败: %v", err)
    }

    // 初始化Redis客户端
    cli := redis.NewClient(&redis.Options{
        Addr:     redisAddr,
        Password: initialToken,
        DB:       0,
    })

    // 每14分钟刷新一次Token(比有效期提前1分钟,避免过期)
    go func() {
        ticker := time.NewTicker(14 * time.Minute)
        defer ticker.Stop()

        for range ticker.C {
            newToken, err := generateIAMToken(ctx, cfg, clusterID)
            if err != nil {
                log.Printf("刷新IAM Token失败: %v", err)
                continue
            }
            // 更新客户端密码
            cli.Options().Password = newToken
            log.Println("IAM认证Token已成功刷新")
        }
    }()

    return cli
}

// 使用示例
func main() {
    cli := createIAMRedisClient()
    ctx := context.Background()

    if _, err := cli.Ping(ctx).Result(); err != nil {
        log.Fatalf("Redis Ping失败: %v", err)
    }
    log.Println("已通过带自动刷新的IAM认证连接Redis")
}

关键注意事项

  • 权限配置:确保IAM实体拥有elasticache:Connect权限,示例策略:
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "elasticache:Connect",
            "Resource": "arn:aws:elasticache:your-region:your-account-id:replicationgroup:your-cluster-id"
        }
    ]
}
  • 集群模式支持:如果ElastiCache是集群模式,需使用redis.NewClusterClient替代redis.NewClient,同样将Token作为密码传入
  • 凭证来源:运行环境需有合法AWS凭证,本地开发可配置~/.aws/credentials,云端环境(EC2/EKS/ECS)可使用IAM角色

内容的提问来源于stack exchange,提问作者vig-go

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 21:24:54