

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 자습서: 구성 요소 업데이트가 지연되는 Greengrass 구성 요소 개발
<a name="defer-component-updates-tutorial"></a>

이 자습서를 완료하여 무선 배포 업데이트가 지연되는 구성 요소를 개발할 수 있습니다. 디바이스에 업데이트를 배포할 때 다음과 같은 조건에 따라 업데이트를 지연시키는 것이 좋습니다.
+ 디바이스의 배터리 잔량이 부족합니다.
+ 중단될 수 없는 프로세스 또는 작업이 디바이스에서 실행되고 있습니다.
+ 디바이스가 제한적이거나 비용이 많이 드는 인터넷에 연결되어 있습니다.

**참고**  
*구성 요소는* AWS IoT Greengrass 코어 디바이스에서 실행되는 소프트웨어 모듈입니다. 구성 요소를 사용하면 복잡한 애플리케이션을 여기저기 Greengrass 코어 디바이스에서 재사용할 수 있는 불연속 빌딩 블록으로 생성하고 관리할 수 있습니다.

이 자습서에서는 다음을 수행합니다.

1. 개발 컴퓨터에 Greengrass 개발 키트 CLI(GDK CLI)를 설치합니다. GDK CLI에서는 사용자 지정 Greengrass 구성 요소를 개발하는 데 도움이 되는 특성이 제공됩니다.

1. 코어 디바이스의 배터리 잔량이 임계값 미만일 때 구성 요소 업데이트가 지연되는 Hello World 구성 요소를 개발합니다. 이 구성 요소에서는 [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates) IPC 작업이 사용되는 업데이트 알림이 구독됩니다. 알림이 수신되면 배터리 잔량이 사용자 지정 가능한 임계값보다 낮은지 확인됩니다. 배터리 잔량이 임계값 미만인 경우 [DeferComponentUpdate](ipc-component-lifecycle.md#ipc-operation-defercomponentupdate) IPC 작업이 사용되어 30초 동안 업데이트가 지연됩니다. GDK CLI를 사용하여 개발 컴퓨터에서 이 구성 요소를 개발합니다.
**참고**  
이 구성 요소에서는 코어 디바이스에서 생성하는 파일의 배터리 잔량이 읽히며 실제 배터리가 모방되므로 배터리 없이 코어 디바이스에서 이 자습서를 완료할 수 있습니다.

1. 해당 구성 요소를 AWS IoT Greengrass 서비스에 게시합니다.

1. 해당 구성 요소를에서 Greengrass 코어 디바이스 AWS 클라우드 로 배포하여 테스트합니다. 그런 다음에 코어 디바이스에서 가상 배터리 잔량을 수정하고 추가 배포를 생성하여 배터리 잔량이 부족할 때 코어 디바이스에서 업데이트가 지연되는 방식을 참조합니다.

이 자습서의 예상 소요 시간은 20\$130분입니다.

# 사전 조건
<a name="defer-component-updates-tutorial-prerequisites"></a>

이 자습서를 완료하려면 다음이 필요합니다.
+ AWS 계정. 없으면 [설정 AWS 계정](setting-up.md#set-up-aws-account) 단원을 참조하세요.
+ 관리자 권한이 있는 AWS Identity and Access Management(IAM) 사용자.
+ 인터넷에 연결된 Greengrass 코어 디바이스. 코어 디바이스 설정 방법에 대한 자세한 내용은 [AWS IoT Greengrass 코어 디바이스 설정](setting-up.md) 단원을 참조하세요.
  + 디바이스의 모든 사용자에 대해 [Python](https://www.python.org/downloads/) 3.6 이상이 설치되고 `PATH` 환경 변수에 추가되어야 합니다. Windows에서는 모든 사용자에 대해 Windows용 Python 런처가 설치되어 있어야 합니다.
**중요**  <a name="windows-core-device-python-installation"></a>
Windows에서 Python은 기본적으로 모든 사용자를 대상으로 설치되지 않습니다. Python을 설치할 때는 AWS IoT Greengrass 코어 소프트웨어에서 Python 스크립트가 실행되도록 설치 구성을 사용자 지정해야 합니다. 예를 들어 그래픽 Python 설치 관리자를 사용하는 경우 다음을 수행합니다.  
**모든 사용자에 대해 런처 설치(권장)**를 선택합니다.
를 선택합니다..**Customize installation**
를 선택합니다..**Next**
을 선택합니다..**Install for all users**
을 선택합니다..**Add Python to environment variables**
**설치**를 선택합니다.
자세한 내용은 *Python 3 설명서*의 [Windows에서 Python 사용](https://docs.python.org/3/using/windows.html)을 참조하세요.
+ 인터넷에 연결된 Windows, macOS 또는 Unix 계열 개발 컴퓨터.
  + 개발 컴퓨터에 설치된 [Python](https://www.python.org/downloads/) 3.6 이상.
  + 개발 컴퓨터에 설치된 [Git](https://git-scm.com/).
  + <a name="development-component-aws-cli-prerequisite"></a>자격 증명을 사용하여 개발 컴퓨터에 AWS Command Line Interface(AWS CLI)가 설치되어 있어야 합니다. 자세한 내용은 *AWS Command Line Interface 사용 설명서*의 [AWS CLI 설치, 업데이트, 제거](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) 및 [AWS CLI 구성](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) 단원을 참조하세요.
**참고**  
Raspberry Pi 또는 다른 32비트 ARM 디바이스를 사용하는 경우 AWS CLI V1을 설치합니다. AWS CLI 32비트 ARM 디바이스에서는 V2를 사용할 수 없습니다. 자세한 내용은 [AWS CLI 버전 1 설치, 업데이트 및 제거](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html) 단원을 참조하세요.

# 1단계: Greengrass 개발 키트 CLI 설치
<a name="install-gdk-cli-defer-updates"></a>

[Greengrass 개발 키트 CLI(GDK CLI)](greengrass-development-kit-cli.md)는 사용자 지정 Greengrass 구성 요소를 개발하는 데 도움이 되는 기능을 제공합니다. GDK CLI를 사용하여 사용자 지정 구성 요소를 생성, 빌드 및 게시할 수 있습니다.

개발 컴퓨터에 GDK CLI를 설치하지 않은 경우 다음 단계를 완료하여 설치합니다.

**GDK CLI의 최신 버전 설치**

1. 개발 컴퓨터에서 다음 명령을 실행하여 [GitHub 리포지토리](https://github.com/aws-greengrass/aws-greengrass-gdk-cli)에서 최신 버전의 GDK CLI를 설치합니다.

   ```
   python3 -m pip install -U git+https://github.com/aws-greengrass/aws-greengrass-gdk-cli.git@v1.6.2
   ```

1. <a name="gdk-cli-verify-installation"></a>다음 명령을 실행하여 GDK CLI가 성공적으로 설치되었는지 확인합니다.

   ```
   gdk --help
   ```

   `gdk` 명령을 찾을 수 없는 경우 해당 폴더를 PATH에 추가합니다.
   + Linux 디바이스에서 PATH에 `/home/MyUser/.local/bin`을 추가하고 *MyUser*를 사용자 이름으로 바꿉니다.
   + Windows 디바이스에서 PATH에 `PythonPath\\Scripts`를 추가하고 *PythonPath*를 디바이스의 Python 폴더 경로로 바꿉니다.

# 2단계: 업데이트가 지연되는 구성 요소 개발
<a name="develop-component-defer-updates"></a>

이 섹션에서는 코어 디바이스의 배터리 잔량이 구성 요소를 배포할 때 구성하는 임계값 미만일 때 구성 요소 업데이트가 지연되는 Python의 Hello World 구성 요소를 개발합니다. 이 구성 요소에서는 Python용 AWS IoT Device SDK v2의 [프로세스 간 통신(IPC) 인터페이스를](interprocess-communication.md) 사용합니다. 코어 디바이스에 배포가 수신될 때 [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates) IPC 작업을 사용하여 알림을 받습니다. 그런 다음에 [DeferComponentUpdate](ipc-component-lifecycle.md#ipc-operation-defercomponentupdate) IPC 작업을 사용하여 디바이스의 배터리 잔량에 따라 업데이트를 연기하거나 승인합니다.

**업데이트가 지연되는 Hello World 구성 요소를 개발하려면**

1. 개발 컴퓨터에서 구성 요소 소스 코드의 폴더를 생성합니다.

   ```
   mkdir com.example.BatteryAwareHelloWorld
   cd com.example.BatteryAwareHelloWorld
   ```

1. 텍스트 편집기를 사용하여 `gdk-config.json`이라는 파일을 생성합니다. GDK CLI에서는 `gdk-config.json`라는 [GDK CLI 구성 파일](gdk-cli-configuration-file.md)의 구성 요소 읽기, 빌드 및 게시가 진행됩니다. 이 구성 파일은 구성 요소 폴더의 루트에 있습니다.

   <a name="nano-command-intro"></a>예를 들어 Linux 기반 시스템에서 다음 명령을 실행하면 GNU nano를 사용하여 파일을 생성할 수 있습니다.

   ```
   nano gdk-config.json
   ```

   다음 JSON을 파일로 복사합니다.
   + 자신의 이름으로 *Amazon*을 바꿉니다.
   + *us-west-2*를 코어 디바이스가 작동하는 AWS 리전 로 바꿉니다. GDK CLI에서는 이 AWS 리전에 구성 요소가 게시됩니다.
   + 사용할 S3 버킷 접두사로 *greengrass-component-artifacts*를 바꿉니다. GDK CLI를 사용하여 구성 요소를 게시하면 GDK CLI는 다음 형식을 사용하여 이름이이 값, AWS 리전및 AWS 계정 ID로 구성된 S3 버킷에 구성 요소의 아티팩트를 업로드합니다`bucketPrefix-region-accountId`.

     예를 들어 **greengrass-component-artifacts** 및를 지정**us-west-2**하고 AWS 계정 ID가 인 경우 **123456789012**GDK CLI는 라는 S3 버킷을 사용합니다`greengrass-component-artifacts-us-west-2-123456789012`.

   ```
   {
     "component": {
       "com.example.BatteryAwareHelloWorld": {
         "author": "Amazon",
         "version": "NEXT_PATCH",
         "build": {
           "build_system" : "zip"
         },
         "publish": {
           "region": "us-west-2",
           "bucket": "greengrass-component-artifacts"
         }
       }
     },
     "gdk_version": "1.0.0"
   }
   ```

   구성 파일에서 다음 구성이 지정됩니다.
   + GDK CLI가 Greengrass 구성 요소를 클라우드 서비스에 게시할 AWS IoT Greengrass 때 사용할 버전입니다.는 AWS IoT Greengrass 클라우드 서비스에서 사용할 수 있는 최신 버전 이후의 다음 패치 버전을 선택하도록 `NEXT_PATCH` 지정합니다. 구성 요소에 아직 AWS IoT Greengrass 클라우드 서비스에 버전이 없는 경우 GDK CLI는를 사용합니다`1.0.0`.
   + 구성 요소의 빌드 시스템입니다. `zip` 빌드 시스템을 사용하면 GDK CLI에서는 구성 요소의 단일 아티팩트가 되는 ZIP 파일로 구성 요소의 소스가 패키징됩니다.
   + GDK CLI AWS 리전 가 Greengrass 구성 요소를 게시하는 입니다.
   + GDK CLI에서 구성 요소의 아티팩트가 업로드되는 S3 버킷의 접두사입니다.

1. 텍스트 편집기를 사용하여 `main.py`라는 파일에서 구성 요소 소스 코드를 생성합니다.

   <a name="nano-command-intro"></a>예를 들어 Linux 기반 시스템에서 다음 명령을 실행하면 GNU nano를 사용하여 파일을 생성할 수 있습니다.

   ```
   nano main.py
   ```

   다음 Python 코드를 파일에 복사합니다.

   ```
   import json
   import os
   import sys
   import time
   import traceback
   
   from pathlib import Path
   
   from awsiot.greengrasscoreipc.clientv2 import GreengrassCoreIPCClientV2
   
   HELLO_WORLD_PRINT_INTERVAL = 15  # Seconds
   DEFER_COMPONENT_UPDATE_INTERVAL = 30 * 1000  # Milliseconds
   
   
   class BatteryAwareHelloWorldPrinter():
       def __init__(self, ipc_client: GreengrassCoreIPCClientV2, battery_file_path: Path, battery_threshold: float):
           self.battery_file_path = battery_file_path
           self.battery_threshold = battery_threshold
           self.ipc_client = ipc_client
           self.subscription_operation = None
   
       def on_component_update_event(self, event):
           try:
               if event.pre_update_event is not None:
                   if self.is_battery_below_threshold():
                       self.defer_update(event.pre_update_event.deployment_id)
                       print('Deferred update for deployment %s' %
                             event.pre_update_event.deployment_id)
                   else:
                       self.acknowledge_update(
                           event.pre_update_event.deployment_id)
                       print('Acknowledged update for deployment %s' %
                             event.pre_update_event.deployment_id)
               elif event.post_update_event is not None:
                   print('Applied update for deployment')
           except:
               traceback.print_exc()
   
       def subscribe_to_component_updates(self):
           if self.subscription_operation == None:
               # SubscribeToComponentUpdates returns a tuple with the response and the operation.
               _, self.subscription_operation = self.ipc_client.subscribe_to_component_updates(
                   on_stream_event=self.on_component_update_event)
   
       def close_subscription(self):
           if self.subscription_operation is not None:
               self.subscription_operation.close()
               self.subscription_operation = None
   
       def defer_update(self, deployment_id):
           self.ipc_client.defer_component_update(
               deployment_id=deployment_id, recheck_after_ms=DEFER_COMPONENT_UPDATE_INTERVAL)
   
       def acknowledge_update(self, deployment_id):
           # Specify recheck_after_ms=0 to acknowledge a component update.
           self.ipc_client.defer_component_update(
               deployment_id=deployment_id, recheck_after_ms=0)
   
       def is_battery_below_threshold(self):
           return self.get_battery_level() < self.battery_threshold
   
       def get_battery_level(self):
           # Read the battery level from the virtual battery level file.
           with self.battery_file_path.open('r') as f:
               data = json.load(f)
               return float(data['battery_level'])
   
       def print_message(self):
           message = 'Hello, World!'
           if self.is_battery_below_threshold():
               message += ' Battery level (%d) is below threshold (%d), so the component will defer updates' % (
                   self.get_battery_level(), self.battery_threshold)
           else:
               message += ' Battery level (%d) is above threshold (%d), so the component will acknowledge updates' % (
                   self.get_battery_level(), self.battery_threshold)
           print(message)
   
   
   def main():
       # Read the battery threshold and virtual battery file path from command-line args.
       args = sys.argv[1:]
       battery_threshold = float(args[0])
       battery_file_path = Path(args[1])
       print('Reading battery level from %s and deferring updates when below %d' % (
           str(battery_file_path), battery_threshold))
   
       try:
           # Create an IPC client and a Hello World printer that defers component updates.
           ipc_client = GreengrassCoreIPCClientV2()
           hello_world_printer = BatteryAwareHelloWorldPrinter(
               ipc_client, battery_file_path, battery_threshold)
           hello_world_printer.subscribe_to_component_updates()
           try:
               # Keep the main thread alive, or the process will exit.
               while True:
                   hello_world_printer.print_message()
                   time.sleep(HELLO_WORLD_PRINT_INTERVAL)
           except InterruptedError:
               print('Subscription interrupted')
           hello_world_printer.close_subscription()
       except Exception:
           print('Exception occurred', file=sys.stderr)
           traceback.print_exc()
           exit(1)
   
   
   if __name__ == '__main__':
       main()
   ```

   이 Python 애플리케이션에서는 다음이 수행됩니다.
   + 나중에 코어 디바이스에서 생성할 가상 배터리 잔량 파일에서 코어 디바이스의 배터리 잔량을 읽습니다. 이 가상 배터리 잔량 파일에서는 실제 배터리가 모방되므로 배터리가 없는 코어 디바이스에서 이 자습서를 완료할 수 있습니다.
   + 배터리 임계값 및 가상 배터리 잔량 파일의 경로에 대한 명령줄 인수를 읽습니다. 구성 요소 레시피에서는 구성 파라미터를 기반으로 이러한 명령줄 인수가 설정되므로 구성 요소를 배포할 때 이러한 값을 사용자 지정할 수 있습니다.
   + Python용 vV2의 IPC 클라이언트 V2를 사용하여 AWS IoT Greengrass 코어 소프트웨어와 통신합니다. [AWS IoT Device SDK](https://github.com/aws/aws-iot-device-sdk-python-v2) 원래 IPC 클라이언트에 비해 IPC 클라이언트 V2에서는 사용자 지정 구성 요소에서 IPC를 사용하려면 작성해야 할 코드 양이 감소합니다.
   + [SubscribeToComponentUpdates](ipc-component-lifecycle.md#ipc-operation-subscribetocomponentupdates) IPC 작업이 사용되는 업데이트 알림을 구독합니다. AWS IoT Greengrass 코어 소프트웨어는 각 배포 전후에 알림을 보냅니다. 구성 요소에서는 알림을 수신될 때마다 다음 함수가 직접적으로 호출됩니다. 알림이 예정된 배포용이라면 구성 요소에서는 배터리 잔량이 임계값보다 낮은지 확인됩니다. 배터리 잔량이 임계값 미만인 경우 구성 요소에서는 [DeferComponentUpdate](ipc-component-lifecycle.md#ipc-operation-defercomponentupdate) IPC 작업이 사용되어 30초 동안 업데이트가 지연됩니다. 그렇지 않으면 배터리 잔량이 임계값 미만이 아닌 경우 구성 요소에서 업데이트가 승인되므로 업데이트가 진행될 수 있습니다.

     ```
     def on_component_update_event(self, event):
         try:
             if event.pre_update_event is not None:
                 if self.is_battery_below_threshold():
                     self.defer_update(event.pre_update_event.deployment_id)
                     print('Deferred update for deployment %s' %
                           event.pre_update_event.deployment_id)
                 else:
                     self.acknowledge_update(
                         event.pre_update_event.deployment_id)
                     print('Acknowledged update for deployment %s' %
                           event.pre_update_event.deployment_id)
             elif event.post_update_event is not None:
                 print('Applied update for deployment')
         except:
             traceback.print_exc()
     ```
**참고**  
 AWS IoT Greengrass 코어 소프트웨어는 로컬 배포에 대한 업데이트 알림을 보내지 않으므로 AWS IoT Greengrass 클라우드 서비스를 사용하여이 구성 요소를 배포하여 테스트합니다.

1. 텍스트 편집기를 사용하여 `recipe.json` 또는 `recipe.yaml`이라는 파일에서 구성 요소 레시피를 생성합니다. 구성 요소 *레시피*에서는 구성 요소의 메타데이터, 기본 구성 파라미터 및 플랫폼별 수명 주기 스크립트가 정의됩니다.

------
#### [ JSON ]

   <a name="nano-command-intro"></a>예를 들어 Linux 기반 시스템에서 다음 명령을 실행하면 GNU nano를 사용하여 파일을 생성할 수 있습니다.

   ```
   nano recipe.json
   ```

   다음 JSON을 파일로 복사합니다.

   ```
   {
     "RecipeFormatVersion": "2020-01-25",
     "ComponentName": "COMPONENT_NAME",
     "ComponentVersion": "COMPONENT_VERSION",
     "ComponentDescription": "This Hello World component defers updates when the battery level is below a threshold.",
     "ComponentPublisher": "COMPONENT_AUTHOR",
     "ComponentConfiguration": {
       "DefaultConfiguration": {
         "BatteryThreshold": 50,
         "LinuxBatteryFilePath": "/home/ggc_user/virtual_battery.json",
         "WindowsBatteryFilePath": "C:\\Users\\ggc_user\\virtual_battery.json"
       }
     },
     "Manifests": [
       {
         "Platform": {
           "os": "linux"
         },
         "Lifecycle": {
           "install": "python3 -m pip install --user awsiotsdk --upgrade",
           "Run": "python3 -u {artifacts:decompressedPath}/com.example.BatteryAwareHelloWorld/main.py \"{configuration:/BatteryThreshold}\" \"{configuration:/LinuxBatteryFilePath}\""
         },
         "Artifacts": [
           {
             "Uri": "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.BatteryAwareHelloWorld.zip",
             "Unarchive": "ZIP"
           }
         ]
       },
       {
         "Platform": {
           "os": "windows"
         },
         "Lifecycle": {
           "install": "py -3 -m pip install --user awsiotsdk --upgrade",
           "Run": "py -3 -u {artifacts:decompressedPath}/com.example.BatteryAwareHelloWorld/main.py \"{configuration:/BatteryThreshold}\" \"{configuration:/WindowsBatteryFilePath}\""
         },
         "Artifacts": [
           {
             "Uri": "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.BatteryAwareHelloWorld.zip",
             "Unarchive": "ZIP"
           }
         ]
       }
     ]
   }
   ```

------
#### [ YAML ]

   <a name="nano-command-intro"></a>예를 들어 Linux 기반 시스템에서 다음 명령을 실행하면 GNU nano를 사용하여 파일을 생성할 수 있습니다.

   ```
   nano recipe.yaml
   ```

   다음 YAML을 파일에 복사합니다.

   ```
   ---
   RecipeFormatVersion: "2020-01-25"
   ComponentName: "COMPONENT_NAME"
   ComponentVersion: "COMPONENT_VERSION"
   ComponentDescription: "This Hello World component defers updates when the battery level is below a threshold."
   ComponentPublisher: "COMPONENT_AUTHOR"
   ComponentConfiguration:
     DefaultConfiguration:
       BatteryThreshold: 50
       LinuxBatteryFilePath: "/home/ggc_user/virtual_battery.json"
       WindowsBatteryFilePath: "C:\\Users\\ggc_user\\virtual_battery.json"
   Manifests:
     - Platform:
         os: linux
       Lifecycle:
         install: python3 -m pip install --user awsiotsdk --upgrade
         Run: python3 -u {artifacts:decompressedPath}/com.example.BatteryAwareHelloWorld/main.py "{configuration:/BatteryThreshold}" "{configuration:/LinuxBatteryFilePath}"
       Artifacts:
         - Uri: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.BatteryAwareHelloWorld.zip"
           Unarchive: ZIP
     - Platform:
         os: windows
       Lifecycle:
         install: py -3 -m pip install --user awsiotsdk --upgrade
         Run: py -3 -u {artifacts:decompressedPath}/com.example.BatteryAwareHelloWorld/main.py "{configuration:/BatteryThreshold}" "{configuration:/WindowsBatteryFilePath}"
       Artifacts:
         - Uri: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/com.example.BatteryAwareHelloWorld.zip"
           Unarchive: ZIP
   ```

------

   이 레시피에서는 다음이 지정됩니다.
   + 배터리 임계값, Linux 코어 디바이스의 가상 배터리 파일 경로 및 Windows 코어 디바이스의 가상 배터리 파일 경로에 대한 기본 구성 파라미터입니다.
   + Python용 AWS IoT Device SDK v2의 최신 버전이 설치되는 `install` 수명 주기입니다.
   + `main.py`에서 Python 애플리케이션 실행되는 `run` 수명 주기입니다.
   + GDK CLI에서 구성 요소 레시피가 빌드될 때 정보가 바뀌는 자리 표시자(예: `COMPONENT_NAME` 및 `COMPONENT_VERSION`)입니다.

   구성 요소 레시피에 대한 자세한 내용은 [AWS IoT Greengrass 구성 요소 레시피 참조](component-recipe-reference.md) 섹션을 참조하세요.

# 3단계: AWS IoT Greengrass 서비스에 구성 요소 게시
<a name="publish-component-defer-updates"></a>

이 단원에서는 Hello World 구성 요소를 AWS IoT Greengrass 클라우드 서비스에 게시합니다. AWS IoT Greengrass 클라우드 서비스에서 구성 요소를 사용할 수 있게 되면 코어 디바이스에 배포할 수 있습니다. GDK CLI를 사용하여 개발 컴퓨터에서 AWS IoT Greengrass 클라우드 서비스로 구성 요소를 게시합니다. GDK CLI는 구성 요소의 레시피와 아티팩트를 업로드합니다.

**Hello World 구성 요소를 AWS IoT Greengrass 서비스에 게시하려면**

1. 다음 명령을 실행하여 GDK CLI를 통해 구성 요소를 빌드합니다. [구성 요소 빌드 명령](greengrass-development-kit-cli-component.md#greengrass-development-kit-cli-component-build)은 GDK CLI 구성 파일을 기반으로 레시피와 아티팩트를 생성합니다. 이 프로세스에서 GDK CLI는 구성 요소의 소스 코드를 포함하는 ZIP 파일을 생성합니다.

   ```
   gdk component build
   ```

   다음 예제와 비슷한 메시지가 표시되어야 합니다.

   ```
   [2022-04-28 11:20:16] INFO - Getting project configuration from gdk-config.json
   [2022-04-28 11:20:16] INFO - Found component recipe file 'recipe.yaml' in the  project directory.
   [2022-04-28 11:20:16] INFO - Building the component 'com.example.BatteryAwareHelloWorld' with the given project configuration.
   [2022-04-28 11:20:16] INFO - Using 'zip' build system to build the component.
   [2022-04-28 11:20:16] WARNING - This component is identified as using 'zip' build system. If this is incorrect, please exit and specify custom build command in the 'gdk-config.json'.
   [2022-04-28 11:20:16] INFO - Zipping source code files of the component.
   [2022-04-28 11:20:16] INFO - Copying over the build artifacts to the greengrass component artifacts build folder.
   [2022-04-28 11:20:16] INFO - Updating artifact URIs in the recipe.
   [2022-04-28 11:20:16] INFO - Creating component recipe in 'C:\Users\finthomp\greengrassv2\com.example.BatteryAwareHelloWorld\greengrass-build\recipes'.
   ```

1. 다음 명령을 실행하여 구성 요소를 AWS IoT Greengrass 클라우드 서비스에 게시합니다. [구성 요소 게시 명령](greengrass-development-kit-cli-component.md#greengrass-development-kit-cli-component-publish)은 구성 요소의 ZIP 파일 아티팩트를 S3 버킷에 업로드합니다. 그런 다음 구성 요소 레시피에서 ZIP 파일의 S3 URI를 업데이트하고 레시피를 AWS IoT Greengrass 서비스에 업로드합니다. 이 프로세스에서 GDK CLI는 AWS IoT Greengrass 클라우드 서비스에서 이미 사용할 수 있는 Hello World 구성 요소의 버전을 확인하므로 해당 버전 이후의 다음 패치 버전을 선택할 수 있습니다. 구성 요소가 아직 없는 경우 GDK CLI는 버전 `1.0.0`을 사용합니다.

   ```
   gdk component publish
   ```

   다음 예제와 비슷한 메시지가 표시되어야 합니다. 출력에서는 GDK CLI가 생성한 구성 요소의 버전을 알려줍니다.

   ```
   [2022-04-28 11:20:29] INFO - Getting project configuration from gdk-config.json
   [2022-04-28 11:20:29] INFO - Found component recipe file 'recipe.yaml' in the  project directory.
   [2022-04-28 11:20:29] INFO - Found credentials in shared credentials file: ~/.aws/credentials
   [2022-04-28 11:20:30] INFO - No private version of the component 'com.example.BatteryAwareHelloWorld' exist in the account. Using '1.0.0' as the next version to create.
   [2022-04-28 11:20:30] INFO - Publishing the component 'com.example.BatteryAwareHelloWorld' with the given project configuration.
   [2022-04-28 11:20:30] INFO - Uploading the component built artifacts to s3 bucket.
   [2022-04-28 11:20:30] INFO - Uploading component artifacts to S3 bucket: greengrass-component-artifacts-us-west-2-123456789012. If this is your first time using this bucket, add the 's3:GetObject' permission to each core device's token exchange role to allow it to download the component artifacts. For more information, see https://docs.aws.amazon.com/greengrass/v2/developerguide/device-service-role.html.
   [2022-04-28 11:20:30] INFO - Not creating an artifacts bucket as it already exists.
   [2022-04-28 11:20:30] INFO - Updating the component recipe com.example.BatteryAwareHelloWorld-1.0.0.
   [2022-04-28 11:20:31] INFO - Creating a new greengrass component com.example.BatteryAwareHelloWorld-1.0.0
   [2022-04-28 11:20:31] INFO - Created private version '1.0.0' of the component in the account.'com.example.BatteryAwareHelloWorld'.
   ```

1. 출력에서 S3 버킷 이름을 복사합니다. 나중에 버킷 이름을 사용하여 코어 디바이스가 이 버킷에서 구성 요소 아티팩트를 다운로드할 수 있도록 합니다.

1. (선택 사항) AWS IoT Greengrass 콘솔에서 구성 요소를 보고 성공적으로 업로드되었는지 확인합니다. 해결 방법:

   1. [AWS IoT Greengrass 콘솔](https://console.aws.amazon.com/greengrass) 탐색 메뉴에서 **구성 요소**를 선택합니다.

   1. **구성 요소** 페이지에서 **내 구성 요소** 탭을 선택한 다음에 **com.example.BatteryAwareHelloWorld**를 선택합니다.

      이 페이지에서 구성 요소의 레시피와 구성 요소에 대한 기타 정보를 볼 수 있습니다.

1. <a name="core-device-allow-s3-bucket-access-console-intro-1"></a>코어 디바이스가 S3 버킷의 구성 요소 아티팩트에 액세스하도록 허용합니다.

   <a name="core-device-allow-s3-bucket-access-console-intro-2"></a>각 코어 디바이스에는 AWS 클라우드와 상호 작용 AWS IoT 하고 로그를 전송할 수 있는 [코어 디바이스 IAM 역할](device-service-role.md)이 있습니다. 이 디바이스 역할은 기본적으로 S3 버킷에 대한 액세스를 허용하지 않으므로 코어 디바이스가 S3 버킷에서 구성 요소 아티팩트를 검색할 수 있도록 허용하는 정책을 생성하고 연결해야 합니다.

   <a name="core-device-allow-s3-bucket-access-console-intro-3"></a>디바이스의 역할이 이미 S3 버킷에 대한 액세스를 허용하는 경우 이 단계를 건너뛸 수 있습니다. 그렇지 않으면 다음과 같이 액세스를 허용하는 IAM 정책을 생성하여 역할에 연결합니다.

   1. <a name="core-device-allow-s3-bucket-access-console-step-1"></a>[IAM 콘솔](https://console.aws.amazon.com/iam) 탐색 메뉴에서 **정책**을 선택한 다음 **정책 생성**을 선택합니다.

   1. **JSON** 탭에서 자리 표시자 콘텐츠를 다음 정책으로 바꿉니다. *greengrass-component-artifacts-us-west-2-123456789012*를 GDK CLI가 구성 요소의 아티팩트를 업로드한 S3 버킷의 이름으로 바꿉니다.

      예를 들어 GDK CLI 구성 파일에서 **greengrass-component-artifacts** 및 **us-west-2**를 지정했고 AWS 계정 ID가 **123456789012**인 경우 GDK CLI는 `greengrass-component-artifacts-us-west-2-123456789012`라는 S3 버킷을 사용합니다.

------
#### [ JSON ]

****  

      ```
      {
        "Version":"2012-10-17",		 	 	 
        "Statement": [
          {
            "Effect": "Allow",
            "Action": [
              "s3:GetObject"
            ],
            "Resource": "arn:aws:s3:::greengrass-component-artifacts-us-west-2-123456789012/*"
          }
        ]
      }
      ```

------

   1. <a name="core-device-allow-s3-bucket-access-console-step-3"></a>**다음**을 선택합니다.

   1. <a name="core-device-allow-s3-bucket-access-console-step-4"></a>**정책 세부 정보** 섹션에서 **이름**에 **MyGreengrassV2ComponentArtifactPolicy**를 입력합니다.

   1. <a name="core-device-allow-s3-bucket-access-console-step-5"></a>**정책 생성**을 선택합니다.

   1. <a name="core-device-allow-s3-bucket-access-console-step-6"></a>[IAM 콘솔](https://console.aws.amazon.com/iam) 탐색 메뉴에서 **역할**을 선택한 다음 코어 디바이스에 대한 역할 이름을 선택합니다. AWS IoT Greengrass 코어 소프트웨어를 설치할 때이 역할 이름을 지정했습니다. 이름을 지정하지 않은 경우 기본값은 `GreengrassV2TokenExchangeRole`입니다.

   1. <a name="core-device-allow-s3-bucket-access-console-step-7"></a>**권한**에서 **권한 추가**, **정책 연결**을 차례로 선택합니다.

   1. <a name="core-device-allow-s3-bucket-access-console-step-8"></a>**권한 추가** 페이지에서 생성한 `MyGreengrassV2ComponentArtifactPolicy` 정책 옆의 확인란을 선택한 다음 **권한 추가**를 선택합니다.

# 4단계: 디바이스에서 구성 요소 배포 및 테스트
<a name="deploy-component-defer-updates"></a>

이 섹션에서는 코어 디바이스에 구성 요소를 배포하여 해당 기능을 테스트합니다. 실제 배터리가 모방되는 가상 배터리 잔량 파일을 코어 디바이스에서 생성합니다. 그런 다음에 코어 디바이스에서 추가 배포를 생성하고 구성 요소 로그 파일을 관찰하여 구성 요소 지연 및 승인 업데이트를 참조합니다.

**업데이트가 지연되는 Hello World 구성 요소를 배포하고 테스트하려면**

1. 텍스트 편집기를 사용하여 가상 배터리 잔량 파일을 생성합니다. 이 파일에서는 실제 배터리가 모방됩니다.
   + Linux 코어 디바이스에서 `/home/ggc_user/virtual_battery.json`이라는 파일을 생성합니다. `sudo` 권한으로 텍스트 편집기를 실행합니다.
   + Windows 코어 디바이스에서 `C:\Users\ggc_user\virtual_battery.json`이라는 파일을 생성합니다. 관리자로 텍스트 편집기를 실행합니다.

   <a name="nano-command-intro"></a>예를 들어 Linux 기반 시스템에서 다음 명령을 실행하면 GNU nano를 사용하여 파일을 생성할 수 있습니다.

   ```
   sudo nano /home/ggc_user/virtual_battery.json
   ```

   다음 JSON을 파일로 복사합니다.

   ```
   {
     "battery_level": 50
   }
   ```

1. Hello World 구성 요소를 코어 디바이스에 배포합니다. 해결 방법:

   1. [AWS IoT Greengrass 콘솔](https://console.aws.amazon.com/greengrass) 탐색 메뉴에서 **구성 요소**를 선택합니다.

   1. **구성 요소** 페이지에서 **내 구성 요소** 탭을 선택한 다음에 **com.example.BatteryAwareHelloWorld**를 선택합니다.

   1. **com.example.BatteryAwareHelloWorld** 페이지에서 **배포**를 선택합니다.

   1. <a name="deploy-component-choose-deployment-step"></a>**배포에 추가**에서 수정할 기존 배포를 선택하거나 새 배포 생성을 선택하고 **다음**을 선택합니다.

   1. <a name="deploy-component-choose-target-step"></a>새 배포 생성을 선택한 경우 배포의 대상 코어 디바이스 또는 사물 그룹을 선택합니다. **대상 지정** 페이지의 **배포 대상**에서 코어 디바이스 또는 사물 그룹을 선택하고 **다음**을 선택합니다.

   1. **구성 요소 선택** 페이지에서 **com.example.BatteryAwareHelloWorld** 구성 요소가 선택되었는지 확인하고 **다음**을 선택합니다.

   1. **구성 요소 구성** 페이지에서 **com.example.BatteryAwareHelloWorld**를 선택하고 다음을 수행합니다.

      1. **구성 요소 구성**을 선택합니다.

      1. **구성 com.example.BatteryAwareHelloWorld** 모달에서 **구성 업데이트** 아래의 **병합할 구성**에 다음 구성 업데이트를 입력합니다.

         ```
         {
           "BatteryThreshold": 70
         }
         ```

      1. **확인**을 선택하여 모달을 닫고 **다음**을 선택합니다.

   1. **고급 설정 확인** 페이지에서 **배포 정책** 섹션의 **구성 요소 업데이트 정책**에서 **구성 요소에 알림**이 선택되었는지 확인합니다. **구성 요소에 알림**은 새 배포를 생성할 때 기본적으로 선택됩니다.

   1. <a name="deploy-component-review-and-deploy-step"></a>**검토** 페이지에서 **배포**를 선택합니다.

      배포를 완료하는 데 최대 1분이 걸릴 수 있습니다.

1.  AWS IoT Greengrass 코어 소프트웨어는 구성 요소 프로세스의 stdout을 `logs` 폴더의 로그 파일에 저장합니다. 다음 명령을 실행하여 Hello World 구성 요소가 실행되고 상태 메시지가 인쇄되는지 확인합니다.

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/com.example.BatteryAwareHelloWorld.log
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   type C:\greengrass\v2\logs\com.example.BatteryAwareHelloWorld.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2\logs\com.example.BatteryAwareHelloWorld.log -Tail 10 -Wait
   ```

------

   다음 예제와 비슷한 메시지가 표시되어야 합니다.

   ```
   Hello, World! Battery level (50) is below threshold (70), so the component will defer updates.
   ```
**참고**  
파일이 없으면 배포가 아직 완료되지 않았을 수 있습니다. 30초 이내에 파일이 존재하지 않으면 배포에 실패했을 수 있습니다. 예를 들어, S3 버킷에서 구성 요소의 아티팩트를 다운로드할 권한이 코어 디바이스에 없으면 이 문제가 발생할 수 있습니다. 다음 명령을 실행하여 AWS IoT Greengrass 코어 소프트웨어 로그 파일을 확인합니다. 이 파일에는 Greengrass 코어 디바이스의 배포 서비스의 로그가 포함되어 있습니다.  

   ```
   sudo tail -f /greengrass/v2/logs/greengrass.log
   ```

   ```
   type C:\greengrass\v2\logs\greengrass.log
   ```
<a name="windows-cmd-type-observe-logs"></a>`type` 명령에서는 파일의 내용이 터미널이 기록됩니다. 이 명령을 여러 번 실행하여 파일의 변경 사항을 관찰합니다.

   ```
   gc C:\greengrass\v2\logs\greengrass.log -Tail 10 -Wait
   ```

1. 코어 디바이스에 대한 새 배포를 생성하여 구성 요소에서 업데이트가 지연되는지 확인합니다. 해결 방법:

   1. [AWS IoT Greengrass 콘솔](https://console.aws.amazon.com/greengrass) 탐색 메뉴에서 **배포**를 선택합니다.

   1. 이전에 생성하거나 수정한 배포를 선택합니다.

   1. 배포 페이지에서 **수정**을 선택합니다.

   1. **배포 수정** 모달에서 **배포 수정**을 선택합니다.

   1. 각 단계에서 **다음**을 선택한 다음에 **배포**를 선택합니다.

1. 다음 명령을 실행하여 구성 요소의 로그를 다시 보고 업데이트가 지연되는지 확인합니다.

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/com.example.BatteryAwareHelloWorld.log
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   type C:\greengrass\v2\logs\com.example.BatteryAwareHelloWorld.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2\logs\com.example.BatteryAwareHelloWorld.log -Tail 10 -Wait
   ```

------

   다음 예제와 비슷한 메시지가 표시되어야 합니다. 구성 요소에서는 업데이트가 30초 동안 지연되므로 이 메시지가 구성 요소에서 반복적으로 인쇄됩니다.

   ```
   Deferred update for deployment 50722a95-a05f-4e2a-9414-da80103269aa.
   ```

1. 배포가 진행될 수 있도록 텍스트 편집기를 사용하여 가상 배터리 잔량 파일을 편집하고 배터리 잔량을 임계값보다 높은 값으로 변경합니다.
   + Linux 코어 디바이스에서 `/home/ggc_user/virtual_battery.json`이라는 파일을 편집합니다. `sudo` 권한으로 텍스트 편집기를 실행합니다.
   + Windows 코어 디바이스에서 `C:\Users\ggc_user\virtual_battery.json`이라는 파일을 편집합니다. 관리자로 텍스트 편집기를 실행합니다.

   <a name="nano-command-intro"></a>예를 들어 Linux 기반 시스템에서 다음 명령을 실행하면 GNU nano를 사용하여 파일을 생성할 수 있습니다.

   ```
   sudo nano /home/ggc_user/virtual_battery.json
   ```

   배터리 잔량을 `80`으로 변경합니다.

   ```
   {
     "battery_level": 80
   }
   ```

1. 다음 명령을 실행하여 구성 요소의 로그를 다시 보고 업데이트가 승인되는지 확인합니다.

------
#### [ Linux or Unix ]

   ```
   sudo tail -f /greengrass/v2/logs/com.example.BatteryAwareHelloWorld.log
   ```

------
#### [ Windows Command Prompt (CMD) ]

   ```
   type C:\greengrass\v2\logs\com.example.BatteryAwareHelloWorld.log
   ```

------
#### [ PowerShell ]

   ```
   gc C:\greengrass\v2\logs\com.example.BatteryAwareHelloWorld.log -Tail 10 -Wait
   ```

------

   다음 예제와 비슷한 메시지가 표시되어야 합니다.

   ```
   Hello, World! Battery level (80) is above threshold (70), so the component will acknowledge updates.
   Acknowledged update for deployment f9499eb2-4a40-40a7-86c1-c89887d859f1.
   ```

이 자습서를 완료했습니다. Hello World 구성 요소에서는 코어 디바이스의 배터리 잔량에 따라 업데이트가 지연되거나 승인됩니다. 이 자습서에서 살펴보는 주제에 대한 자세한 내용은 다음을 참조하세요.
+ [AWS IoT Greengrass 구성 요소 개발](develop-greengrass-components.md)
+ [디바이스에 AWS IoT Greengrass 구성 요소 배포](manage-deployments.md)
+ [AWS IoT Device SDK 를 사용하여 Greengrass nucleus, 기타 구성 요소 및 AWS IoT CoreGreengrass nucleus, 기타 구성 요소 및와 통신 AWS IoT Core](interprocess-communication.md)
+ [AWS IoT Greengrass 개발 키트 명령줄 인터페이스](greengrass-development-kit-cli.md)