Terraform provider for SORACOMを使ってAWSとの連携を自動化する

ついに、[Terraform provider for SORACOM](https://registry.terraform.io/providers/ks6088ts/soracom/0.0.3)が公開されました🎉

https://registry.terraform.io/providers/ks6088ts/soracom/0.0.3

本記事は公開をお祝いすることと作者へのリスペクトをお伝えしたく執筆しています。

## SORACOMを使う上で感じていた課題感

みなさんはIoTシステムを作るとき、クラウド側の設定やリソースはどのように管理していますか？私はIoT開発におけるAWS周りの設定やリソースの管理にTerraformを使っています。[AWS Provider](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) が大抵のサービスに対応していてドキュメントもしっかりしていますし、デプロイが速い・変更される箇所がわかりやすい・変更に強いといったメリットを感じているためです。

一方、SORACOMについてはIaCができておらず、正直なところ毎回SORACOMコンソールにログインして手動で設定していました。これは冪等性という点でも非常に弱いですし、この作業が属人化しやすいことも課題でした。

![SIM_グループ_-_SORACOM_ユーザーコンソール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/c7560381-181d-7c25-71c0-ba48090f42f1.png)


## SORACOMの設定をTerraformで管理するメリット

### メリット1. 冪等性が担保される

これはIaCそのもののメリットですね。IoTシステムを開発していて「同じような環境(ステージングなど)をもう一つ作りたい」というときも、コマンドを一発叩くだけで同じ環境を構築できます。壊してしまっても作り直せる、というのは心理的負担が軽減されるのでとても良いです。

### メリット2. クラウドとの連携が楽

これはTerraformならではのメリットです。Providerを使うことで様々なクラウドサービスのリソースをコード化できるが故に、AWSに作成したリソースの情報(ARNなど)をそのままSORACOMの設定に反映できます。

例えばSORACOM Funnelの場合、AWS IoT Coreのエンドポイントや認証に使用するIAM RoleのARNを、SORACOMのSIMグループのSORACOM Funnel設定に入力する必要がありました。Terraformを使うことで
それが全自動で連携されます。

### メリット3. SORACOMをより理解できる

SORACOMはコンソールがわかりやすく、ドキュメントが非常に充実しているので、各サービスを直感的に利用することができます。これ自体はとても良いことなのですが、各リソースの関係性を理解できていなかったり、オプショナルな設定項目に気づけなかったりといった弊害もあります。

Terraformでリソースを定義することで、それらをしっかり理解することができます。

## 試してみる

というわけで早速利用してみます。今回はSORACOM Funnelを使ってAWS IoT Coreへデータを転送する、という環境一式をTerraformで作ってみました。

![funnel_drawio_—_drawio-saves.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/0e276f9e-0a65-a6f6-e6ec-ac4e3cbb189d.png)

### SORACOM CLIでプロファイルを作る

こちらのドキュメントを参考にプロファイルを作ります。このプロファイルを使ってTerraformはSORACOM上の設定を操作します。

https://users.soracom.io/ja-jp/tools/cli/getting-started/#%E3%82%B9%E3%83%86%E3%83%83%E3%83%97-2-%E8%AA%8D%E8%A8%BC%E6%83%85%E5%A0%B1%E3%82%92%E6%BA%96%E5%82%99%E3%81%99%E3%82%8B

注意点として、現状では `認証キー ID および認証キーシークレット` を使った認証にのみ対応しているようです。[^1] `ルートユーザーのメールアドレスとパスワード` を使った認証だとエラーが発生しますのでご注意ください。

### Terraform provider for SORACOMを使用する

Terraform provider for SORACOMを使うために、以下のような記述を追加します。

```terraform:main.tf
terraform {
  required_providers {
    soracom = {
      source  = "ks6088ts/soracom"
      version = "~> 0.0.3"
    }
  }
}

provider "soracom" {
  profile = "default" # SORACOM CLIで登録済のprofile名
}
```

あとは `terraform init` を実行すればProviderを利用する準備は完了です。以下はSORACOMのSIMグループを定義する例です。

```terraform
resource "soracom_group" "my_group" {
  tags = {
    name = "soracom-funnel-aws-iot-core-terraform"
  }
}
```

### AWSとの連携も楽チン！

AWS IAM Roleを作って、SORACOMの認証情報ストアを作成する例です。いつもアカウントIDやARN、外部IDを手動でコピペしていたので、全自動で連携できるようになってとてもありがたいです！

```terraform
# AWS IAM Role
resource "aws_iam_role" "my_role" {
  name = "soracom-funnel-aws-iot-core-terraform"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          AWS = "arn:aws:iam::762707677580:root" // SORACOM 日本カバレッジのアカウントID
        }
        Condition = {
          StringEquals = {
            "sts:ExternalId" = var.aws_iam_role_external_id
          }
        }
      }
    ]
  })

  # 中略...
}

# SORACOM 認証情報ストア
resource "soracom_credentials" "my_aws_iam_role_credentials" {
  credentials_id = "aws-iam-role-credentials"
  description    = "AWS IAM role credentials by terraform-provider-soracom"
  type           = "aws-iam-role-credentials"
  credentials = {
    roleArn    = aws_iam_role.my_role.arn
    externalId = var.aws_iam_role_external_id
  }
}
```

## 動作確認

最終的に出来上がったソースコードはこちらに公開しています。 

https://gist.github.com/yuuu/004ded728ca2083a19e6a2a1ecb4b0a6

このソースコードを手元において、`terraform init` → `terraform apply` することでデプロイできます。

今回はSORACOM Arcで作成した仮想SIMを出来上がったSIMグループに紐付けました。[^2]

![SIM_管理_-_SORACOM_ユーザーコンソール.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/6963611e-1374-d567-86fe-0561e963b9ea.png)

この状態でデバイス側からデータを送信すると、AWS IoT Coreで受信を確認できました。

![Screenshot_2022-10-24_at_05-40-11_AWS_IoT_-_MQTT_test_client.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/60996/29dd1fdb-26fc-7fda-16f4-6944943ca4c1.png)

## まとめ

残念ながらTerraform provider for SORACOMは、現時点では非公式なProviderですし、SORACOMが提供するサービスの一部には対応できていません。しかし、そういった制約付きであってもProviderが登場したことは大きな一歩です。

少なくとも自分はSORACOMとAWSを連携させたIoTシステムを今現在も開発しているので、積極的に活用していきますし、できればコントリビュートもしていきたいと思っています。

みなさまもぜひお試しください。

[^1]: https://github.com/ks6088ts/terraform-provider-soracom/blob/f02e4b10ff844218fe9767ccb4614136a4c06cad/internal/conns/conns.go#L131
[^2]: https://tech.fusic.co.jp/posts/2022-04-24-m5stack-soracom-arc/