Amazon web services 调用CloudFormation delete stack时是否有方法卸载卷?
我正在使用CloudFormation创建我的环境。堆栈的一部分包括从快照创建卷,将其与EC2实例关联,然后装载它Amazon web services 调用CloudFormation delete stack时是否有方法卸载卷?,amazon-web-services,amazon-ec2,amazon-cloudformation,Amazon Web Services,Amazon Ec2,Amazon Cloudformation,我正在使用CloudFormation创建我的环境。堆栈的一部分包括从快照创建卷,将其与EC2实例关联,然后装载它 "Resources" : { "EBSData" : { "Type" : "AWS::EC2::Volume", ...snip... }, "MountPoint" : { "Type" : "AWS::EC2::VolumeAttachment", ...snip... }, "
"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
第二次调用删除堆栈成功,因为实例已被销毁
运行实例中是否有任何钩子被cloudformation delete堆栈调用,我可以在其中卸载卷?还有其他方法吗?我找到了“DependsOn”资源属性问题的答案 基本上,这能够解决我的问题(在对您的问题的评论中描述): 注意在卷资源中添加了
“DependsOn”:“myTestInstance”
。由于VolumeAttachment资源具有卷的内置“DependsOn”,因此一切都应该正常
附加说明:此尚未测试,但测试后将更新。为了使其正常工作,我必须更改连接卷的方式。您可以在实例的属性中指定要附加到实例的EBS卷,而不是使用AWS::EC2::VolumeAttachment:
"Resources" : {
"EBSData" : {
"Type" : "AWS::EC2::Volume",
...snip...
},
"myTestInstance" : {
"Type" : "AWS::EC2::Instance",
"Properties": {
"Volumes": [ { "VolumeId": { "Ref": "EBSData" }, "Device": "<device mount point>" }]
...snip...
},
...snip...
}
},
“资源”:{
“EBSData”:{
“类型”:“AWS::EC2::卷”,
剪
},
“我的证明”:{
“类型”:“AWS::EC2::实例”,
“财产”:{
“卷”:[{“VolumeId”:{“Ref”:“EBSData”},“设备”:“}]
剪
},
剪
}
},
以这种方式附加卷似乎可以使CloudFormation以正确的顺序删除实例和卷。即,在删除卷之前关闭实例
请确保
EBSData
没有使用对myTestInstance
的任何引用,否则您将获得循环依赖关系。CloudFormation没有做什么,它无法撤消:您的卷由您装载(通过UserData或其他方式使用CloudInit),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,该子模板包含一个SQS队列和一个SNS主题
您可以在上查看完整的示例和脚本。我实际上也有同样的问题。我正在创建在创建EC2实例时装载的新卷,但当我删除时,删除流会在尝试删除实例之前尝试删除卷。卷删除失败,但实例成功。除非再次调用delete,否则整个状态将失败,因为实例已经不存在了。我相信这是云形成并行时引入的错误。最初,这些东西中有很多是连续的,使其并行引入了竞争条件。几个月前,在它变得痛苦之前,它就消失了,所以我们从未真正彻底地测试过它,让我超越“我相信”到“它是”。有人成功地测试过解决方案吗?我遇到了完全相同的问题,如上所述尝试了DependsOn,但堆栈删除仍然失败。关于这方面的文档不多,但您的答案似乎是当前的最佳实践,确实解决了问题。非常感谢。herebedragons:您创建的卷需要与EC2实例位于同一可用性区域,但这一点事先无法确定,因此您需要向卷中添加
Fn:GetAtt:[myTestInstance,AvailabilityZone]
,但这当然引入了我们需要的循环依赖avoid@lsh我从实例获取AvailabilityZone时遇到了相同的循环依赖性问题。找到解决方法了吗?您需要使用一个AWS::EC2::VolumeAttachment
,将EC2实例与卷关联起来,并在那里指定可用性区域。要点:对不起,这没什么意义。希望要点能把事情弄清楚。
"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"
}
},