如何从CloudFormation将创建的SecurityGroup分配给ELB?

Seb*_*Seb 14 amazon-web-services amazon-elb aws-cloudformation

我有一个生成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" }
            ]
        }
    }
Run Code Online (Sandbox Code Playgroud)

不幸的是,这失败了:

Invalid id: "sebelbtest2-ELBSecurityGroup-1F5Z5DIIVQKD1" (expecting "sg-...")
Run Code Online (Sandbox Code Playgroud)

那么如何引用ELBSecurityGroup作为ELB创建中的属性?

谢谢!

sor*_*han 12

正如mytwocents所提到的,解决方案是使用Fn :: GetAtt.此功能现在支持SecurityGroups:http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html

这适用于ELB:

...
"SecurityGroups" : [
    { "Fn::GetAtt" : [ "ELBSecurityGroup", "GroupId" ] }
]
...
Run Code Online (Sandbox Code Playgroud)

注意.如果您将其置于非默认VPC中,则还需要为安全组指定VPC,并为ELB指定子网ID.


Seb*_*Seb 7

由于我的CloudFormation脚本都是在VPC中完成的,我弄清楚问题是什么 - 我正在创建安全组,但没有为它指定VpcId.

安全组似乎是普通安全组或VPC安全组; 如果您{ "Ref": "MySecurityGroup" }使用普通的名称,则会获得安全组名称,但不会获得ID.如果您{ "Ref": "MySecurityGroup" }在VPC上执行此操作,则会返回sg-abcdefid,这是ELB安全组参数所需的ID.

完整的答案是:

"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" } ]
    }
}
Run Code Online (Sandbox Code Playgroud)

这一切都很完美(如果你正在做的一切都在你的VPC中),并且在我的配置中,将成功地限制对OfficeIP设置的访问.