【发布时间】:2017-06-20 10:30:57
【问题描述】:
我正在使用一个 CloudFormation 模板,该模板会根据我的请求调出尽可能多的实例,并希望在堆栈创建/更新被视为完成之前等待它们完成初始化(通过用户数据)。
期待
创建或更新堆栈应等待来自所有新创建实例的信号,以确保它们的初始化已完成。
如果任何创建的实例未能初始化,我不希望堆栈创建或更新被视为成功。
现实
CloudFormation 似乎只在首次创建堆栈时等待来自实例的信号。更新堆栈和增加实例的数量似乎忽略了信号。更新操作很快就成功完成,而实例仍在初始化中。
由于更新堆栈而创建的实例可能无法初始化,但更新操作已被视为成功。
问题
使用 CloudFormation,我怎样才能让现实达到预期?
我希望在创建堆栈时应用相同的行为,以在更新堆栈时应用。
类似问题
我只找到了与我的问题相匹配的以下问题:UpdatePolicy in Autoscaling group not working correctly for AWS CloudFormation update
已经开了一年了,还没有收到回复。
我正在创建另一个问题,因为我有更多信息要添加,我不确定这些细节是否与该问题中作者的匹配。
复制
为了演示这个问题,我根据Auto Scaling Group header on this AWS documentation page 下面的示例创建了一个模板,其中包括信号。
创建的模板已被改编为:
- 它使用 Ubuntu AMI(区域
ap-northeast-1)。考虑到这一变化,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",
...
}
...
您可以看到 Auto Scaling 组在 05:33:33 开始启动。 05:36:42(启动后 3 分钟),它收到了成功信号。这使得 Auto Scaling 组仅在片刻之后,即 05:36:45 达到自己的成功状态。
太棒了 - 像魅力一样工作。
现在让我们尝试通过更新堆栈将这个 Auto Scaling 组中的实例数增加到 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"
},
....
现在您可以看到,虽然 Auto Scaling 组在 05:44:20 开始更新,但它在 05:45:43 完成 - 完成时间不到一分半钟,考虑到用户数据中的休眠时间为 120 秒。
然后堆栈更新继续完成,而 Auto Scaling 组从未收到任何信号。
新实例确实存在。
在我的实际用例中,我通过 SSH 连接到其中一个新实例,发现即使在堆栈更新完成后它仍在初始化过程中。
我的尝试
我已经阅读并重新阅读了有关 CreationPolicy 和 UpdatePolicy 的文档,但未能确定我缺少什么。
查看上面使用的更新策略,我不明白它实际上在做什么。为什么WaitOnResourceSignals 是真的,但它没有等待?它是否有其他用途?
或者这些新实例不属于“滚动更新”政策?如果它们不属于那里,那么我希望它们属于创建政策,但这似乎也不适用。
因此,我真的不知道还能尝试什么。
我有一种偷偷摸摸的感觉,它按设计/预期运行,但如果是这样,那么 WaitOnResourceSignals 属性的意义何在?我如何才能满足上述预期?
【问题讨论】:
标签: amazon-web-services amazon-cloudformation autoscaling