我创建了一个AWS Cloudformation模板,但我无法克服循环依赖。我正在创建EC2实例和负载均衡器,负载均衡器依赖于EC2实例,因为它在其Instances属性中引用它。一切正常,直到我必须在EC2实例Init部分中引用负载均衡器的DNSName属性。
"AppServer": {
"Type": "AWS::EC2::Instance",
"Metadata": {
"AWS::CloudFormation::Init" : {
"configSets" : {
"Install" : [ "Install" ]
},
...
...
...
"Install" : {
"commands" : {
"update hostname rmi" : {
"command" : { "Fn::Join" : [ "", [ "runuser -lm rlt -c \"/home/ec2-user/awscf/update-rmi.sh ", { "Fn::GetAtt" : [ "WebLoadBalancer", "DNSName" ] }, "\"" ] ] }
},
}
因此,问题在于EC2实例无法引用负载均衡器,因为它尚未创建,并且无法首先创建负载均衡器,因为它需要EC2实例ID,因此它可以与它相关联。
我查看了WaitConditions以及CreationPolicy,但除非我误解他们的工作方式,否则我不认为他们会帮助我。基本上我需要的是a)创建EC2实例但是在创建LoadBalancer之前不执行UserData或b)首先创建LoadBalancer并且在EC2实例之后不要将它与EC2实例关联创建后返回并更新LoadBalancer以将其与EC2实例关联。有谁知道这样的事情是否可能?在创建完整堆栈之外,然后返回并手动更新它?理想情况下,我希望在堆栈的单个创建中发生这种情况。
答案 0 :(得分:0)
您可以考虑使用EC2实例中的cfn-get-metadata助手脚本来检索Stack :: Resource信息。
http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-get-metadata.html
答案 1 :(得分:0)
您可能需要为每个资源逻辑名称添加Ref
。
我遇到同样的错误(循环依赖):
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -xe
# ...
echo "<h1>I amrunning on ASG ${MyAutoScalingGroup}</h1>
添加Ref
会将其解析如下:
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -xe
# ...
echo "<h1>I amrunning on ASG ${!Ref MyAutoScalingGroup}</h1>
注意:我使用的是YAML,因为JSON对于Cloudformation非常糟糕。