AWS – 启动NAT实例之前启动的LaunchConfig(CloudFormation)

我的情景

在CloudFormation模板中,我有一个VPC,一个公有子网和一个私有子网。 在公有子网中,我有一个实例中的amazons NAT AMI。 在私有子网中,我有一个内部LoadBalancer后面的自动缩放组。 这个autoScaling组有一个LaunchConfig来安装带有演示网页的httpd。

问题

在此私有子网自动扩展组中启动的EC2实例不安装Web服务器。 这会导致我的ELB失败并回滚整个cloudformation栈。 但是,我可以在创build后SSH,在那里我可以成功wget互联网网页和手动使用yum安装httpd。 这通过使ELB检查高兴来修复我的cloudFormation堆栈。 /var/log/cloudinit-output.log表示实例在初始化期间无法parsingamazon yum存储库。

我有一种感觉,这可能是由于在NAT实例完全启动并正常工作之前,在新的EC2实例中启动LaunchConfig引起的。 我曾尝试在AutoScaling组中添加“DependsOn”:“NATInstance”,但这并没有解决问题。

你能帮我吗?

Cloudwatcher对他的回答是正确的,但是我想为将来有类似问题的任何人阐述。

当资源发出信号时,CloudFormation模板中的“DependsOn”属性会被满足。 默认情况下,我相信这是当亚马逊已经创build的资源。 在我的例子中,NAT实例实际上已经被创build,这是实例发送信号的时间。 但是,实例内部的configuration和设置还没有完成,因此在其他实例试图利用它之前,NAT仍然不可操作。 其他实例然后失败,因为他们无法通过NAT实例获得互联网连接。

您可以自己手动覆盖默认信号。 这意味着你可以做你的行动,然后一旦完成信号。 依赖它的所有其他资源的“DependsOn”属性将正常工作。 您可以通过在EC2实例中使用一些亚马逊帮助程序脚本来执行此操作,具体为“cfn-init”和“cfn-signal”。 在EC2实例(或自动扩展组)的“UserData”属性中,您可以安装aws-cfn-bootstrap来获取脚本(或您正在使用的包pipe理器)。 然后,您可以在UserData内部执行初始化步骤,一旦完成,然后使用cfn-signal完成资源信号。 这是我的例子:

"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [ "#!/bin/bash -xe\n", "yum update -y aws-cfn-bootstrap\n", "wget <<URL FOR YOUR INIT BASH SCRIPT HERE>> -O - | bash\n", "/opt/aws/bin/cfn-init -v ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource <RESOURCE TO SIGNAL HERE> ", " --region ", { "Ref" : "AWS::Region" }, "\n", "/opt/aws/bin/cfn-signal -e $? ", " --stack ", { "Ref" : "AWS::StackName" }, " --resource <RESOURCE TO SIGNAL HERE> ", " --region ", { "Ref" : "AWS::Region" }, "\n" ]]}} 

我希望这可以帮助别人。

有几件事需要考虑安全组,并允许stream量。 但对于具体的NAT,请确保在NAT启动configuration你不发出

 /opt/aws/bin/cfn-signal 

直到您的设置和传递脚本完成。 鉴于您是“DependsOn”NAT,它将不会继续,直到CloudFormation堆栈收到此信号。

[编辑]如果有人今天(2015-12-18)之后看到这个,你应该考虑移动AWS提供的NATpipe理服务。 https://aws.amazon.com/about-aws/whats-new/2015/12/introducing-amazon-vpc-nat-gateway-a-managed-nat-service/