AWS - JITR,Just-in-Time Registration,即時註冊。
目錄
1. 前情提要
2. 複習 Lambda
3. 裝置首次連線
3-1 Arduino 呈現狀態
4. 最終流程
⦿ 前情提要
⦿ 複習 Lambda
⦿ 裝置首次連線
⦿ Arduino 呈現狀態
⦿ 最終流程
前情提要
由前一篇文章,我們知道設備(裝置)要與 AWS 交互時有更簡便的方法 —— JITP,JITP 允許設備第一次連線 AWS 時,註冊
設備憑證,並為設備憑證附加政策
、產生 Thing
⋯⋯,這樣在 AWS IoT Core 中就不會有多餘的、預先產生的憑證佔據頁面,並且也不好追蹤及管理。
不過使用 JITP 仍然有一些限制,沒辦法很靈活地做一些想要做的其他事,像是設備第一次連線時,在產生 Thing 的當下,為 Thing 取
一個帥氣卻保有規則的名
字,於此同時產生 Shadow
,為了將來能夠同步
設備與手機 APP 中的狀態
。
關於 Shadow 可以參考下面的文章:
而在另一篇文章中,我們使用了 Lambda,在設備已經設置憑證
、private key
的時候,對特定的 Topic
傳送訊息,以訊息內容驅動 Lambda
為設備產生 Thing,於此同時產生 Shadow 以及其他種種。
這個方法其實相當不錯,不過每次連線都得朝特定 Topic 發送特定訊息,這會不會出問題?例如一個憑證產生多個 Thing 或多個 Shadow,所幸,AWS 的 Thing 與 Shadow 的名稱是不能重複的,這即是說即便多次驅動 Lambda,最終仍只會產生一個 Thing 與特定的 Shadow,缺點是在於 Lambda Function 的驅動計費
可能會不斷地增加。
而為了做出更靈活的事情,AWS 也提供了一個相當不錯的作法 —— JITR,Just-in-Time Registration,即時註冊。即時註冊實現的方法也是透過 Lambda Function 的驅動,來為設備憑證產生 Thing、Shadow 等,差別僅是當設備憑證首次連線自動註冊時,會朝 AWS 預留的 Topic(含有 $ 做開頭的 Topic) 發送相關訊息。
融合 JITP 的優點,我們這篇文章來講講 JITR,由於會使用到 Lambda Function,所以下面我們也先來複習 Lambda Function。
繼續閱讀|回目錄
複習 Lambda
我們參考關於 Lambda 的文章:
首先,進到 AWS Lambda 的服務中,建立函式
,並選擇你要用來撰寫
函式的語言
,接著,點選組態 => 許可 => 為你的執行角色加入權限,由於這個權限是以 IoT Core 特定的 Topic 做為 Trigger,所以加入 IoT 相應權限,最後,加入 Trigger,選擇 IoT,以 SQL 設定特定 Topic。
前置作業就完成了!
我們看到範例程式碼:
import json
import boto3
from botocore.exceptions import BotoCoreError, ClientError
iot = boto3.client('iot')
iot_data = boto3.client('iot-data', region_name='ap-southeast-2')
def lambda_handler(event, context):
mac_address = event['mac']
thing_name = f'sensor_{mac_address}'
group_name = 'Sensor'
try:
# Activates the certificate
iot.update_certificate(
certificateId=event['cid'],
newStatus='ACTIVE'
)
# Creates a new Thing
iot.create_thing(
thingName=thing_name
)
# Attaches the certificate to the Thing
iot.attach_thing_principal(
principal=event['carn'],
thingName=thing_name
)
# Adds the Thing to the Thing Group
iot.add_thing_to_thing_group(
thingGroupName=group_name,
thingName=thing_name
)
# Interacts with the named shadows to create them
iot_data.update_thing_shadow(
thingName=thing_name,
payload=json.dumps({
'state': {
'desired': {
'info': 'Initial info shadow message'
}
}
}),
shadowName=f'sensor_{mac_address}_factory'
)
iot_data.update_thing_shadow(
thingName=thing_name,
payload=json.dumps({
'state': {
'desired': {
'LED': 'off'
},
'reported': {
'LED': 'off'
}
}
}),
shadowName=f'sensor_{mac_address}_event'
)
print('JITR process completed successfully for', thing_name)
return {
'statusCode': 200,
'body': 'Success'
}
except (BotoCoreError, ClientError) as error:
print(error)
return {
'statusCode': 400,
'body': str(error)
}
在這段程式碼中,接收到訊息有三個,分別是 MAC
、CID
、CARN
,即是 MAC Address,還有 Certificate 的 ID 與 ARN,這是由設備發出的,event[‘mac’]
、event[‘cid’]
、event[‘carn’]
就是從事件讀取而來的三個訊息。
MAC 被組成 Thing Name,而 Group 是在 IoT Core 上設置的實物群組
,所以在 Lambda Handler 中,我們 try 了,iot.update_certificate
更新憑證狀態為 ACTIVE;iot.create_thing
產生 Thing,Thing Name 包含 MAC;iot.attach_thing_principal
將憑證與 Thing 關聯起來;iot.add_thing_to_thing_group
將 Thing 加入特定實物群組;iot_data.update_thing_shadow
產生兩個 Shadow,一個用來打設備初始資訊,一個用來打設備初始狀態,兩者的名稱皆包含 MAC。
後面則是成功
驅動印出成功訊息,失敗
也印出錯誤訊息。
繼續閱讀|回目錄
裝置首次連線
AWS 告訴我們,如果 CA 憑證已經 AWS 認證過,並且 CA 憑證設為 ACTIVE
,自動註冊
也打開,而當裝置憑證註冊時,沒有將憑證狀態設為 ACTIVE,那麼,當裝置使用裝置憑證進行首次連線,憑證的狀態會變成 PENDING_ACTIVATION
。
實際例子如下:
這個憑證會處於等待啟用
(PENDING_ACTIVATION)的狀態。
此外,憑證還會朝特定的、AWS 保留的 Topic 發送訊息,這個預留的 Topic 是 $aws/events/certificates/registered/<caCertificateId>
,後面即是你用來簽署這個裝置憑證的 CA Certificate 的 ID。
測試時可以訂閱這個預留的 Topic,裝置第一次連線時,AWS 就會從這個 Topic 收到訊息:
而我收到的訊息如下:
{
"certificateId": "9f9b7fbab5d86559943826bbb255d7c65ffd3323b8318b00550dc2edb7654e38",
"caCertificateId": "6b271c84e220102e4a9594bd7b9eea4a9fd28536b06a1537e13c4705f91d929c",
"timestamp": 1708501227363,
"certificateStatus": "PENDING_ACTIVATION",
"awsAccountId": "123456789012",
"certificateRegistrationTimestamp": null,
"sourceIp": "XX.XX.XX.XX"
}
你可以看到裝置憑證的 ID,也有 CA 憑證的 ID,事實上有這兩個 ID 等於也有了兩者的 ARN,因為我們說 ARN 裡面就包含了 ID,訊息也告訴我們,裝置憑證的狀態是等待啟用。
接著,我們就可以更改 Lambda 的 Trigger 為 $aws/events/certificates/registered/<caCertificateId>
這個 Topic,如下:
即是將原本打到 mcu/esp32/fakedata/tap 的這個動作,改成打到 AWS 預留的 Topic,並且經過實測,裝置無論連線幾次,只會朝這 Topic 打一次相關訊息,這就變成了有效的、單次 Trigger Lambda Function 的設計。
Arduino 呈現狀態
接著,我們來看看 PENDING_ACTIVATION 的狀態實際發生情況,看到 Arduino Monitor 如下:
第一個是已註冊
並且作用中的憑證嘗試連線,但該憑證並無相應權限(附加正確政策)而得到的結果,就是說這是一個看起來正常卻沒辦法正常以 MQTT 方式連接到 AWS IoT Core 的憑證。
解決辦法當然是幫憑證附加上正確的政策
。
第二個是初次連線
的憑證處於 PENDING_ACTIVATION
,等待 Lambda 被 Trigger,設置憑證為作用中,附加政策、產生 Thing & Shadow⋯⋯等,實際上我在 Arduino 的寫法是,那個「⋯⋯」若在沒有正確連上 AWS 時會不斷地嘗試連線,也就是「⋯⋯」會一直延續下去,而這次卻在中間斷掉了,這即是處於 PENDING_ACTIVATION
造成的結果。
當然 Trigger Lambda
後,後續就會成為正常的連線憑證。
繼續閱讀|回目錄
最終流程
那麼,在 JITP、JITR,以及 Trigger Lambda 這些組合技中,可能就有一個不錯的解決方案,我們試著順過裝置憑證註冊流程。
- 以
乾淨模板
,或不使用模板
的情況下,向 AWS 註冊自簽 CA 憑證,當然,憑證必須設定為作用中
,並且自動註冊
必須打開 - 以 CA 憑證簽署裝置憑證,但不去更改裝置憑證的狀態,所以預設為非作用中,在首次連線 AWS 時會變成
PENDING_ACTIVATION
- 首次連線,自動會將憑證相關資訊發到 AWS 預設 MQTT Topic:$aws/events/certificates/registered/<caCertificateId>
- Trigger Lambda,改動憑證的狀態為 ACTIVE、附加政策、產生 Thing、將 Thing 與憑證關聯起來、產生兩種 Shadow(一個裝出廠資訊,一個裝裝置初始狀態)
以此流程設計憑證產出,將會簡化許多步驟,我們不用將裝置韌體加入程式碼,讓它朝特定 MQTT Topic 去打相關資訊,而是 AWS 在 INACTIVE 狀態的憑證初次連上線時,自動將狀態改為 PENDING_ACTIVATION,並且該憑證會自動朝 AWS 預留的 Topic 發送相關訊息,其中重要資訊為 Certificate ID,有了 ID 就有 ARN,有 ARN 就可以做相應操作(設置狀態、附加政策、產生 Thing⋯⋯)。
那麼,我們就對 IoT 產線流程,或說產線流程部份多了些概念,以便找到適合你企業的解決方案。
這次就分享到這,感謝您的閱讀。
繼續閱讀|回目錄
Reference: