使用自定义资源创建自定义预置逻辑 - Amazon CloudFormation
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

使用自定义资源创建自定义预置逻辑

自定义资源为您提供了一种将自定义预置逻辑写入 CloudFormation 模板,并让 CloudFormation 在创建、更新(如果更改了自定义资源)或删除堆栈期间运行该逻辑的方式。预置要求涉及无法使用 CloudFormation 的内置资源类型表达的复杂逻辑或工作流程时,这会很有帮助。

例如,您可能需要包含不可作为 CloudFormation 资源类型的资源。您可以使用自定义资源包含这些资源。这样,您仍然可以在一个堆栈中管理所有相关资源。

要在 CloudFormation 模板中定义自定义资源,可以使用 AWS::CloudFormation::CustomResourceCustom::MyCustomResourceTypeName 资源类型。自定义资源需要一个属性,即服务令牌,它指定 CloudFormation 发送请求的目标,如 Amazon SNS 主题或 Lambda 函数。

以下主题提供有关如何使用自定义资源的信息。

注意

CloudFormation 注册表和自定义资源各有其优点。自定义资源具有以下优点:

  • 您不需要注册资源。

  • 您无需注册即可将整个资源作为模板的一部分。

  • 支持 CreateUpdateDelete 操作

基于注册表的资源具有以下优点:

  • 支持对第三方应用程序资源进行建模、预置和管理

  • 支持 CreateReadUpdateDeleteList (CRUDL) 操作

  • 支持对私有和第三方资源类型的偏差检测

与自定义资源不同,基于注册表的资源不需要关联 Amazon SNS 主题或 Lambda 函数即可执行 CRUDL 操作。有关更多信息,请参阅 通过 CloudFormation 注册表管理扩展

自定义资源的工作原理

设置新自定义资源的一般过程包括以下步骤。这些步骤涉及两个角色:拥有该自定义资源的自定义资源提供者和创建包含某个自定义资源类型的模板的模板开发者。这两个角色可以是同一个人,但如果不是同一个人,自定义资源提供者应该与模板开发者合作。

  1. 自定义资源提供者编写的逻辑决定了如何处理来自 CloudFormation 的请求以及如何对自定义资源执行操作。

  2. 自定义资源提供者可创建 Amazon SNS 主题或 Lambda 函数,然后 CloudFormation 可向该主题或函数发送请求。该 Amazon SNS 主题或 Lambda 函数必须位于堆栈所在区域。

  3. 自定义资源提供者将 Amazon SNS 主题 ARN 或 Lambda 函数 ARN 提供给模板开发者。

  4. 模板开发者定义其 CloudFormation 模板中的自定义资源。这包括服务令牌和任何输入数据参数。服务令牌和输入数据的结构由自定义资源提供者定义。服务令牌指定了 Amazon SNS 主题 ARN 或 Lambda 函数 ARN,并且始终为必填项,而输入数据是可选的,具体取决于自定义资源。

现在,每当有人使用模板创建、更新或删除该自定义资源时,CloudFormation 都会向指定的服务令牌发送请求并等待响应,然后才会执行堆栈操作。

以下总结了使用该模板创建堆栈的流程:

  1. CloudFormation 向指定的服务令牌发送请求。该请求包含请求类型以及自定义资源用于向其发送请求的预签名 Amazon Simple Storage Service URL 等信息。有关请求中包含的内容的更多信息,请参阅自定义资源请求对象

    以下示例数据演示了 CloudFormation 在 Create 请求中包含的内容:在本示例中,ResourceProperties 允许 CloudFormation 创建发送到 Lambda 函数的自定义负载。

    { "RequestType" : "Create", "ResponseURL" : "http://pre-signed-S3-url-for-response", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this create request", "ResourceType" : "Custom::TestResource", "LogicalResourceId" : "MyTestResource", "ResourceProperties" : { "Name" : "Value", "List" : [ "1", "2", "3" ] } }
  2. 自定义资源提供商处理 CloudFormation 请求并向预签名 URL 返回 SUCCESSFAILED 响应。custom resource provider 提供采用 JSON 格式文件的响应并将响应上传到预签名的 S3 URL。有关更多信息,请参阅《Amazon Simple Storage Service 用户指南》中的使用预签名 URL 上传对象

    在响应中,custom resource provider还可以包含template developer可以访问的名称-值对。例如,如果请求成功,响应可以包含输出数据,如果请求失败,可以包含错误消息。有关响应的更多信息,请参阅自定义资源响应对象

    重要

    如果名称值对包含敏感信息,应使用 NoEcho 字段遮蔽自定义资源的输出。否则,这些值通过显示属性值的 API(例如 DescribeStackEvents)可见。

    有关使用 NoEcho 遮蔽敏感信息的更多信息,请参阅 请勿将凭证嵌入您的模板 最佳实践。

    custom resource provider负责侦听和响应请求。例如,对于 Amazon SNS 通知,自定义资源提供商必须侦听并响应发送到特定主题 ARN 的通知。CloudFormation 在预签名 URL 位置等待并侦听响应。

    以下示例数据说明自定义资源在响应中可以包含的内容:

    { "Status" : "SUCCESS", "PhysicalResourceId" : "TestResource1", "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/5b918d10-cd98-11ea-90d5-0a9cd3354c10", "RequestId" : "unique id for this create request", "LogicalResourceId" : "MyTestResource", "Data" : { "OutputName1" : "Value1", "OutputName2" : "Value2", } }
  3. 获得 SUCCESS 响应后,CloudFormation 继续堆栈操作。如果收到 FAILED 响应或未返回任何响应,则操作失败。来自自定义资源的所有输出数据都存储在预签名 URL 位置。template developer可使用 Fn::GetAtt 函数检索该数据。

注意

如果您使用 Amazon PrivateLink,则 VPC 中的自定义资源必须能够访问特定于 CloudFormation 的 S3 存储桶。自定义资源必须将响应发送到预签名的 Amazon S3 URL。如果这些资源不能向 Amazon S3 发送响应,则 CloudFormation 将不会收到响应,并且堆栈操作会失败。有关更多信息,请参阅 使用接口端点(Amazon PrivateLink)访问 CloudFormation

响应超时

自定义资源的默认超时为 3600 秒(1 小时)。如果在此期间内没有收到任何响应,则该堆栈操作将会失败。

您可以根据预期从自定义资源收到响应将需要的时间来调整超时值。例如,在预置将调用某个 Lambda 函数的自定义资源并且预期会在五分钟内收到响应时,您可以在堆栈模板中通过指定 ServiceTimeout 属性将超时设置为五分钟。有关更多信息,请参阅 自定义资源请求对象。这样,如果 Lambda 函数出现错误导致其停滞,CloudFormation 将在五分钟后使堆栈操作失败,而不是等待整整一个小时。

但是,请注意不要将超时值设置得过低。为避免意外超时,请确保您的自定义资源有足够的时间来执行必要的操作并返回响应。