Как назначить созданную SecurityGroup для ELB из CloudFormation?
У меня есть CloudFormation script, который генерирует SecurityGroup и ELB; Я пытаюсь ссылаться на SecurityGroup в создании ELB; здесь бит ресурсов:
"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?
Спасибо!
Ответы
Ответ 1
Поскольку моя CloudFormation script выполняется в VPC, я выяснил, в чем проблема: я создавал группу безопасности, но не указывал VpcId для нее.
Группы безопасности представляют собой либо обычные группы безопасности, либо группы безопасности VPC; если вы выполняете { "Ref": "MySecurityGroup" }
на обычном, вы получаете имя группы безопасности, но не идентификатор. Если вы выполняете { "Ref": "MySecurityGroup" }
на VPC, вы возвращаете идентификатор sg-abcdef
, что и требуется для параметра группы безопасности 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
Как упоминалось выше, решение заключается в использовании Fn:: GetAtt. SecurityGroups теперь поддерживаются этой функцией: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html
Это работает на ELB:
...
"SecurityGroups" : [
{ "Fn::GetAtt" : [ "ELBSecurityGroup", "GroupId" ] }
]
...
Примечание. Если вы помещаете это в не-по умолчанию VPC, вам также необходимо указать VPC для группы безопасности и идентификатор подсети для ELB.
Ответ 3
Хммм...
Кажется, что шаблон возвращает имя группы безопасности вместо идентификатора.
Основываясь на документации, похоже, что SecurityGroups
можно подключить только к балансировщику нагрузки в VPC.
Если бы это был я, я бы сделал одну из двух вещей (или обоих):
Ответ 4
У меня была та же проблема, но я решил, что, поскольку это только для первоначальной настройки, балансировщик эластичной нагрузки можно управлять отдельно от облачного образования, пока они не будут работать с этой ошибкой. Кроме того, облако прежнего не является полностью надежным, особенно когда у вас есть группы безопасности, ссылающиеся на другие группы безопасности.
Я надеялся, что вызов функции GetAttr для ID будет работать, но группы безопасности не находятся в поддерживаемом списке GetAttr:
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html
Ответ 5
Попробуйте это для вашей SecurityGroup:
"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" ] }
} ]
}
},
и удалите "SecurityGroups"
из вашего определения ELB. Это позволит трафик с вашего ELB на серверы приложений.
Похоже, вы также хотите ограничить трафик ELB на IP-адрес вашего офиса. Это было бы лучше сделать с чем-то вроде директив apache.