Bulk registration 란?

IoT Core 서비스에 사물 등록을 대량으로 할 수 있게 도와주는 기능 입니다.

https://docs.aws.amazon.com/ko_kr/iot/latest/developerguide/bulk-provisioning.html

 

이번 게시물에서는 IoT Device Management의 기능 중 하나인 Bulk registration을 활용해 IoT Core 서비스에 많은 수의 디바이스를 한번에 등록하는 과정을 보여드리겠습니다.

* 실습 참고: https://catalog.us-east-1.prod.workshops.aws/workshops/753d4f22-945d-486d-8f65-8e655441c571/ko-KR/3/1


AWS Cloud9 instance를 IoT device로 활용

Cloud9의 환경 생성 화면으로 이동합니다.

(버지니아 북부(us-east-1) 리전을 기준으로 진행됩니다.)

 

1) 이름을 지정합니다.

2) 나머지 설정값은 모두 default 값을 그대로 사용합니다. 아래로 스크롤하여 생성을 클릭합니다.

 

3) Cloud9 환경이 생성 중인 대시보드를 확인할 수 있습니다. 열림 버튼을 클릭 합니다.

4) 잠시 후 Cloud9 IDE가 생성 완료되고, 아래 이미지와 같은 화면을 볼 수 있습니다.

설정 버튼을 클릭해 Show Home in Favorites를 체크합니다.

여기까지 진행했을 때 실습에 사용할 IoT device가 준비되었습니다.

 

CloudFormation template으로 resource 생성

링크를 클릭해 이번 실습에서 사용할 IAM Role resource를 생성합니다.

 

1) '스택 생성' 화면에서 다음을 클릭합니다.

2) '스택 세부 정보 지정' 화면에서 다음을 클릭합니다.

3) '스택 옵션 구성' 화면에서 다음을 클릭합니다.

4) '검토' 화면에서 문구가 있는 체크박스에 체크하고 전송을 클릭합니다.

 

리소스의 생성이 완료되는 데까지 시간이 걸립니다.

 

Bulk registration

1) 고유한 이름의 S3 버킷을 command를 활용해 생성합니다.

(여기서부터 사용되는 command들은 cloud9 terminal에 입력합니다.)

AWS account의 number를 변수로 입력받아 버킷 이름의 일부로 사용합니다.

MY_AWS_ACCOUNT_NUMBER=`aws sts get-caller-identity --query Account --output text`
aws s3 mb s3://mybucket-$MY_AWS_ACCOUNT_NUMBER

2) 새로운 사물 그룹과 타입을 생성합니다. 

aws iot create-thing-group --thing-group-name bulk-group
aws iot create-thing-type --thing-type-name bulk-type

3) mk-bulk.sh 파일을 다운로드 합니다. 이후 해당 스크립트에 실행 권한을 부여 합니다.

bulk registration을 위한 registration template을 생성하기 위한 스크립트 파일 입니다.

wget "https://ke-eu-central-1.s3.eu-central-1.amazonaws.com/devicemanagement/mk-bulk.sh"
chmod +x mk-bulk.sh

4) 아래 command를 활용해 스크립트를 실행합니다.

뒤에 파라미터로 전달되는 bulk-thing는 대량으로 등록되는 사물의 base name이고 100은 100개의 사물에 대한 정보를 registration template에 생성하겠다는 것을 의미합니다.

openssl rand -out /home/ubuntu/.rnd -hex 256
./mk-bulk.sh bulk-thing 100

위 스크립트의 결과물로 bulk-[사물이름]-[datetime] 형식의 디렉토리에 100개의 사물에 대한 key와 CSR(Certificate Signing)가 생성된 것을 확인할 수 있습니다.

bulk registration을 위한 registration template로써 bulk.json 파일이 생성된 것을 확인할 수 있습니다.

5) 생성된 디렉토리로 이동한 뒤 위에서 생성했던 S3 bucket에 registration template 파일을 업로드 합니다.

cd  bulk-thing-2023-10-18_05-00-27/
aws s3 cp bulk.json s3://mybucket-$MY_AWS_ACCOUNT_NUMBER

6) bulk registration에 사용할 template body를 아래와 같은 명령으로 다운로드 받습니다.

template body에는 bulk registration에 사용되는 파라미터와 리소스에 대한 정의가 되어 있습니다.

sudo wget "https://ke-eu-central-1.s3.eu-central-1.amazonaws.com/devicemanagement/templateBody.json"

7) 아래의 형식의 command를 활용하여, bulk registration task를 진행합니다.

[bulk registration을 수행하기 위한 IAM Role의 ARN]은 앞서 생성하신 CloudFormation의 output 탭에서 확인할 수 있습니다.

aws iot start-thing-registration-task \
  --template-body file://templateBody.json \
  --input-file-bucket mybucket-$MY_AWS_ACCOUNT_NUMBER \
  --input-file-key bulk.json --role-arn [bulk registration을 수행하기 위한 IAM Role의 ARN]

8) "taskId"를 이용해 아래 명령어로 bulk registration 수행 중 발생된 에러 및 결과를 확인합니다.

aws iot list-thing-registration-task-reports \
  --report-type ERRORS --task-id [YOUR_TASK_ID]

aws iot list-thing-registration-task-reports \
  --report-type RESULTS --task-id [YOUR_TASK_ID]

명령의 결과로써 resourceLinks가 리턴됩니다. 이는 뒤에 이어지는 절차를 위해 사용됩니다.

 

9) resoureLinks로 부터 결과를 저장합니다.

sudo wget -O results.json [resourceLinks]

결과는 results.json이라는 이름의 파일로 저장됩니다.

10) 마지막으로 bulk registration을 통하여 등록된 100개의 사물에 대한 인증서를 results.json 파일에서 추출하여 저장하기 위해 python script를 다운로드 받고 실행합니다.

wget "https://ke-eu-central-1.s3.eu-central-1.amazonaws.com/devicemanagement/bulk-result.py"
python bulk-result.py results.json

 

아래의 명령으로 bulk registration을 통해 등록된 사물의 목록을 확인합니다.

aws iot list-things

IoT Core 콘솔 화면에서도 확인할 수 있습니다.


간단하게 위 실습에서 사용했던 스크립트들의 내용을 확인하고자 합니다.

 

bulk registration을 사용하기 위해서는 아래 이미지와 같은 형식의 JSON 파일이 필요합니다.

이와 같은 파일을 얻기 위해 사용했던 스크립트가 mk-bulk.sh 이며, 결과물은 bulk.json 입니다.

 

  • mk-bulk.sh
#!/bin/bash

# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

set -e

if [ -z $1 ] || [ -z $2 ]; then
    echo "usage: $0 <base_thingname> <num_things>"
    exit 1
fi

thing_name=$1
num_things=$2

date_time=$(date "+%Y-%m-%d_%H-%M-%S")

out_dir=$thing_name-$date_time
mkdir $out_dir || exit 1


for i in $(seq 1 $num_things) ; do
  openssl req -new -newkey rsa:2048 -nodes -keyout $out_dir/$thing_name$i.key -out $out_dir/$thing_name$i.csr -subj "/C=DE/ST=Berlin/L=Berlin/O=AWS/CN=Big Orchestra"

  one_line_csr=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' $out_dir/$thing_name$i.csr)

  echo "{\"ThingName\": \"$thing_name$i\", \"SerialNumber\": \"$i\", \"CSR\": \"$one_line_csr\"}" >> $out_dir/bulk.json
done

echo "output written to $out_dir/bulk.json"
  • bulk.json
{"ThingName": "bulk-thing1", "SerialNumber": "1", "CSR": "-----BEGIN CERTIFICATE REQUEST-----\nMIICmjCCAYICAQAwVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0G\nA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBPcmNoZXN0\ncmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrJZg2YorjtNRTTpkn\nJqaEHZDwvjixOObRNJQTKDVfpEhN5SUpxSqFZW+1aCNtH4w3Wj50lGTYomPB0BjA\n1hUlUiSqYWKgzQdXbc3EvmML/vZ2O8ky1qbTv0PiV7VyBvwPbhpTf8F+zqNwJ5WQ\nZdxkLTqNqe2b1W8EppN98mDmbKN6cN0olRTVGhbwMggHmaViVKQRgO5Mv7AcZzxX\n0MlANi52SPiP+gzx1fPj7R3SGTse2E9/eaIQfzUYWZ5woiF+L2pfvHfwAWOdRWX7\nrqiWGZmw87fq7CKox92Gid16hWuz9cifVHnpCMCQnK3j3n7eaaSYZYoFHWyHi4Kx\nnvmPAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAe/O21OLOFbzk0MiLLaIiW9EV\nR67WSaaaTSU+aurp4dQOUE7yY3u7VvdTYl4kmwSnFUipkv9KnR0WtdUvzOakXJNj\nOLlDUSFIxWWI2ovPM50kqH8u9b3f1B9XuvzU9OxBoAsTyOMPLK3SnZ5Mb1MV2wir\nUg9NqAnRAJxmOg7Zvlf4YVOw+fXvULIcbbWDEVYewu7Rxrk+uYmGOQPnDtmKi1NV\nj/Dr43YKoeweO1o86dxWkbu7ybEVCEYvX7b7n3gnAso9ppDFS0ObiveB4Jv6SIr3\nKBwDq19ojtO3f72/zqBLN5fAksWzMDlZ+pSa4cpUqqaASuOxZywS4AOGTlZk/w==\n-----END CERTIFICATE REQUEST-----\n"}
{"ThingName": "bulk-thing2", "SerialNumber": "2", "CSR": "-----BEGIN CERTIFICATE REQUEST-----\nMIICmjCCAYICAQAwVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0G\nA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBPcmNoZXN0\ncmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgbZ69aKZTREVx8ieG\nptNZsWF8sm2YB46EehpVjtFY+ITNv6Ubo22K52DanoMlFqlCWRcCPWM0wmY1q3ui\ndcx1yD/bDSXP88UR/KMbe7UhPyz6zJTynFIzSmxgtlr1G5W3XBVhSKOsOlc161JA\nouVxwQyFknkIIBxTAcloRCG4/BiFTj0Sq/W9qUSBudsoOG1WCTyGYYxkuXa7OYX6\ncCNK4BFOXsptvUXJOEV3fhQLqb++Ubngrofe1tSoSjU2xOylRwkz18sqA6R0+Wie\n7AGTiCSQJK+PJmyxct7ieqzzcEocMFt75zl3vNI1xQJ3hJCXJ+tbB6LtSlW247S2\nErDtAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAdmEQEX4efWKC0WV9jAEOgBO9\nMikEnJvFdjK38K0gfK3RYarsJKlWqnUmL6tL+jCpHfqygMuxdvKwk4ewvAYI1RQA\ntMaF87DeF19vf6pVqyBIAI1+Njniio2v8BKPWNTfgbRZXwGgru2JJL4hsIkxcvnK\nGSRSNuRKstZ9oNbRizXYKSgq1BTzt9+ufXqYYPd50ReU5AZ5o9DTeUOkJI92UihN\nIH/abMGZJ0t23mGRRMHriWWRozaonp+kxnpI6VLdZamgDVk1WVRB24K7S6pYnUgw\n0MfVXkNFeUB+xgQshPi+GaLoEDT6flPqKNiorml3aoaVQ6BtcWuJm4icDHKZ3g==\n-----END CERTIFICATE REQUEST-----\n"}
{"ThingName": "bulk-thing3", "SerialNumber": "3", "CSR": "-----BEGIN CERTIFICATE REQUEST-----\nMIICmjCCAYICAQAwVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0G\nA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBPcmNoZXN0\ncmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEVVg+gbu7hA2g+cUu\nlSnR7QkGUe3Z7ZKz/zEfN24yfY4xjJDdmcSyGYGfCUlmByfL5p80kuqv4GBvhVPK\nU9Re8xFU3CfMCjW1HEDWFbPo97SUrHWVk2glPsz9TJUi8+GcB6X6Zq5NTzkCYtcv\nF0eX+E7YeQBrSu8JqzrfCXlvNvNGS4m25Iug1i64Z+OD85opfxZogVc69Ans/PvN\nPvZH26gEtimab2Bvz74D/tMZ3GmU4Ox3lZfUU26XLgHRFEltP0leuBZJ5CTYqBHK\nhAVXExtITFdpR1jrCGWkXrR4cFibrjAxjGeCNVdnaKJvwlqyLDewEhYI5+FfCBy+\nKItbAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAls4+bShW0Oo5h7iAX6YABswk\nHVn12D3t0ab5gh1+cad15MdvlwMd4nXXxTp1eKiWoRCxERnBcfz49axkmCtO46/S\nG33A2Zf6pLmDUHToZymPwrthogKN7FadqLK9cS0OUNylCVB9pZiyhTcqEIe4uPtw\nwESKkEiKzYdtKq5904flBi/VEv01xXrh+FrnBsxprCwJ+bqFpZPpRPISPr74JX2M\nK+zqCdTZGT4J5I2yLm4jyTRiG9jyEaMt46aZnVnc0I3A0PBuKa7a9yhIph8s/6t8\nuixtflUid0kUrAodW4mHlVFiaDXNf89HvFTz27Cven7GHcJ8DZNIcwIg18Kh6A==\n-----END CERTIFICATE REQUEST-----\n"}
{"ThingName": "bulk-thing4", "SerialNumber": "4", "CSR": "-----BEGIN CERTIFICATE REQUEST-----\nMIICmjCCAYICAQAwVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0G\nA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBPcmNoZXN0\ncmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDExTtxTw21CqyV4szp\neC1T8ilN1lxn4VUrna1HtrLkj2PRcjzggz4/s5EG4pntHgM5cbdknhUZ11eQHrLk\naB/YVm/lsAo4LlzCsFnzSDQlLBUuWNggzdkJDjrvhG9ZUYt75XD9gOfD2diLFCij\nLdF4BkaPLlO/4K+M90zrW5H6P6laflUQQ2r3jVH57YfhDeEBdpd21ykF/mBq1zgp\nyNzrdeamzizrTDu9vrfvlRKrPMQqiiuH0JLaSDX26zLjp6H2LoF7d3e5LiTyWosu\nV0VCq74JktWT9T9V7FMxeHnNfvlKa8o0DPjBDc6myshReMuH9ncEmgdITi9OWcvc\nnG0fAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAXo8KdoTFwtgkwSJM+4YdYeE9\n24vbVJZiwkXcVwm20wgYgrRFDwLAADfaWylo9gWXMjM8gZh5/DH77ixkhJw833F5\nhxRRG+oFGrUZMFutUSg0jO2HoFEh7bIpzNy3CVzpO8LXPZ1rzTvBR9ZLYutdTE03\noRHwvV4XL5DLoRHoU9+KhcF0B5+hmRI9fAavJLieOw3lezfjwEaERhrB5CwGv4mS\nkQeR03sBKuI2AyKDClH0AHHDjaQgOG2kQ/uVIMJ+XzrMRtG2k5J6MqkZlTpAvh1G\n7nfc6jRKetK9pZzyqHqnaFUgal9flMfoHgmJeGdpN7HXwOKI3ioCcv9NPyidMw==\n-----END CERTIFICATE REQUEST-----\n"}
{"ThingName": "bulk-thing5", "SerialNumber": "5", "CSR": "-----BEGIN CERTIFICATE REQUEST-----\nMIICmjCCAYICAQAwVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjEPMA0G\nA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBPcmNoZXN0\ncmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsGjxWIhhjVMa7YuPx\nuSHfJQmkoZuInblb4MzsYRTiRuopbqq9PKEX3ChNstRuByp/XzebxRbbfvH58kDu\n+npB8W0gb+HRHnheLfp3uDTHvo6USq5oMSpVlz5ASpdoouP1cpTkUhwK7FGdv9xi\nBQ9RDDyJSIfYcCLC+qe+ldFeoehchWFlpPhz0nU1zBDhcvekTarBl77a+5cEPu2K\nvmPGoFf8TsXqG5zBe6CSXyTa+7MUeEYBndLugcGCHTCZbmUIV4Qjm73QeRteC7q+\nwsgRgRpeDtdMVtYL0y4k0AJ15TJeBGDJtu62YH6rdNGfxecjaZ7U9smsQNGWt2WQ\nnGbtAgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAah1FTcn1B2KxlPuxAKxLS6Py\nIJljoAKAXsZM0VSk7N0vfuurSepkd2XHTxFaj6gobxPpmT2Mu5zbnILpL8kC5sGX\nx+hEF1OXomkIsfw4WXMF0yKqMBrQdMTqTa+TlqG5te+TA2JfgZjp7Kot6iLdLC8H\nZuvBg4PUKtIlk2o6S0V/fORg70ZhHKb3G9qCJbotsg6zcChKTWzfSF1IgZzhe79V\nB4ZgECv60c8XpzpxYLGvcKc6CX/Yl9NppmrteXGJvTAhdzMaJUagWM58Oh3XJsQh\nUX726VmnZM78PmY46KcZt3O5z3IEv0EbmytAFoZS+leLqT7b1cDf2mAQRU7Uhg==\n-----END CERTIFICATE REQUEST-----\n"}
...

 

bulk registration은 start-thing-registration-task 명령을 사용해 진행합니다.

inputFileBucketS3 bucket, inputFileKeybulk.json, roleArn은 위에서 cloudformation으로 생성했던 role이며

templatebody는 아래의 스크립트 입니다. 

templatebody는 bulk registration에 사용되는 파라미터와 리소스에 대한 정의가 되어 있어야 합니다.

  • templateBody.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" :  "bulk-type",
        "ThingGroups" : ["bulk-group"]
      }
    },
    "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:*\"],\"Resource\": [\"*\"]}]}"
      }
    }
  }
}

 

결과로 Task ID를 확인할 수 있으며 resourceLinks 리턴 값을 확인하기 위해 필요합니다.

얻은 resourceLinks로 부터 실행 결과를 저장합니다. 저장한 파일이 results.json 파일 입니다.

  • results.json
{"lineNumber":1,"offset":1057,"response":{"CertificatePem":"-----BEGIN CERTIFICATE-----\nMIIDkDCCAnigAwIBAgIUWS2Okfw8JY6kC/+jEJfv8vvwyPEwDQYJKoZIhvcNAQEL\nBQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g\nSW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTIzMTAxODA1MTEz\nMloXDTQ5MTIzMTIzNTk1OVowVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxp\nbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBP\ncmNoZXN0cmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCrJZg2Yorj\ntNRTTpknJqaEHZDwvjixOObRNJQTKDVfpEhN5SUpxSqFZW+1aCNtH4w3Wj50lGTY\nomPB0BjA1hUlUiSqYWKgzQdXbc3EvmML/vZ2O8ky1qbTv0PiV7VyBvwPbhpTf8F+\nzqNwJ5WQZdxkLTqNqe2b1W8EppN98mDmbKN6cN0olRTVGhbwMggHmaViVKQRgO5M\nv7AcZzxX0MlANi52SPiP+gzx1fPj7R3SGTse2E9/eaIQfzUYWZ5woiF+L2pfvHfw\nAWOdRWX7rqiWGZmw87fq7CKox92Gid16hWuz9cifVHnpCMCQnK3j3n7eaaSYZYoF\nHWyHi4KxnvmPAgMBAAGjYDBeMB8GA1UdIwQYMBaAFDLldBsUWUJZzfI2E7nzlgYh\nSyocMB0GA1UdDgQWBBSoES/LeLU38FdLKaCbwqDZeXYEszAMBgNVHRMBAf8EAjAA\nMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAj+SDRZTvuqib7bTH\nz5YRxuCTNlFFV/n0VgI6NY2J/taZTscYQowanA6dQoKK3Run00qsW/MjbBpVQGrb\nC67SabsZNIjkGmCHpiW1VwlMYwapMAbZJNzRVi9amO0EEJYS+Gdy1wlT/qwE2YRD\n2hOtTwG/L9E+Oy9xTVMzRDDU4snuVQfYuHH3HL/KxEEg9MZbM8VMYI+VQmiKHZe8\nYQXYR37t9Hxq7bfyQvpfSIsKsZ283aYxY3dmHB+xrFQ2tjS8dfuXpEzrgjdYwddm\nmR6SEf7kwsPgTPDJM/U5FciNcuXmnrVki4wuGIqeI3Iwt9qHpWcnuixqmb7rHf7c\nM7mCDQ==\n-----END CERTIFICATE-----\n","ResourceArns":{"certificate":"arn:aws:iot:us-east-1:986611521344:cert/df6c6420c47571595daba7446b203a2ffdabafc68e2e7a94972e9e77a696cb38","policy":"arn:aws:iot:us-east-1:986611521344:policy/EA1A0CDFCEDEAEE65D65B7AB012F0D7D89208F1EDA825C85F28063F9DC4005BC","thing":"arn:aws:iot:us-east-1:986611521344:thing/bulk-thing1"}}}
{"lineNumber":2,"offset":2114,"response":{"CertificatePem":"-----BEGIN CERTIFICATE-----\nMIIDkDCCAnigAwIBAgIUS/f0saWs0Lc5U/Hy407Gj8wN3A4wDQYJKoZIhvcNAQEL\nBQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g\nSW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTIzMTAxODA1MTEz\nMloXDTQ5MTIzMTIzNTk1OVowVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxp\nbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBP\ncmNoZXN0cmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCgbZ69aKZT\nREVx8ieGptNZsWF8sm2YB46EehpVjtFY+ITNv6Ubo22K52DanoMlFqlCWRcCPWM0\nwmY1q3uidcx1yD/bDSXP88UR/KMbe7UhPyz6zJTynFIzSmxgtlr1G5W3XBVhSKOs\nOlc161JAouVxwQyFknkIIBxTAcloRCG4/BiFTj0Sq/W9qUSBudsoOG1WCTyGYYxk\nuXa7OYX6cCNK4BFOXsptvUXJOEV3fhQLqb++Ubngrofe1tSoSjU2xOylRwkz18sq\nA6R0+Wie7AGTiCSQJK+PJmyxct7ieqzzcEocMFt75zl3vNI1xQJ3hJCXJ+tbB6Lt\nSlW247S2ErDtAgMBAAGjYDBeMB8GA1UdIwQYMBaAFCehQabmnQRs29ETKNaNKTJo\nFGySMB0GA1UdDgQWBBQgQze4qB6CJG06d8Xjbh7WqsQzJTAMBgNVHRMBAf8EAjAA\nMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAi2JZadms+v2srXlJ\nDgcg4gvVWXoPaQk0ujnaHqE4545urRn70vy8JMpB1IeBsbPxLFML2C/gCARdcXE2\nOEhcIw1Y3XKDxYTxSbUU6U7XilXpPNItJf4AnS2e37y9ufHHTDq7dMuNV91SyCNn\nnlscbdbatjkLDojeu3/Wv5WIiKHf8WGHN1Hrso+uZeDJxYrtkgTD9G/ypkdzCPw6\nuSCpN4j0J6Qg8pvR/TaL7lisXoRqFna9BTm9B1FIrheZlDCcvi6XtbaPoDAkuqeQ\nIuKeV9N5DR9k1fuuu7RENftkVfOiIJnS76FI7N9cuU9KL/LB2yYDh/Z0bEPz2kd5\nwO6RaA==\n-----END CERTIFICATE-----\n","ResourceArns":{"certificate":"arn:aws:iot:us-east-1:986611521344:cert/c305346f959b269a9e434397ffd6b3c8dbe7ed12539440483fd4bbf5f55bef14","policy":"arn:aws:iot:us-east-1:986611521344:policy/EA1A0CDFCEDEAEE65D65B7AB012F0D7D89208F1EDA825C85F28063F9DC4005BC","thing":"arn:aws:iot:us-east-1:986611521344:thing/bulk-thing2"}}}
{"lineNumber":3,"offset":3171,"response":{"CertificatePem":"-----BEGIN CERTIFICATE-----\nMIIDkDCCAnigAwIBAgIUBeVIR2wCJdZMO2XFaxph/dSWBJgwDQYJKoZIhvcNAQEL\nBQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g\nSW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTIzMTAxODA1MTEz\nMloXDTQ5MTIzMTIzNTk1OVowVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxp\nbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBP\ncmNoZXN0cmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDEVVg+gbu7\nhA2g+cUulSnR7QkGUe3Z7ZKz/zEfN24yfY4xjJDdmcSyGYGfCUlmByfL5p80kuqv\n4GBvhVPKU9Re8xFU3CfMCjW1HEDWFbPo97SUrHWVk2glPsz9TJUi8+GcB6X6Zq5N\nTzkCYtcvF0eX+E7YeQBrSu8JqzrfCXlvNvNGS4m25Iug1i64Z+OD85opfxZogVc6\n9Ans/PvNPvZH26gEtimab2Bvz74D/tMZ3GmU4Ox3lZfUU26XLgHRFEltP0leuBZJ\n5CTYqBHKhAVXExtITFdpR1jrCGWkXrR4cFibrjAxjGeCNVdnaKJvwlqyLDewEhYI\n5+FfCBy+KItbAgMBAAGjYDBeMB8GA1UdIwQYMBaAFF2PWXbNwWujfogNBhqjK4/6\nNPg/MB0GA1UdDgQWBBSB+SGoDg4XKzQWd3NFY8Qg8VOVrjAMBgNVHRMBAf8EAjAA\nMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAllSQWPysC1p3IkyX\nJ4Pzvl2chkRCBFR9/tob90SOXJSJ3WYN/5Bbgl/WURppj9VJXCxawj3AxqBxBMfx\n66a0uL1dxEgYYOJf79ODxupipUFxIg1yTfQSKpIoL9UDZ+84y9h4wMpzIHyIXxMP\nntKuOIivw2qizIEuSyqvIc2nZ2W9gMxxVVvN2KhfBkJ9QBDdM4Q2TJ8gSKoSDt8r\noP5b4oeVVPYKuP+QYlth2MsJJEr0Zwzlq6jZe8tLofbqkl+Vk+nAVj8DyoPqANi4\n17zbWYb37zMfrx21Y5NEZY25JxgkU5lnONzbpoTIZpJCM/0D7hvhgPWdXidCDzW1\nn/eObQ==\n-----END CERTIFICATE-----\n","ResourceArns":{"certificate":"arn:aws:iot:us-east-1:986611521344:cert/4d3db30b101486d79bdba67acdd044e006b03be805662e2fcdf54c98b83425e0","policy":"arn:aws:iot:us-east-1:986611521344:policy/EA1A0CDFCEDEAEE65D65B7AB012F0D7D89208F1EDA825C85F28063F9DC4005BC","thing":"arn:aws:iot:us-east-1:986611521344:thing/bulk-thing3"}}}
{"lineNumber":4,"offset":4228,"response":{"CertificatePem":"-----BEGIN CERTIFICATE-----\nMIIDkTCCAnmgAwIBAgIVAIWvypjuGj6W2AIslOrGetxD0ZFrMA0GCSqGSIb3DQEB\nCwUAME0xSzBJBgNVBAsMQkFtYXpvbiBXZWIgU2VydmljZXMgTz1BbWF6b24uY29t\nIEluYy4gTD1TZWF0dGxlIFNUPVdhc2hpbmd0b24gQz1VUzAeFw0yMzEwMTgwNTEx\nMzJaFw00OTEyMzEyMzU5NTlaMFUxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIDAZCZXJs\naW4xDzANBgNVBAcMBkJlcmxpbjEMMAoGA1UECgwDQVdTMRYwFAYDVQQDDA1CaWcg\nT3JjaGVzdHJhMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxMU7cU8N\ntQqsleLM6XgtU/IpTdZcZ+FVK52tR7ay5I9j0XI84IM+P7ORBuKZ7R4DOXG3ZJ4V\nGddXkB6y5Ggf2FZv5bAKOC5cwrBZ80g0JSwVLljYIM3ZCQ4674RvWVGLe+Vw/YDn\nw9nYixQooy3ReAZGjy5Tv+CvjPdM61uR+j+pWn5VEENq941R+e2H4Q3hAXaXdtcp\nBf5gatc4Kcjc63Xmps4s60w7vb6375USqzzEKoorh9CS2kg19usy46eh9i6Be3d3\nuS4k8lqLLldFQqu+CZLVk/U/VexTMXh5zX75SmvKNAz4wQ3OpsrIUXjLh/Z3BJoH\nSE4vTlnL3JxtHwIDAQABo2AwXjAfBgNVHSMEGDAWgBQy5XQbFFlCWc3yNhO585YG\nIUsqHDAdBgNVHQ4EFgQUhYszV4B85CElJU6VACJzmZDWEhgwDAYDVR0TAQH/BAIw\nADAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggEBALQjwi6ksFANrA6t\nVm0OAKC6yRYD3yNr7BubqnIWlhyNhzYCvUbC/tmOh2lCA/20Cnrkf4BLofYVb227\nt1jsE65zVgPtAt5dAiG0DrJqdSKtieftkGsZ0iSKsKtFUc3s5HxGuwsn/eJn+GTG\nOBWlK9J1PeQJf07iHWimWzZCaPJwK9aT+m8s7vfgmOJ01dtyOW2yrrxYiCEQAyA6\nYLL2/uA8X/WqJVsqPaVku0t0LEKmg6Ir6MkPi3auLDEUKkuKljsQ3CuD4eqON19T\nJzNHFlsiYOhtDn+G0KYiqMmt495hsegvIbdiPyseYeU/DcNLocp8fEeiNS2WSWnA\n4fE3ges=\n-----END CERTIFICATE-----\n","ResourceArns":{"certificate":"arn:aws:iot:us-east-1:986611521344:cert/0f084113392b5c78e57dfc1e00040617eb1e5d71c17215d3963b7ca40fb3cf74","policy":"arn:aws:iot:us-east-1:986611521344:policy/EA1A0CDFCEDEAEE65D65B7AB012F0D7D89208F1EDA825C85F28063F9DC4005BC","thing":"arn:aws:iot:us-east-1:986611521344:thing/bulk-thing4"}}}
{"lineNumber":5,"offset":5285,"response":{"CertificatePem":"-----BEGIN CERTIFICATE-----\nMIIDkDCCAnigAwIBAgIUFcHa6lHkMdUDK7SSUkMWxe4tbZkwDQYJKoZIhvcNAQEL\nBQAwTTFLMEkGA1UECwxCQW1hem9uIFdlYiBTZXJ2aWNlcyBPPUFtYXpvbi5jb20g\nSW5jLiBMPVNlYXR0bGUgU1Q9V2FzaGluZ3RvbiBDPVVTMB4XDTIzMTAxODA1MTEz\nMloXDTQ5MTIzMTIzNTk1OVowVTELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxp\nbjEPMA0GA1UEBwwGQmVybGluMQwwCgYDVQQKDANBV1MxFjAUBgNVBAMMDUJpZyBP\ncmNoZXN0cmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsGjxWIhhj\nVMa7YuPxuSHfJQmkoZuInblb4MzsYRTiRuopbqq9PKEX3ChNstRuByp/XzebxRbb\nfvH58kDu+npB8W0gb+HRHnheLfp3uDTHvo6USq5oMSpVlz5ASpdoouP1cpTkUhwK\n7FGdv9xiBQ9RDDyJSIfYcCLC+qe+ldFeoehchWFlpPhz0nU1zBDhcvekTarBl77a\n+5cEPu2KvmPGoFf8TsXqG5zBe6CSXyTa+7MUeEYBndLugcGCHTCZbmUIV4Qjm73Q\neRteC7q+wsgRgRpeDtdMVtYL0y4k0AJ15TJeBGDJtu62YH6rdNGfxecjaZ7U9sms\nQNGWt2WQnGbtAgMBAAGjYDBeMB8GA1UdIwQYMBaAFOopp+NqKhItJByY4EHCINF9\nPRqTMB0GA1UdDgQWBBQdKrfT2/+w3Or5AF6icH14JjXJjjAMBgNVHRMBAf8EAjAA\nMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAQEAUUvQ8JaYwaUW99Ma\nE+Yk5GdqSzkR4hqlKzdt/GOWw+KP3dVa8fUlSmWwQd3B7IgbBegwFLbSykjPWfru\n+rpYvzkV9PQjV1PRDPbtEf4CUEj2skOMWj/bz0nOpi38cbNcCZTNDQ61Oq+h0Qt9\nLYmyl+Dg4gwlzmyfMArlmUqQVT3+9mbo4DLkX2DcMiElYkF9soJ8RlKImLf266UR\nNLV4NCafl70h/3fAnDSI4/ch+Jhcs+h2yEPMk5RksFGhvSf8cPqiZ00ndCE++yAG\nMpfhYyNVL1NsixL4wBlgylwS2zlD5OvSQatXp5VzoqGQKjexgr/5cBxS8Juzw28n\nHN7X3A==\n-----END CERTIFICATE-----\n","ResourceArns":{"certificate":"arn:aws:iot:us-east-1:986611521344:cert/125249f7baa1510da78a560e83de53fb4c59730837d7a91e2ede0a93c1cc333e","policy":"arn:aws:iot:us-east-1:986611521344:policy/EA1A0CDFCEDEAEE65D65B7AB012F0D7D89208F1EDA825C85F28063F9DC4005BC","thing":"arn:aws:iot:us-east-1:986611521344:thing/bulk-thing5"}}}
...

 

인증서(pem 파일)를 results.json 파일에서 추출하여 파일로 저장하기 위해 아래의 python 스크립트를 실행합니다.

(해당 응답을 잃어버리면 인증서를 얻을 방법이 없기 때문에 파일로 추출해 저장하는 것이 좋습니다.)

  • bulk-result.py
#!/usr/bin/python

# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

import json
import os
import sys


def process_line(line):
    d = json.loads(line)
    crt = d["response"]["CertificatePem"]
    thing = d["response"]["ResourceArns"]["thing"].split('/')[1]
    print("creating file {}.cert.pem for thing {}".format(thing, thing))
    file = open(thing + ".cert.pem", "w")
    file.write(crt)
    file.close()

def process_results(file):
    try:
        with open(file) as f:
            for line in f:
                process_line(line)
        f.close()
    except Exception as e:
        print("error opening file {}: {}".format(file,e))
        return None

def main(argv):
    if len(argv) == 0:
        print("usage: {} <result_filename>".format(os.path.basename(__file__)))
        sys.exit(1)

    process_results(argv[0])

if __name__ == "__main__":
    main(sys.argv[1:])

 

감사합니다.

+ Recent posts