我创建了一个 CloudFormation 脚本,用于克隆我们现有的 AWS 堆栈。我添加了信息,以便 CloudFormation 可以从现有 RDS 实例的快照创建 RDS,或者使用命名数据库创建新实例。但是,当我尝试将同一脚本应用于我们的现存的堆栈(通过使用现有堆栈中的脚本创建新堆栈,然后尝试通过新脚本升级进行验证),CloudFormation 始终创建一个新的 RDS 实例。
CloudFormation 脚本的提取部分如下。
{
"Parameters": {
"liveDbName" : {
"Default": "default",
"Description" : "The live database name to create by default",
"Type": "String",
"MinLength": "1",
"MaxLength": "64",
"AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
"ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
},
"liveDbSnapshotIdentifier" : {
"Description" : "This overrides Default Production Db name",
"Type": "String",
"Default": ""
},
},
"Metadata": {
"AWS::CloudFormation::Interface": {
"ParameterGroups": [
{
"Label": {
"default": "Db Layer Configuration"
},
"Parameters": [
"webDbInstanceType",
"liveDbName",
"liveDbSnapshotIdentifier",
"dbTimeZone",
"dbMasterUser",
"dbMasterPassword"
]
}
]
}
},
"Conditions": {
"UseLiveDbSnapshot" : { "Fn::Not" : [{ "Fn::Equals" : [ {"Ref" : "liveDbSnapshotIdentifier"}, "" ] }] },
}
"Resources": {
"WebDb": {
"Type": "AWS::RDS::DBInstance",
"DeletionPolicy": "Snapshot",
"Properties": {
"AllocatedStorage": "100",
"AutoMinorVersionUpgrade": "true",
"BackupRetentionPeriod": "30",
"CopyTagsToSnapshot": "true",
"DBName" : {
"Fn::If" : [ "UseLiveDbSnapshot", { "Ref" : "AWS::NoValue"}, { "Ref" : "liveDbName" } ]
},
"DBSnapshotIdentifier" : {
"Fn::If" : [ "UseLiveDbSnapshot", { "Ref" : "liveDbSnapshotIdentifier" }, { "Ref" : "AWS::NoValue"} ]
},
"DBInstanceClass": {
"Ref": "webDbInstanceType"
},
"DBParameterGroupName": {
"Ref": "WebDbParameterGroup"
},
"DBSubnetGroupName": {
"Ref": "DbSubnetGroup"
},
"Engine": "mysql",
"MasterUsername": {
"Ref": "dbMasterUser"
},
"MasterUserPassword": {
"Ref": "dbMasterPassword"
},
"MultiAZ": "true",
"PubliclyAccessible": "false",
"StorageType": "gp2",
"Tags": [
{
"Key": "Name",
"Value": "WebDb"
}
]
}
}
}
}
当然,脚本还有其他部分,但这是处理数据库部分的部分(我相信是完全“命名空间”的)。
我的脚本哪里出错了?有没有正确的方法?显然,我不希望 CloudFormation 在我们现有的实例上恢复快照,但我也不希望它使用命名数据库创建新实例。
编辑:包含“现有”堆栈脚本
我已将现有的堆栈脚本添加为 Dropbox 的链接,因为该文件太长,无法直接包含在此处:https://www.dropbox.com/s/313kmcnzk0pvyqi/sanitized-cloudformation.json?dl=0
答案1
您的原始 CloudFormation 模板不包含DBName
或DBSnapshotIdentifier
属性。因此,RDS 实例是在没有的情况下创建的DBName
。您的 RDS 实例所包含的任何数据库都是事后创建的,而不是由 CloudFormation 创建的。
您的新模板包含 或DBName
,DBSnapshotIdentifier
具体取决于输入参数。
根据AWS::RDS::DBInstance
资源的 CloudFormation 参考文档,如果您添加/更改/删除或属性DBName
,DBSnapshotIdentifier
则将重新创建 RDS 实例。
我猜想,当您应用更新的模板时,您正在尝试使用 RDS 实例内部的数据库名称作为 的值liveDbName
。但是,就 CloudFormation 而言,这是对 RDS 实例的更改,需要替换。
要应用模板更新,您需要对其进行修改,以使既不应用DBName
也不DBSnapshotIdentifier
应用。