TerraformでInstanaのカスタムダッシュボードを作ってみた（with jsonencode / jsondecode）


## はじめに

InstanaでカスタムダッシュボードをTerraformから作成しようとしたら、  
意外とハマりポイントがあったので、成功までの手順をまとめてみました。

特に `widgets` の扱い（JSONをどうTerraformに渡すか）でつまづきがちなので、  
そのあたりも詳しく触れています。

> 今回のダッシュボード構成は、Instana が対応している AWS 環境のアプリケーション監視にも応用可能です。  
> ECS / Lambda / RDS などのモニタリング構成としても取り入れやすく、IaCの一環として活用できます。

---

## 環境構築（Ubuntu 22.04）

Terraformとjqのインストール手順です。

### Terraform v1.11.3 のインストール

```bash
sudo apt update
sudo apt install -y gnupg software-properties-common curl

curl -fsSL https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /usr/share/keyrings/hashicorp-archive-keyring.gpg

echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list

sudo apt update
sudo apt install terraform

terraform -v  # Terraform v1.11.3 を確認
```

### jq のインストール（Instanaのユーザー情報整形に使用）

```bash
sudo apt install -y jq
```

---

## Instanaの `USER` の ID ってメールじゃないの？

Terraform の `relation_type = "USER"` に渡す `related_id` は、  
**メールアドレスではなく、Instana が内部的に管理している UUID形式のID** を使う必要があります！

取得方法：

```bash
curl -s -H "Authorization: apiToken <YOUR_TOKEN>" \
  https://<YOUR_ENDPOINT>/api/settings/users | jq
```

レスポンス内の `"id"` を使いましょう！

---

## では、Terraformの構成ファイルを用意していきましょう

Instanaのカスタムダッシュボードを定義するには、Terraform側で  
`main.tf`, `variables.tf`, `terraform.tfvars`、そして `widgets.json` を使って構成します。

##  構成ファイル一覧

### `widgets.json`

```json
[
  {
    "id": "widget-1",
    "title": "Sample Widget",
    "x": 0,
    "y": 0,
    "width": 6,
    "height": 3,
    "type": "apdex",
    "config": {
      "apdexConfigId": "some-config-id",
      "entityType": "website",
      "entityId": "some-entity-id"
    }
  }
]
```

---

### `main.tf`

```hcl
terraform {
  required_providers {
    instana = {
      source  = "instana/instana"
      version = "~> 1.0"
    }
  }
}

provider "instana" {
  api_token = var.instana_api_token
  endpoint  = var.instana_endpoint
}

locals {
  widgets = jsondecode(file("${path.module}/widgets.json"))
}

resource "instana_custom_dashboard" "example" {
  title = "Test Dashboard"

  access_rule {
    access_type   = "READ_WRITE"
    relation_type = "USER"
    related_id    = var.instana_user_id
  }

  widgets = jsonencode(local.widgets)
}
```

---

### `variables.tf`

```hcl
variable "instana_api_token" {}
variable "instana_endpoint" {}
variable "instana_user_id" {}
```

---

### `terraform.tfvars`

```hcl
instana_api_token = "YOUR_API_TOKEN"
instana_endpoint  = "https://your-instana-endpoint"
instana_user_id   = "1234567890abcdefg"  # ← Instana APIで取得した内部ユーザーID
```

---

## 実行手順

```bash
terraform init
terraform plan
terraform apply
```

### デバッグしたい場合は：

```bash
TF_LOG=DEBUG terraform apply
```

---

## よくあるエラーとその対処

| エラー | 原因 | 対処法 |
|--------|------|--------|
| `unsupported 'Body' type/value` | `widgets` に文字列を渡している | `jsondecode → jsonencode` で構造体として扱う |
| `"USER is unknown"` | メールを `related_id` に渡している | Instanaの内部IDを使う |
| `lookup https on 127.0.0.53` | URL が `https://https//...` になっている | `instana_endpoint` の記述ミス修正 |

---

## 成功時の出力例

```bash
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
```

Instana にカスタムダッシュボードが作成されていれば成功！

---

## ✨ おわりに

Terraform と Instana を組み合わせてダッシュボードを自動化することで、  
監視の構成もコードで管理できるようになります。

**`jsondecode` + `jsonencode`** を正しく使うことで、  
Terraform の `widgets` の扱いも思ったよりシンプルになります。

---

## 🔗 参考リンク

- [Instana Terraform Provider](https://registry.terraform.io/providers/instana/instana/latest/docs)
- [Terraform `jsonencode`](https://developer.hashicorp.com/terraform/language/functions/jsonencode)
- [Terraform `file` 関数](https://developer.hashicorp.com/terraform/language/functions/file)