具有 launchConfiguration 和 AutoScalingGroup 的 aws cloudformation 中的 cfn 信号

cfn-signal in aws cloudformation with launchConfiguration and AutoScalingGroup

我的 AWS Cloudformation 模板中有以下配置。

模板基于instance1创建一个EC2实例。我在 LaunchConfiguration 中使用对相同实例的引用来创建相同类型的实例。 我面临的问题是在我的 AutoScalingGroup 模板中包含 CreationPolicy 元素。当 ASG 启动实例并等待 cfn 信号时,我收到以下错误。

+ /opt/aws/bin/cfn-signal -e 0 --stack ss07 --resource Instance1 --region us-west-2
ValidationError: Resource Instance1 is in CREATE_COMPLETE state and cannot be signaled

似乎以某种方式引用了已存在的 instance1,而不是 LaunchConfig 创建的实例。我看到了其中嵌入了 LaunchConfig 的示例,但我想将实例详细信息保存在一处而不是两处。

"instance1": {
      "Type": "AWS::EC2::Instance",
      "Metadata": {
        "AWS::CloudFormation::Init": {
          "configSets": {
            "install": ["yum_packages","install_cfn"]
          },

          "yum_packages": {
              "packages" : {
                  "yum" : {
                    "awslogs"        : [],
                    "ruby"        : [],
                    "wget"        : [],
                    "httpd"       : []
                  }
            }
          },
          "install_cfn": {
            "files": {
              "/etc/cfn/cfn-hup.conf": {
                "content": {
                  "Fn::Join": [
                    "",
                    [
                      "[main]\n",
                      "stack=",
                      {
                        "Ref": "AWS::StackId"
                      },
                      "\n",
                      "region=",
                      {
                        "Ref": "AWS::Region"
                      },
                      "\n"
                    ]
                  ]
                },
                "mode": "000400",
                "owner": "root",
                "group": "root"
              },
              "/etc/cfn/hooks.d/cfn-auto-reloader.conf": {
                "content": {
                  "Fn::Join": [
                    "",
                    [
                      "[cfn-auto-reloader-hook]\n",
                      "triggers=post.update\n",
                      "path=Resources.WebServer.Metadata.AWS::CloudFormation::Init\n",
                      "action=/opt/aws/bin/cfn-init -v ",
                      "         --stack ",
                      {
                        "Ref": "AWS::StackName"
                      },
                      "         --resource splitsweetInstance ",
                      "         --configsets install ",
                      "         --region ",
                      {
                        "Ref": "AWS::Region"
                      },
                      "\n"
                    ]
                  ]
                },
                "mode": "000400",
                "owner": "root",
                "group": "root"
              }             
            },
            "services": {
              "sysvinit": {
                "cfn-hup": { "enabled": "true",  "ensureRunning": "true",  "files": [
                    "/etc/cfn/cfn-hup.conf",
                    "/etc/cfn/hooks.d/cfn-auto-reloader.conf"
                                ]
                            }
              }
            }
          }
        }
      },
      "CreationPolicy": {
        "ResourceSignal": {
          "Timeout": "PT10M"
        }
      },
      "Properties": {
        "ImageId": {
                "Fn::FindInMap": [
                    "AWSRegionArch2AMI", {
                        "Ref": "AWS::Region"
                    }, {
                        "Fn::FindInMap": [
                            "AWSInstanceType2Arch", {
                                "Ref": "instanceType1"
                            },
                            "Arch"
                        ]
                    }
                ]
            },
        "InstanceType": {"Ref": "instanceType1"},
        "KeyName": {"Ref": "KeyName"},
        "Monitoring": "false",
        "UserData"       : { "Fn::Base64" : { "Fn::Join" : ["", [
             "#!/bin/bash -xe\n",
             "yum install -y aws-cfn-bootstrap\n",

             "# Install the files and packages from the metadata\n",
             "/opt/aws/bin/cfn-init -v ",
             "         --stack ", { "Ref" : "AWS::StackName" },
             "         --resource splitsweetInstance ",
             "         --configsets install ",
             "         --region ", { "Ref" : "AWS::Region" }, "\n",

             "wget ", { "Fn::FindInMap": [  "Region2CodeDeployAgent", { "Ref": "AWS::Region"},  "url"] }, "\n",
             "chmod +x ./install\n",
             "./install auto\n",

             "# Signal the status from cfn-init\n",
             "/opt/aws/bin/cfn-signal -e $? ",
             "         --stack ", { "Ref" : "AWS::StackName" },
             "         --resource splitsweetInstance ",
             "         --region ", { "Ref" : "AWS::Region" }, "\n"

        ]]}},
        "Tags": [
          {
            "Key": "Name",
            "Value": "inst1"
          }
        ],
        "SecurityGroupIds": [
            { "Fn::GetAtt" : [ "instance1Sg", "GroupId" ] }
        ]
      }
    }

我的启动配置如下 -

"LaunchConfig1": {
       "Type" : "AWS::AutoScaling::LaunchConfiguration",
       "Properties" : {
          "ImageId": {
            "Fn::FindInMap": [
                "AWSRegionArch2AMI", {
                    "Ref": "AWS::Region"
                }, {
                    "Fn::FindInMap": [
                        "AWSInstanceType2Arch", {
                            "Ref": "instanceType1"
                        },
                        "Arch"
                    ]
                }
            ]
          },
          "InstanceId" : { "Ref":"instance1"},
          "InstanceMonitoring" : "false",
          "InstanceType" : { "Ref": "instanceType1"},
          "KeyName" : { "Ref" : "KeyName" },
          "SecurityGroups" : [ { "Fn::GetAtt" : [ "instance1Sg", "GroupId" ] } ]
       }
    }

这是我的 AutoScalingGroup 模板 -

    "AutoScalingGroup1":    {
       "Type" : "AWS::AutoScaling::AutoScalingGroup",
       "Properties" : {
          "AvailabilityZones" :  {  "Fn::GetAZs": { "Ref": "AWS::Region" }   },
          "Cooldown" : "60",
          ....
          "LaunchConfigurationName" : {"Ref":"LaunchConfig1"},
          "MaxSize" : "3",
          "MinSize" : "1",
          "TargetGroupARNs" : [ {"Ref":"TargetGroup1"} ],
          "VPCZoneIdentifier" : [   { "Ref": "subnetCache1" },   { "Ref": "subnetCache2" },  { "Ref": "subnetCache3" }  ]
       },
       "CreationPolicy" : {
        "ResourceSignal" : {
          "Timeout" : "PT6M",
          "Count"   : "1"
         }
       }
    }   

问题在于,通过指定 InstanceId property in your LaunchConfiguration 资源,它重新使用了用于启动初始 EC2 实例的相同用户数据,包括对由 [= 发出信号的逻辑资源的硬编码引用12=] 命令。根据文档,

When you use an instance to create a launch configuration, all properties are derived from the instance with the exception of BlockDeviceMapping and AssociatePublicIpAddress. You can override any properties from the instance by specifying them in the launch configuration.

要让 cfn-signal 发出正确的资源信号,您需要覆盖 LaunchConfiguration 资源中的 UserData 以包含引用启动配置而不是引用启动配置的用户数据脚本原始 EC2 实例。不幸的是,这将需要复制用户数据脚本,或重写脚本以动态找出与脚本当前 运行 所在的实例关联的逻辑资源,因此可以使用完全相同的用户数据原始 EC2 实例和自动缩放组。

我同意 wjordan 的观点,您遇到的部分问题是 LaunchConfiguration 中的 InstanceId 属性。另外查看您的代码示例,我无法弄清楚 splitsweetInstance 在哪里被引用。

但是我的 CloudFormation AutoScalingGroup 不是这样设置的,我仍然遇到同样的错误 CREATE_COMPLETE state and cannot be signaled

我的解决方案是在 AutoScalingGroup 上设置 DesiredCapacity(希望这对其他人也有帮助)可以在这里找到: http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-as-group.html#cfn-as-group-desiredcapacity

根据文档:

CloudFormation will not mark the Auto Scaling group as successful (by setting its status to CREATE_COMPLETE) until the desired capacity is reached.

这就是我的 CloudFormation 模板部分的样子:

"WebServerGroup" : {
  "Type" : "AWS::AutoScaling::AutoScalingGroup",
  "Properties" : {
    "VPCZoneIdentifier" : { "Ref" : "Subnets" },
    "LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
    "MinSize" : "2",
    "MaxSize" : "4",
    "DesiredCapacity" : "2",
    "TargetGroupARNs" : [ { "Ref" : "ALBTargetGroup" } ]
  }

下面是 UserData 部分的 "signal" 部分:

         "# Signal the status from cfn-init\n",
         "/opt/aws/bin/cfn-signal -e $? ",
         "         --stack ", { "Ref" : "AWS::StackName" },
         "         --resource WebServerGroup ",
         "         --region ", { "Ref" : "AWS::Region" }, "\n",

为了解决这个问题,我确保添加了 CreationPolicyUpdatePolicy[=在使用 UserData[= 中的 cfn-signal 之前,Autoscaling 组中的 21=] 21=] LaunchTemplate 部分

    CreationPolicy:
      AutoScalingCreationPolicy:
        MinSuccessfulInstancesPercent: somepercent
      ResourceSignal:
      Count: somenumber
      Timeout: someminutes
    UpdatePolicy:
      AutoScalingScheduledAction:
        IgnoreUnmodifiedGroupSizeProperties: 'true'
    AutoScalingRollingUpdate:
      MinInstancesInService: 'somenumber'
      MaxBatchSize: 'somenumber'
      PauseTime: someminutes
      WaitOnResourceSignals: 'true'