是否可以使用 cloudformation 堆栈强制重新创建 EC2 或 RDS 实例?
我的堆栈卡在一个点上,只需销毁并创建资源即可解决问题,而不是必须删除整个堆栈才能继续工作。
编辑:
这个问题困扰了我两次。首先,我创建了一个具有一些默认值的 AWS::RDS::Instance,然后尝试将其降级为“EngineVersion”:“5.5”。更改此值应该会有一些中断,但 mysql 实例无法从 5.6 降级到 5.5,因此堆栈处于 UPDATE_FAILED 状态,如果不使用一些卑鄙的技巧,我就无法重新创建 RDS。
另一个情况是,我有几个“AWS::EC2::Instance”,它们从其“UserData”下载并执行脚本,显然,如果 Y 更改下载的脚本,我必须重新创建实例,但没有办法这样做。我再次使用相同的卑鄙技巧来重新创建机器。
卑鄙的伎俩:
我没有使用一台机器的自动缩放组,而是通过更改属性中的可用区域解决了这两个问题……但给我留下了不好的印象
答案1
对于实例存储支持的 EC2 实例,一个技巧是在用户数据脚本中添加包含版本号、日期或类似内容的注释,然后在您想要重新创建实例时更改它:
{
"Resources" : {
"MyEC2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
// ... other properties ...
"UserData": {
"Fn::Base64" : {
"Fn::Join" : [ ":", [
"#!/bin/bash\n",
"# Version: 1.0\n",
// ... rest of user data ...
]]}
}
}
}
}
任何更改UserData
都会导致实例被替换(即重新生成)。不过,用户数据脚本的行为应该相同,因为唯一的修改是注释。请注意,这不适用于 EBS 支持的实例。
对于 RDS,您可以采取数据库快照当前 RDS 实例,然后修改模板以使用该快照DBSnapshotIdentifier
:
{
"Resources" : {
"MyDB" : {
"Type" : "AWS::RDS::DBInstance",
"Properties" : {
// ... other properties ...
"DBSnapshotIdentifier": "<db snapshot ID>"
}
}
}
每当DBSnapshotIdentifier
发生更改时,数据库实例都将被替换。使用快照还可以让您保留创建快照时的数据。(如果您想要擦除数据,您可以创建一个空快照并将其作为输入传递。或者删除并重新创建整个 CloudFormation 堆栈。)
更通用的方法是更改资源的逻辑名称。从 修改堆栈模板在 CloudFormation 文档中:
对于大多数资源,更改资源的逻辑名称相当于删除该资源并将其替换为新资源。依赖于重命名资源的任何其他资源也需要更新,并可能导致它们被替换。其他资源需要您更新属性(而不仅仅是逻辑名称)才能触发更新。
答案2
如果将其放入 AutoScalingGroup,则可以将 AutoScalingGroup 最小值/最大值/默认值编辑为 0,然后一旦它开始销毁旧实例,就可以将最小值/最大值/默认值设置为 1/1/1,然后 presto:新实例。
答案3
如果您的 EC2 属于 AutoScalingGroup,您可以设置AutoScalingGroupName
带有版本号的属性。
每次更改版本号时,CFN 都会:1. 创建一个新的自动扩展组并启动所需的实例 2. 终止旧自动扩展组中的实例并将其删除
这是我的堆栈中的一段代码,我使用此技术强制大量 EC2 机器重新创建并自动从 S3 中提取新软件。
AutoScalingGroup:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: !Sub "${StackName}-${ServiceName}-${ServiceVersion}"