Terraform部署AWS ElastiCache Redis连接超时、安全组未创建问题
问题背景
Terraform配置执行后可成功创建AWS资源,但本地发起ElastiCache Redis集群端点连接时触发超时,且配置中定义的安全组未关联到集群,疑似未生效。
现有Terraform配置
provider "aws" { region = "us-west-2" } resource "aws_elasticache_cluster" "example" { cluster_id = "cluster-example" engine = "redis" node_type = "cache.m4.large" num_cache_nodes = 1 parameter_group_name = "default.redis3.2" engine_version = "3.2.10" port = 6379 } resource "aws_security_group" "example" { name = "example" description = "Used by the example Redis cluster" vpc_id = "${aws_vpc.example.id}" ingress { description = "TLS from VPC" from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = [aws_vpc.example.cidr_block] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] ipv6_cidr_blocks = ["::/0"] } } resource "aws_vpc" "example" { cidr_block = "10.0.0.0/16" tags = { Name = "example" } } resource "aws_subnet" "example" { vpc_id = "${aws_vpc.example.id}" cidr_block = "10.0.0.0/20" tags = { Name = "example" } } resource "aws_elasticache_subnet_group" "example" { name = "example" description = "Example subnet group" subnet_ids = ["${aws_subnet.example.id}"] }
连接测试代码
import os import redis ENDPOINT = os.environ.get('REDIS_HOST') client = redis.Redis(host=ENDPOINT, port=6379, db=0) client.ping()
补充说明:集群未配置密码,连接请求从本地公网机器发起。
问题根因
配置存在3个核心错误,直接导致连接超时、安全组未生效:
- 资源未做关联绑定:
aws_elasticache_cluster资源块中没有指定subnet_group_name和security_group_ids参数,Terraform创建集群时不会关联你自建的子网组和安全组,集群会默认部署在AWS账号的默认VPC中,使用ElastiCache默认安全组。你定义的安全组实际已经在自建VPC中创建完成,只是没有绑定到任何资源,在集群详情页看不到就会误以为安全组未生成。 - 安全组规则配置错误:当前安全组入站仅放通了443端口的VPC内网访问,Redis服务使用的6379端口没有放通,且允许的访问源仅为VPC内网网段,本地公网发起的请求本身就不在允许范围内。
- 部署架构不支持本地直连:你使用的Redis 3.2.10版本不支持ElastiCache公网访问能力,就算安全组、关联关系配置正确,部署在自建VPC私有子网的集群只有私有IP,本地公网无法直接路由到该地址。
修复方案
按以下步骤修改配置即可解决问题:
- 补全ElastiCache集群的关联配置,在
aws_elasticache_cluster "example"块中添加以下两个参数,绑定自建的子网组和安全组:
subnet_group_name = aws_elasticache_subnet_group.example.name security_group_ids = [aws_security_group.example.id]
- 修正安全组入站规则:
- 如果选择同VPC跳板机访问(推荐,符合安全最佳实践):把入站端口改为6379,访问源保留VPC内网网段即可,后续在同VPC的EC2跳板机上运行测试代码,或通过SSH隧道转发本地端口到跳板机再连接。修改后的入站规则如下:
ingress { description = "Redis access from VPC internal" from_port = 6379 to_port = 6379 protocol = "tcp" cidr_blocks = [aws_vpc.example.cidr_block] }- 如果选择公网直连(仅测试环境临时使用):需要先把Redis引擎版本升级到6.0及以上,在集群配置中开启公网访问开关,同时在安全组入站规则中添加6379端口的放通规则,源地址设置为你本地的公网出口IP(禁止直接配置0.0.0.0/0,会暴露Redis到全公网)。
- 执行
terraform plan确认变更内容,检查输出中ElastiCache集群是否包含绑定子网组、安全组的操作,确认无误后执行terraform apply完成资源更新。 - 资源更新完成后,先在VPC控制台确认安全组已关联到ElastiCache集群的弹性网卡,再按你选择的访问方式测试连接即可。
内容的提问来源于stack exchange,提问作者apinanyogaratnam
相关产品推荐
相关产品推荐

