

# 解决只写属性问题
<a name="generate-IaC-write-only-properties"></a>

使用 CloudFormation IaC 生成器，您可以使用账户中已预置但尚未由 CloudFormation 管理的资源生成模板。但是，某些资源属性被指定为*只写*，这意味着 CloudFormation 可以写入但不能读取这些属性，例如数据库密码。

利用现有资源生成 CloudFormation 模板时，只写属性会带来挑战。通常，CloudFormation 会在生成的模板中将这些属性转换为参数。这允许您在导入操作期间输入属性作为参数值。但在某些情况下无法实现这种转换，而且 CloudFormation 对这些情况的处理方式有所不同。

## 互斥属性
<a name="write-only-mutually-exclusive-properties"></a>

一些资源有多组互斥属性，其中至少有一些是只写属性。对于这些情况，IaC 生成器无法确定在创建期间对资源应用了哪组互斥属性。例如，您可以使用其中一组属性提供 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) 代码。
+ `Code/S3Bucket`、`Code/S3Key` 以及可选的 `Code/S3ObjectVersion`
+ `Code/ImageUri`
+ `Code/ZipFile`

所有这些属性均为只写属性。IaC 生成器会选择其中一组独占属性并将其添加到生成的模板中。为每个只写属性添加参数。参数名称包括 `OneOf`，参数说明表示相应的属性可以替换为其他独占属性。IaC 生成器为包含的属性设置的警告类型为 `MUTUALLY_EXCLUSIVE_PROPERTIES`。

## 互斥类型
<a name="write-only-mutually-exclusive-types"></a>

在某些情况下，只写属性可以为多种数据类型。例如，[https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-restapi.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-restapi.html) 的 `Body` 属性可以是 `object` 或 `string`。遇到这种情况时，IaC 生成器会使用 `string` 类型在生成的模板中包含该属性，并将警告类型设置为 `MUTUALLY_EXCLUSIVE_TYPES`。

## Array 属性
<a name="write-only-array-properties"></a>

如果只写属性的类型为 `array`，则 IaC 生成器无法将其包含在生成的模板中，因为参数只能是标量值。在这种情况下，模板中会忽略该属性，并设置 `UNSUPPORTED_PROPERTIES` 警告类型。

## 可选属性
<a name="write-only-optional-properties"></a>

对于可选的只写属性，IaC 生成器无法检测在设置资源时是否使用过该属性。在这种情况下，生成的模板中会忽略该属性，并设置 `UNSUPPORTED_PROPERTIES` 警告类型。

## 警告和后续步骤
<a name="write-only-properties-warnings-and-next-steps"></a>

要确定哪些属性为只写属性，您必须查看 IaC 生成器控制台返回的警告。[AWS 资源和属性类型参考](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-template-resource-type-ref.html)并未指示某个属性是否为只写属性，也未指示其是否支持多种类型。

您也可从资源提供程序架构中查看哪些属性为只写属性。要下载资源提供程序架构，请参阅 [CloudFormation 资源提供程序架构](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/resource-type-schemas.html)。

**解决只写属性问题**

1. 打开 CloudFormation 控制台的 [IaC 生成器页面](https://console.aws.amazon.com/cloudformation/home?#iac-generator)。

1. 在屏幕顶部的导航栏中，选择模板所在的 AWS 区域。

1. 选择**模板**选项卡，然后选择您创建的模板的名称。

1. 在**模板定义**选项卡中，当生成的模板包含具有只写属性的资源时，IaC 生成器控制台会显示一条警告，其中包含问题类型的摘要。例如：  
![\[IaC 生成器控制台关于生成的模板中包含只写属性的警告\]](http://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/images/IaC-generator-write-only-property-warning.png)

1. 选择**查看警告详细信息**以了解更多详情。具有只写属性的资源由生成的模板中使用的逻辑 ID 和资源类型标识。

   使用警告列表来识别具有只写属性的资源，并查看每个资源以确定需要对生成的模板进行哪些更改（如果有）。  
![\[IaC 生成器控制台关于生成的模板中包含只写属性的详细警告\]](http://docs.aws.amazon.com/zh_cn/AWSCloudFormation/latest/UserGuide/images/IaC-generator-write-only-property-resource-warning.png)

1. 如果必须更新模板才能解决只写属性问题，请执行以下操作：

   1. 选择**下载**以下载模板的副本。

   1. 编辑模板。

   1. 完成更改后，您可以选择**导入已编辑的模板**按钮以继续完成导入过程。

# 如何解决 AWS::ApiGateway::RestAPI 资源中的只写属性问题
<a name="generate-IaC-apigateway-restapi"></a>

本主题介绍如何解决在使用 IaC 生成器时的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-restapi.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-apigateway-restapi.html) 资源只写属性问题。

## 问题
<a name="apigateway-restapi-write-only-properties-issue"></a>

当生成的模板包含 `AWS::ApiGateway::RestApi` 资源时，会生成警告，指明 `Body`、`BodyS3Location` 和 `CloneFrom` 属性将标识为 `UNSUPPORTED_PROPERTIES`。这是因为这些是可选的只写属性。IaC 生成器不知道这些属性是否曾应用于资源，因此生成的模板中会忽略这些属性。

## 解决方案
<a name="apigateway-restapi-write-only-properties-resolution"></a>

要为您的 REST API 设置 `Body` 属性，请更新生成的模板。

1. 使用 Amazon API Gateway [https://docs.aws.amazon.com/apigateway/latest/api/API_GetExport.html](https://docs.aws.amazon.com/apigateway/latest/api/API_GetExport.html) API 操作下载 API。例如，通过使用 [https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-export.html](https://docs.aws.amazon.com/cli/latest/reference/apigateway/get-export.html) AWS CLI 命令。有关更多信息，请参阅《API Gateway 开发人员指南》**中的[从 API Gateway 导出 REST API](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html)。

1. 从 `GetExport` API 操作的响应中检索 `Body` 属性。将其上传到 Amazon S3 存储桶。

1. 下载生成的模板。

1. 将 `BodyS3Location/Bucket` 和 `BodyS3Location/Key` 属性添加到模板中，指定存储 `Body` 的桶名称和密钥。

1. 在 IaC 生成器控制台中打开生成的模板，然后选择**导入编辑的模板**。

# 如何解决 AWS::Lambda::Function 资源中的只写属性问题
<a name="generate-IaC-lambda-function"></a>

本主题介绍如何解决在使用 IaC 生成器时的 [https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html](https://docs.aws.amazon.com/AWSCloudFormation/latest/TemplateReference/aws-resource-lambda-function.html) 资源只写属性问题。

## 问题
<a name="lambda-function-mutually-exclusive-properties-issue"></a>

`AWS::Lambda::Function` 资源具有三组互斥属性，用于指定 Lambda 代码：
+ `Code/S3Bucket` 和 `Code/S3Key` 属性，以及可选的 `Code/S3ObjectVersion` 属性
+ `Code/ImageUri` 属性
+ `Code/ZipFile` 属性

任何给定的 `AWS::Lambda::Function` 资源只能使用其中的一组属性。

IaC 生成器无法确定使用了哪组互斥只写属性来创建或更新资源，因此，生成的模板中仅包含第一组属性。`Code/ImageUri` 和 `Code/ZipFile` 属性将被忽略。

此外，IaC 生成器会发出以下警告：
+ **`MUTUALLY_EXCLUSIVE_PROPERTIES`** – 警告 `Code/S3Bucket` 和 `Code/S3Key` 被标识为互斥属性。
+ **`UNSUPPORTED_PROPERTIES`** – 警告 `Code/S3ObjectVersion` 属性不受支持。

要在生成的模板中包含 `AWS::Lambda::Function` 资源，您必须下载模板并使用正确的代码属性更新该模板。

## 解决方案
<a name="lambda-function-mutually-exclusive-properties-resolution"></a>

**如果您将 Lambda 代码存储在 Amazon S3 存储桶中并且不使用 `S3ObjectVersion` 属性**，则无需任何修改即可导入生成的模板。在导入操作期间，IaC 生成器将要求您提供 Amazon S3 存储桶和密钥作为模板参数。

****如果将 Lambda 代码存储为 Amazon ECR 存储库**，则您可以按照以下说明更新您的模板：**

1. 下载生成的模板。

1. 从生成的模板中删除 `Code/S3Bucket` 和 `Code/S3Key` 属性的属性和相应参数。

1. 将生成的模板中已删除的属性替换为 `Code/ImageUri` 属性，指定 Amazon ECR 存储库的 URL。

1. 在 IaC 生成器控制台中打开生成的模板，然后选择**导入编辑的模板**按钮。

****如果您将 Lambda 代码存储为 zip 文件**，则可以按照以下说明更新您的模板：**

1. 下载生成的模板。

1. 从生成的模板中删除 `Code/S3Bucket` 和 `Code/S3Key` 属性的属性和相应参数。

1. 将生成的模板中已删除的属性替换为 `Code/ZipFile` 属性。

1. 在 IaC 生成器控制台中打开生成的模板，然后选择**导入编辑的模板**按钮。

****如果没有 Lambda 代码的副本**，则您可以按照以下说明更新您的模板：**

1. 使用 AWS Lambda [https://docs.aws.amazon.com/lambda/latest/api/API_GetFunction.html](https://docs.aws.amazon.com/lambda/latest/api/API_GetFunction.html) API 操作（例如，通过使用 [https://docs.aws.amazon.com/cli/latest/reference/lambda/get-function.html](https://docs.aws.amazon.com/cli/latest/reference/lambda/get-function.html) AWS CLI 命令）。

1. 在响应中，如果代码位于 Amazon S3 存储桶中，则 `RepositoryType` 参数为 `S3`；如果代码位于 Amazon ECR 存储库中，则该参数为 `ECR`。

1. 在响应中，`Location` 参数包含一个预签名 URL，您可以用其下载部署包 10 分钟。下载代码。

1. 将代码上传到 Amazon S3 存储桶。

1. 使用生成的模板运行导入操作，并提供桶名称和密钥作为参数值。