

# CloudFormation 自定义资源请求和响应参考
<a name="crpg-ref"></a>

Amazon CloudFormation 通过与您的自定义资源提供商通信的请求-响应协议管理自定义资源。每个请求都包含一个请求类型（`Create`、`Update` 或 `Delete`），并遵循这一高级工作流：

1. 模板开发者在模板中使用 `ServiceToken` 和 `ServiceTimeout` 定义自定义资源并启动堆栈操作。

1. CloudFormation 通过 SNS 或 Lambda 向自定义资源提供商发送 JSON 请求。

1. 该自定义资源提供商会处理请求，并在超时时间到期之前向预签名的 Amazon S3 存储桶 URL 返回一个 JSON 响应。

1. CloudFormation 会读取响应并继续堆栈操作。如果在超时期限结束之前没有收到任何响应，则该请求被视为不成功，并且堆栈操作将会失败。

有关更多信息，请参阅 [自定义资源的工作原理](template-custom-resources.md#how-custom-resources-work)。

本节介绍每种请求类型的结构、参数和预期响应。

**注意**  
响应正文的总大小不能超过 4096 字节。

## 模板设置
<a name="crpg-ref-template-setup"></a>

在模板中定义自定义资源时，模板开发者会使用具有以下属性的 [https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html)：

`ServiceToken`  
来自与堆栈相同区域的 Amazon SNS 主题 ARN 或 Lambda 函数 ARN。  
*是否必需*：是  
*类型*：字符串

`ServiceTimeout`  
自定义资源操作超时前的最长时间（以秒为单位）。此值必须介于 1 和 3600 之间。默认值：3600 秒（1 小时）。  
*必需*：否  
*类型*：字符串

支持其他资源属性。资源属性将以 `ResourceProperties` 形式包含在请求中。自定义资源提供商必须确定哪些属性有效以及它们的可接受值。

## 请求对象
<a name="crpg-ref-requesttypes"></a>

------
#### [ Create ]

当模板开发者创建包含自定义资源的堆栈时，CloudFormation 会发送一条将 `RequestType` 设置为 `Create` 的请求。

创建请求包含以下字段：

`RequestType`  
`Create`.  
*是否必需*：是  
*类型*：字符串

`RequestId`  
请求的唯一 ID。  
将 `StackId` 与 `RequestId` 组合形成一个值，您可以使用该值唯一标识对特定自定义资源的请求。  
*是否必需*：是  
*类型*：字符串

`StackId`  
标识包含自定义资源的堆栈的 Amazon 资源名称（ARN）。  
将 `StackId` 与 `RequestId` 组合形成一个值，您可以使用该值唯一标识对特定自定义资源的请求。  
*是否必需*：是  
*类型*：字符串

`ResponseURL`  
响应 URL 标识一个预签名 S3 存储桶，该存储桶接收从自定义资源提供商到 CloudFormation 的响应。  
*是否必需*：是  
*类型*：字符串

`ResourceType`  
CloudFormation 模板中模板开发人员选择的自定义资源的资源类型。自定义资源类型名称的长度最多为 60 个字符，并且可包含字母数字字符和以下字符：`_@-`。  
*是否必需*：是  
*类型*：字符串

`LogicalResourceId`  
CloudFormation 模板中模板开发人员选择的自定义资源的名称（逻辑 ID）。  
*是否必需*：是  
*类型*：字符串

`ResourceProperties`  
此字段包含模板开发人员发送的 `Properties` 对象的内容。其内容由自定义资源提供商定义。  
*必需*：否  
*类型*：JSON 对象

*示例*

```
{
   "RequestType" : "Create",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-create-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "ResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------
#### [ Update ]

当模板开发者更改模板中某个自定义资源的属性并更新堆栈时，CloudFormation 会向自定义资源提供者发送一条将 `RequestType` 设置为 `Update` 的请求。这意味着自定义资源代码无需检测资源中的更改，因为在请求类型为 `Update` 时，代码会知道其属性已经更改。

更新请求包含以下字段：

`RequestType`  
`Update`.  
*是否必需*：是  
*类型*：字符串

`RequestId`  
请求的唯一 ID。  
将 `StackId` 与 `RequestId` 组合形成一个值，您可以使用该值唯一标识对特定自定义资源的请求。  
*是否必需*：是  
*类型*：字符串

`StackId`  
标识包含自定义资源的堆栈的 Amazon 资源名称（ARN）。  
将 `StackId` 与 `RequestId` 组合形成一个值，您可以使用该值唯一标识对特定自定义资源的请求。  
*是否必需*：是  
*类型*：字符串

`ResponseURL`  
响应 URL 标识一个预签名 S3 存储桶，该存储桶接收从自定义资源提供商到 CloudFormation 的响应。  
*是否必需*：是  
*类型*：字符串

`ResourceType`  
CloudFormation 模板中模板开发人员选择的自定义资源的资源类型。自定义资源类型名称的长度最多为 60 个字符，并且可包含字母数字字符和以下字符：`_@-`。更新期间不能更改类型。  
*是否必需*：是  
*类型*：字符串

`LogicalResourceId`  
CloudFormation 模板中模板开发人员选择的自定义资源的名称（逻辑 ID）。  
*是否必需*：是  
*类型*：字符串

`PhysicalResourceId`  
自定义资源提供商定义的物理 ID，该 ID 对于该提供程序是唯一的。  
*是否必需*：是  
*类型*：字符串

`ResourceProperties`  
此字段包含模板开发人员发送的 `Properties` 对象的内容。其内容由自定义资源提供商定义。  
*必需*：否  
*类型*：JSON 对象

`OldResourceProperties`  
仅用于 `Update` 请求。模板开发人员之前在 CloudFormation 模板中声明的资源属性值。  
*是否必需*：是  
*类型*：JSON 对象

*示例*

```
{
   "RequestType" : "Update",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-update-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "PhysicalResourceId" : "provider-defined-physical-id",
   "ResourceProperties" : {
      "key1" : "new-string",
      "key2" : [ "new-list" ],
      "key3" : { "key4" : "new-map" }
   },
   "OldResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------
#### [ Delete ]

当模板开发者删除该堆栈或从模板中移除该自定义资源然后更新堆栈时，CloudFormation 会发送一条将 `RequestType` 设置为 `Delete` 的请求。

删除请求包含以下字段：

`RequestType`  
`Delete`.  
*是否必需*：是  
*类型*：字符串

`RequestId`  
请求的唯一 ID。  
*是否必需*：是  
*类型*：字符串

`StackId`  
标识包含自定义资源的堆栈的 Amazon 资源名称（ARN）。  
*是否必需*：是  
*类型*：字符串

`ResponseURL`  
响应 URL 标识一个预签名 S3 存储桶，该存储桶接收从自定义资源提供商到 CloudFormation 的响应。  
*是否必需*：是  
*类型*：字符串

`ResourceType`  
CloudFormation 模板中模板开发人员选择的自定义资源的资源类型。自定义资源类型名称的长度最多为 60 个字符，并且可包含字母数字字符和以下字符：`_@-`。  
*是否必需*：是  
*类型*：字符串

`LogicalResourceId`  
CloudFormation 模板中模板开发人员选择的自定义资源的名称（逻辑 ID）。  
*是否必需*：是  
*类型*：字符串

`PhysicalResourceId`  
自定义资源提供商定义的物理 ID，该 ID 对于该提供程序是唯一的。  
*是否必需*：是  
*类型*：字符串

`ResourceProperties`  
此字段包含模板开发人员发送的 `Properties` 对象的内容。其内容由自定义资源提供商定义。  
*必需*：否  
*类型*：JSON 对象

*示例*

```
{
   "RequestType" : "Delete",
   "RequestId" : "unique-request-id",
   "StackId" : "arn:aws:cloudformation:us-west-2:123456789012:stack/mystack/id",
   "ResponseURL" : "pre-signed-url-for-delete-response",
   "ResourceType" : "Custom::MyCustomResourceType",
   "LogicalResourceId" : "resource-logical-id",
   "PhysicalResourceId" : "provider-defined-physical-id",
   "ResourceProperties" : {
      "key1" : "string",
      "key2" : [ "list" ],
      "key3" : { "key4" : "map" }
   }
}
```

------

## 响应对象
<a name="crpg-ref-responses"></a>

对于所有的请求类型，自定义资源提供商会向预签名 URL 发送一条响应。如果自定义资源提供商没有发送响应，CloudFormation 会等待直到操作超时。

该响应必须为具有以下字段的 JSON 对象：

`Status`  
必须是 `SUCCESS` 或 `FAILED`。  
*是否必需*：是  
*类型*：字符串

`RequestId`  
请求的唯一 ID。完全按照请求中显示的值复制该值。  
*是否必需*：是  
*类型*：字符串

`StackId`  
标识包含自定义资源的堆栈的 Amazon 资源名称（ARN）。完全按照请求中显示的值复制该值。  
*是否必需*：是  
*类型*：字符串

`LogicalResourceId`  
CloudFormation 模板中模板开发人员选择的自定义资源的名称（逻辑 ID）。完全按照请求中显示的值复制该值。  
*是否必需*：是  
*类型*：字符串

`PhysicalResourceId`  
该值应该为自定义资源供应商的唯一标识符，并且最大为 1KB。该值必须为非空字符串，并且对于同一资源的所有响应都必须相同。  
更新自定义资源时，`PhysicalResourceId` 返回的值决定了更新行为。如果值保持相同，则 CloudFormation 将其视为正常更新。如果值发生更改，CloudFormation 会将该更新解读为替换，并向旧资源发送删除请求。有关更多信息，请参阅 [https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html](https://docs.amazonaws.cn/AWSCloudFormation/latest/TemplateReference/aws-resource-cloudformation-customresource.html)。  
*是否必需*：是  
*类型*：字符串

`Reason`  
描述失败响应的原因。  
如果 `Status` 为 `FAILED`，则必需。否则，它是可选的。  
*必需*：条件  
*类型*：字符串

`NoEcho`  
指示在使用 `Fn::GetAtt` 函数检索时是否遮蔽自定义资源的输出。如果设置为 `true`，则*除模板 `Metadata` 区段中存储的值*外，所有返回值都将用星号 (\$1\$1\$1\$1\$1) 遮蔽。CloudFormation 不会转换、修改或编辑您在 `Metadata` 部分中包含的任何信息。默认值为 `false`。  
有关使用 `NoEcho` 遮蔽敏感信息的更多信息，请参阅 [请勿将凭证嵌入您的模板](security-best-practices.md#creds) 最佳实践。  
仅适用于 `Create` 和 `Update` 响应。不支持 `Delete` 响应。  
*必需*：否  
*类型*：布尔值

`Data`  
自定义资源提供商定义的名称值对，随响应一起发送。您可以使用 `Fn::GetAtt` 在模板中按名称访问此处提供的值。  
仅适用于 `Create` 和 `Update` 响应。不支持 `Delete` 响应。  
如果名称值对包含敏感信息，应使用 `NoEcho` 字段遮蔽自定义资源的输出。否则，这些值通过显示属性值的 API（例如 `DescribeStackEvents`）可见。
*必需*：否  
*类型*：JSON 对象

### 成功响应示例
<a name="crpg-ref-success-response-examples"></a>

#### `Create` 和 `Update` 响应
<a name="crpg-ref-success-response-example-1"></a>

```
{
   "Status": "SUCCESS",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id", 
   "PhysicalResourceId": "provider-defined-physical-id",
   "NoEcho": true,
   "Data": {
      "key1": "value1",
      "key2": "value2"
   }
}
```

#### `Delete` 响应
<a name="crpg-ref-success-response-example-2"></a>

```
{
   "Status": "SUCCESS",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id", 
   "PhysicalResourceId": "provider-defined-physical-id"
}
```

### 失败的响应示例
<a name="crpg-ref-failed-response-example"></a>

```
{
   "Status": "FAILED",
   "RequestId": "unique-request-id",
   "StackId": "arn:aws:cloudformation:us-west-2:123456789012:stack/name/id",
   "LogicalResourceId": "resource-logical-id",
   "PhysicalResourceId": "provider-defined-physical-id",
   "Reason": "Required failure reason string"
}
```