我有一个生成SecurityGroup和ELB的CloudFormation脚本;我正在尝试在ELB创建中引用SecurityGroup;这是资源位:
"ELBSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Security group for the Arena dev stack",
"SecurityGroupIngress" : [
{"IpProtocol" : "tcp", "FromPort" : 80, "ToPort" : 80, "CidrIp" : { "Ref" : "OfficeIp" }}
]
}
},
"ProjectLoadBalancerTest" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"AvailabilityZones" : { "Fn::GetAZs" : "" },
"Instances" : [ ],
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : "12345",
"Protocol" : "HTTP"
} ],
"HealthCheck" : {
"Target" : {
"Fn::Join" : [ "", [ "HTTP:", "12345", "/status.json" ] ]
},
"HealthyThreshold" : "2",
"UnhealthyThreshold" : "5",
"Interval" : "60",
"Timeout" : "30"
},
"SecurityGroups" : [
{ "Ref" : "ELBSecurityGroup" }
]
}
}
不幸的是,这失败了:
Invalid id: "sebelbtest2-ELBSecurityGroup-1F5Z5DIIVQKD1" (expecting "sg-...")
那么如何引用ELBSecurityGroup作为ELB创建中的属性?
谢谢!
答案 0 :(得分:11)
正如mytwocents所说,解决方案是使用Fn :: GetAtt。此功能现在支持SecurityGroup:http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html
这适用于ELB:
...
"SecurityGroups" : [
{ "Fn::GetAtt" : [ "ELBSecurityGroup", "GroupId" ] }
]
...
请注意。如果您将其置于非默认VPC中,则还需要为安全组指定VPC,并为ELB指定子网ID。
答案 1 :(得分:7)
由于我的CloudFormation脚本都是在VPC中完成的,我想出了问题所在 - 我正在创建安全组,但没有为它指定VpcId。
安全组似乎是普通安全组或VPC安全组;如果您在正常情况下执行{ "Ref": "MySecurityGroup" }
,则会获得安全组名称,但不会获取ID。如果您在VPC上执行{ "Ref": "MySecurityGroup" }
,则会返回sg-abcdef
ID,这是ELB安全组参数所需的内容。
完整的答案是:
"ELBSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Security group for the ELB",
"VpcId" : { "Ref" : "VpcId" },
"SecurityGroupIngress" : [
{"IpProtocol" : "tcp", "FromPort" : 80, "ToPort" : 80, "CidrIp" : { "Ref" : "OfficeIp" }}
]
}
},
"MyELB": {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"AvailabilityZones" : { "Fn::GetAZs" : "" },
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : 8000,
"Protocol" : "HTTP"
} ],
"SecurityGroups" : [ { "Ref" : "ELBSecurityGroup" } ]
}
}
这一切都完美无缺(如果您所做的一切都在您的VPC中),并且在我的配置中,将成功限制对OfficeIP设置的访问权限。
答案 2 :(得分:1)
嗯...
好像模板正在返回安全组的名称而不是其ID。
根据the documentation,SecurityGroups
似乎只能附加到VPC中的负载均衡器。
如果是我,我会做两件事之一(或两件事):
答案 3 :(得分:0)
我遇到了同样的问题 - 但我认为,由于这只是初始设置,弹性负载均衡器可以从云形成中单独管理,直到它们解决了这个问题。此外,云端实例并不完全可靠,尤其是当您有安全组引用其他安全组时。
我希望GetAttr函数调用ID可以正常工作,但安全组不在GetAttr支持的列表中: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html
答案 4 :(得分:0)
试试这个安全组:
"ELBSecurityGroup" : {
"Type" : "AWS::EC2::SecurityGroup",
"Properties" : {
"GroupDescription" : "Security group for the Arena dev stack",
"SecurityGroupIngress" : [ {
"IpProtocol" : "tcp",
"FromPort" : 80,
"ToPort" : 80,
"SourceSecurityGroupOwnerId" : { "Fn::GetAtt" : [ "ProjectLoadBalancerTest", "SourceSecurityGroup.OwnerAlias" ] },
"SourceSecurityGroupName" : { "Fn::GetAtt" : [ "ProjectLoadBalancerTest", "SourceSecurityGroup.GroupName" ] }
} ]
}
},
并从ELB定义中删除"SecurityGroups"
。这将允许从您的ELB到您的应用服务器的流量。
看起来您还希望将ELB流量限制在您的办公室IP上。用apache指令这样做会更好。