Я создал сценарий 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
Ваш исходный шаблон CloudFormation не включал DBName
или DBSnapshotIdentifier
свойства. Таким образом, экземпляр RDS был создан без DBName
. Любая база данных, размещенная в вашем экземпляре RDS, была создана постфактум, а не CloudFormation.
Ваш новый шаблон включает либо DBName
или DBSnapshotIdentifier
, в зависимости от входных параметров.
Согласно справочной документации CloudFormation для AWS::RDS::DBInstance
ресурс, если вы добавите / измените / удалите любой из DBName
или DBSnapshotIdentifier
properties, то экземпляр RDS будет воссоздан.
Я предполагаю, что, когда вы применяете обновленный шаблон, вы пытаетесь использовать имя своей базы данных, которая есть внутри вашего экземпляра RDS, в качестве значения для liveDbName
. Однако, что касается CloudFormation, это изменение экземпляра RDS и требует замены.
Чтобы применить обновление шаблона, вам нужно изменить его так, чтобы ни DBName
ни DBSnapshotIdentifier
применяются.