我在Amazon CloudFormation模板中有多个实例,并试图通过UserData将它们连接在一起,即互相告知其他计算机的IP地址。
模板看起来像这样:
"Instance1" : { "Type" : "AWS::EC2::Instance", ... "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "\n", [ { "Fn::Join" : [ "=", [ "Instance2", { "Fn::GetAtt" : [ "Instance2" , "PrivateIp"] } ] ] } ] ] } } } }, "Instance2" : { "Type" : "AWS::EC2::Instance", ... "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "\n", [ { "Fn::Join" : [ "=", [ "Instance1", { "Fn::GetAtt" : [ "Instance1" , "PrivateIp"] } ] ] } ] ] } } } },
Amazon CloudFormation拒绝处理此CloudFormation,并报告无法处理这两个实例之间的循环依赖关系。
有没有办法解决这个问题,而不必自己build立一些东西。 即我希望有两个实例的UserData反映了另一台机器的IP地址,而事后没有手动修改UserData。
我实际上想通过使用ElasticIP来单独使用Cloud Formation模板来做到这一点。
我创build一个ElasticIP(在这种情况下,不能直接将它分配给一个实例!)
"ServerEIP" : { "Type" : "AWS::EC2::EIP", "Properties" : { } },
然后我在UserData中引用该IP
"Client" : { ... "UserData" : { { "Fn::Join" : [ "=", [ "Server", { "Ref" : "ServerEIP" } ] ] }
服务器可以直接引用客户端
"Server" : { "Type" : "AWS::EC2::Instance", ... "UserData" : { ... { "Fn::Join" : [ "=", [ "Client", { "Fn::GetAtt" : [ "Client" , "PrivateIp"] } ] ] },
之后,我将Elastic与实际服务器相关联,以使Cloud Formation正确处理依赖性:
"ServerIPAssoc" : { "Type" : "AWS::EC2::EIPAssociation", "Properties" : { "InstanceId" : { "Ref" : "Server" }, "EIP" : { "Ref" : "ServerEIP" } } },
完成! 我现在有两个知道另一个节点的IP地址的实例。
唯一的缺点是stream量现在是通过公共IP地址完成的,因此导致stream量成本,可能不太安全。
更新:我现在遇到这里描述的问题,不知道我是否可以在这里解决这个问题。
您可以完成高层目标,但不能满足您列出的约束条件(例如,包括两个实例的用户数据中的原始IP地址)。 简单的原因是:
用户数据必须在实例启动之前指定。
直到实例启动后才知道IP地址。
CloudFormation可以启动一个实例,并将其IP地址提供给第二个实例,但不能同时提供(循环依赖)。
你可以采取多种方法和技术来解决这种双向交stream。 在高层次上:
你可以把A的IP地址传给B,然后让B联系A,让它知道它的IP地址是什么(注意安全)。
您可以将每个实例的IP地址存储在外部存储器(例如Route53,SimpleDB)中,然后每个实例在启动时都会查询该外部存储器以查找其伙伴。
build议
这里有一个简单的方法可以用于CloudFormation和可靠的AWS服务:
在Route53中设置一个域(托pipe区域)。 这可以完全独立于您目前使用的任何公共领域,但如果您已经使用Route53,则可以将此function插入到相同的域中。
在您的CloudFormation模板中,为每个实例生成一个唯一的名称,可能是基于当前的CloudFormation堆栈名称(例如,“MYSTACK-server-a.example.com”和“MYSTACK-server-b.example.com”)
在CloudFormation模板中,将实例名称传递到每个服务器中各自的用户数据中。
将指令添加到您的CloudFormation模板,以将这些新的DNS名称(logging集)注入到Route53中,并将它们映射到实例的IP地址。
CloudFormation将启动实例,传入用户数据。 当IP地址被分配给实例时,CloudFormation会将它们映射到Route53 DNS中的主机名。 然后您的实例可以使用主机名查找对方。
如果您的实例需要在启动时find他们的合作伙伴,他们将需要保持轮询DNS,直到合作伙伴已经转移到运行状态并被分配了一个IP地址。 小心使用cachingDNS“未命中”的软件。