我在这里吃了一点。 我有一个特定的应用程序(我无法修改),我需要使用CloudFormation自动在3个AWS EC2实例上部署这些应用程序,并且我需要其中的3个在引导时相互了解,或者至less在任何stream量击中他们。
简而言之,需要发生的事情是,随着机器的启动, 每个机器都需要运行一个本地命令(一个Windows Shell脚本),其中包含所有 3台机器的主机名或IP。 想象一下:
c:\>node startReplication.js server1.aws.com,server2.aws.com,server3.aws.com
更难的是我不能使用静态IP或名称,我需要这是完全dynamic的每个堆栈。 我也不能使用任何非AWS本地工具,如厨师或Terraform或任何其他第三方,因为在这里指定不相干的原因。 一切都必须通过本地AWS服务完成。
我试过做这样的事情:
"UserData" : { "Fn::Base64" : { "Fn::Join" : [ ",", [ { "Fn::GetAtt" : [ "server1", "PublicDnsName" ] }, { "Fn::GetAtt" : [ "server2", "PublicDnsName" ] }, { "Fn::GetAtt" : [ "server3", "PublicDnsName" ] } ] } }
为了只传递dns的名字,甚至还没有到达如何实际运行脚本/命令的地步 – 但是由于循环引用,这已经失败了。
我的理解是CloudFormation将这些引用视为依赖关系 – 所以要引用“server1”我需要创build它,但是如果所有3台机器都需要全部3个引用,那么我已经碰到了一堵砖墙。
我没有用AWS(实际上根本没有足够的经验)为此找出另一种途径,但是我有一些理论上的想法,你可能能够确认,或者build议你自己去做:
UserData引用另外两个代理服务器,然后将该信息发送给另外两个以触发所述脚本 userdata脚本启动的节点进程中运行cf-init来获取这些信息并将其传递给需要运行的后续脚本(不知道cf-init是如何工作的,以及在所有3台机器分配了dns名字后) 我想避免一个过于复杂或复杂的解决scheme,因为我的知识有限,时间有限(是不是现在成功的秘诀?)
我希望我已经明确了这个问题。 提前致谢!
使用CloudFormation堆栈名称作为3个服务器域名的子域。 这样你就知道DNS名字是什么了,可以注入到configuration文件中。
"DNSRecordInstance1": { "Type": "AWS::Route53::RecordSet", "Properties": { "HostedZoneName": { "Ref": "HostedZone" }, "Name": { "Fn::Join": [ ".", [ "server1", { "Ref": "AWS::StackName" }, ".", { "Ref": "HostedZone" } ] ] }, "Type": "A", "TTL": "900", "ResourceRecords": [ { "Fn::GetAtt": [ "Instance1", "PrivateIp" ] } ] } }
这将创build一个DNSloggingserver1.<stack-name>.<hosted-zone> ,例如server1.test-stack.example.com 。 你为所有3个实例做。
然后,在每个实例的元数据中,您可以立即创buildconfiguration文件,因为您知道DNS名称将是什么,不需要知道IP是什么 – DNS将处理该名称。
"Instance1": { "Type": "AWS::EC2::Instance", "Properties": { [...] "UserData": { "Fn::Base64": { "Fn::Join": ["", [ "<script>\n", "cfn-init.exe -v -s ", { "Ref" : "AWS::StackId" }, " -r Instance1", " --region ", { "Ref" : "AWS::Region" }, "\n", "</script>" ] ] } } }, "Metadata": { "AWS::CloudFormation::Init": { "config": { "files": { "c:\\servers.conf": { "content": { "Fn::Join": ["", [ "server1.", { "Ref": "AWS::StackName" }, ".", { "Ref": "HostedZone" }, "\n", "server2.", { "Ref": "AWS::StackName" }, ".", { "Ref": "HostedZone" }, "\n", "server3.", { "Ref": "AWS::StackName" }, ".", { "Ref": "HostedZone" }, "\n" ]]} } } } [...]
这将创buildC:\servers.conf与您的服务器的3个DNS名称的列表。 再次,做你的每个实例,你完成了:)
上面的模板片段还应该帮助您运行Cloud Init脚本。 确保实例引用保持正确,即Instance1的UserData中的cfn-init.exe -r Instance1 。 将其更新到cfn-init.exe -r Instance2等。 cfn-init.exe -r Instance2后面的标签必须是其定义的资源名称。
希望有所帮助!