

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# 預先佈建掛接
<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` 物件包含在 [RegisterThing](fleet-provision-api.md#register-thing) 請求承載中傳遞之 `parameters` 引數中的屬性。

## 預先佈建掛接傳回值
<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`，且錯誤會記錄到 CloudWatch Logs。
如果 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 ]

JavaScript 中預先佈建掛接 Lambda 的範例。

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

------