将挂起的进程添加到具有 Cloudformation 的自动缩放组



我需要将挂起的进程添加到 Cloudformation 中。

我尝试添加SuspendedProcesses属性。

  ASG:
    Type: AWS::AutoScaling::AutoScalingGroup
    Properties:
      DesiredCapacity: 1
      MinSize: 1
      MaxSize: 2
      LaunchConfigurationName: !Ref LaunchConfigurationName
      SuspendedProcesses:
        - ReplaceUnhealthy

但是,我收到一个错误,指出这是一个不受支持的属性。

您可以创建一个 Lambda 函数来修改使用自定义资源创建的 ASG。这也需要一个 IAM::Role,因为 Lambda 函数需要引用一个作为其定义的一部分。

其中

大部分归功于 https://gist.github.com/atward/9573b9fbd3bfd6c453158c28356bec05:

ASG:
  Type: AWS::AutoScaling::AutoScalingGroup
  Properties:
    DesiredCapacity: 1
    MinSize: 1
    MaxSize: 2
    LaunchConfigurationName: !Ref LaunchConfigurationName
AsgProcessModificationRole:
  Type: AWS::IAM::Role
  Properties:
    AssumeRolePolicyDocument:
      Version: '2012-10-17'
      Statement:
      - Action:
        - sts:AssumeRole
        Effect: Allow
        Principal:
          Service:
          - lambda.amazonaws.com
    Policies:
      - PolicyName: AsgProcessModification
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - autoscaling:ResumeProcesses
            - autoscaling:SuspendProcesses
            Resource: "*"
          - Effect: Allow
            Action:
            - logs:CreateLogGroup
            - logs:CreateLogStream
            - logs:PutLogEvents
            Resource: arn:aws:logs:*:*:*
AsgProcessModifierFunction:
  Type: AWS::Lambda::Function
  Properties:
    Description: Modifies ASG processes during CF stack creation
    Code:
      ZipFile: |
        import cfnresponse
        import boto3
        def handler(event, context):
          props = event['ResourceProperties']
          client = boto3.client('autoscaling')
          try:
            response = client.suspend_processes(AutoScalingGroupName=props['AutoScalingGroupName'], 'ReplaceUnhealthy'])
            cfnresponse.send(event, context, cfnresponse.SUCCESS, {})
          except Exception as e:
            cfnresponse.send(event, context, cfnresponse.FAILED, {})
    Handler: index.handler
    Role:
      Fn::GetAtt:
      - AsgProcessModificationRole
      - Arn
    Runtime: python2.7
ModifyAsg:
  Type: AWS::CloudFormation::CustomResource
  Version: 1
  Properties:
    ServiceToken:
      Fn::GetAtt:
      - AsgProcessModifierFunction
      - Arn
    AutoScalingGroupName:
      Ref: ASG
    ScalingProcesses:
    - ReplaceUnhealthy

您可以向AutoScaleGroup添加UpdatePolicy属性来控制这一点。

AWS 在此处提供了一些文档:
https://aws.amazon.com/premiumsupport/knowledge-center/auto-scaling-group-rolling-updates/

以下是SuspendProcesses中添加的示例:

ASG:
  Type: AWS::AutoScaling::AutoScalingGroup
  UpdatePolicy: 
    AutoScalingRollingUpdate:
      SuspendProcesses:
        - "ReplaceUnhealthy"
  Properties:
    DesiredCapacity: 1
    MinSize: 1
    MaxSize: 2
    LaunchConfigurationName: !Ref LaunchConfigurationName

有关使用 UpdatePolicy 属性的完整信息,请访问:
https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-updatepolicy.html#cfn-attributes-updatepolicy-rollingupdate-maxbatchsize

如果您使用的是 AWS CDK,则以下内容应该有效

const autoscaling = require('@aws-cdk/aws-autoscaling');
const custom_resource = require('@aws-cdk/custom-resources');
function stopAsgScaling(stack, asgName) {
  return new custom_resource.AwsCustomResource(stack, 'MyAwsCustomResource', {
    policy: custom_resource.AwsCustomResourcePolicy.fromSdkCalls({
      resources: custom_resource.AwsCustomResourcePolicy.ANY_RESOURCE
    }),
    onCreate: {
      service: 'AutoScaling',
      action: 'suspendProcesses',
      parameters: {
        AutoScalingGroupName: asgName,
      },
      physicalResourceId: custom_resource.PhysicalResourceId.of(
        'InvokeLambdaResourceId1234'),
    },
    onDelete: {
      service: 'AutoScaling',
      action: 'resumeProcesses',
      parameters: {
        AutoScalingGroupName: asgName,
      },
      physicalResourceId: custom_resource.PhysicalResourceId.of(
        'InvokeLambdaResourceId1234'),
    },
  })
};
class MainStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);
    const autoScalingGroupName = "my-asg"
    const myAsg = new autoscaling.AutoScalingGroup(
      this,
      autoScalingGroupName,
      {autoScalingGroupName: autoScalingGroupName})
    const acr = stopAsgScaling(this, autoScalingGroupName);
    acr.node.addDependency(myAsg);
  }
};

最新更新