Amazon Web Services ブログ

AWS IoT Greengrass V2 コンポーネントのワークフローを自動化する

この記事は Automating workflows for AWS IoT Greengrass V2 components を翻訳したものです。

はじめに

AWS re:Invent 2021 で AWS IoT Greengrass V2 Development Kit Command-Line Interface (GDK CLI) が発表されました。GDK CLI を使うと、AWS IoT Greengrass V2 コンポーネントを簡単に作成し、柔軟にレシピを定義し、そのコンポーネントを AWS IoT Greengrass V2 にパブリッシュすることができます。しかし、AWS Greengrass V2 コンポーネントのレシピに変更があるたびに、通常、手動でプロビジョニングする必要があります。例えば、コンポーネントの新バージョンが出るたびに再ビルドして再パブリッシュする必要があり、冗長な作業となります。さらに、コンポーネントが自動化されたワークフローの一部である場合、再ビルドと再パブリッシュのタスクは、開発作業全体にとって不便なものになります。

これらの課題を克服するために、AWS CodeCommit および AWS CodeBuild とともに AWS CodePipeline を使用して自動化されたワークフローを作成することができます。自動化されたワークフローは、ソースへの新しい変更が検出されるたびに、コンポーネントをビルドしてパブリッシュします。このブログで紹介するソリューションは、例を使ってこのワークフローを説明しています。

以下の画像は、自動化されたワークフローで使用される AWS サービスの概要です。AWS CodeCommit は GitHub や GitLab のような他の Git リポジトリに置き換えることができ、最終的には AWS CodeCommit リポジトリにミラーリングすることができます。

1. 始め方

このセクションでは、使用するさまざまなサービスに対する AWS Identity and Access Management (IAM) ポリシー のセットアップなどの基本的な要件について説明します。IAM ポリシーは、リソースに付与されるアクセス権を定義します。例えば、AWS CodeBuild はコンポーネントをパブリッシュするために、AWS IoT Greengrass V2 への読み取り/書き込みアクセス権を持っている必要があります。

前提条件

以下は、ビルドソリューションを進めるための要件です。

1.1 AWS CodePipeline

AWS CodePipeline は、継続的デリバリーサービスの作成と管理に使用されます。AWS CodeCommit のログにアクセスすることで、プロセスの管理に利用することができます。AWS CodeCommit にプッシュされた変更をもとに、AWS CodeBuild を実行するパイプラインが起動し、指定されたビルドコマンドが実行されます。ビルドアーティファクトを保存するためには、Amazon S3 へのアクセスを IAM ポリシーで指定する必要があります。

IAMポリシー:

1.2 AWS CodeCommit

AWS CodeCommit は、Git リポジトリをホストするために使用されるソースコード管理サービスです。これは、以下のようにいくつかの異なる方法で実現することができます。

  1. AWS CodeCommit に直接 Git リポジトリを作成する – IAM ポリシーへの追加要件はありません。
  2. GitLab や GitHub にある Git リポジトリを AWS CodeCommit にミラーリングする – AWS CodeCommit にミラーリングするために GitLab や GitHub のリポジトリを設定するか、Git リポジトリを AWS CodeCommit に移行する必要があります。

1.3 AWS CodeBuild

AWS CodeBuild は AWS CodeCommit にソースを格納してプロジェクトをビルドするため、git pull を実施するために AWS CodeCommit にアクセスできるようデフォルトの IAM ポリシーを設定する必要があります。さらに、ビルドアーティファクトを保存するために Amazon S3 へのアクセスも必要です。これはオプションですが、将来のアクセスのためにアーティファクトを保存しておくとよいでしょう。AWS IoT Greengrass V2 コンポーネントをビルドしてパブリッシュするには、コンポーネントのリストと作成のためのパーミッションを追加する必要があります。

IAMポリシー:

1.4 AWS IoT Greengrass V2

コンポーネントをビルドして AWS IoT Greengrass V2 にパブリッシュすると、AWS IoT Greengrass V2 のコンソールまたは CLI からコンポーネントにアクセスすることができるようになります。AWS IoT Greengrass V2 デプロイは、適切なコンポーネントがパブリッシュされ、利用可能になれば、必要に応じて行うことができます。

2. ソースとビルドの管理

GDK でコンポーネントをビルドして公開するには、Python と Bash スクリプトを使用することができます。このセクションでは、GDK の Python サンプルを使用して、コンポーネントのビルドとパブリッシュを実現する方法を紹介します。

2.1 GDK

ステップ2.1.1: GDK の Python サンプルの使用

Python コンポーネントの場合、GDK を使用して基本的なサンプルを作成します。このコマンドでは、以下のファイルが作成されます。

- README.md - 標準的な Readme ファイル 
- gdk-config.json - GDK のビルドパラメータを定義するために使用 
- recipe.yaml - コンポーネントの実行プロセスおよび関連するパラメータを定義するために使用 
- main.py - コンポーネントがデプロイされたときに実行される Python スクリプトの例 
- src/ - main.py のサポートスクリプトのディレクトリ 
- tests/ - テストスクリプトのディレクトリ

Pythonベースのデフォルトコンポーネントを作成するためのコマンド:

$ mkdir HelloWorldPython
$ cd HelloWorldPython/
$ gdk component init -l python -t HelloWorld

ステップ2.1.2: GDK の Python サンプルの修正

次に、デフォルトの main.py スクリプトと src/greeter.py スクリプトを以下のように修正します。run.sh の bash スクリプトのサンプルも追加してください。現在、サンプルとして、GDK は Python と Java をサポートしています。しかし、バイナリや Bash スクリプト、その他のターミナル / CMD コマンドを実行する必要があるアプリケーションでは、run.sh Bashスクリプトを使用することができます。したがって、main.py Python スクリプトを直接実行する代わりに、run.sh Bash スクリプトを使用して実行することができます。

以下は、変更した main.py スクリプトの例です。

import sys
import src.greeter as greeter

def main():
    args = sys.argv[1:]
    if len(args) == 2:
        print(greeter.get_greeting(args[0], args[1]))

if __name__ == "__main__":
    main()

これは、変更した src/greeter.py スクリプトの例です。

def get_greeting(msg1, msg2):
   """
   Returns greeting string

   Parameters
   ----------
       msg1(string): msg1 to append in the greeting.
       msg2(string): msg2 to append in the greeting.

   Returns
   -------
       string : Returns greeting for the name
   """

   print('The message is {} and {}!'.format(msg1, msg2))
   return '{} {}!'.format(msg1, msg2)

以下は、run.sh スクリプトの内容の例です。

#!/bin/bash

print_usage() { printf "Usage: run.sh -a message1 -b message2" }

while getopts a:b: flag; do
    case "${flag}" in
        a) message1=${OPTARG} ;;
        b) message2=${OPTARG} ;;
        *) print_usage
            exit 1 ;;
    esac
done

echo "Message #1 = $message1"
echo "Message #2 = $message2"

echo "Running main.py script ..."
python3 -u main.py $message1 $message2

これは、更新された gdk-config.json ファイルの内容の例です。

{
  "component": {
    "com.example.HelloWorldPython": {
      "author": "<PLACEHOLDER_AUTHOR>",
      "version": "0.0.1",
      "build": {
        "build_system": "zip"
      },
      "publish": {
        "bucket": "<PLACEHOLDER FOR BUCKET>",
        "region": "<PLACEHOLDER FOR REGION>"
      }
    }
  },
  "gdk_version": "1.0.0"
}

これは、更新された recipe.yaml ファイルの内容の例です。

---
RecipeFormatVersion: "2020-01-25"
ComponentName: "{COMPONENT_NAME}"
ComponentVersion: "0.0.1"
ComponentDescription: "This is simple Hello World component written in Python."
ComponentPublisher: "{COMPONENT_AUTHOR}"
ComponentConfiguration:
  DefaultConfiguration:
    configMessage1: "Hello"
    configMessage2: "World"
Manifests:
  - Platform:
      os: all
    Artifacts:
      - URI: "s3://BUCKET_NAME/COMPONENT_NAME/COMPONENT_VERSION/HelloWorldPythonComponent.zip"
        Unarchive: ZIP
    Lifecycle:
      Run: "/bin/bash {artifacts:decompressedPath}/HelloWorldPythonComponent/run.sh -a {configuration:/configMessage1} -b {configuration:/configMessage2}

AWS CodeBuild がプリビルド、ビルド、ポストビルド処理のコマンドを実行するために使用される buildspec.yml ファイルを追加します。以下は、必要なコマンドを含む buildspec.yml ファイルの例です。

version: 0.2

phases:
  install:
    commands:
      - apt-get update && apt-get install -y zip unzip build-essential wget git curl software-properties-common python3.7 python3-pip
      - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && unzip awscliv2.zip && ./aws/install && rm awscliv2.zip
  build:
    commands:
      - python3 -m pip install -U git+https://github.com/aws-greengrass/aws-greengrass-gdk-cli.git@v1.1.0
      - export PATH=$PATH:~/.local/bin
      - CURRDIR=$(basename "$PWD")
      - cd ../ && mv $CURRDIR HelloWorldPythonComponent && cd HelloWorldPythonComponent
      - gdk component build
      - gdk component publish
      - mkdir package && cp -r greengrass-build package/. && cp -r zip-build package/.
      - pwd && ls -al && ls -al ..
artifacts:
  files:
    - package/**/*
  name: gg-component-$(date +%Y-%m-%d-%H-%M-%S).zip

2.2 AWS CodeCommit

AWS CodeCommit のリポジトリを作成するには、デベロッパー用ツールから、CodeCommit、リポジトリを作成を選択します。リポジトリ名やタグなどの詳細を入力するプロンプトが表示されます。リポジトリが作成されると、あらかじめ作成されたコードをプッシュすることができます。

次の画像は、GDK CLI コンポーネントのビルドとパブリッシュコマンドに必要なファイルを含む AWS CodeCommit リポジトリの例を示しています。これには、修正したスクリプト、すなわち run.sh, main.py, src/greeter.py, recipe.yaml, gdk-config.json および buildspec.yml も含まれています。

2.3 AWS CodeBuild

次に、上記の AWS CodeCommit リポジトリをソースとして、buildspec.yml ファイルで提供されるビルドコマンドを使用してビルド処理を実行するよう AWS CodeBuild を設定します。そのために、デベロッパー用ツールから CodeBuild を選択し、プロジェクトを作成します。AWS CodeBuild をセットアップする手順は以下の通りです。

ステップ2.3.1: ビルド環境の設定

AWS CodeBuild のビルド環境を設定するには、Ubuntu 18.04 の Amazon Elastic Container Registry (ECR) サービス: public.ecr.aws/ubuntu/ubuntu:18.04 を使用します。以下は、ビルド環境の設定方法です。

ステップ2.3.2: ビルド用のソースを選択する

ソースは AWS CodeCommit リポジトリを接続し、正しい Branch/Tag/Commit ID を指定します。この例では、master ブランチに接続されます。あらかじめプロビジョニングした IAM ポリシーを選択します。

ステップ2.3.3: ビルドを実行するコマンドを選択する

次に、実際のビルドを実行するためのコマンドを使用するビルド仕様を定義します。このビルド仕様は、ソースの一部である buildspec.yml に定義されています。したがって、ここでファイル名を指定する必要があります。buildspec.yml ファイルを使用しない場合は、オプションでビルドコマンドをここに追加することができます。

ステップ2.3.4: ビルドのアーティファクトを保存する

ビルドアーティファクトを保存するために、適切な Amazon S3 バケットを指定します。Amazon S3 のロケーションに圧縮されたパッケージでビルドアーティファクトを保存するために、オプションとして zip を選択します。

2.4 パイプラインの作成

アーティファクトの管理、GDK のビルド、および変更のパブリッシュのために、ビルドパイプラインを作成し、ビルドプロセスを自動化することができます。

ステップ2.4.1: パイプラインの設定を選択する

デベロッパー用ツールから、CodePipeline を選択し、新しいパイプラインを作成します。サービスロールについては、あらかじめ定義されたロールを選択します。

ステップ2.4.2: ソースステージの追加

次に、先ほど作成した AWS CodeCommit のリポジトリとブランチを選択します。このセクションで Amazon CloudWatch Events を選択すると、ここで設定した AWS CodeCommit リポジトリに対して Amazon CloudWatch Events で何らかの変更を検出した場合に Pipeline が開始されるトリガーとなります。

ステップ2.4.3: ビルドステージの追加

AWS CodeCommit の変更からビルドを開始するために、このステージに AWS CodeBuild Project を接続します。

ステップ2.4.4: デプロイステージの追加

AWS CodeDeploy とパイプラインを接続する場合、このセクションを使用してその部分を追加します。AWS CodeDeploy のステージはここでは説明しないのでスキップしてください。

ステップ2.4.5: パイプラインのレビュー

すべてのピースが接続されたので、パイプラインを作成できます。Amazon CloudWatch Events からパイプラインが呼び出されると、ビルドが開始されます。以下の画像は、AWS CodePipeline で定義されているフローです。ここでは、ソースからビルドに接続されています。したがって、パイプラインはまずソースからプルし、次に AWS CodeBuild buildspec.yml に記載されているビルドコマンドを実行します。

3. コンポーネントのデプロイ

3.1 AWS CodePipeline のログを確認する

  • AWS CodePipeline が正常に実行されると、コンポーネントがビルドされパブリッシュされます。
  • ログを確認するには、AWS CodeBuild のプロジェクトに移動し、ビルド履歴からビルドログを選択します。
  • ログを確認すると、コンポーネントが Amazon S3 バケットに格納され、AWS IoT Greengrass V2 コンポーネントにパブリッシュされていることが確認できます。

3.2 AWS IoT Greengrass V2で のコンポーネントの確認

  • AWS IoT Greengrass V2 でコンポーネントが利用可能になると、IoT Things にデプロイすることができるようになります。更新されたコンポーネントを使用して既存のデプロイメントを修正するか、IoT Thing または Thing グループ用に新しいデプロイメントを作成することによって、これを行うことができます。
  • AWS IoT Greengrass V2 コンソールでコンポーネントを確認すると、「デフォルト設定」、「ライフサイクル」の詳細、Amazon S3 バケットの「アーティファクト」の場所などの詳細が確認できますが、これらはすべて recipe.yaml スクリプトに基づくものです。

4. クリーンアップ

AWS CodePipeline は Amazon CloudWatch Events をリッスンするように設定されているので、AWS CodeCommit リポジトリへの小さな更新があるたびにパイプラインが起動し、コンポーネントのビルドとパブリッシュが行われます。したがって、実行を停止を選択することでパイプラインを停止することができます。

これにより、Amazon S3 内のコンポーネントアーティファクトだけでなく、ビルドアーティファクトも更新されなくなります。

5. まとめ

AWS IoT Greengrass V2 サービスは、通常、コンポーネントのデプロイメントが特定のイベントに基づいてプロビジョニングされる自動化されたフレームワークで使用されています。GDK CLI は、Python/Java/Bash を使用して AWS IoT Greengrass V2 コンポーネントを作成するための、より柔軟な手助けをします。しかし、コンポーネントに変更があるたびに手動でビルドとパブリッシュタスクをプロビジョニングするのではなく、自動化が理想的でしょう。このビルドソリューションは、AWS CodePipeline を使用して AWS IoT Greengrass V2 コンポーネントをビルド/パブリッシュすることに注目し、開発工数だけでなく手動の工程も削減します。さらに、継続的インテグレーションと継続的デプロイメント(CI/CD) のために、バージョニングは、このビルドソリューションによって簡素化し、自動化することができるための重要な側面です。

AWS IoT Greengrass V2 についての詳細は、ドキュメント開発ツールをご覧ください。自動化されたワークフローを始めるには、ブログをご覧ください。

著者について


Romil Shah は、AWS プロフェッショナルサービスの IoT Edge データサイエンティストです。コンピュータービジョン、機械学習、IoT エッジデバイスの分野で6年以上の業界経験があります。エッジデバイスのための機械学習モデルの最適化とデプロイの支援に携わっています。

Fabian Benitez-Quiroz は AWS プロフェッショナルサービスの IoT エッジデータサイエンティストです。オハイオ州立大学にてコンピュータビジョンとパターン認識の博士号を取得しました。IoT デバイス上で低レイテンシーで機械学習モデルを実行するお客様の支援に携わっています。

この記事はソリューションアーキテクトの三平が翻訳しました。