10

我正在使用 CloudFormation 创建我的环境。堆栈的一部分包括从快照创建卷,将其与 EC2 实例关联,然后挂载它。

"Resources" : {
    "EBSData" : {
        "Type" : "AWS::EC2::Volume",
     ...snip...
    },

    "MountPoint" : {
        "Type" : "AWS::EC2::VolumeAttachment",
     ...snip...
    },

    "myTestInstance" : {
        "Type" : "AWS::EC2::Instance",
     ...snip...
    }
 },

当我尝试调用 delete-stack 时,它失败了,因为该卷仍然挂载:

  "StackStatusReason": "The following resource(s) failed to delete: [EBSData, MountPoint].", 
  "CreationTime": "2013-12-03T13:40:58.646Z", 
  "StackName": "myTestStack", 
  "StackStatus": "DELETE_FAILED", 
  "DisableRollback": false

第二次调用 delete-stack 成功,因为实例已经被销毁。

正在运行的实例中是否有任何被 cloudformation delete-stack 调用的挂钩,我可以在其中卸载卷?还有其他方法可以做到这一点吗?

4

3 回答 3

6

为了让它工作,我不得不改变我附加卷的方式。AWS::EC2::VolumeAttachment您可以在该实例的属性中指定要附加到该实例的 EBS 卷,而不是使用:

"Resources" : {
    "EBSData" : {
        "Type" : "AWS::EC2::Volume",
     ...snip...
    },

    "myTestInstance" : {
        "Type" : "AWS::EC2::Instance",
        "Properties": {
            "Volumes": [ { "VolumeId": { "Ref": "EBSData" }, "Device": "<device mount point>" }]
        ...snip...
        },
     ...snip...
    }
 },

以这种方式附加卷似乎会使 CloudFormation 以正确的顺序删除实例和卷。即在删除卷之前关闭实例。

确保EBSData不使用任何引用,myTestInstance否则您将获得循环依赖。

于 2014-09-22T02:44:40.470 回答
3

我在这里使用“DependsOn”资源属性找到了我的问题的答案。

从本质上讲,这能够解决我的问题(在对您问题的评论中描述):

"Resources" : {
    "EBSData" : {
        "Type" : "AWS::EC2::Volume",
        "DependsOn": "myTestInstance",
     ...snip...
    },
    "MountPoint" : {
        "Type" : "AWS::EC2::VolumeAttachment",
     ...snip...
    },

    "myTestInstance" : {
        "Type" : "AWS::EC2::Instance",
     ...snip...
    }
 },

注意"DependsOn": "myTestInstance"卷资源中的添加。由于 VolumeAttachment 资源有一个内置的“DependsOn”用于卷,所以一切都应该是好的。

附加说明:这尚未经过测试,但一旦经过测试就会更新。

于 2014-03-07T17:01:25.363 回答
1

CloudFormation 没有做什么,它无法撤消:您的卷是由您安装的(使用 CloudInit 通过 UserData 或其他方式),而 CloudFormation 不知道如何撤消此操作。因此,堆栈删除被停止,因为设备保持安装状态,并且卷处于“忙碌状态”。

推荐的方式是使用 CloudFormation CustomRessource 来声明挂载点:

"ExampleVolumeMount" : {
    "Type" : "Custom::VolumeMount",
    "Version" : "1.0",
    "DependsOn" : ["VolumeAttachment", "ExampleWaitCondition"],
    "Properties" : {
        "ServiceToken" : { "Fn::GetAtt" : ["CustomResourcePipeline", "Outputs.CustomResourceTopicARN"] },
        "Device" : "/dev/xvdh",
        "MountPoint" : "/mnt/disk",
        "FsType" : "ext3",
        "Format" : "true"
    }
},

它使用由子模板创建的 ServiceToken:https ://s3.amazonaws.com/cloudformation-examples/cr-backend-substack-template.template ,其中包含一个 SQS 队列和一个 SNS 主题。

您可以在AWSlabs github account上查看完整的示例和脚本。

于 2015-04-17T13:07:47.317 回答