CloudFormation AutoScalingGroup 不等待更新/扩展信号

2024-02-28

我正在使用一个 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财产以及我如何才能满足上述期望?


The AutoScalingRollingUpdate http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html#cfn-attributes-updatepolicy-rollingupdate策略处理轮换 Auto Scaling 组中的整组实例,以响应底层的更改LaunchConfiguration。它不适用于对现有组中实例数量的单独更改。根据更新策略属性 http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html文档,

The AutoScalingReplacingUpdate and AutoScalingRollingUpdate仅当您执行以下一项或多项操作时,政策才适用:

  • 更改 Auto Scaling 组的AWS::AutoScaling::LaunchConfiguration.
  • 更改 Auto Scaling 组的VPCZoneIdentifier财产
  • 更新包含与当前实例不匹配的实例的 Auto Scaling 组LaunchConfiguration.

更改 Auto Scaling 组的DesiredCapacity属性不在此列表中,因此AutoScalingRollingUpdate政策不适用于此类变更。

据我所知,不可能(使用标准 AWS CloudFormation 资源)延迟堆栈更新修改的完成DesiredCapacity直到添加到 Auto Scaling 组的所有新实例均已完全配置。

以下是一些替代选项:

  1. 而不是仅仅修改DesiredCapacity,修改一个LaunchConfiguration同时财产。这将触发一个AutoScalingRollingUpdate到所需的容量(缺点是它还会更新现有实例,实际上可能不需要修改)。
  2. Add an AWS::AutoScaling::LifecycleHook http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-as-lifecyclehook.html资源到您的 Auto Scaling 组,然后调用aws autoscaling complete-lifecycle-action http://docs.aws.amazon.com/cli/latest/reference/autoscaling/complete-lifecycle-action.html此外cfn-signal,表示生命周期挂钩完成。这不会根据需要延迟您的 CloudFormation 堆栈更新,但它will延迟各个自动缩放实例进入InService状态直到收到生命周期信号。 (看生命周期挂钩 http://docs.aws.amazon.com/autoscaling/latest/userguide/AutoScalingGroupLifecycle.html#as-lifecycle-hooks文档以获取更多信息。)
  3. 作为 #2 的扩展,应该可以将 Lifecycle Hook 添加到 Auto Scaling 组,以及自定义资源 http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html轮询您的 Auto Scaling 组,并且仅当 Auto Scaling 组包含DesiredCapacity全部实例数InService state.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CloudFormation AutoScalingGroup 不等待更新/扩展信号 的相关文章

随机推荐