当我调用CloudFormation删除堆栈时,有没有办法将卷卸载?

时间:2013-12-03 16:26:27

标签: amazon-web-services amazon-ec2 amazon-cloudformation

我正在使用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调用,我可以卸载卷?还有其他办法吗?

3 个答案:

答案 0 :(得分:6)

为了使这个工作,我不得不改变我附加音量的方式。您可以指定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...
    }
 },

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

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

答案 1 :(得分:3)

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

基本上,这能够解决我的问题(在对你的问题的评论中描述):

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

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

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

附加说明:尚未经过测试,但经测试后会更新。

答案 2 :(得分:1)

CloudFormation不做什么,它无法撤消:您的卷是由您安装的(通过UserData或其他方式使用CloudInit),CloudFormation也不知道如何撤消此操作。因此,堆栈删除被停止,因为设备保持mouted状态,并且音量处于&#34; Busy状态&#34;。

recommended way是使用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上的完整示例和脚本。