【新機能】SIMからAWSサービスにデータを自由に振り分ける「SORACOM Funnel」が登場 #soracom

2016.01.27

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは、せーのです。
今日は今やSIMの世界の有名人になったSORACOMのできたてほやほやの新機能「SORACOM Funnel」をご紹介します。
こちらを使うとデバイスはデータをとりあえずSORACOMに投げておけばSORACOM側でどのクラウドに投げるかを設定することができます。



検証はベータ版なので公開時点と仕様が異なる場合があります

デバイスは何も考えない

通常IoTでデータのアップロードを実装する時は、当たり前ですがデータの投げ先であるクラウドのエンドポイントをコード上で指定し、API KeyやSecret Keyをデバイス内に保存して、それを使ってクラウドとやり取りします。
今回の「SORACOM Fuunel」の面白いところは、デバイスが認識しているターゲットはSORACOMになります。 SORACOMの中で受け取ったデータをどこに投げるかを設定することでデータがダイレクトにそのリソースに投げられる、というところです。

つまり、API KeyやSecret KeyはSORACOMの中に保存されていて、認証もSORACOMとクラウドの間で行われることになります。デバイスはSORACOMにデータを投げた時点で役割は終了で、どの認証キーを使ってどのクラウドに投げるか、は一切考えなくて良くなります。

soracom_funnel0

構成図としてはこのようになります。この図にも書いているように色々な「アダプタ」がSORACOMの中にあって、それを付け替えることで色々なクラウドリソースにデータの流れを変えられる、というイメージです。

対応サービス

現在使える「アダプタ」は

  • Amazon Kinesis Stream
  • Amazon Kinesis Firehose
  • Microsoft Azure Event Hubs

の3種類になります。

対応プロトコル

現在デバイスからSORACOM Funnelに投げられるデータのプロトコルは

  • TCP
  • UDP
  • HTTP

となります。今後対応プロトコルが増えるといいですね。ちなみにHTTPで投げる場合、フォーマットは今のところJSONに限られるそうなので気をつけましょう。

SORACOM Beamとの違い

デバイスがSORACOMに対してデータを投げ、SORACOMがデータをフックしてクラウドを指定する、という機能は「SORACOM Beam」というものが今までありました。これとはどうちがうのでしょう。

SORACOM Beamはエンドポイントやプロトコル等をわりと自由に、汎用的なもので決められる一方、エンドポイントの不整合を防ぐためのコーディング等、クラウド側の制約に合わせてデバイス側のコーディングをする必要がありました。SORACOM Funnelはアダプタ、という形でどのサービスに投げるかが決まっていますので、デバイス側はコーディングに関しては特にクラウドに対する配慮が要らなくなります。

やってみた

ではやってみましょう。今回はKinesis Firehoseを使ってS3にデータをなげてみます。
手順は以下のようになります。

soracomFunnel

  • AWSのリソースを作る
  • SoracomのCredentials Storeに認証情報をアップロードする
  • Soracom Groupを作り、Credentials情報とつなげる
  • Soracom AirSIMにGroupを設定する

それではやってみましょう。

Kinesis Firehose, S3の作成

まずはKinesis Firehoseのストリームを作ります。マネージメントコンソールよりKinesisを開き、新しいFirehoseのストリームを作ります。

soracom_funnel6

対象となるS3のバケットもここで作っておきます。

soracom_funnel5

IAMユーザの作成

次に認証用のIAMユーザを作成します。このユーザーはKinesisに対するPut権限だけもたせます。

soracom_funnel2

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1452092255000",
            "Effect": "Allow",
            "Action": [
                "kinesis:PutRecord",
                "kinesis:PutRecords"
            ],
            "Resource": [
                "arn:aws:kinesis:*:000000000000:stream/my-kinesis-stream"
       ] 
        },
        {
            "Sid": "Stmt1452101987000",
            "Effect": "Allow",
            "Action": [
                "firehose:PutRecord"
            ],
            "Resource": [
              "arn:aws:firehose:*:000000000000:deliverystream/my-kinesis-firehose"
       ] 
    }
  ]
}

※例としてkinesis streamとkinesis firehose両方のIAM Policyを乗せています。実際は使う方だけで良いです。

ユーザーを作成したらAPI Key、Secret Keyを含むCredentialsファイルをダウンロードし、中に書いてあるキーを使ってこのようなJSONファイルを作成します。

my-aws-credentials.json

{
 "type": "aws-credentials",
 "credentials": {
 "accessKeyId": "XXXXXXXXXXXXXXXXXXXXXX",
 "secretAccessKey": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
 },
 "description": "Kinesis Put only"
}

SORACOM GROUPの作成

次にSORACOMの設定を行います。SORACOMコンソールからGROUPナビをクリックして新しいGROUPを作成します。

soracom_funnel3

GROUPを作ったらIDをコピーしておきましょう。

soracom_funnel4

Credentialsストアの作成

先程作ったIAMユーザーの権限をSORACOMのCredentialsストアに登録します。ここらへんの操作はSORACOM CLIにて行います。

$ soracom credentials create-credentials --credentials-id=my-aws-credentials --
credentials-body=file://my-aws-credentials.json

レスポンスはこんな感じです。

{
 "description": "Kinesis Put only",
 "type": "aws-credentials",
 "credentials": {
 "accessKeyId": "XXXXXXXXXXXXXXXXXXXXX"
 },
 "credentialsId": "my-aws-credentials",
 "createDateTime": 1234567890,
 "updateDateTime": 1234567890,
 "lastUsedDateTime": null
}

GROUPにCredentialsを設定

次に作ったGROUPに上で作ったCredentialsを設定します。まずは投げ先のfirehoseを表すARNとcredentialsIDの関係を記したJSONを記述します。

kinesis_firehose.json

{
  "destination": {
    "provider": "aws",
    "service": "firehose",
    "resourceUrl": "https://firehose.us-east-1.amazonaws.com/my-kinesis-firehose"
  },
  "credentialsId": "my-aws-credentials",
  "enabled": true
}

次にそのJSONを使ってGROUPの設定を変更します。

$ soracom group update-configuration --group-id XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX --namespace SoracomFunnel --params file://kinesis_firehose.json | jq .configuration.SoracomFunnel

SIMをGROUPに割り当てる

最後にGROUPをSIMに割り当てます。これはSORACOMコンソールを使ってみましょう。

soracom_funnel7

soracom_funnel8

テスト

ではテストしてみます。SORACOMのSIMを使ったネットワークからSORACOM Funnelに向けてメッセージを投げてみましょう。

TCP

$ nc funnel.soracom.io 23081
Hello SORACOM Funnel via TCP![Enter]
200

UDP

$ nc -u funnel.soracom.io 23081
Hello SORACOM Funnel via UDP!
200

HTTP

$  curl -vX POST http://funnel.soracom.io -d '{"message":"Hello SORACOM Funnel via
HTTP!"}' -H Content-Type:application/json
* Rebuilt URL to: http://funnel.soracom.io/
*   Trying 100.127.65.43...
* Connected to funnel.soracom.io (100.127.65.43) port 80 (#0)
> POST / HTTP/1.1
> Host: funnel.soracom.io
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Type:application/json
> Content-Length: 44
>
* upload completely sent off: 44 out of 44 bytes
< HTTP/1.1 204 No Content
< Date: Mon, 25 Jan 2016 04:39:20 GMT
< Connection: keep-alive
<
* Connection #0 to host funnel.soracom.io left intact

無事デバイスからメッセージが飛びました。本当にAWSのAの字も書かなくていいんですね。データがクラウドに届いたかどうかS3をみてみましょう。

soracom_funnel9

おおー届きました!中身をみてみます。

{"operatorId": "XXXXXXXXXXXXX", "timestamp": 1453696760830, "destination": {"resourceUrl": "https://firehose.us-east-1.amazonaws.com/my-kinesis-firehose", "service": "firehose", "provider": "aws"}, "credentialsId": "my-aws-credentials", "payloads": "{\"message\":\"Hello SORACOM Funnel via\nHTTP!\"}", "sourceProtocol": "http", "imsi": "123456789012"}
{"operatorId": "XXXXXXXXXXXXX", "timestamp": 1453696869920, "destination": {"resourceUrl": "https://firehose.us-east-1.amazonaws.com/my-kinesis-firehose", "service": "firehose", "provider": "aws"}, "credentialsId": "my-aws-credentials", "payloads": "Hello SORACOM Funnel via UDP!\n", "sourceProtocol": "udp", "imsi": "123456789012"}
{"operatorId": "XXXXXXXXXXXXX", "timestamp": 1453696883384, "destination": {"resourceUrl": "https://firehose.us-east-1.amazonaws.com/my-kinesis-firehose", "service": "firehose", "provider": "aws"}, "credentialsId": "my-aws-credentials", "payloads": "Hello SORACOM Funnel via TCP!\n", "sourceProtocol": "tcp", "imsi": "123456789012"}

メッセージの他にもタイムスタンプやサービス名等が書いてありますね。IMSI(SIMの管理ID)もかいてあるので、こちらを元にデバイスごとにデータの振分け等も出来そうです。

まとめ

いかがでしたでしょうか。使えるサービスはまだ限定されているものの、未来を感じさせるサービスですね。IoTデバイスからKinesisを使いたい時には是非使ってみて、今のうちに慣れておきましょう。