Terraform配置安全组入站规则如何引用EC2堡垒机实例IP
问题解答
你不需要为堡垒机分配静态IP即可完成规则配置,AWS安全组提供了比固定IP更灵活可靠的配置方式。
最佳实践方案:通过安全组引用配置规则(推荐)
AWS安全组的入站规则支持直接指定另一个安全组作为信任源,不需要填写具体IP段,只要是绑定了被引用安全组的资源,自动获得对应访问权限,完全不受实例IP变动、实例重建替换的影响,是官方推荐的同VPC资源访问控制方式。
你当前的配置把堡垒机和NGINX的安全组规则混在了同一个安全组里,建议先拆分两个独立安全组分别绑定对应资源:
- 堡垒机安全组:绑定公有子网的堡垒机EC2,仅开放你本地公网IP的22端口入站,全流量出站
- NGINX安全组:绑定私有子网的NGINX EC2,入站规则仅放行堡垒机安全组的22端口访问,其余端口按需配置
参考配置代码
# 堡垒机专属安全组 resource "aws_security_group" "bastion_sg" { name = "bastion-host-sg" description = "Security group for public subnet bastion host" vpc_id = aws_vpc.vpc_server_nginx.id ingress { from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["187.74.121.76/32"] # 替换为你本地的公网IP/32 } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "bastion-host-sg" } } # NGINX专属安全组(替换你原来的public_sg配置) resource "aws_security_group" "nginx_sg" { name = "private-nginx-sg" description = "Security group for private subnet NGINX server" vpc_id = aws_vpc.vpc_server_nginx.id ingress { from_port = 22 to_port = 22 protocol = "tcp" # 直接引用堡垒机安全组ID作为源,无需填写任何IP security_groups = [aws_security_group.bastion_sg.id] } egress { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] } tags = { Name = "private-nginx-sg" } }
备选方案:直接引用EC2实例IP(不推荐)
如果你一定要用IP段配置规则,也不需要提前分配静态IP。Terraform会自动处理资源间的依赖关系:你在安全组规则中直接引用堡垒机EC2实例的私网IP属性即可,Terraform会先创建堡垒机EC2实例,拿到实例私网IP后再自动更新安全组规则。
注意:堡垒机访问同VPC私有子网的NGINX走内网链路,需要使用堡垒机的私网IP而非公网IP作为源地址。
规则配置示例
假设你定义的堡垒机EC2资源地址为aws_instance.bastion,入站规则可以这么写:
ingress { protocol = "tcp" from_port = 22 to_port = 22 # 直接引用堡垒机私网IP,Terraform自动处理依赖 cidr_blocks = ["${aws_instance.bastion.private_ip}/32"] }
这种方式的缺点是如果堡垒机被销毁重建、私网IP发生变动,需要重新执行terraform apply同步安全组规则,维护成本比安全组引用高。
关于静态IP的说明
你不需要为了配置NGINX的访问规则特意给堡垒机分配弹性公网IP(EIP,静态公网IP):
- 弹性公网IP的作用是固定堡垒机的公网访问地址,避免堡垒机重启后公网IP变动,导致你本地SSH连接需要更换地址、修改堡垒机安全组的本地IP放行规则
- 内网访问控制通过安全组引用即可实现,和公网IP是否固定完全无关
内容的提问来源于stack exchange,提问作者rbmxrenato
相关产品推荐
相关产品推荐

