CloudFormation 更改集显示替换尽管没有更改

问题描述

AWS::RDS::DBInstance 类型的资源已部署。即使我没有在模板中指定它,数据库也会自动使用标准端口 3306。这很好,符合预期。

但是,现在我想通过添加 that property: final class GrandChildobject: Embeddedobject { @objc dynamic var child: GrandChildobject? } 显式指定模板中的端口号。

问题是,当我将它添加到模板时,CloudFormation 更改集告诉我这是一个会导致替换数据库修改。这是变更集:

Port: "3306"

预期行为

我希望 CloudFormation 说:未检测到任何更改。因为数据库已经在使用 3306 端口,所以有效没有变化。

如果它已经在使用我想要的端口,我为什么要弄清楚这一点?

这样我就可以为 Postgres 重新使用我的 MysqL 模板,有条件地将端口号更改为标准 5432。奇怪的是,当我部署 Postgres 数据库时没有指定端口号,它使用了 3306——这对于我,因为我想要标准端口 5432。

我尝试过的事情:

  • 通过在 MysqL 部署时使用 [ { "resourceChange": { "logicalResourceId": "RDSDBInstanceA","action": "Modify","physicalResourceId": "awesome-db","resourceType": "AWS::RDS::DBInstance","replacement": "True","moduleInfo": null,"details": [ { "target": { "name": "Port","requiresRecreation": "Always","attribute": "Properties" },"causingEntity": null,"evaluation": "Static","changeSource": "DirectModification" } ],"changeSetId": null,"scope": [ "Properties" ] },"hookInvocationCount": null,"type": "Resource" } ] 作为 AWS::Novalue 属性的值,欺骗 CloudFormation 认为没有变化:
Port

结果相同。

如果这是 terraform...

它会检查状态,看到端口已经是 3306,然后说“没有变化”。

我的问题

如何在仍将此属性添加到模板的同时避免替换数据库

解决方法

CloudFormation 不会查看已部署的资源来识别更改,它只是将当前部署的堆栈与新的堆栈进行比较。因此,在这种情况下,您有一个以前不包含值的堆栈,现在包含它,CF 认为这是一个更改。我有点惊讶 AWS::NoValue 选项不起作用。

解决这个问题的一个选择是利用堆栈导入。步骤如下:

  1. 通过将当前 RDS 实例的 DeletionPolicy 设置为 RETAIN(如果还没有)来更新当前堆栈。
  2. 更新当前堆栈,移除 RDS 实例。 RDS 实例仍然存在,但不再受 CF 控制。
  3. 将 RDS 添加回您的模板,按照您希望的方式进行配置,并使用 CF 中的“将资源导入堆栈”选项。这应该允许您将 RDS 实例重新添加到您的堆栈中,并按照您希望的方式进行配置。

请记住,当您将某些内容导入堆栈时,CF 仅假设模板中的配置与导入的资源匹配。