CloudFormation中如何配置两个安全组的双向访问依赖
问题1:当前代码无法正常运行,存在2个核心错误
- 端口范围配置错误:InstanceSecurityGroup的第一条入站规则
FromPort设为8080、ToPort设为22,不符合AWS要求的端口范围起始值必须小于等于结束值的规则,提交后会直接返回参数错误。 - 循环依赖错误:两个安全组都在自身的内置入站规则中引用了对方的ID,CloudFormation无法判断资源创建顺序,会直接报循环依赖异常,栈创建失败。
问题2:添加DependsOn属性无法解决问题
不管给哪个安全组添加DependsOn配置,先创建的安全组在初始化时需要引用的另一个安全组还未创建,无法获取到对应的安全组ID,依然会创建失败。DependsOn只能解决线性依赖问题,无法处理循环依赖场景。
问题3:你需要使用AWS::EC2::SecurityGroupIngress独立资源替代内置入站规则
这是解决跨安全组引用循环依赖的标准方案,调整逻辑如下:
- 先定义两个不带内置
SecurityGroupIngress的空安全组资源 - 再单独定义所有入站规则,关联到已经声明的安全组上
调整后的参考代码如下:
"InstanceSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Enable tomcat, ssh, mysql access via port 8080, 22, 3306 as well" } }, "DatabaseSecurityGroup": { "Type": "AWS::EC2::SecurityGroup", "Properties": { "GroupDescription": "Enable mysql database access to instance and back via port 3306" } }, // 实例安全组的入站规则 "InstanceSshIngress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupId": {"Ref": "InstanceSecurityGroup"}, "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22, "CidrIp": "0.0.0.0/0" } }, "InstanceTomcatIngress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupId": {"Ref": "InstanceSecurityGroup"}, "IpProtocol": "tcp", "FromPort": 8080, "ToPort": 8080, "CidrIp": "0.0.0.0/0" } }, "InstanceMysqlFromDbIngress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupId": {"Ref": "InstanceSecurityGroup"}, "IpProtocol": "tcp", "FromPort": 3306, "ToPort": 3306, "SourceSecurityGroupId": {"Ref":"DatabaseSecurityGroup"} } }, // 数据库安全组的入站规则 "DbMysqlFromInstanceIngress": { "Type": "AWS::EC2::SecurityGroupIngress", "Properties": { "GroupId": {"Ref": "DatabaseSecurityGroup"}, "IpProtocol": "tcp", "FromPort": 3306, "ToPort": 3306, "SourceSecurityGroupId": {"Ref": "InstanceSecurityGroup"} } }
注:原配置中8080端口的错误规则已拆分为独立的8080端口开放规则,避免放开不必要的端口范围,提升安全性。
内容的提问来源于stack exchange,提问作者DozezQuest
相关产品推荐
相关产品推荐

