为什么 AWS Cloudformation UpdatePolicy 暂停时间在更新期间未使用



我设置了一个CloudFormation堆栈,该堆栈创建了一个自动扩展组(ASG(以及其他一些不相关的项目。

助理秘书长有如下更新政策:

UpdatePolicy:
AutoScalingReplacingUpdate:
WillReplace: 'false'
AutoScalingScheduledAction:
IgnoreUnmodifiedGroupSizeProperties: 'true'
AutoScalingRollingUpdate:
MinInstancesInService: '0'
MinSuccessfulInstancesPercent: '50'
MaxBatchSize: '2'
PauseTime: PT10M
WaitOnResourceSignals: 'true'

作为发布过程的一部分,我们更新了 CloudFormation 中的启动配置。 这会触发 ASG 更新,这是需要的。

有一个生命周期挂钩,设置了 600 秒的超时值,以防止 EC2 实例在完成一些检查之前进入服务。 如果这些检查失败,我会将错误信号发送回 ASG,并向生命周期挂钩发送放弃。

/opt/aws/bin/cfn-signal -e 1 --stack ${AWS::StackId} --resource MyASG --region ${AWS::Region}
INSTANCE_ID=$(curl -s http://169.254.169.254/latest/meta-data/instance-id)
ASG_NAME=$(aws ec2 --region ${AWS::Region} describe-tags --filters Name=resource-type,Values=instance Name=resource-id,Values=$(/opt/aws/bin/ec2-metadata -i | cut -d: -f2 | tr -d '[:space:]') Name=key,Values='aws:autoscaling:groupName' | jq '.Tags[] |  .Value' -r)
HOOK_NAME=$(aws autoscaling describe-lifecycle-hooks --auto-scaling-group-name $ASG_NAME --region ${AWS::Region} |jq -r '.LifecycleHooks[0].LifecycleHookName')
aws autoscaling complete-lifecycle-action --lifecycle-hook-name $HOOK_NAME --auto-scaling-group-name $ASG_NAME --lifecycle-action-result $1 --instance-id $INSTANCE_ID --region ${AWS::Region}

这适用于 EC2 实例被取消和终止的情况。 我遇到的问题是 CloudFormation 堆栈中的 ASG 继续在UPDATE_IN_PROGRESS中停留一个小时,然后它因"组未稳定"错误而失败,并且一切都开始回滚。

由于暂停时间设置为"PT10M",我希望它最多等待 10 分钟,并在发送 cfn 信号错误信号后立即开始回滚。

我无法确定为什么堆栈要等待一个小时。 这里有什么想法吗?

考虑到您的用例,您可以从 ASG 中删除AutoScalingReplacingUpdate属性。据我所知,AutoScalingReplacingUpdateAutoScalingRollingUpdate通常是相互排斥的。这也许可以解释为什么没有考虑PT10M。

此外,暂停时间是新启动的实例触发SUCCESS信号的时间上限。我可能会给ABANDON生命周期事件的发生留出一些余地,也许是一两分钟。

我实际上想通了我的问题。 问题在于,AWS显然仅在更新开始时的服务实例数大于0(或可能等于所需实例数(时才将更新视为"滚动更新"。

在这种情况下,首先关闭实例以在进行数据库更改时断开它们与 RDS 的连接。 因此,AWS并没有将其视为滚动更新。 它将其视为只是更新。 似乎没有任何方法可以指示常规更新失败或更改超时时间的方法。 就这样,它只等了一个小时。

这里有两种可能的解决方案:

  1. 执行数据库维护后,在启动 ASG 更新之前备份实例。 这样做似乎有点愚蠢,因为实例会立即再次关闭。 此外,滚动更新似乎会尝试多次,超时值每次都会重置。

  2. 让 cfinit 脚本发送在堆栈上执行"取消-更新-堆栈"。 这是处理这种情况的一种相当笨拙的方式,但它应该有效。

无论哪种方式,答案都是CloudFormation没有进行滚动更新,因此没有使用AutoScalingRollingUpdate块。

最新更新