SORACOM Arcはデバイスだけじゃなくてクラウドでも動かせるんだよ！という話

# はじめに

2021/6/22 〜 24に開催されたSORACOM Discovery 2021 Onlineにて、SORACOMの新しいコネクティビティサービス「SORACOM Arc」が発表されました。
https://users.soracom.io/ja-jp/docs/arc/

SORACOMの提唱する「Connectivity Agnostic」を大幅に拡大する、すごいサービスです。(語彙力なし)
詳しいことは別ブログで書きますが、SORACOM Arcの可能性の一端として、今までSORACOMサービスに繋げなかったところ、すなわちクラウド環境でもSORACOMが使えるようになったんだよ、ということを見せたいと思います。

# 準備

まずはドキュメントを確認しましょう。
https://users.soracom.io/ja-jp/docs/arc/

必要なものは、

- 仮想SIM
- 仮想SIMの認証情報
- Wireguardの実装

なのですが、このあたりは全部soratunがやってくれるようです。
soratunを使ってみましょう。

リリースページからsoratunをダウンロードします。
https://github.com/soracom/soratun/releases

次にbootstrapをするのですが、クラウド環境ではAirやSIMを使ったbootstrapはできません。
以下のページに従って、authkeyを使った認証をします。
https://users.soracom.io/ja-jp/docs/arc/bootstrap-authkey/
Arcの仮想SIMが作れるSAMを作って、それを使ってbootstrapするようですね。

```
1stship % ./soratun bootstrap authkey
Not enough information to bootstrap. Launching wizard.
SORACOM API auth key ID (starts with "keyId-"): **************************************
SORACOM API auth key (starts with "secret-"): ***********************************************************************
✔ Japan coverage (api.soracom.io)
Virtual subscriber SIM ID: 8900001091171284665
Created/updated configuration file: /Users/1stship/soratun_1.0.0_darwin_arm64/arc.json
```

するとarc.jsonという設定ファイルができます。
この設定ファイルをsoratunで指定すればもう接続できちゃうみたいです。
超簡単ですね。こんな簡単にVPNが作れてしまっていいのか。

# クラウドで動かしてみよう

どうせクラウド使うんだったら、使ってる時だけ課金される系のサービスを使いたいですよね？
ということで、AWSのCodeBuildを使ってみたいと思います。
CodeBuildは実行している時しか課金されないサービスです。

以下のようなbuildspec.yamlを作成します。

```
version: 0.2

phases:
  build:
    commands:
      - ./soratun up --config arc.json &
      - sleep 5
      - curl http://metadata.soracom.io/v1/subscriber
```

メタデータを取得するだけの簡単な処理ですが、今まではSORACOM Airのネットワークからしか使えませんでした。

これをsoratun、arc.jsonと一緒にZIPアーカイブし、Amazon S3にアップロードしておきましょう。
これを指定してCodeBuildのビルドプロジェクトを作り、実行してみます。
(すみませんが、CodeBuild自体の説明はしません)

```
[Container] 2021/06/23 04:04:09 Running command ./soratun up --config arc.json &
ERROR: (utun) 2021/06/23 04:04:09 failed to create new tunnel: CreateTUN("utun") failed; /dev/net/tun does not exist
```

おや？なにか失敗しました。
これはネットワークを作成するLinuxの権限が足りないためです。
CodeBuildではDockerに特権を与える必要があります。(なのでどの環境でも使える、というわけではなかったです)

![スクリーンショット 2021-06-23 13.12.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542185/df136e42-d179-5d59-092c-5916680ca9e3.png)

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

```
[Container] 2021/06/23 04:14:28 Running command ./soratun up --config arc.json &
[Container] 2021/06/23 04:14:29 Running command sleep 5
DEBUG: (utun) 2021/06/23 04:14:29 device started
DEBUG: (utun) 2021/06/23 04:14:29 UAPI listener started
DEBUG: (utun) 2021/06/23 04:14:29 Routine: encryption worker 1 - started
DEBUG: (utun) 2021/06/23 04:14:29 Routine: decryption worker 1 - started
DEBUG: (utun) 2021/06/23 04:14:29 Routine: handshake worker 1 - started
DEBUG: (utun) 2021/06/23 04:14:29 Routine: encryption worker 2 - started
DEBUG: (utun) 2021/06/23 04:14:29 Routine: decryption worker 2 - started
DEBUG: (utun) 2021/06/23 04:14:29 Routine: handshake worker 2 - started
DEBUG: (utun) 2021/06/23 04:14:29 Routine: TUN reader - started
DEBUG: (utun) 2021/06/23 04:14:29 Routine: event worker - started
DEBUG: (utun) 2021/06/23 04:14:29 Interface up requested
DEBUG: (utun) 2021/06/23 04:14:29 UDP bind has been updated
DEBUG: (utun) 2021/06/23 04:14:29 Interface state was Down, requested Up, now Up
DEBUG: (utun) 2021/06/23 04:14:29 Routine: receive incoming v6 - started
DEBUG: (utun) 2021/06/23 04:14:29 UAPI: Updating private key
DEBUG: (utun) 2021/06/23 04:14:29 UAPI: Removing all peers
DEBUG: (utun) 2021/06/23 04:14:29 Routine: receive incoming v4 - started
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - Starting
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - UAPI: Created
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - UAPI: Updating endpoint
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - UAPI: Updating persistent keepalive interval
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - Sending keepalive packet
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - Sending handshake initiation
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - UAPI: Removing all allowedips
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - UAPI: Adding allowedip
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - Routine: sequential receiver - started
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - Routine: sequential sender - started
DEBUG: (utun) 2021/06/23 04:14:29 assign IP address: 10.171.40.94
DEBUG: (utun) 2021/06/23 04:14:29 set link up: utun
DEBUG: (utun) 2021/06/23 04:14:29 Interface up requested
DEBUG: (utun) 2021/06/23 04:14:29 add route: 100.127.0.0/16
DEBUG: (utun) 2021/06/23 04:14:29 peer(QIuO…qBh4) - Received handshake response

[Container] 2021/06/23 04:14:34 Running command curl http://metadata.soracom.io/v1/subscriber
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100    41  100    41    0     0    506      0 --:--:-- --:--:-- --:--:--   506
No group ID is specified: 999999117128466
```

成功しました！soratunでVPN接続ができて、メタデータサービスにアクセスできていることがわかります。
ただし肝心のメタデータが取得できていません。
これはエラーメッセージの通りSIMグループが設定されていないためです。
メタデータサービスを使うためには、SIMをグループに入れ、グループでメタデータサービスを有効にする必要があります。
逆に言えば、ちゃんとグループ設定がされているか、というテストがクラウドでできる、ということになります。

ではグループとメタデータを設定してみましょう。

```
[Container] 2021/06/23 04:18:38 Running command ./soratun up --config arc.json &

[Container] 2021/06/23 04:18:38 Running command sleep 5
DEBUG: (utun) 2021/06/23 04:18:38 device started
略...
DEBUG: (utun) 2021/06/23 04:18:38 Interface up requested
DEBUG: (utun) 2021/06/23 04:18:38 peer(QIuO…qBh4) - Received handshake response

[Container] 2021/06/23 04:18:43 Running command curl http://metadata.soracom.io/v1/subscriber
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  1301  100  1301    0     0  14296      0 --:--:-- --:--:-- --:--:-- 14296
{"imsi":"999999XXXXXXXXX","msisdn":null,"ipAddress":null,"operatorId":"OP00XXXXXXXX","apn":"arc.soracom.io","type":"arc.standard","groupId":"XXXX","createdAt":1624419705861,"lastModifiedAt":1624421858519,"expiredAt":null,"registeredTime":null,"expiryAction":"doNothing","terminationEnabled":true,"status":"active","tags":{"name":"ArcTest"},"sessionStatus":{"gtpcTeid":1780190711,"lastUpdatedAt":1624419706667,"imei":null,"location":null,"ueIpAddress":"10.171.40.94","dnsServers":["0.0.0.0","0.0.0.0"],"online":true},"arcSessionStatus":{"gtpcTeid":1780190711,"lastUpdatedAt":1624419706667,"location":null,"arcClientPeerIpAddress":"10.171.40.94","arcClientPeerPublicKey":"XXXX","XXXX","arcServerEndpoint":"link.arc.soracom.io:11010","arcAllowedIPs":["100.127.0.0/16"]},"imeiLock":null,"speedClass":"arc.standard","simId":"XXXX","moduleType":"virtual","plan":0,"iccid":"XXXX","serialNumber":null,"subscription":"planArc01","lastPortMappingCreatedTime":null,"packetCaptureSessions":null,"arcClientPeerPublicKey":"XXXX","lastModifiedTime":1624421858519,"expiryTime":null,"createdTime":1624419705861}
```

おお〜、ちゃんとメタデータが取得できましたね。(固有の情報は隠してます)
クラウド環境から、便利なSORACOMサービスを利用できる！ということがわかりました。
(ちなみにメタデータサービスもめちゃくちゃ便利です)
SORACOMのサービスは自動テストに組み込むのが結構大変、というのがありましたが、Arcを使えばクラウドCIサービスの中で動かせるので、この課題は解決ですね！
当然、BeamやFunk、FunnelやUnified Endpointなど、どんなサービスでも利用することができます。

# おわりに

SORACOMが提唱して来たConnectivity Agnosticを大幅に拡大するサービスが「SORACOM Arc」です。

SORACOMにはマルチクラウド対応の入り口となるSORACOM Funnel、Funkや簡単に可視化できるHarvest + Lagoon、遠隔操作を簡単にするNapter、パケットキャプチャが簡単にできるPeekなど、これまで作り上げて来たさまざまなサービスがあります。
これまではSIMを使ったSORACOM Airの通信が必須だったのですが、SORACOM ArcができたことによりIoTデバイスはもちろん、開発者のPCやクラウドサービス上など、さまざまなところでSORACOMサービスを利用することができます。(しかもArc自体はかなり安い)
便利なサービスをちょっと足すために使うもよし、従量課金製のクラウドサービスと組み合わせるのもよし、色々な使い方が考えられますね。
皆さんもぜひSORACOM Arcを試して、便利な使い方を編み出していきましょう！