

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 设备预调配
<a name="iot-provision"></a>

AWS 提供了几种不同的方法来配置设备并在其上安装唯一的客户端证书。本部分介绍各种方式，以及如何选择适合您的物联网解决方案的最佳方法。这些选项在标题为[在 AWS IoT Core中使用 X.509 证书进行设备制造和预调配](https://docs.aws.amazon.com/whitepapers/latest/device-manufacturing-provisioning/device-manufacturing-provisioning.html)的白皮书中进行了详细介绍。

**选择最适合您情况的选项**
+ 

**您可以在物联网设备上安装证书，然后再予交付**  
如果能够在物联网设备交付给最终用户使用之前将其安全地安装在物联网设备上，则需要使用[*just-in-time*配置 (JITP)](jit-provisioning.md) 或[*just-in-time*注册 (JITR](auto-register-device-cert.md))。

  使用 JITP 和 JITR，用于签署设备证书的证书颁发机构 (CA) 在设备首次连接 AWS IoT 时注册 AWS IoT 并被识别。设备将在首次连接时使用其配置模板的详细信息进行配置。 AWS IoT 

  有关单件事物、JITP、JITR 和具有唯一证书的设备批量预调配的详细信息，请参阅 [预调配具有设备证书的设备](provision-w-cert.md)。
+ 

**终端用户或安装人员可以使用应用程序在其物联网设备上安装证书**  
如果您无法在物联网设备上安全地安装唯一的客户端证书以供终端用户使用，但终端用户或安装程序可以使用应用程序注册设备并安装唯一设备证书，则需要执行[通过信任用户预调配](provision-wo-cert.md#trusted-user)的过程。

  使用信任用户（如终端用户或具有已知账户的安装程序）可以简化设备制造过程。设备没有唯一的客户端证书，而是临时证书，仅允许设备连接 5 分钟。 AWS IoT 在这 5 分钟的窗口中，信任用户将获得具有更长寿命的唯一客户端证书，并将其安装在设备上。申请证书的寿命有限，因此能够最大限度地减少证书受损的风险。

  有关更多信息，请参阅 [由可信用户预调配](provision-wo-cert.md#trusted-user)。
+ 

**终端用户无法使用应用程序在其物联网设备上安装证书**  
如果上述两个选项都不适用于您的物联网解决方案，则可选择[通过申请预调配](provision-wo-cert.md#claim-based)流程。通过此流程，您的物联网设备将拥有由实例集中其它设备共享的申请证书。设备首次使用声明证书连接时，使用其配置模板 AWS IoT 注册该设备，并向设备颁发其唯一的客户端证书以供后续访问 AWS IoT。

   此选项允许在设备连接时自动配置设备 AWS IoT，但如果索赔证书泄露，则可能会带来更大的风险。如果申请证书受损，您可以停用该证书。停用申请证书可防止具有该申请证书的所有设备在将来不会被注册。但是，停用申请证书不会阻止已预调配的设备。

  有关更多信息，请参阅 [通过申请进行预调配](provision-wo-cert.md#claim-based)。

## 在中配置设备 AWS IoT
<a name="provisioning-in-iot"></a>

使用配置设备时 AWS IoT，必须创建资源，这样您的设备 AWS IoT 才能安全地通信。您可以创建其它资源来帮助管理设备实例集。在预调配过程中可以创建以下资源：
+ IoT 事物。

  物联网事物是 AWS IoT 设备注册表中的条目。每个事物都有一个唯一的名称和一组属性，并与物理设备相关联。事物可以使用事物类型来定义，或者分组为事物组。有关更多信息，请参阅 [使用管理设备 AWS IoT](iot-thing-management.md)。

   虽然创建事物并非必需，但这使您能够按事物类型、事物组和事物属性来搜索设备，以更有效地管理设备实例集。有关更多信息，请参阅 [机群索引](iot-indexing.md)。
**注意**  
要使对事物的连接状态数据编制索引，请预调配事物并对其进行配置，以便事物名称与连接请求中使用的客户端 ID 匹配。
+ X.509 证书。

  设备使用 X.509 证书与执行相互身份验证。 AWS IoT您可以注册现有证书，也可以为您 AWS IoT 生成和注册新证书。通过将证书附加到表示设备的事物，您可以将证书与设备关联。您还必须将证书和关联的私有密钥复制到设备上。设备在连接时会出示证书 AWS IoT。有关更多信息，请参阅 [身份验证](authentication.md)。
+ IoT 策略。

  IoT 策略确定设备可在 AWS IoT中执行的操作。IoT 策略附加到设备证书。当设备向其提供证书时 AWS IoT，它将被授予策略中指定的权限。有关更多信息，请参阅 [Authorization](iot-authorization.md)。每个设备都需要一个证书来与 AWS IoT通信。

AWS IoT 支持使用配置模板自动配置队列。配置模板描述了配置设备 AWS IoT 所需的资源。模板包含变量，使您能够使用一个模板来预调配多个设备。在您预调配设备时，您可以使用字典或*映射* 为设备特定的变量指定值。要预调配其它设备，请在字典中指定新值。

无论设备是否具有唯一的证书（及其关联的私有密钥），您都可以使用自动预调配。

## 舰队配置 APIs
<a name="provisioning-apis"></a>

舰队配置中 APIs 使用了以下几种类型：
+ 这些控制面板函数可创建和管理实例集预调配模板，并配置可信用户策略。
  + [CreateProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html)
  + [ CreateProvisioningTemplateVersion](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplateVersion.html)
  + [DeleteProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_DeleteProvisioningTemplate.html)
  + [DeleteProvisioningTemplateVersion](https://docs.aws.amazon.com/iot/latest/apireference/API_DeleteProvisioningTemplateVersion.html)
  + [DescribeProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeProvisioningTemplate.html)
  + [DescribeProvisioningTemplateVersion](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeProvisioningTemplateVersion.html)
  + [ListProvisioningTemplates](https://docs.aws.amazon.com/iot/latest/apireference/API_ListProvisioningTemplates.html)
  + [ListProvisioningTemplateVersions](https://docs.aws.amazon.com/iot/latest/apireference/API_ListProvisioningTemplateVersions.html)
  + [UpdateProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateProvisioningTemplate.html)
+ 可信用户可以使用此控制面板函数生成临时信息载入申请。此临时申请在 Wi-Fi 配置或类似方法期间传递给设备。
  + [CreateProvisioningClaim](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningClaim.html)
+ 预调配过程中设备使用的 MQTT API，其中包含嵌入设备中的预调配申请证书，或由可信用户传递到其中。
  + [CreateCertificateFromCsr](fleet-provision-api.md#create-cert-csr)
  + [CreateKeysAndCertificate](fleet-provision-api.md#create-keys-cert)
  + [RegisterThing](fleet-provision-api.md#register-thing)

# 使用实例集预调配来预调配没有设备证书的设备
<a name="provision-wo-cert"></a>

通过使用 AWS IoT 队列配置， AWS IoT 可以在设备首次连接时生成设备证书和私钥并将其安全地交付 AWS IoT 给您的设备。 AWS IoT 提供由 Amazon 根证书颁发机构 (CA) 签署的客户证书。

使用实例集预调配的方法有两种：
+ [通过申请进行预调配](#claim-based)
+ [由可信用户预调配](#trusted-user)

## 通过申请进行预调配
<a name="claim-based"></a>

设备在制造时可以嵌入预调配申请证书和私有密钥（这是特殊用途凭证）。如果注册了这些证书 AWS IoT，则该服务可以将它们交换为设备可用于常规操作的唯一设备证书。此过程包括以下步骤：

**在交付设备之前**

1. 调用 [https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningTemplate.html](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningTemplate.html) 以创建预调配模板。此 API 返回模板 ARN。有关更多信息，请参阅 [设备预调配 MQTT API](fleet-provision-api.md)。

   您也可以在 AWS IoT 控制台中创建队列配置模板。

   1. 从导航窗格中，选择**连接多个设备**下拉菜单。然后，选择**连接多个设备**。

   1. 选择**创建预调配模板**。

   1. 选择最符合您安装流程的**配置场景**。然后选择**下一步**。

   1. 完成模板工作流程。

1. 创建用作预调配申请证书的证书以及关联的私有密钥。

1. 将这些证书注册到限制证书使用的 IoT 策略 AWS IoT 并关联该策略。以下示例物联网策略限制使用与此策略关联的证书来预调配设备。  
****  

   ```
   {
       "Version":"2012-10-17",		 	 	 
       "Statement": [
           {
               "Effect": "Allow",
               "Action": [
                   "iot:Connect"
               ],
               "Resource": "*"
           },
           {
               "Effect": "Allow",
               "Action": [
                   "iot:Publish",
                   "iot:Receive"
               ],
               "Resource": [
               "arn:aws:iot:us-east-1:123456789012:topic/$aws/certificates/create/*",
       "arn:aws:iot:us-east-1:123456789012:topic/$aws/provisioning-templates/templateName/provision/*"
               ]
           },
           {
               "Effect": "Allow",
               "Action": "iot:Subscribe",
               "Resource": [
               "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/certificates/create/*",
       "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/provisioning-templates/templateName/provision/*"
               ]
           }
       ]
   }
   ```

1. 在配置设备时，授予 AWS IoT 服务权限以创建或更新您账户中的物联网资源和证书。为此，请将`AWSIoTThingsRegistration`托管策略附加到信任 AWS IoT 服务委托人的 IAM 角色（称为配置角色）。

1. 制造在其中安全地嵌入了预调配申请证书的设备。

设备现在已准备就绪，可以运输到要安装以使用它的位置。

**重要**  
预调配申请私有密钥应始终得到保护，包括在设备上时。我们建议您使用 AWS IoT CloudWatch 指标和日志来监控是否存在滥用迹象。如果您检测到滥用，请关闭预调配申请证书，以使其不能用于设备预调配。

**初始化设备以供使用**

1. 设备[AWS IoT Device SDK、Mobile SDK 和 AWS IoT Device Client](iot-sdks.md)使用连接设备上安装的 AWS IoT 配置声明证书并进行身份验证。
**注意**  
为了安全起见，由 `CreateCertificateFromCsr` 和 `CreateKeysAndCertificate` 返回的 `certificateOwnershipToken` 将在一小时后过期。必须在 `certificateOwnershipToken` 过期前调用 `RegisterThing`。如果由 `CreateCertificateFromCsr` 或 `CreateKeysAndCertificate` 创建的证书尚未激活，并且在令牌过期时尚未附加到策略或事物，则该证书将被删除。如果令牌过期，设备可以再次调用 `CreateCertificateFromCsr` 或 `CreateKeysAndCertificate` 以生成新证书。

1. 设备通过使用以下选项之一获取永久证书和私有密钥。设备将使用证书和密钥进行 future 的所有身份验证 AWS IoT。

   1. 调用[`CreateKeysAndCertificate`](fleet-provision-api.md#create-keys-cert)以使用证书颁发机构创建新的 AWS 证书和私钥。

      Or

   1. 调用 [`CreateCertificateFromCsr`](fleet-provision-api.md#create-cert-csr) 以通过证书签名请求生成证书，这可确保其私有密钥安全。

1. 从设备中，调用 [`RegisterThing`](fleet-provision-api.md#register-thing) 以向 AWS IoT 注册设备并创建云资源。

   实例集预调配服务使用预调配模板来定义和创建云资源，如 IoT 事物。该模板可以指定事物的属性和所属的组。在将新事物添加到事物组之前，事物组必须先存在。

1. 在设备上保存永久证书后，设备必须断开与它使用预调配申请证书发起的会话的连接，并使用此永久证书重新连接。

设备现已准备就绪，可以与之进行正常通信 AWS IoT。

## 由可信用户预调配
<a name="trusted-user"></a>

在许多情况下，当可信用户（例如最终用户或安装技术人员）使用移动应用程序在其部署位置配置设备时，设备才会首次连接到该设备。 AWS IoT 

**重要**  
您必须管理可信用户的访问和权限才能执行此流程。做到这一点的一种方法是为可信用户提供和维护一个账户，该账户对他们进行身份验证，并授予他们对执行此过程所需的 AWS IoT 特征和 API 操作的访问权限。

**在交付设备之前**

1. 调[https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningTemplate.html](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningTemplate.html)用创建配置模板并返回其*templateArn*和*templateName*。

1. 创建由信任用户用于启动预调配过程的 IAM 角色。预调配模板仅允许该用户预调配设备。例如：

   ```
   {
       "Effect": "Allow",
       "Action": [
           "iot:CreateProvisioningClaim"
       ],
       "Resource": [
           "arn:aws:iot:aws-region:aws-account-id:provisioningtemplate/templateName"
       ]
   }
   ```

1. 在配置设备时，向 AWS IoT 服务授予创建或更新物联网资源的权限，例如您账户中的东西和证书。为此，您可以将`AWSIoTThingsRegistration`托管策略附加到信任 AWS IoT 服务委托人的 IAM *角色（称为配置角色*）。

1. 提供识别可信用户的方式，例如为他们提供一个账户，该账户可以对他们进行身份验证，并授权他们与注册其设备所需 AWS 的 API 操作进行交互。

**初始化设备以供使用**

1. 可信用户登录您的预调配移动应用程序或 Web 服务。

1. 移动应用程序或 Web 应用程序使用 IAM 角色并调用 [https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningClaim.html](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateProvisioningClaim.html)，以从 AWS IoT获取临时预调配申请证书。
**注意**  
出于安全考虑，`CreateProvisioningClaim` 返回的临时预调配申请证书只有五分钟的有效期。在临时预调配申请证书过期之前，以下步骤必须成功地返回有效证书。临时预调配申请证书不会显示在您账户的证书列表中。

1. 移动应用程序或 Web 应用程序将临时预调配申请证书以及任何必需的配置信息（如 Wi-Fi 凭证）提供给设备。

1. 设备使用临时预调配申请证书，通过 [AWS IoT Device SDK、Mobile SDK 和 AWS IoT Device Client](iot-sdks.md) 连接到 AWS IoT 。

1. 设备在使用临时配置声明证书连接后的五分钟内使用其中一个选项获得永久证书和私钥。 AWS IoT 设备将使用这些选项返回的证书和密钥进行未来的所有身份验证 AWS IoT。

   1. 调用[`CreateKeysAndCertificate`](fleet-provision-api.md#create-keys-cert)以使用证书颁发机构创建新的 AWS 证书和私钥。

      Or

   1. 调用 [`CreateCertificateFromCsr`](fleet-provision-api.md#create-cert-csr) 以通过证书签名请求生成证书，这可确保其私有密钥安全。
**注意**  
请记住[`CreateKeysAndCertificate`](fleet-provision-api.md#create-keys-cert)或[`CreateCertificateFromCsr`](fleet-provision-api.md#create-cert-csr)必须在连接到 AWS IoT 临时配置声明证书后的五分钟内返回有效的证书。

1. 设备调[`RegisterThing`](fleet-provision-api.md#register-thing)用注册设备 AWS IoT 并创建云资源。

   实例集预调配服务使用预调配模板来定义和创建云资源，如 IoT 事物。该模板可以指定事物的属性和所属的组。在将新事物添加到事物组之前，事物组必须先存在。

1. 在设备上保存永久证书后，设备必须断开与它使用临时预调配申请证书发起的会话的连接，并使用此永久证书重新连接。

设备现已准备就绪，可以与之进行正常通信 AWS IoT。

## 在 CLI 中使用预配置挂钩 AWS
<a name="hooks-cli-instruc"></a>

以下流程使用预先预调配挂钩创建预调配模板。此处使用的 Lambda 函数是一个可以修改的示例。

**创建预先预调配挂钩并将其应用到预调配模板**

1. 创建一个具有定义输入和输出的 Lambda 函数。Lambda 函数高度可自定义，需要 `allowProvisioning` 和 `parameterOverrides` 来创建预调配挂钩。有关创建 Lambda 函数的更多信息，请参阅[在 AWS 命令行界 AWS Lambda 面中使用](https://docs.aws.amazon.com/lambda/latest/dg/gettingstarted-awscli.html)。

   以下是 Lambda 函数输出的示例：

   ```
   {
     "allowProvisioning": True,
     "parameterOverrides": {
       "incomingKey0": "incomingValue0",
       "incomingKey1": "incomingValue1"
     }
   }
   ```

1. AWS IoT 使用基于资源的策略来调用 Lambda，因此您必须授 AWS IoT 予调用 Lambda 函数的权限。
**重要**  
请务必在附加到 Lambda 操作策略的全局条件上下文键中包含 `source-arn` 或 `source-account`，以便防范权限操纵。有关此问题的更多信息，请参阅[防止跨服务混淆座席](cross-service-confused-deputy-prevention.md)。

   以下示例使用 [add-permission](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) 将物联网权限授予您的 Lambda。

   ```
   aws lambda add-permission \
       --function-name myLambdaFunction \
       --statement-id iot-permission \
       --action lambda:InvokeFunction \
       --principal iot.amazonaws.com
   ```

1. 使用[create-provisioning-template](https://docs.aws.amazon.com/cli/latest/reference/iot/create-provisioning-template.html)或[update-provisioning-template](https://docs.aws.amazon.com/cli/latest/reference/iot/update-provisioning-template.html)命令向模板添加预置挂钩。

   [create-provisioning-template](https://docs.aws.amazon.com/cli/latest/reference/iot/create-provisioning-template.html)以下 CLI 示例使用创建具有预置挂钩的配置模板：

   ```
   aws iot create-provisioning-template \
       --template-name myTemplate \
       --provisioning-role-arn arn:aws:iam:us-east-1:1234564789012:role/myRole \
       --template-body file://template.json \
       --pre-provisioning-hook file://hooks.json
   ```

   此命令的输出如下所示：

   ```
   {
       "templateArn": "arn:aws:iot:us-east-1:1234564789012:provisioningtemplate/myTemplate",
       "defaultVersionId": 1,
       "templateName": myTemplate
   }
   ```

   您也可以从文件加载参数，而不是将其作为命令行参数值完全键入，以节省时间。有关更多信息，请参阅[从文件加载 AWS CLI 参数](https://docs.aws.amazon.com/cli/latest/userguide/cli-usage-parameters-file.html)。下面显示了扩展 JSON 格式的 `template` 参数：

   ```
   {
       "Parameters" : {
           "DeviceLocation": {
               "Type": "String"
           }
       },
       "Mappings": {
           "LocationTable": {
               "Seattle": {
                   "LocationUrl": "https://example.aws"
               }
           }
       },
       "Resources" : {
           "thing" : {
               "Type" : "AWS::IoT::Thing",
               "Properties" : {
                   "AttributePayload" : {
                       "version" : "v1",
                       "serialNumber" : "serialNumber"
                   },
                   "ThingName" : {"Fn::Join":["",["ThingPrefix_",{"Ref":"SerialNumber"}]]},
                   "ThingTypeName" : {"Fn::Join":["",["ThingTypePrefix_",{"Ref":"SerialNumber"}]]},
                   "ThingGroups" : ["widgets", "WA"],
                   "BillingGroup": "BillingGroup"
               },
               "OverrideSettings" : {
                   "AttributePayload" : "MERGE",
                   "ThingTypeName" : "REPLACE",
                   "ThingGroups" : "DO_NOTHING"
               }
           },
           "certificate" : {
               "Type" : "AWS::IoT::Certificate",
               "Properties" : {
                   "CertificateId": {"Ref": "AWS::IoT::Certificate::Id"},
                   "Status" : "Active",
                   "ThingPrincipalType" : "EXCLUSIVE_THING"
               }
           },
           "policy" : {
               "Type" : "AWS::IoT::Policy",
               "Properties" : {
                   "PolicyDocument" : {
                       "Version": "2012-10-17",		 	 	 
                       "Statement": [{
                           "Effect": "Allow",
                           "Action":["iot:Publish"],
                           "Resource": ["arn:aws:iot:us-east-1:504350838278:topic/foo/bar"]
                       }]
                   }
               }
           }
       },
       "DeviceConfiguration": {
           "FallbackUrl": "https://www.example.com/test-site",
           "LocationUrl": {
               "Fn::FindInMap": ["LocationTable",{"Ref": "DeviceLocation"}, "LocationUrl"]}
       }
   }
   ```

   下面显示了扩展 JSON 格式的 `pre-provisioning-hook` 参数：

   ```
   {
        "targetArn" : "arn:aws:lambda:us-east-1:765219403047:function:pre_provisioning_test",
        "payloadVersion" : "2020-04-01"
   }
   ```

# 预调配具有设备证书的设备
<a name="provision-w-cert"></a>

AWS IoT 当设备上已有设备证书（和关联的私钥）时，提供了三种配置设备的方式：
+ 使用预调配模板进行单一事物预调配。如果您只需一次预调配一台设备，那么这是一个很好的选择。
+ Just-in-time 使用模板进行配置 (JITP)，该模板可在设备首次连接时对其进行 AWS IoT配置。如果您需要注册大量设备，但没有可以整合到批量预调配列表中的有关这些设备的信息，那么这是一个很好的选择。
+ 批量注册。此选项可让您指定存储在 S3 存储桶内的文件中的单一事物预调配模板值。如果您有大量已知设备，并且可以将它们所需的特性整合到列表中，则此方法很有用。

**Topics**
+ [单个事物预调配](single-thing-provisioning.md)
+ [Just-in-time 资源调配](jit-provisioning.md)
+ [批量注册](bulk-provisioning.md)

# 单个事物预调配
<a name="single-thing-provisioning"></a>

要配置事物，请使用 [RegisterThing](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterThing.html)API 或 `register-thing` CLI 命令。`register-thing` CLI 命令接受以下参数：

--template-body  
预调配模板。

--parameters  
在预调配模板中使用的参数的名称-值对列表，采用 JSON 格式（例如，`{"ThingName" : "MyProvisionedThing", "CSR" : "csr-text"}`）。

请参阅[预置模板](provision-template.md)。

[RegisterThing](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterThing.html)或者`register-thing`返回 ARNs 资源及其创建的证书的文本：

```
{
    "certificatePem": "certificate-text",
    "resourceArns": {
    "PolicyLogicalName": "arn:aws:iot:us-west-2:123456789012:policy/2A6577675B7CD1823E271C7AAD8184F44630FFD7",
    "certificate": "arn:aws:iot:us-west-2:123456789012:cert/cd82bb924d4c6ccbb14986dcb4f40f30d892cc6b3ce7ad5008ed6542eea2b049",
    "thing": "arn:aws:iot:us-west-2:123456789012:thing/MyProvisionedThing"
    }
}
```

如果在字典中省略了参数，则使用默认值。如果未指定默认值，则不使用值来替换参数。

# Just-in-time 资源调配
<a name="jit-provisioning"></a>

当您的设备首次尝试连接时，您可以使用 just-in-time配置 (JITP) 对其进行配置。 AWS IoT要预调配设备，您必须启用自动注册，并将预调配模板与用于对设备证书进行签名的 CA 证书关联。配置成功和错误的记录与[设备预调配指标](metrics_dimensions.md#provisioning-metrics)在 Amazon 中相同 CloudWatch。

**Topics**
+ [JITP 概览](#jit-provisioning-overview)
+ [使用预调配模板注册 CA](#jit-provisioning-registerCA-template)
+ [使用预调配模板名称注册 CA](#jit-provisioning-registerCA-templateName)

## JITP 概览
<a name="jit-provisioning-overview"></a>

当设备尝试使用 AWS IoT 由已注册的 CA 证书签名的证书进行连接时，会从 CA 证书 AWS IoT 加载模板并使用它进行调用[RegisterThing](fleet-provision-api.md#register-thing)。JITP 工作流首先将注册一个状态值为 `PENDING_ACTIVATION` 的证书。当设备预调配流程完成时，该证书的状态将更改为 `ACTIVE`。

AWS IoT 定义了您可以在置备模板中声明和引用的以下参数：
+ `AWS::IoT::Certificate::Country`
+ `AWS::IoT::Certificate::Organization`
+ `AWS::IoT::Certificate::OrganizationalUnit`
+ `AWS::IoT::Certificate::DistinguishedNameQualifier`
+ `AWS::IoT::Certificate::StateName`
+ `AWS::IoT::Certificate::CommonName`
+ `AWS::IoT::Certificate::SerialNumber`
+ `AWS::IoT::Certificate::Id`

这些预调配模板参数的值被限制为 JITP 可从正在预调配的设备的证书的使用者字段中提取的内容。证书必须包含模板正文中所有参数的值。`AWS::IoT::Certificate::Id` 参数指内部生成的 ID，而不是证书包含的 ID。您可以使用 AWS IoT 规则中的`principal()`函数获取此 ID 的值。

**注意**  
您可以使用 AWS IoT Core just-in-time 配置 (JITP) 功能配置设备，而不必在设备首次连接时将整个信任链发送到 AWS IoT Core。可以选择出示 CA 证书，但当设备连接到 AWS IoT Core时，需要发送[服务器名称指示（SNI）](https://datatracker.ietf.org/doc/html/rfc3546#section-3.1)扩展。

### 示例模板正文
<a name="jit-provisioning-example-templatebody"></a>

以下 JSON 文件是完整 JITP 模板的示例模板正文。

```
{
   "Parameters":{
      "AWS::IoT::Certificate::CommonName":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::SerialNumber":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::Country":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::Id":{
         "Type":"String"
      }
   },
   "Resources":{
      "thing":{
         "Type":"AWS::IoT::Thing",
         "Properties":{
            "ThingName":{
               "Ref":"AWS::IoT::Certificate::CommonName"
            },
            "AttributePayload":{
               "version":"v1",
               "serialNumber":{
                  "Ref":"AWS::IoT::Certificate::SerialNumber"
               }
            },
            "ThingTypeName":"lightBulb-versionA",
            "ThingGroups":[
               "v1-lightbulbs",
               {
                  "Ref":"AWS::IoT::Certificate::Country"
               }
            ]
         },
         "OverrideSettings":{
            "AttributePayload":"MERGE",
            "ThingTypeName":"REPLACE",
            "ThingGroups":"DO_NOTHING"
         }
      },
      "certificate":{
         "Type":"AWS::IoT::Certificate",
         "Properties":{
            "CertificateId":{
               "Ref":"AWS::IoT::Certificate::Id"
            },
            "Status":"ACTIVE"
         }
      },
      "policy":{
         "Type":"AWS::IoT::Policy",
         "Properties":{
            "PolicyDocument":"{ \"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:aws:iot:us-east-1:123456789012:topic/foo/bar\"] }] }"
         }
      }
   }
}
```

此示例模板声明了从证书中提取并在 `Resources` 部分中使用的 `AWS::IoT::Certificate::CommonName`、`AWS::IoT::Certificate::SerialNumber`、`AWS::IoT::Certificate::Country` 和 `AWS::IoT::Certificate::Id` 预调配参数的值。JITP 工作流随后将使用此模板执行以下操作：
+ 注册一个证书并将其状态设置为 PENDING\$1ACTIVE。
+ 创建一个事物资源。
+ 创建一个策略资源。
+ 将策略附加到证书。
+ 将证书附加到 事物。
+ 将证书状态更新为 ACTIVE。

如果证书不具有 `templateBody` 的 `Parameters` 部分中提及的所有属性，则设备将会预调配失败。例如，如果 `AWS::IoT::Certificate::Country` 包含在模板中，但证书没有 `Country` 属性，设备预调配操作将会失败。

您还可以使用 CloudTrail 对 JITP 模板的问题进行故障排除。有关 Amazon 中记录的指标的信息 CloudWatch，请参阅[设备预调配指标](metrics_dimensions.md#provisioning-metrics)。有关预调配模板的更多信息，请参阅[预调配模板](provision-template.md)。

**注意**  
在配置过程中， just-in-time配置 (JITP) 会调用其他 AWS IoT 控制平面 API 操作。这些调用可能会超过为您账户设置的 [AWS IoT 节流配额](https://docs.aws.amazon.com/general/latest/gr/iot-core.html#throttling-limits)，导致调用受到限制。如有必要，请联系 [AWS 客户支持](https://console.aws.amazon.com/support/home)来增大节流配额。

## 使用预调配模板注册 CA
<a name="jit-provisioning-registerCA-template"></a>

要使用完整的预调配模板注册 CA，请执行以下步骤：

1. 将预调配模板和角色 ARN 信息（如下例所示）保存为 JSON 文件：

   ```
   { 
        "templateBody" : "{\r\n    \"Parameters\" : {\r\n        \"AWS::IoT::Certificate::CommonName\": {\r\n            \"Type\": \"String\"\r\n        },\r\n        \"AWS::IoT::Certificate::SerialNumber\": {\r\n            \"Type\": \"String\"\r\n        },\r\n        \"AWS::IoT::Certificate::Country\": {\r\n            \"Type\": \"String\"\r\n        },\r\n        \"AWS::IoT::Certificate::Id\": {\r\n            \"Type\": \"String\"\r\n        }\r\n    },\r\n    \"Resources\": {\r\n        \"thing\": {\r\n            \"Type\": \"AWS::IoT::Thing\",\r\n            \"Properties\": {\r\n                \"ThingName\": {\r\n                    \"Ref\": \"AWS::IoT::Certificate::CommonName\"\r\n                },\r\n                \"AttributePayload\": {\r\n                    \"version\": \"v1\",\r\n                    \"serialNumber\": {\r\n                        \"Ref\": \"AWS::IoT::Certificate::SerialNumber\"\r\n                    }\r\n                },\r\n                \"ThingTypeName\": \"lightBulb-versionA\",\r\n                \"ThingGroups\": [\r\n                    \"v1-lightbulbs\",\r\n                    {\r\n                        \"Ref\": \"AWS::IoT::Certificate::Country\"\r\n                    }\r\n                ]\r\n            },\r\n            \"OverrideSettings\": {\r\n                \"AttributePayload\": \"MERGE\",\r\n                \"ThingTypeName\": \"REPLACE\",\r\n                \"ThingGroups\": \"DO_NOTHING\"\r\n            }\r\n        },\r\n        \"certificate\": {\r\n            \"Type\": \"AWS::IoT::Certificate\",\r\n            \"Properties\": {\r\n                \"CertificateId\": {\r\n                    \"Ref\": \"AWS::IoT::Certificate::Id\"\r\n                },\r\n                \"Status\": \"ACTIVE\"\r\n            },\r\n            \"OverrideSettings\": {\r\n                \"Status\": \"DO_NOTHING\"\r\n            }\r\n        },\r\n        \"policy\": {\r\n            \"Type\": \"AWS::IoT::Policy\",\r\n            \"Properties\": {\r\n                \"PolicyDocument\": \"{ \\\"Version\\\": \\\"2012-10-17		 	 	 \\\", \\\"Statement\\\": [{ \\\"Effect\\\": \\\"Allow\\\", \\\"Action\\\":[\\\"iot:Publish\\\"], \\\"Resource\\\": [\\\"arn:aws:iot:us-east-1:123456789012:topic\/foo\/bar\\\"] }] }\"\r\n            }\r\n        }\r\n    }\r\n}",
        "roleArn" : "arn:aws:iam::123456789012:role/JITPRole"
   }
   ```

   在本例中，`templateBody` 字段的值必须是指定为转义字符串的 JSON 对象，并且只能使用[前述表](#jit-provisioning-overview)中的值。您可以使用各种工具来创建所需的 JSON 输出，例如 `json.dumps`（Python）或 `JSON.stringify`（节点）。`roleARN` 字段的值必须是附加有 `AWSIoTThingsRegistration` 的角色的 ARN。此外，您的模板还可以在示例中使用现有 `PolicyName`，而不是内联 `PolicyDocument`。

1. 使用注册 CACertificate API 操作或 C [https://docs.aws.amazon.com//cli/latest/reference/iot/register-ca-certificate.html](https://docs.aws.amazon.com//cli/latest/reference/iot/register-ca-certificate.html)LI 命令[注册](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCACertificate.html) CA 证书。您将指定预调配模板的目录以及您在上一步中保存的角色 ARN 信息：

   下面显示了如何使用 AWS CLI在 `DEFAULT` 模式中注册 CA 证书的示例：

   ```
   aws iot register-ca-certificate --ca-certificate file://your-ca-cert --verification-cert file://your-verification-cert 
                   --set-as-active --allow-auto-registration --registration-config file://your-template
   ```

   下面显示了如何使用 `SNI_ONLY` 在 AWS CLI模式中注册 CA 证书的示例：

   ```
   aws iot register-ca-certificate --ca-certificate file://your-ca-cert --certificate-mode SNI_ONLY
                    --set-as-active --allow-auto-registration --registration-config file://your-template
   ```

   有关更多信息，请参阅[注册 CA 证书](https://docs.aws.amazon.com//iot/latest/developerguide/register-CA-cert.html)。

1.  （可选）使用更新 CACertificate API 操作或 C [https://docs.aws.amazon.com//cli/latest/reference/iot/update-ca-certificate.html](https://docs.aws.amazon.com//cli/latest/reference/iot/update-ca-certificate.html)LI 命令[更新](https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateCACertificate.html) CA 证书的设置。

   下面显示了如何使用 AWS CLI更新 CA 证书的示例：

   ```
   aws iot update-ca-certificate --certificate-id caCertificateId
                   --new-auto-registration-status ENABLE --registration-config file://your-template
   ```

## 使用预调配模板名称注册 CA
<a name="jit-provisioning-registerCA-templateName"></a>

要使用预调配模板名称注册 CA，请执行以下步骤：

1. 将预调配模板正文保存为 JSON 文件。您可以在[示例模板正文](#jit-provisioning-example-templatebody)中找到一个示例模板正文。

1. 要创建配置模板，请使用 [CreateProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html)API 或 [https://docs.aws.amazon.com//cli/latest/reference/iot/create-provisioning-template.html](https://docs.aws.amazon.com//cli/latest/reference/iot/create-provisioning-template.html)CLI 命令：

   ```
   aws iot create-provisioning-template --template-name your-template-name \
           --template-body file://your-template-body.json --type JITP \
           --provisioning-role-arn arn:aws:iam::123456789012:role/test
   ```
**注意**  
对于 just-in-time配置 (JITP)，您必须在创建置备模板`JITP`时指定模板类型。有关模板类型的更多信息，请参阅 *AWS API 参考[CreateProvisioningTemplate](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html)*中的。

1. 要使用模板名称注册 CA，请使用[注册 CACertificate](https://docs.aws.amazon.com/iot/latest/apireference/API_RegisterCACertificate.html) API 或 [https://docs.aws.amazon.com//cli/latest/reference/iot/register-ca-certificate.html](https://docs.aws.amazon.com//cli/latest/reference/iot/register-ca-certificate.html)CLI 命令：

   ```
   aws iot register-ca-certificate --ca-certificate file://your-ca-cert --verification-cert file://your-verification-cert \
           --set-as-active --allow-auto-registration --registration-config templateName=your-template-name
   ```

# 批量注册
<a name="bulk-provisioning"></a>

您可以使用 [https://docs.aws.amazon.com/iot/latest/apireference/API_StartThingRegistrationTask.html](https://docs.aws.amazon.com/iot/latest/apireference/API_StartThingRegistrationTask.html) 命令批量注册事物。此命令接受预调配模板、S3 桶名称、键名称以及允许访问 S3 桶中文件的角色 ARN。S3 存储桶中的文件包含用于替换模板中参数的值。该文件必须为以换行符分隔的 JSON 文件。每一行包含用于注册单个设备的所有参数值。例如：

```
{"ThingName": "foo", "SerialNumber": "123", "CSR": "csr1"}
{"ThingName": "bar", "SerialNumber": "456", "CSR": "csr2"}
```

以下批量注册相关的 API 操作可能很有用：
+ [ListThingRegistrationTasks](https://docs.aws.amazon.com/iot/latest/apireference/API_ListThingRegistrationTasks.html)：列出当前的批量事物配置任务。
+ [ DescribeThingRegistrationTask](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeThingRegistrationTask.html)：提供有关特定批量事物注册任务的信息。
+ [StopThingRegistrationTask](https://docs.aws.amazon.com/iot/latest/apireference/API_StopThingRegistrationTask.html): 停止批量事物注册任务。
+ [ListThingRegistrationTaskReports](https://docs.aws.amazon.com/iot/latest/apireference/API_ListThingRegistrationTaskReports.html)：用于检查批量事物注册任务的结果和失败。

**注意**  
一次只能运行一个批量注册操作任务（每个账户）。
批量注册操作会调用其他 AWS IoT 控制平面 API 操作。这些调用可能会超出您账户的 [AWS IoT 节流配额](https://docs.aws.amazon.com/general/latest/gr/iot-core.html#throttling-limits)，导致节流错误。如有必[AWS 要，请联系 Customer Supp](https://console.aws.amazon.com/support/home) ort 以提高您的限 AWS IoT 流配额。

# 预置模板
<a name="provision-template"></a>

配置模板是一个 JSON 文档，它使用参数来描述您的设备必须使用哪些资源才能与之交互 AWS IoT。预调配模板包含两个部分：`Parameters` 和 `Resources`。中有两种类型的配置模板 AWS IoT。一个用于 just-in-time配置 (JITP) 和批量注册，第二个用于队列配置。

**Topics**
+ [参数部分](#parameters-section)
+ [资源部分](#resources-section)
+ [批量注册的模板示例](#bulk-template-example)
+ [just-in-time置备模板示例 (JITP)](#JITP-template-example)
+ [实例集预置](#fleet-provision-template)

## 参数部分
<a name="parameters-section"></a>

`Parameters` 部分声明在 `Resources` 部分中使用的参数。每个参数声明一个名称、一个类型以及一个可选的默认值。在随模板传入的字典不包含参数的值时，会使用默认值。模板文档的 `Parameters` 部分类似于以下所示：

```
{
    "Parameters" : {
        "ThingName" : {
            "Type" : "String"
        },
        "SerialNumber" : {
            "Type" : "String"
        },
        "Location" : {
            "Type" : "String",
            "Default" : "WA"
        },
        "CSR" : {
            "Type" : "String"    
        }
    }
}
```

此模板正文片段声明四个参数：`ThingName`、`SerialNumber`、`Location` 和 `CSR`。所有这些参数均为 `String` 类型。`Location` 参数声明了默认值 `"WA"`。

## 资源部分
<a name="resources-section"></a>

模板正`Resources`文的部分声明了您的设备与之通信所需的资源 AWS IoT：事物、证书以及一个或多个 IoT 策略。每个资源指定一个逻辑名称、一个类型和一组属性。

您可以使用逻辑名称在模板的其它位置引用资源。

类型指定您所声明的资源的种类。有效类型为：
+ `AWS::IoT::Thing`
+ `AWS::IoT::Certificate`
+ `AWS::IoT::Policy`

您指定的属性取决于所声明的资源的类型。

### 事物资源
<a name="thing-resources"></a>

事物资源使用以下属性进行声明：
+ `ThingName`: 字符串。
+ `AttributePayload`: 可选。名称-值对的列表。
+ `ThingTypeName`: 可选。用于事物的关联事物类型的字符串。
+ `ThingGroups`: 可选。事物所属的组的列表。
+ `BillingGroup`: 可选。关联账单组名称的字符串。
+ `PackageVersions`: 可选。关联软件包名称和版本名称的字符串。

### 证书资源
<a name="certificate-resources"></a>

您可以通过以下方式之一指定证书：
+ 证书签名请求（CSR）。
+ 现有设备证书的证书 ID。（只有证书 IDs 可以与队列配置模板一起使用。）
+ 使用注册到 AWS IoT的 CA 证书创建的设备证书。如果您有多个 CA 证书注册到同一使用者字段，则还必须传入用于对设备证书进行签名的 CA 证书。

**注意**  
当您在模板中声明证书时，请只使用这些方法之一。例如，如果您使用了 CSR，就不能同时指定证书 ID 或设备证书。有关更多信息，请参阅 [X.509 客户端证书](x509-client-certs.md)。

有关更多信息，请参阅 [X.509 证书概览](authentication.md#x509-certificate-overview)。

证书资源使用以下属性进行声明：
+ `CertificateSigningRequest`: 字符串。
+ `CertificateId`: 字符串。
+ `CertificatePem`: 字符串。
+ `CACertificatePem`: 字符串。
+ `Status`: 可选。字符串可以是 `ACTIVE` 或 `INACTIVE`。默认值为 ACTIVE。
+ `ThingPrincipalType`: 可选。指定事物与主体（证书）之间关系类型的字符串。
  + `EXCLUSIVE_THING`：建立独占关系。该主体只能附加到此特定事物，不能附加到其他事物。
  + `NON_EXCLUSIVE_THING`：将指定主体附加到事物。您可以将多个事物附加到该主体。如果未指定，这是默认值。
**注意**  
您也可以在没有设备证书的情况下配置设备。有关更多信息，请参阅 [使用实例集预调配来预调配没有设备证书的设备](provision-wo-cert.md)。

示例：
+ 使用 CSR 指定的证书：

  ```
  {
      "certificate" : {
          "Type" : "AWS::IoT::Certificate",
          "Properties" : {
              "CertificateSigningRequest": {"Ref" : "CSR"},
              "Status" : "ACTIVE"      
          }
      }
  }
  ```
+ 使用现有证书 ID 指定的证书：

  ```
  {
      "certificate" : {
          "Type" : "AWS::IoT::Certificate",
          "Properties" : {
              "CertificateId": {"Ref" : "CertificateId"}
          }
      }
  }
  ```
+ 使用现有证书 .pem 和 CA 证书 .pem 指定的证书：

  ```
  {
      "certificate" : {
          "Type" : "AWS::IoT::Certificate",
          "Properties" : {
              "CACertificatePem": {"Ref" : "CACertificatePem"},
              "CertificatePem": {"Ref" : "CertificatePem"}
          }
      }
  }
  ```
+ 独占地将一个事物附加到主体：

  ```
  {
      "certificate" : {
          "Type" : "AWS::IoT::Certificate",
          "Properties" : {
              "ThingPrincipalType" : "EXCLUSIVE_THING"
          }
      }
  }
  ```

### 策略资源
<a name="policy-resources"></a>

策略资源使用以下属性之一进行声明：
+ `PolicyName`: 可选。字符串。默认值为策略文档的哈希值。`PolicyName` 只能参考 AWS IoT 策略但不是 IAM 策略。如果您使用现有的 AWS IoT 策略，则对于 `PolicyName` 属性，输入策略的名称。请勿包含 `PolicyDocument` 属性。
+ `PolicyDocument`: 可选。指定为转义字符串的 JSON 对象。如果未提供 `PolicyDocument`，则必须已经创建了策略。

**注意**  
如果存在 `Policy` 部分，则必须指定 `PolicyName` 或 `PolicyDocument`，但不能同时指定。

### 覆盖设置
<a name="override-settings"></a>

如果模板指定了已经存在的资源，则使用 `OverrideSettings` 部分可以指定要采取的操作：

`DO_NOTHING`  
将资源保留为原样。

`REPLACE`  
使用在模板中指定的资源替换该资源。

`FAIL`  
导致请求失败，出现 `ResourceConflictsException`。

`MERGE`  
仅对 `ThingGroups` 的 `AttributePayload` 和 `thing` 属性有效。将事物的现有属性或组成员资格与模板中指定的同等内容合并。

当您声明事物资源时，您可以为以下属性指定 `OverrideSettings`：
+ `ATTRIBUTE_PAYLOAD`
+ `THING_TYPE_NAME`
+ `THING_GROUPS`

当您声明证书资源时，您可以为 `OverrideSettings` 属性指定 `Status`。

`OverrideSettings` 不可用于策略资源。

### 资源示例
<a name="resource-example"></a>

以下模板片段声明了一个事物、一个证书和一个策略：

```
{ 
    "Resources" : {
        "thing" : {
            "Type" : "AWS::IoT::Thing",
            "Properties" : {
                "ThingName" : {"Ref" : "ThingName"},
                "AttributePayload" : { "version" : "v1", "serialNumber" :  {"Ref" : "SerialNumber"}}, 
                "ThingTypeName" :  "lightBulb-versionA",
                "ThingGroups" : ["v1-lightbulbs", {"Ref" : "Location"}]
            },
            "OverrideSettings" : {
                "AttributePayload" : "MERGE",
                "ThingTypeName" : "REPLACE",
                "ThingGroups" : "DO_NOTHING"
            }
        },  
        "certificate" : {
            "Type" : "AWS::IoT::Certificate",
            "Properties" : {
                "CertificateSigningRequest": {"Ref" : "CSR"},
                "Status" : "ACTIVE"      
            }
        },
        "policy" : {
            "Type" : "AWS::IoT::Policy",
            "Properties" : {
                "PolicyDocument" : "{ \"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:aws:iot:us-east-1:123456789012:topic/foo/bar\"] }] }"
            }
        }
    }
}
```

使用以下项声明事物：
+ 逻辑名称 `"thing"`。
+ 类型 `AWS::IoT::Thing`。
+  一组事物属性。

  事物属性包括事物名称、一组属性、一个事物类型名称（可选）以及事物所属的事物组列表（可选）。

使用 `{"Ref":"parameter-name"}` 引用参数。评估模板时，使用随模板传入的字典中提供的参数值来替换参数。

使用以下项声明证书：
+ 逻辑名称 `"certificate"`。
+ 类型 `AWS::IoT::Certificate`。
+ 一组属性。

  属性包括证书的 CSR 并将状态设置为 `ACTIVE`。CSR 文本作为随模板传入的字典中的参数传递。

使用以下项声明策略：
+ 逻辑名称 `"policy"`。
+ 类型 `AWS::IoT::Policy`。
+ 现有策略的名称或策略文档的名称。

## 批量注册的模板示例
<a name="bulk-template-example"></a>

以下 JSON 文件是使用 CSR 指定证书的完整预调配模板的一个示例：

（`PolicyDocument` 字段值必须是指定为转义字符串的 JSON 对象。）

```
{
    "Parameters" : {
        "ThingName" : {
            "Type" : "String"
        },
        "SerialNumber" : {
            "Type" : "String"
        },
        "Location" : {
            "Type" : "String",
            "Default" : "WA"
        },
        "CSR" : {
            "Type" : "String"    
        }
    },
    "Resources" : {
        "thing" : {
            "Type" : "AWS::IoT::Thing",
            "Properties" : {
                "ThingName" : {"Ref" : "ThingName"},
                "AttributePayload" : { "version" : "v1", "serialNumber" :  {"Ref" : "SerialNumber"}}, 
                "ThingTypeName" :  "lightBulb-versionA",
                "ThingGroups" : ["v1-lightbulbs", {"Ref" : "Location"}]
            }
        },
        "certificate" : {
            "Type" : "AWS::IoT::Certificate",
            "Properties" : {
                "CertificateSigningRequest": {"Ref" : "CSR"},
                "Status" : "ACTIVE",
                "ThingPrincipalType" : "EXCLUSIVE_THING"
            }
        },
        "policy" : {
            "Type" : "AWS::IoT::Policy",
            "Properties" : {
                "PolicyDocument" : "{ \"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:aws:iot:us-east-1:123456789012:topic/foo/bar\"] }] }"
            }
        }
    }
}
```

## just-in-time置备模板示例 (JITP)
<a name="JITP-template-example"></a>

以下 JSON 文件是使用证书 ID 指定现有证书的完整预调配模板的一个示例：

```
{
   "Parameters":{
      "AWS::IoT::Certificate::CommonName":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::SerialNumber":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::Country":{
         "Type":"String"
      },
      "AWS::IoT::Certificate::Id":{
         "Type":"String"
      }
   },
   "Resources":{
      "thing":{
         "Type":"AWS::IoT::Thing",
         "Properties":{
            "ThingName":{
               "Ref":"AWS::IoT::Certificate::CommonName"
            },
            "AttributePayload":{
               "version":"v1",
               "serialNumber":{
                  "Ref":"AWS::IoT::Certificate::SerialNumber"
               }
            },
            "ThingTypeName":"lightBulb-versionA",
            "ThingGroups":[
               "v1-lightbulbs",
               {
                  "Ref":"AWS::IoT::Certificate::Country"
               }
            ]
         },
         "OverrideSettings":{
            "AttributePayload":"MERGE",
            "ThingTypeName":"REPLACE",
            "ThingGroups":"DO_NOTHING"
         }
      },
      "certificate":{
         "Type":"AWS::IoT::Certificate",
         "Properties":{
            "CertificateId":{
               "Ref":"AWS::IoT::Certificate::Id"
            },
            "Status":"ACTIVE",
            "ThingPrincipalType" : "EXCLUSIVE_THING"
         }
      },
      "policy":{
         "Type":"AWS::IoT::Policy",
         "Properties":{
            "PolicyDocument":"{ \"Version\": \"2012-10-17\",		 	 	  \"Statement\": [{ \"Effect\": \"Allow\", \"Action\":[\"iot:Publish\"], \"Resource\": [\"arn:aws:iot:us-east-1:123456789012:topic/foo/bar\"] }] }"
         }
      }
   }
}
```

**重要**  
您必须在用于 JIT 预调配的模板中使用 `CertificateId`。

有关配置模板类型的更多信息，请参阅 AWS API 参考[https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html#iot-CreateProvisioningTemplate-request-type](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateProvisioningTemplate.html#iot-CreateProvisioningTemplate-request-type)中的。

有关如何使用此模板进行 just-in-time置备的更多信息，请参阅：[J Provisi ust-in-time oning](https://docs.aws.amazon.com/iot/latest/developerguide/jit-provisioning.html)。

## 实例集预置
<a name="fleet-provision-template"></a>

队列配置模板 AWS IoT 用于设置云和设备配置。这些模板使用与 JITP 和批量注册模板相同的参数和资源。有关更多信息，请参阅 [预置模板](#provision-template)。实例集预调配模板可以包含一个 `Mapping` 部分和一个 `DeviceConfiguration` 部分。您可以在实例集预调配模板中使用内置函数来生成设备特定的配置。舰队配置模板被命名为资源，并由 ARNs （例如`arn:aws:iot:us-west-2:1234568788:provisioningtemplate/templateName`）标识。

### 映像
<a name="mappings"></a>

可选的 `Mappings` 部分将密钥与对应的一组命名值相匹配。例如，如果要根据某个 AWS 区域设置值，则可以创建一个使用该 AWS 区域 名称作为键并包含要为每个特定区域指定的值的映射。您使用 `Fn::FindInMap` 内置函数来检索映射中的值。

您不得在 `Mappings` 部分包含参数、虚拟参数或调用内置函数。

### 设备配置
<a name="device-config"></a>

设备配置部分包含要在预调配时发送到设备的任意数据。例如：

```
{
    "DeviceConfiguration": {
        "Foo":"Bar"
    }
}
```

如果您使用 JavaScript 对象表示法 (JSON) 有效负载格式向设备发送消息， AWS IoT Core 请将此数据格式化为 JSON。如果您使用 Concise Binary Object Representation（CBOR）有效载荷格式， AWS IoT Core 会将此数据格式化为 CBOR。`DeviceConfiguration` 部分不支持嵌套 JSON 对象。

### 内置函数
<a name="intrinsic-functions"></a>

内置函数在预调配模板中除了 `Mappings` 部分以外的任何部分使用。

`Fn::Join`  
将一组值附加到单值中，中间用特定分隔符隔开。如果分隔符为空字符串，则值连接在一起而不使用分隔符。  
`Fn::Join` 不受 [策略资源](#policy-resources) 支持。

`Fn::Select`  
通过索引返回对象列表中的单个对象。  
`Fn::Select` 不会检查 `null` 值，或检查索引是否超出数组边界。这两种情况都会导致预调配错误，因此您应确保选择了一个有效的索引值，并且列表中包含非空值。

`Fn::FindInMap`  
返回与 `Mappings` 部分声明的双层映射中的键对应的值。

`Fn::Split`  
将字符串拆分为字符串值列表，以便您可以从字符串列表中选择一个元素。您可以指定一个分隔符（如逗号），用于确定拆分字符串的位置。拆分字符串后，使用 `Fn::Select` 选择一个元素。  
例如，如果将以逗号分隔的子网 IDs 字符串导入到堆栈模板中，则可以在每个逗号处拆分字符串。在子网列表中 IDs，使用`Fn::Select`为资源指定子网 ID。

`Fn::Sub`  
将输入字符串中的变量替换为您指定的值。您可以使用此函数构建命令或输出，其中包含在创建或更新堆栈之前不可用的值。

### 实例集预调配的模板示例
<a name="fleet-provisioning-example"></a>

```
{
    "Parameters" : {
        "ThingName" : {
            "Type" : "String"
        },
        "SerialNumber": {
            "Type": "String"
        },
        "DeviceLocation": {
            "Type": "String"
        }
    },
    "Mappings": {
        "LocationTable": {
            "Seattle": {
                "LocationUrl": "https://example.aws"
            }
        }
    },
    "Resources" : {
        "thing" : {
            "Type" : "AWS::IoT::Thing",
            "Properties" : {
                "AttributePayload" : { 
                    "version" : "v1",
                    "serialNumber" : "serialNumber"
                },
                "ThingName" : {"Ref" : "ThingName"},
                "ThingTypeName" : {"Fn::Join":["",["ThingPrefix_",{"Ref":"SerialNumber"}]]},
                "ThingGroups" : ["v1-lightbulbs", "WA"],
                "BillingGroup": "LightBulbBillingGroup"
            },
            "OverrideSettings" : {
                "AttributePayload" : "MERGE",
                "ThingTypeName" : "REPLACE",
                "ThingGroups" : "DO_NOTHING"
            }
        },
        "certificate" : {
            "Type" : "AWS::IoT::Certificate",
            "Properties" : {
                "CertificateId": {"Ref": "AWS::IoT::Certificate::Id"},
                "Status" : "Active",
                "ThingPrincipalType" : "EXCLUSIVE_THING"
            }
        },
        "policy" : {
            "Type" : "AWS::IoT::Policy",
            "Properties" : {
                "PolicyDocument" : {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [{
                        "Effect": "Allow",
                        "Action":["iot:Publish"],
                        "Resource": ["arn:aws:iot:us-east-1:123456789012:topic/foo/bar"]
                    }]
                }
            }
        }
    },
    "DeviceConfiguration": {
        "FallbackUrl": "https://www.example.com/test-site",
        "LocationUrl": {
            "Fn::FindInMap": ["LocationTable",{"Ref": "DeviceLocation"}, "LocationUrl"]}
        }
}
```

**注意**  
可以对现有预调配模板进行更新以添加[预先预调配挂钩](pre-provisioning-hook.md)。

# 预先预调配挂钩
<a name="pre-provisioning-hook"></a>

AWS 建议在创建配置模板时使用预配置挂钩功能，以便更好地控制您的账户已登录的设备和设备数量。预调配挂钩是 Lambda 函数，可在验证设备传递的参数后允许预调配设备。在您预调配设备之前，此 Lambda 函数必须存在于您的账户中，因为每次设备通过 [RegisterThing](fleet-provision-api.md#register-thing) 发送请求时都会调用该函数。

**重要**  
请务必在附加到 Lambda 操作策略的全局条件上下文键中包含 `source-arn` 或 `source-account`，以便防范权限操纵。有关此问题的更多信息，请参阅[防止跨服务混淆座席](cross-service-confused-deputy-prevention.md)。

对于要预调配的设备，Lambda 函数必须接受输入对象并返回本节所述的输出对象。仅当 Lambda 函数返回带有 `"allowProvisioning": True` 的对象时，预调配才会继续。

## 预先预调配挂钩输入
<a name="pre-provisioning-hook-input"></a>

AWS IoT 当设备向注册时，会将此对象发送到 Lambda 函数。 AWS IoT

```
{
    "claimCertificateId" : "string",
    "certificateId" : "string",
    "certificatePem" : "string",
    "templateArn" : "arn:aws:iot:us-east-1:1234567890:provisioningtemplate/MyTemplate",
    "clientId" : "221a6d10-9c7f-42f1-9153-e52e6fc869c1",
    "parameters" : {
        "string" : "string",
        ...
    }
}
```

传递给 Lambda 函数的 `parameters` 对象包含 `parameters` 参数中的属性，该参数在 [RegisterThing](fleet-provision-api.md#register-thing) 请求有效载荷中传入。

## 预先预调配挂钩返回值
<a name="pre-provisioning-hook-output"></a>

Lambda 函数必须返回一个响应，指示它是否已授权预调配请求以及要覆盖的任意属性的值。

以下是来自预先预调配函数的成功响应示例。

```
{
    "allowProvisioning": true,
    "parameterOverrides" : {
        "Key": "newCustomValue",
        ...
    }
}
```

`"parameterOverrides"` 值将添加到 [RegisterThing](fleet-provision-api.md#register-thing) 申请有效载荷的 `"parameters"` 参数中。

**注意**  
如果 Lambda 函数失败，则配置请求将失败，`ACCESS_DENIED`并在 Logs 中记录错误。 CloudWatch 
如果 Lambda 函数未在响应中返回 `"allowProvisioning": "true"`，则预调配请求将失败并显示 `ACCESS_DENIED`。
Lambda 函数必须在 5 秒内完成执行并返回，否则预调配请求将失败。

## 预先预调配挂钩 Lambda 示例
<a name="pre-provisioning-example"></a>

------
#### [ Python ]

在 Python 中预先预调配挂钩 Lambda 示例。

```
import json

def pre_provisioning_hook(event, context):
    print(event)

    return {
        'allowProvisioning': True,
        'parameterOverrides': {
            'DeviceLocation': 'Seattle'
        }
    }
```

------
#### [ Java ]

在 Java 中预先预调配挂钩 Lambda 示例。

处理程序类：

```
package example;

import java.util.Map;
import java.util.HashMap;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;

public class PreProvisioningHook implements RequestHandler<PreProvisioningHookRequest, PreProvisioningHookResponse> {

    public PreProvisioningHookResponse handleRequest(PreProvisioningHookRequest object, Context context) {
        Map<String, String> parameterOverrides = new HashMap<String, String>();
        parameterOverrides.put("DeviceLocation", "Seattle");

        PreProvisioningHookResponse response = PreProvisioningHookResponse.builder()
                .allowProvisioning(true)
                .parameterOverrides(parameterOverrides)
                .build();

        return response;
    }

}
```

请求类：

```
package example;

import java.util.Map;
import lombok.Builder;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;

@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PreProvisioningHookRequest {
    private String claimCertificateId;
    private String certificateId;
    private String certificatePem;
    private String templateArn;
    private String clientId;
    private Map<String, String> parameters;
}
```

响应类：

```
package example;

import java.util.Map;
import lombok.Builder;
import lombok.Data;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;


@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PreProvisioningHookResponse {
    private boolean allowProvisioning;
    private Map<String, String> parameterOverrides;
}
```

------
#### [ JavaScript ]

中预置挂钩 Lambda JavaScript 的示例。

```
exports.handler = function(event, context, callback) {
    console.log(JSON.stringify(event, null, 2));
    var reply = { 
        allowProvisioning: true,
        parameterOverrides: {
            DeviceLocation: 'Seattle'
        }
     };
     callback(null, reply);
}
```

------

# 使用证书提供程序进行自我管理的 AWS IoT Core 证书签名
<a name="provisioning-cert-provider"></a>

在 AWS IoT 队列配置中，您可以创建 AWS IoT Core 证书提供商来签署证书签名请求 (CSRs)。证书提供者引用 Lambda 函数以及[适用于实例集预调配的 `CreateCertificateFromCsr` MQTT API](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr)。Lambda 函数接受 CSR 并返回签名的客户端证书。

当您的证书提供商没有证书提供商时 AWS 账户，系统会在队列配置中调用 [CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 来从 CSR 生成证书。创建证书提供商后，[CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 的行为将发生变化，对此 MQTT API 的所有调用都将调用证书提供商来颁发证书。

借助 AWS IoT Core 证书提供商，您可以实施利用私有证书颁发机构 (CAs)（例如[AWS 私有 CA](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html)其他公开信任 CAs的证书颁发机构）或您自己的公钥基础设施 (PKI) 来签署 CSR 的解决方案。此外，您还可以使用证书提供者来自定义客户端证书的字段，例如有效期、签名算法、颁发者和扩展等。

**重要**  
每个 AWS 账户只能创建一个证书提供者。签名行为更改适用于调用 [CreateCertificateFromCsr MQTT API](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 的整个队列，直到您 AWS 账户从中删除证书提供商。

**Topics**
+ [自行管理的证书签名在实例集预调配中的工作原理](#provisioning-cert-provider-how-it-works)
+ [证书提供程者 Lambda 函数输入](#provisioning-cert-provider-lambda-input)
+ [证书提供者 Lambda 函数返回值](#provisioning-cert-provider-lambda-return)
+ [示例 Lambda 函数](#provisioning-cert-provider-lambda)
+ [实例集预调配的自行管理的证书签名](#provisioning-self-certificate-signing)
+ [AWS CLI 证书提供商的命令](#provisioning-cert-provider-cli)

## 自行管理的证书签名在实例集预调配中的工作原理
<a name="provisioning-cert-provider-how-it-works"></a>

### 重要概念
<a name="provisioning-cert-provider-concepts"></a>

以下概念提供的详细信息可以帮助您了解自管理证书签名在 AWS IoT 队列配置中的工作原理。有关更多信息，请参阅[使用实例集预调配来预调配没有设备证书的设备](https://docs.aws.amazon.com//iot/latest/developerguide/provision-wo-cert.html)。

**AWS IoT 舰队配置**  
使用 AWS IoT 队列配置（队列配置的缩写），可在设备首次连接时 AWS IoT Core 生成设备证书并将其安全地交付 AWS IoT Core 给您的设备。使用实例集预调配将没有设备证书的设备连接到 AWS IoT Core。

**证书签名请求（CSR）**。  
在队列配置过程中，设备 AWS IoT Core 通过[队列配置 MQTT APIs](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html) 向发出请求。该请求包括证书签名请求（CSR），该请求将会得到签名以创建客户端证书。

**AWS 队列配置中的托管证书签名**  
AWS managed 是队列配置中证书签名的默认设置。使用 AWS 托管证书签名， AWS IoT Core 将 CSRs 使用自己的证书签名 CAs。

**实例集预调配中的自行管理的证书签名**  
自行管理是实例集预调配中的另一个证书签名选项。使用自我管理的证书签名，您可以创建 AWS IoT Core 证书提供商进行签名 CSRs。您可以使用自我管理的证书签名使用 AWS 私 CSRs 有 CA、其他公开信任的 CA 或您自己的公钥基础架构 (PKI) 生成的 CA 进行签名。

**AWS IoT Core 证书提供商**  
AWS IoT Core 证书提供商（证书提供者的缩写）是一种客户管理的资源，用于队列配置中的自我管理证书签名。

### 示意图
<a name="provisioning-cert-provider-diagram"></a>

下图简要说明了自证书签名在 AWS IoT 队列配置中的工作原理。

![\[AWS IoT Core 用于队列配置的证书提供商\]](http://docs.aws.amazon.com/zh_cn/iot/latest/developerguide/images/provisioning-cert-provider.png)

+ 在制造新的物联网设备或将其引入设备队列时，它需要使用客户端证书进行身份验证 AWS IoT Core。
+ 作为队列配置过程的一部分，设备通过队列[配置 MQTT APIs](https://docs.aws.amazon.com//iot/latest/developerguide/fleet-provision-api.html) 向 AWS IoT Core 请求客户端证书。该请求包括证书签名请求（CSR）。
+ AWS IoT Core 调用证书提供者并将 CSR 作为输入传递给提供者。
+ 证书提供者将 CSR 作为输入并颁发客户端证书。

  对于 AWS 托管证书签名， AWS IoT Core 使用自己的 CA 对 CSR 进行签名并颁发客户端证书。
+ 有了颁发的客户端证书，设备将继续进行实例集预调配，并与 AWS IoT Core建立安全连接。

## 证书提供程者 Lambda 函数输入
<a name="provisioning-cert-provider-lambda-input"></a>

AWS IoT Core 当设备向 Lambda 函数注册时，会将以下对象发送到 Lambda 函数。`certificateSigningRequest` 的值是 `CreateCertificateFromCsr` 请求中提供的[隐私增强邮件（PEM）格式](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate-format.html)的 CSR。`principalId`是发出`CreateCertificateFromCsr`请求 AWS IoT Core 时用于连接的主体的 ID。 `clientId`是为 MQTT 连接设置的客户端 ID。

```
{
	"certificateSigningRequest": "string",
	"principalId": "string",
	"clientId": "string"
}
```

## 证书提供者 Lambda 函数返回值
<a name="provisioning-cert-provider-lambda-return"></a>

Lambda 函数必须返回包含 `certificatePem` 值的响应。以下是成功响应的示例。 AWS IoT Core 将使用返回值 (`certificatePem`) 来创建证书。

```
{
	"certificatePem": "string"
}
```

如果注册成功，`CreateCertificateFromCsr` 将在 `CreateCertificateFromCsr` 响应中返回相同的 `certificatePem`。有关更多信息，请参阅的响应负载示例[CreateCertificateFromCsr](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr)。

## 示例 Lambda 函数
<a name="provisioning-cert-provider-lambda"></a>

在创建证书提供者之前，您必须创建 Lambda 函数来签署 CSR。以下是 Python 中的 Lambda 函数示例。此函数使用私有 CA 和 `SHA256WITHRSA` 签名算法调用 AWS 私有 CA 来对输入 CSR 进行签名。返回的客户证书的有效期为一年。有关私有 CA AWS 私有 CA 以及如何创建私有 CA 的更多信息，请参阅[什么是 AWS 私有 CA？](https://docs.aws.amazon.com/privateca/latest/userguide/PcaWelcome.html) 以及[创建私有 CA](https://docs.aws.amazon.com/privateca/latest/userguide/create-CA.html)。

```
import os
import time
import uuid
import boto3

def lambda_handler(event, context):
    ca_arn = os.environ['CA_ARN']
    csr = (event['certificateSigningRequest']).encode('utf-8')

    acmpca = boto3.client('acm-pca')
    cert_arn = acmpca.issue_certificate(
        CertificateAuthorityArn=ca_arn, 
        Csr=csr,
        Validity={"Type": "DAYS", "Value": 365}, 
        SigningAlgorithm='SHA256WITHRSA',
        IdempotencyToken=str(uuid.uuid4())
    )['CertificateArn']
    
    # Wait for certificate to be issued
    time.sleep(1)    
    cert_pem = acmpca.get_certificate(
        CertificateAuthorityArn=ca_arn,
        CertificateArn=cert_arn
    )['Certificate']
    
    return {
        'certificatePem': cert_pem
    }
```

**重要**  
Lambda 函数返回的证书必须具有与证书签名请求（CSR）相同的主题名称和公钥。
Lambda 函数必须在 5 秒钟内完成运行。
Lambda 函数必须与证书提供商 AWS 账户 资源位于同一区域中。
必须向 AWS IoT 服务委托人授予 Lambda 函数的调用权限。为避免[混淆代理问题](https://docs.aws.amazon.com//IAM/latest/UserGuide/confused-deputy.html)，我们建议您设置 `sourceArn` 和 `sourceAccount` 调用权限。有关更多信息，请参阅[防止跨服务混淆代理](https://docs.aws.amazon.com//iot/latest/developerguide/cross-service-confused-deputy-prevention.html)。

以下基于资源的 [Lambda](https://docs.aws.amazon.com//lambda/latest/dg/access-control-resource-based.html) 策略示例授予 AWS IoT 调用 Lambda 函数的权限：

****  

```
{
	"Version":"2012-10-17",		 	 	 
	"Id": "InvokePermission",
	"Statement": [
		{
			"Sid": "LambdaAllowIotProvider",
			"Effect": "Allow",
			"Principal": {
				"Service": "iot.amazonaws.com"
			},
			"Action": "lambda:InvokeFunction",
			"Resource": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
			"Condition": {
				"StringEquals": {
					"AWS:SourceAccount": "123456789012"
				},
				"ArnLike": {
				"AWS:SourceArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider/my-certificate-provider"
				}
			}
		}
	]
}
```

## 实例集预调配的自行管理的证书签名
<a name="provisioning-self-certificate-signing"></a>

您可以使用 AWS CLI 或 AWS 管理控制台选择实例集预调配的自行管理的证书签名。

### AWS CLI
<a name="provisioning-self-certificate-signing-cli"></a>

要选择自我管理的证书签名，您必须创建 AWS IoT Core 证书提供商来 CSRs 登录队列配置。 AWS IoT Core 调用证书提供程序，该提供程序将 CSR 作为输入并返回客户端证书。要创建证书提供者，请使用 `CreateCertificateProvider` API 操作或 `create-certificate-provider` CLI 命令。

**注意**  
创建证书提供者后，[适用于实例集预置的 `CreateCertificateFromCsr` API](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 的行为将发生变化，对 `CreateCertificateFromCsr` 的所有调用都将调用证书提供者来颁发证书。在创建证书提供程者后，此行为可能需要几分钟才会发生变化。

```
aws iot create-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-1 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[CreateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateCertificateProvider.html)`。

### AWS 管理控制台
<a name="provisioning-self-certificate-signing-console"></a>

要选择使用自行管理的证书签名 AWS 管理控制台，请执行以下步骤：

1. 转到 [AWS IoT 控制台](https://console.aws.amazon.com//iot/home)。

1. 在左侧导航栏中的**安全性**下，选择**证书签名**。

1. 在**证书签名**页面的**证书签名详细信息**下，选择**编辑证书签名方法**。

1. 在**编辑证书签名方法**页面的**证书签名方法**下，选择**自行管理**。

1. 在**自行管理设置**部分，输入证书提供者的名称，然后创建或选择 Lambda 函数。

1. 选择**更新证书签名**。

## AWS CLI 证书提供商的命令
<a name="provisioning-cert-provider-cli"></a>

### 创建证书提供者
<a name="provisioning-create-cert-provider"></a>

要创建证书提供者，请使用 `CreateCertificateProvider` API 操作或 `create-certificate-provider` CLI 命令。

**注意**  
创建证书提供者后，[适用于实例集预置的 `CreateCertificateFromCsr` API](https://docs.aws.amazon.com/iot/latest/developerguide/fleet-provision-api.html#create-cert-csr) 的行为将发生变化，对 `CreateCertificateFromCsr` 的所有调用都将调用证书提供者来颁发证书。在创建证书提供程者后，此行为可能需要几分钟才会发生变化。

```
aws iot create-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-1 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[CreateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_CreateCertificateProvider.html)`。

### 更新证书提供者
<a name="provisioning-update-cert-provider"></a>

要更新证书提供者，请使用 `UpdateCertificateProvider` API 操作或 `update-certificate-provider` CLI 命令。

```
aws iot update-certificate-provider \
                --certificateProviderName my-certificate-provider \
                --lambdaFunctionArn arn:aws:lambda:us-east-1:123456789012:function:my-function-2 \
                --accountDefaultForOperations CreateCertificateFromCsr
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviderName": "my-certificate-provider",
	"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[UpdateCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_UpdateCertificateProvider.html)`。

### 描述证书提供者
<a name="provisioning-describe-cert-provider"></a>

要描述证书提供者，请使用 `DescribeCertificateProvider` API 操作或 `describe-certificate-provider` CLI 命令。

```
aws iot describe-certificate-provider --certificateProviderName my-certificate-provider
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviderName": "my-certificate-provider",
	"lambdaFunctionArn": "arn:aws:lambda:us-east-1:123456789012:function:my-function",
	"accountDefaultForOperations": [
		"CreateCertificateFromCsr"
	],
	"creationDate": "2022-11-03T00:15",
	"lastModifiedDate": "2022-11-18T00:15"
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[DescribeCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_DescribeCertificateProvider.html)`。

### 删除证书提供者
<a name="provisioning-delete-cert-provider"></a>

要删除证书提供者，请使用 `DeleteCertificateProvider` API 操作或 `delete-certificate-provider` CLI 命令。如果您删除证书提供商资源，则的行为`CreateCertificateFromCsr`将恢复， AWS IoT 并将创建 AWS IoT 由 CSR 签名的证书。

```
aws iot delete-certificate-provider --certificateProviderName my-certificate-provider
```

此命令不会生成任何输出。

有关更多信息，请参阅《AWS IoT API 参考》****中的 `[DeleteCertificateProvider](https://docs.aws.amazon.com//iot/latest/apireference/API_DeleteCertificateProvider.html)`。

### 列出证书提供者
<a name="provisioning-list-cert-provider"></a>

要列出您的证书提供商 AWS 账户，请使用 `ListCertificateProviders` API 操作或 `list-certificate-providers` CLI 命令。

```
aws iot list-certificate-providers
```

以下内容显示了此命令的示例输出：

```
{
	"certificateProviders": [
		{
			"certificateProviderName": "my-certificate-provider",
			"certificateProviderArn": "arn:aws:iot:us-east-1:123456789012:certificateprovider:my-certificate-provider"
		}
	]
}
```

有关更多信息，请参阅《AWS IoT API 参考》****中的 [https://docs.aws.amazon.com//iot/latest/apireference/API_ListCertificateProviders.html](https://docs.aws.amazon.com//iot/latest/apireference/API_ListCertificateProviders.html)。

# 为安装设备的用户创建 IAM 策略和角色
<a name="provision-create-role"></a>

**注意**  
这些过程仅在 AWS IoT 控制台的指导下使用。  
要从控制台转到此页面，请打开[创建新的预调配模板](https://console.aws.amazon.com//iot/home#/provisioningtemplate/create/provisioningmethods/trustedUser)。

## 为什么不能在 AWS IoT 控制台中完成此操作？
<a name="provision-create-role-why"></a>

为了获得最安全的体验，应在 IAM 控制台中执行 IAM 操作。本节中的步骤将引导您完成创建相关 IAM 角色和策略的步骤，使用预调配模板需要这些 IAM 角色和策略。

## 为将安装设备的用户创建 IAM 策略
<a name="provision-create-role-policy"></a>

此过程介绍如何创建授权用户使用预调配模板安装设备的 IAM 策略。

执行此过程时，您将在 IAM 控制台和控制台之间切换。 AWS IoT 我们建议您在完成此过程时同时打开这两个控制台。

**为将安装设备的用户创建 IAM policy**

1. 打开 [IAM 控制台中的策略中心](https://console.aws.amazon.com//iamv2/home#/policies)。

1. 选择**创建策略**。

1. 在**创建策略**页面上，选择 **JSON** 选项卡。

1. 切换到 AWS IoT 控制台中您选择**配置用户策略和角色**的页面。

1. 在 **Sample provisioning policy**（示例预调配策略）中，选择 **Copy**（复制）。

1. 切换回 IAM 控制台。

1. 在 **JSON** 编辑器中，粘贴您从 AWS IoT 控制台复制的策略。此政策特定于您在 AWS IoT 控制台中创建的模板。

1. 要继续，请选择**下一步：标签**。

1. 在 **Add tags (Optional)** [添加标签（可选）] 页面上，为要添加到此策略的每个标签选择 **Add tag**（添加标签）。如果没有任何标签要添加，您可以跳过该步骤。

1. 要继续，请选择**下一步：审核**。

1. 在**查看策略**页面上，执行以下操作：

   1. 对于 **Name\$1**（名称\$1），为策略输入可帮助您记住其作用的名称。

      记下您为该策略提供的名称，因为您将在下一步中使用该名称。

   1. 您可以选择输入您创建的策略的可选描述。

   1. 查看本策略的其余部分及其标签。

1. 要完成创建新策略，请选择 **Create policy**（创建策略）。

创建新策略后，继续执行 [为将安装设备的用户创建 IAM 角色](#provision-create-role-role)，以创建要附加此策略的用户角色条目。

## 为将安装设备的用户创建 IAM 角色
<a name="provision-create-role-role"></a>

以下步骤介绍如何创建一个 IAM 角色，以对将使用预调配模板安装设备的用户进行身份验证。

**为将安装设备的用户创建 IAM policy**

1. 打开 [IAM 控制台中的 Role（角色）中心](https://console.aws.amazon.com//iamv2/home#/roles)。

1. 选择**创建角色**。

1. 在 **Select trusted entity**（选择可信实体）中，选择可信实体的类型，您要向该可信实体授予对您正在创建的模板的访问权限。

1. 选择或输入您要向其授予访问权限的可信实体的标识，然后选择 **Next**（下一步）。

1. 在 **Add permissions**（添加权限）页面的 **Permission policies**（权限策略）中的搜索框中，输入您在[上一个过程](#provision-create-role-policy)中创建的策略的名称。

1. 对于策略列表，选择在上一个过程中创建的策略，然后选择 **Next**（下一步）。

1. 在 **Name, review, and create**（命名、查看和创建）部分中，执行以下操作：

   1. 对于 **Role name**（角色名称），键入有助于您记住此角色的作用的角色名称。

   1. 对于 **Description**（描述），您可以选择输入角色的可选描述。不需要执行此操作即可继续。

   1. 查看 **Step 1**（步骤 1）和 **Step 2**（步骤 2）中的值。

   1. 对于 **Add tags (Optional)** [添加标签（可选）]，可以选择向该角色添加标签。不需要执行此操作即可继续。

   1. 确保该页面上的信息完整且正确无误，然后选择 **Create role**（创建角色）。

创建新角色后，返回 AWS IoT 控制台继续创建模板。

## 更新现有策略以向新模板授权
<a name="provision-create-role-update"></a>

以下步骤介绍如何向 IAM 策略添加新模板，此策略授权用户使用预调配模板安装设备。

**向现有 IAM 策略添加新的模板**

1. 打开 [IAM 控制台中的 Policies（策略）中心](https://console.aws.amazon.com//iamv2/home#/policies)。

1. 在搜索框中，输入要更新的策略的名称。

1. 在搜索框下方的列表中，找到要更新的策略并选择策略名称。

1. 对于 **Policy summary**（策略摘要），选择 **JSON** 选项卡（如果该面板尚不可见）。

1. 要编辑策略文档，请选择 **Edit policy**（编辑策略）。

1. 在编辑器中，选择 **JSON** 选项卡（如果该面板尚不可见）。

1. 在策略文档中，查找包含 `iot:CreateProvisioningClaim` 操作的策略语句。

   如果策略文档不包含带有 `iot:CreateProvisioningClaim` 操作的策略语句，请复制以下语句片段，并将其作为附加项粘贴到策略文档的 `Statement` 数组中。
**注意**  
此片段必须放在 `Statement` 数组中的结束 `]` 字符之前。您可能需要在此片段之前或之后添加逗号，以更正任何语法错误。

   ```
   {
       "Effect": "Allow",
       "Action": [
           "iot:CreateProvisioningClaim"
       ],
       "Resource": [
           "--PUT YOUR NEW TEMPLATE ARN HERE--"
       ]
   }
   ```

1. 切换到 AWS IoT 控制台中您选择**修改用户角色权限**的页面。

1. 找到模板的 **Resource ARN**（资源 ARN）并选择 **Copy**（复制）。

1. 切换回 IAM 控制台。

1. 将复制的 Amazon 资源名称 (ARN) 粘贴到`Statement`数组 ARNs 中模板列表的顶部，使其成为第一个条目。

   如果这是数组中唯一的 ARN，请删除刚粘贴的值末尾的逗号。

1. 查看更新的策略语句，并更正编辑器指示的任何错误。

1. 要保存更新的策略文档，请选择 **Review policy**（查看策略）。

1. 查看策略，然后选择 **Save changes**（保存更改）。

1. 返回 AWS IoT 控制台。

# 设备预调配 MQTT API
<a name="fleet-provision-api"></a><a name="provision-mqtt-api"></a>

实例集预调配服务支持以下 MQTT API 操作：
+ `CreateCertificateFromCsr`
+ `CreateKeysAndCertificate`
+ `RegisterThing`

此 API 支持简明二进制对象表示 (CBOR) 格式和 JavaScript 对象表示法 (JSON) 的响应缓冲区，具体取决于*payload-format*主题。为了清楚起见，本节中的响应和请求示例以 JSON 格式显示。


| *payload-format* | 响应格式数据类型 | 
| --- | --- | 
| cbor | 简洁二进制对象表示法 (CBOR) | 
| json | JavaScript 对象表示法 (JSON) | 

**重要**  
在发布请求消息主题之前，请订阅响应主题以接收响应。此 API 使用的消息使用 MQTT 的发布/订阅协议来提供请求和响应交互。  
如果您未在发布请求*之前*订阅响应主题，则无法收到该请求的结果。  
IoT Core 实例集配置通过用于发布 API 请求的同一 MQTT 连接返回设备配置 MQTT API 结果。

## CreateCertificateFromCsr
<a name="create-cert-csr"></a>

根据证书签名请求 (CSR) 创建证书。 AWS IoT 提供由 Amazon 根证书颁发机构 (CA) 签署的客户证书。新证书的状态为 `PENDING_ACTIVATION`。当您调用 `RegisterThing` 使用此证书预调配事物时，证书状态将如模板中所述，更改为 `ACTIVE` 或 `INACTIVE`。

有关使用证书颁发机构证书和证书签名请求来创建客户端证书的更多信息，请参阅[使用您的 CA 证书创建客户端证书](create-device-cert.md)。

**注意**  
为了安全起见，`CreateCertificateFromCsr` 返回的 `certificateOwnershipToken` 会在一小时后过期。必须在 `certificateOwnershipToken` 过期前调用 `RegisterThing`。如果由 `CreateCertificateFromCsr` 创建的证书尚未激活，并且在令牌过期时尚未附加到策略或事物，则该证书将被删除。如果令牌过期，设备可以调用 `CreateCertificateFromCsr` 以生成新证书。

### CreateCertificateFromCsr 请求
<a name="create-cert-csr-request"></a>

发布包含 `$aws/certificates/create-from-csr/payload-format` 主题的消息。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

#### CreateCertificateFromCsr 请求有效载荷
<a name="create-cert-csr-request-payload"></a>

```
{
    "certificateSigningRequest": "string"
}
```

`certificateSigningRequest`  
CSR，采用 PEM 格式。

### CreateCertificateFromCsr 响应
<a name="create-cert-csr-response"></a>

订阅 `$aws/certificates/create-from-csr/payload-format/accepted`。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

#### CreateCertificateFromCsr 响应有效载荷
<a name="create-cert-csr-response-payload"></a>

```
{
    "certificateOwnershipToken": "string",
    "certificateId": "string",
    "certificatePem": "string"
}
```

`certificateOwnershipToken`  
在预调配期间证明证书所有权的令牌。

`certificateId`  
证书的 ID。证书管理操作仅接受 certificateId。

`certificatePem`  
PEM 格式的证书数据。

### CreateCertificateFromCsr 错误
<a name="create-cert-csr-error"></a>

要接收错误响应，请订阅 `$aws/certificates/create-from-csr/payload-format/rejected`。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

#### CreateCertificateFromCsr 错误有效载荷
<a name="create-cert-csr-error-payload"></a>

```
{
    "statusCode": int,
    "errorCode": "string",
    "errorMessage": "string"
}
```

`statusCode`  
状态代码。

`errorCode`  
错误代码。

`errorMessage`  
错误消息。

## CreateKeysAndCertificate
<a name="create-keys-cert"></a>

创建新密钥和证书。 AWS IoT 提供由 Amazon 根证书颁发机构 (CA) 签署的客户证书。新证书的状态为 `PENDING_ACTIVATION`。当您调用 `RegisterThing` 使用此证书预调配事物时，证书状态将如模板中所述，更改为 `ACTIVE` 或 `INACTIVE`。

**注意**  
为了安全起见，`CreateKeysAndCertificate` 返回的 `certificateOwnershipToken` 会在一小时后过期。必须在 `certificateOwnershipToken` 过期前调用 `RegisterThing`。如果由 `CreateKeysAndCertificate` 创建的证书尚未激活，并且在令牌过期时尚未附加到策略或事物，则该证书将被删除。如果令牌过期，设备可以调用 `CreateKeysAndCertificate` 以生成新证书。

### CreateKeysAndCertificate 请求
<a name="create-keys-cert-request"></a>

在 `$aws/certificates/create/payload-format` 上发布带有空消息有效载荷的消息。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

### CreateKeysAndCertificate 响应
<a name="create-keys-cert-response"></a>

订阅 `$aws/certificates/create/payload-format/accepted`。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

#### CreateKeysAndCertificate 响应
<a name="create-keys-cert-response-payload"></a>

```
{
    "certificateId": "string",
    "certificatePem": "string",
    "privateKey": "string",
    "certificateOwnershipToken": "string"
}
```

`certificateId`  
证书 ID。

`certificatePem`  
PEM 格式的证书数据。

`privateKey`  
私有密钥。

`certificateOwnershipToken`  
在预调配期间证明证书所有权的令牌。

### CreateKeysAndCertificate 错误
<a name="create-keys-cert-error"></a>

要接收错误响应，请订阅 `$aws/certificates/create/payload-format/rejected`。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

#### CreateKeysAndCertificate 错误有效载荷
<a name="create-keys-cert-error-payload"></a>

```
{
    "statusCode": int,
    "errorCode": "string",
    "errorMessage": "string"
}
```

`statusCode`  
状态代码。

`errorCode`  
错误代码。

`errorMessage`  
错误消息。

## RegisterThing
<a name="register-thing"></a>

使用预定义的模板预调配事物。

### RegisterThing 请求
<a name="register-thing-request"></a>

在 `$aws/provisioning-templates/templateName/provision/payload-format` 上发布消息。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

`templateName`  
预调配模板名称。

#### RegisterThing 请求有效载荷
<a name="register-thing-request-payload"></a>

```
{
    "certificateOwnershipToken": "string",
    "parameters": {
        "string": "string",
        ...
    }
}
```

`certificateOwnershipToken`  
证明证书所有权的令牌。当您通过 MQTT 创建证书时， AWS IoT 会生成令牌。

`parameters`  
可选。来自设备的键/值对由[预先预调配挂钩](pre-provisioning-hook.md)用于评估注册请求。

### RegisterThing 响应
<a name="register-thing-response"></a>

订阅 `$aws/provisioning-templates/templateName/provision/payload-format/accepted`。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

`templateName`  
预调配模板名称。

#### RegisterThing 响应有效载荷
<a name="register-thing-response-payload"></a>

```
{
    "deviceConfiguration": {
        "string": "string",
        ...
    },
    "thingName": "string"
}
```

`deviceConfiguration`  
在模板中定义的设备配置。

`thingName`  
预调配期间创建的物联网事物的名称。

### RegisterThing 错误响应
<a name="register-thing-error"></a>

要接收错误响应，请订阅 `$aws/provisioning-templates/templateName/provision/payload-format/rejected`。

`payload-format`  
消息负载格式为 `cbor` 或 `json`。

`templateName`  
预调配模板名称。

#### RegisterThing 错误响应有效负载
<a name="register-thing-error-payload"></a>

```
{
    "statusCode": int,
    "errorCode": "string",
    "errorMessage": "string"
}
```

`statusCode`  
状态代码。

`errorCode`  
错误代码。

`errorMessage`  
错误消息。