GCP用NEQTO CloudSync
はじめに

NEQTO CloudSyncとは、お客様のNEQTO とGCP環境のデバイスを簡単に同期できるツールです。CloudSyncとNEQTO GCPライブラリ を利用することで、簡単にGCPにIoTデータを送ることができます。
NEQTO CloudSyncはコンテナとしてGCP Marketplaceで配布されています。無料で配布されており、GKE、Compute Instancers、GAE フレキシブル環境上で利用することができます。GAE (Google App Engine) フレキシブル環境上にカスタムランタイム環境でのデプロイを推奨しております。
前提条件
GAE フレキシブル環境 (Custom Runtime)にデプロイ
このチュートリアルでは、Cloud Shell を使用して、CloudSync を App Engine にデプロイします。
はじめに、アプリケーションのzipファイルをCloud Shellにcurl
コマンドでダウンロードします。その後、unzip
コマンドでzipファイルを解凍しアプリケーションのフォルダに移動します。
curl https://download.neqto.com/cloudsync/nqcloudsync-dist-gcp.zip -o nqcloudsync-dist-gcp.zip
unzip nqcloudsync-dist-gcp.zip
cd nqcloudsync-dist-gcp
ディレクトリには2つのファイルがあります。一つ目のファイルは app.yaml
です。これは環境変数に加えて、アプリケーションの実行方法をApp Engineに指示する設定ファイルです。env_variables
セクションをお客様の環境に合わせて編集を行ってください。
注意:
runtime
とenv
は、変更を行わないでください。
runtime: custom
env: flex
env_variables:
COMPANY_CODE: "COMPANYCODEHERE"
NQ_REGION: "NEQTOREGIONHERE"
PROJECT_ID: "GCPPPROJECTIDHERE"
REGISTRY_ID: "REGISTRYID"
CLOUD_REGION: "GCPREGIONHERE"
Key | Value |
---|---|
COMPANY_CODE | NEQTO でログインする際の企業コード。 |
NQ_REGION | 同期対象のNEQTO のリージョンです。(例: asia-pacific-1) |
PROJECT_ID | 同期対象のGCP環境のプロジェクトID。 |
REGISTRY_ID | GCP IoT Coreに同期するRegitry IDです。 |
CLOUD_REGION | GCP IoT Coreの使っているリージョンです。 |
2つ目のファイルは Dockerfile
です。このファイルは、App EngineにCloudSyncのイメージを取得するための場所を指示しています。このファイルはお客様で編集する必要はありません。
FROM marketplace.gcr.io/cloudsync-public/cloudsync
環境変数を設定後、アプリケーションをデプロイします。
gcloud app deploy
あらかじめプロジェクトやApp Engineの環境を設定する必要がります。また、このリリースの詳細が正しいかどうかを確認するために、プロンプトを経由で(Y)を入力し認証を求められる場合があります。
注意: このデプロイ時点でのアプリはインターネット上の誰でもアクセス可能であることに注意してください。
このアプリはGoogle APIとプログラム的に相互作用するため、アクセス権の管理を適切に行うことをお勧めします。これらのセキュリティを有効にする方法ついては、次のセクションをご参照ください。
セキュリティ
Webアプリを保護するために、Google CloudのIdentity Aware Proxy (IAP)を使用します。これによりCloudSyncを利用する上で、Google Cloud Consoleへのログインし、アクセス権を与えられたユーザーであるかを要求できるようになります。
まず、Google Cloudにログインし、使用しているプロジェクトを選択します。次に、検索で「Identity-Aware Proxy」を検索します。
アプリケーションのリストで、App Engine インスタンスを見つけ、IAP のトグルをオンの位置にスライドさせます。
最後に、目的のアプリインスタンスにチェックを入れ、右のパネルで「Add Member」をクリックします。
メンバーのGoogleアカウントに関連するメールアドレスを入力し、ロールの選択をクリックします。「Cloud IAP」オプションを選択し、「IAP-Secured Web App User」オプションを選択し、変更内容を保存します。
プライベートブラウザでアプリに再度アクセスすると、ログインを促すプロンプトが表示されます。明示的にアクセスを許可されていないアカウントにログインするとロックされ、メンバーとして追加したアカウントにログインすると、アプリにアクセスできるようになります。
これで準備は完了です。
使い方
GAEデプロイ後は、App Engineが提供するURLからアクセスすることができます。そのURLにアクセスすると、ログイン画面が表示されます。
CloudSyncを利用する上で、まずはログインが必要です。
注意: 会社コードはインストール時に環境変数として設定されているため、ここでは入力しません。
ログイン後、NEQTO で作成したグループがすべて表示されます。
リスト内のグループをクリックすると、ノードリスト画面に移動します。
ノードは、GCPとNEQTO の両方に存在する場合に同期されます。クラウドはGCP IoT Coreと通信するために必要な環境変数をすべて持っています。
ノード一覧の「同期」欄には、3つのアイコンのいずれかが表示され、ステータスが表示されます。
現在同期中のノードには同期アイコンが表示されます。
同期されていないノードには同期されていないアイコンが表示されます。
GCPにのみ存在するノード、またはNEQTO にのみ存在するノードは、ノードの同期が失敗している可能性があります。
詳細を確認するには、リストの右側の行の情報アイコンをクリックしてください。
どの環境で同期が取れなくなったか等、ノードの様々な情報を確認することができます。
同期が取れなくなったノードを修正するには、まず目的のノードを選択して「同期を解除」します。右上の「非同期」ボタンをクリックすると、デバイスの同期が解除されます。
デバイスの同期を解除すると、Google Cloudからデバイスが削除され、NEQTO Consoleから同期時に作成されたGCP環境変数が削除されます。
デバイスを再度同期したり、新しいデバイスを同期したりするには、すべてを選択してから「同期」アイコンをクリックします。
syncをクリックすると、GCP APIを呼び出してデバイスを登録し、プロビジョニングが行われます。その後、秘密鍵とその他の必要な情報を取得し、それをNEQTO のノードの環境変数に保存します。
作成された環境変数は以下の通りです。
キー | 値 |
---|---|
gcp_cloud_sync_key | GCP IoT Coreに接続するために必要な秘密鍵。 |
gcp_registry_id | GCP IoT Core レジストリの ID です。 |
gcp_project_id | 同期するGCPプロジェクトのIDです。 |
gcp_region_id | レジストリのリージョンです。 |
gcp_device_id | GCPのデバイスID。これは、「nq_」とNEQTO ノードUUIDを連結したものです。 |
これらの環境変数はNEQTO GCP Libraryを通して取得し、GCP IoT Coreへのデータ送信を開始することができます。
Sample Script
// Ref: GCP IoT Core Library documentation
var gcpIotCa = "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----\n";
var params = {
privateKey: ENV["gcp_cloud_sync_key"],
project: ENV["gcp_project_id"],
location: ENV["gcp_region_id"],
registry: ENV["gcp_registry_id"],
device: ENV["gcp_device_id"],
};
var iot_core = new GOOGLE_IOT_CORE(params);
iot_core.setRootCa(gcpIotCa);
var host = iot.buildGrpcUrl();
var payload = secure.base64Encode("Publishing via HTTP");
var callback = function(err, resp) {
if (err) {
print(JSON.stringify(err));
}
if (resp) {
print(JSON.stringify(resp));
}
}
var body = {
"binary_data": payload
}
var jwt = iot.makeDeviceJWT(3600); //update JWT each connection. 3600 == 1 hour.
iot.httpPost(jwt, `${host}:publishEvent`, JSON.stringify(body), callback);