Cloudformation 模板在 UserData 完成之前完成部署

Unb*_*ess 5 amazon-ec2 amazon-web-services aws-cloudformation

在我正在部署的 CloudFormation 模板中,我在 UserData 块中运行了一些命令。这些命令之一为 NICE DCV 启动会话:https : //aws.amazon.com/hpc/dcv/

它看起来如下:

"UserData": {
    "Fn::Base64" : {
        "Fn::Join" : [
        "",
        [
        dcv create-session --type virtual ",
        " --owner ubuntu",
        " --user ubuntu",
        " my-session, "\n",
        "while ! (dcv list-sessions | grep -q 'my-session'); do sleep 1; done\n"
        ]
        ]
     }
}
Run Code Online (Sandbox Code Playgroud)

首先,我用命令创建一个会话:

$ dcv create-session --type virtual --owner ubuntu --user ubuntu my-session
Run Code Online (Sandbox Code Playgroud)

之后,我等待使用命令检查会话是否已成功创建:

$ while ! (dcv list-sessions | grep -q 'my-session'); do sleep 1; done
Run Code Online (Sandbox Code Playgroud)

我看到的问题是我相信 CloudFormation 模板在 UserData 脚本完成运行之前完成了它的部署。我相信是这种情况,因为如果我足够快并通过 ssh 进入实例,我会看到如下内容:

$ dcv list-sessions
There are no sessions available
$ dcv list-sessions
There are no sessions available
$ dcv list-sessions
There are no sessions available
$ dcv list-sessions
There are no sessions available
$ dcv list-sessions
Session: 'my-session' (owner: ubuntu)
Run Code Online (Sandbox Code Playgroud)

这表明实例中仍有某些东西在运行。


如何确保 UserData 代码得到实际遵守?

Unb*_*ess 4

为了确保 CloudFormation 模板等待 UserData 脚本完成,您必须执行以下两件事:

  1. CreationPolicy添加到您要定位的资源(在我的例子中是虚拟机)。

  2. 在脚本中添加逻辑以表明其完成。此自定义逻辑使用cfn-signal实用程序,您可能必须在实例中安装该实用程序。


模板现在的外观如下:

"UserData": {
    "Fn::Base64" : {
        "Fn::Join" : [
            "",
            [
            "/usr/local/bin/mylongrunningscript.sh"
            ]
        ]
    }
},
"CreationPolicy": {
    "ResourceSignal" : {
        "Count": "1",
        "Timeout": "PT10M"
    }
}
Run Code Online (Sandbox Code Playgroud)

cfn-signal实用程序用于发出脚本终止信号:

"/home/ubuntu/aws-cfn-bootstrap-*/bin/cfn-signal -e $? ",
" --stack ", { "Ref": "AWS::StackName" },
" --resource MyInstance" ,
" --region ", { "Ref" : "AWS::Region" }, "\n"
Run Code Online (Sandbox Code Playgroud)

请参阅此处的 Windows 示例。