我正在使用一个 CloudFormation 模板,该模板会根据我的请求提供尽可能多的实例,并希望在堆栈创建/更新被视为完成之前等待它们完成初始化(通过用户数据)。
期望
创建或更新堆栈应该等待来自所有新创建的实例的信号,以确保它们的初始化完成。
如果任何创建的实例未能初始化,我不希望堆栈创建或更新被视为成功。
现实
CloudFormation 似乎仅在首次创建堆栈时等待来自实例的信号。更新堆栈和增加实例数量似乎忽略了信号。更新操作很快成功完成,同时实例仍在初始化。
由于更新堆栈而创建的实例可能无法初始化,但更新操作已被视为成功。
问题
使用CloudFormation,如何让现实达到预期?
我希望在创建堆栈时和更新堆栈时应用相同的行为。
类似的问题
我只发现以下问题符合我的问题:Autoscaling 组中的 UpdatePolicy 对于 AWS CloudFormation 更新无法正常工作 https://stackoverflow.com/questions/30525972/updatepolicy-in-autoscaling-group-not-working-correctly-for-aws-cloudformation-u
它已经开放一年了,但尚未收到答复。
我正在创建另一个问题,因为我有更多信息要添加,并且我不确定这些细节是否与该问题中的作者的细节相匹配。
繁殖
为了演示这个问题,我根据下面的示例创建了一个模板此 AWS 文档页面上的 Auto Scaling 组标题 http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-creationpolicy.html,其中包括信令。
创建的模板已进行如下调整:
- 它使用 Ubuntu AMI(在区域
ap-northeast-1
). The cfn-signal
考虑到此更改,命令已根据需要进行引导和调用。
- 新参数指示在 Auto Scaling 组中启动多少个实例。
- 在发出信号之前添加了 2 分钟的睡眠时间,以模拟初始化时所花费的时间。
这是模板,保存到template.yml
:
Parameters:
DesiredCapacity:
Type: Number
Description: How many instances would you like in the Auto Scaling Group?
Resources:
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AvailabilityZones: !GetAZs ''
LaunchConfigurationName: !Ref LaunchConfig
MinSize: !Ref DesiredCapacity
MaxSize: !Ref DesiredCapacity
CreationPolicy:
ResourceSignal:
Count: !Ref DesiredCapacity
Timeout: PT5M
UpdatePolicy:
AutoScalingScheduledAction:
IgnoreUnmodifiedGroupSizeProperties: true
AutoScalingRollingUpdate:
MinInstancesInService: 1
MaxBatchSize: 2
PauseTime: PT5M
WaitOnResourceSignals: true
LaunchConfig:
Type: AWS::AutoScaling::LaunchConfiguration
Properties:
ImageId: ami-b7d829d6
InstanceType: t2.micro
UserData:
'Fn::Base64':
!Sub |
#!/bin/bash -xe
sleep 120
apt-get -y install python-setuptools
TMP=`mktemp -d`
curl https://s3.amazonaws.com/cloudformation-examples/aws-cfn-bootstrap-latest.tar.gz | \
tar xz -C $TMP --strip-components 1
easy_install $TMP
/usr/local/bin/cfn-signal -e $? \
--stack ${AWS::StackName} \
--resource AutoScalingGroup \
--region ${AWS::Region}
现在,我通过以下方式创建具有单个实例的堆栈:
$ aws cloudformation create-stack \
--region=ap-northeast-1 \
--stack-name=asg-test \
--template-body=file://template.yml \
--parameters ParameterKey=DesiredCapacity,ParameterValue=1
等待几分钟创建完成后,让我们看看一些关键的堆栈事件:
$ aws cloudformation describe-stack-events \
--region=ap-northeast-1 \
--stack-name=asg-test
...
{
"Timestamp": "2017-02-03T05:36:45.445Z",
...
"LogicalResourceId": "AutoScalingGroup",
...
"ResourceStatus": "CREATE_COMPLETE",
...
},
{
"Timestamp": "2017-02-03T05:36:42.487Z",
...
"LogicalResourceId": "AutoScalingGroup",
...
"ResourceStatusReason": "Received SUCCESS signal with UniqueId ...",
"ResourceStatus": "CREATE_IN_PROGRESS"
},
{
"Timestamp": "2017-02-03T05:33:33.274Z",
...
"LogicalResourceId": "AutoScalingGroup",
...
"ResourceStatusReason": "Resource creation Initiated",
"ResourceStatus": "CREATE_IN_PROGRESS",
...
}
...
您可以看到自动伸缩组于 05:33:33 开始启动。 05:36:42(启动后3分钟)收到成功信号。这使得 Auto Scaling 组在不久后的 05:36:45 就达到了自己的成功状态。
太棒了——工作起来很有魅力。
现在,我们尝试通过更新堆栈将此自动缩放组中的实例数量增加到 2:
$ aws cloudformation update-stack \
--region=ap-northeast-1 \
--stack-name=asg-test \
--template-body=file://template.yml \
--parameters ParameterKey=DesiredCapacity,ParameterValue=2
等待更新完成的时间要短得多,让我们看看一些新的堆栈事件:
$ aws cloudformation describe-stack-events \
--region=ap-northeast-1 \
--stack-name=asg-test
{
"ResourceStatus": "UPDATE_COMPLETE",
...
"ResourceType": "AWS::CloudFormation::Stack",
...
"Timestamp": "2017-02-03T05:45:47.063Z"
},
...
{
"ResourceStatus": "UPDATE_COMPLETE",
...
"LogicalResourceId": "AutoScalingGroup",
"Timestamp": "2017-02-03T05:45:43.047Z"
},
{
"ResourceStatus": "UPDATE_IN_PROGRESS",
...,
"LogicalResourceId": "AutoScalingGroup",
"Timestamp": "2017-02-03T05:44:20.845Z"
},
{
"ResourceStatus": "UPDATE_IN_PROGRESS",
...
"ResourceType": "AWS::CloudFormation::Stack",
...
"Timestamp": "2017-02-03T05:44:15.671Z",
"ResourceStatusReason": "User Initiated"
},
....
现在您可以看到,虽然自动缩放组在 05:44:20 开始更新,但它在 05:45:43 完成 - 不到一分半钟就完成了,考虑到睡眠时间为用户数据中的120秒。
然后,堆栈更新将继续完成,而自动缩放组不会收到任何信号。
新实例确实存在。
在我的实际用例中,我通过 SSH 连接到这些新实例之一,发现即使在堆栈更新完成后它仍然处于初始化过程中。
我尝试过的
我已经阅读并重新阅读了相关文档CreationPolicy http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-creationpolicy.html and UpdatePolicy http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html,但未能确定我缺少什么。
看看上面使用的更新策略,我不明白它实际上在做什么。为什么是WaitOnResourceSignals
确实如此,但它没有等待?它还有其他目的吗?
或者这些新实例不属于“滚动更新”政策?如果它们不属于那里,那么我希望它们属于创建政策的范围,但这似乎也不适用。
因此,我真的不知道还能尝试什么。
我有一种隐隐的感觉,它正在按设计/预期运行,但如果是这样,那还有什么意义呢?WaitOnResourceSignals
财产以及我如何才能满足上述期望?