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

CloudFormation Change Set Showing Replacement Despite no change

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

但是,现在我想明确地指定模板中的端口号,通过添加that propertyPort: "3306".

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

[
  {
    "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"
  }
]

预期行为

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

如果它已经在使用我想要的端口,为什么我要尝试解决这个问题?

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

我尝试过的事情:

Port: !If [IsMySQL, AWS::NoValue, "5432"]

结果相同。

如果这是 Terraform...

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

我的问题

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

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

解决这个问题的一个方法是利用堆栈导入。步骤将是这样的:

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

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