如何在堆栈中存储和重用来自 CloudFormation 自定义资源 Lambda 函数的响应数据?

How to store & reuse response data from a CloudFormation Custom Resource Lambda function within the stack?

我正在根据 this documentation.

为 Cloudformation 自定义资源设计 AWS Lambda 函数

创建自定义资源后,关联的 Lambda 函数应 (a) 创建外部资源,以及 (b) return 与该外部资源关联的 ID。

更新或删除自定义资源后,关联的 Lambda 函数应将现有外部资源的 ID 作为 parameter/property,并相应地 update/delete 该外部资源。

为此,CloudFormation 堆栈需要存储在创建自定义资源 时由 Lambda 编辑的 ID return。理想情况下,它还应该 将该 ID 与自定义资源本身相关联。

如何实现?

相关场景的示例代码:

Resources:
  CustomResource:
    Type: AWS::CloudFormation::CustomResource
    Properties:
      ServiceToken:
        Fn::GetAtt: Lambda.Arn
      ID: <see-below>
  Lambda:
    Type: AWS::Lambda::Function
    Properties:
      ...

(其中ID在CustomResource创建前不存在,创建时需要用Lambda的结果填充)

你混淆了几件事。

Upon the update or deletion of the Custom Resource, the associated Lambda function should take the ID of the existing external resource as a parameter/property, and update/delete that external resource accordingly.

这是通过 PhysicalResourceId 属性 处理的。创建资源时,您需要在响应中 return 此项。 CloudFormation 然后会将此值传递给 Lambda 以进行更新或删除。

该 ID 的内容对 CloudFormation 是不透明的,您最多可以在其中存储 1KB。因此,您可以对存储在其中的内容充满创意。例如,您可以存储用于调用某些第三方 Web 服务的 URL。

ID: <see-below>

在这种情况下,您指定了一个 属性 并传递给 自定义资源 Lambda。您会在活动的 ResourceProperties 属性 中找到它。您链接到的示例未显示任何自定义属性,但如果您记录调用,您将在此处看到 ID

return the ID associated with that external resource

您可能不应该 return 外部资源的 ID;它应该仍然是一个不透明的标识符。但是,如果您 想要 return 它,那么您需要向自定义资源响应添加一个 Data 元素。这是一个 JSON 对象,其中包含可以使用 Fn::GetAtt.

检索的资源“属性”

有关自定义资源的更多信息,我推荐 this doc,它指定了请求和响应对象中的所有字段。

此外,如果您正在使用 cfnresponse 模块(出现在许多 AWS 官方文档中),您不应该这样做:它依赖于 requests 的“供应商”副本在 boto3 库中,并且已被弃用至少两年。在某些时候,您会发现您的模板停止工作(并且失败的自定义资源可能很难恢复)。