【Splunk】TerraformでSplunk Enterpriseのリソースを管理してみる

# はじめに

[Splunk](https://www.splunk.com/ja_jp)は様々なデータに対応した統合ログプラットフォームです。
SPLというサーチ言語を利用してログから自分の見たい情報を抽出、Commnadsを活要して集計処理やデータの加工など様々なことが可能です。

本記事ではSplunkそのものや様々なCommandsの解説はしないためSplunkをより詳しく知りたい方は[チートシート](splunk.com/pdfs/solution-guides/splunk-quick-reference-guide-jp.pdf)や公式ドキュメントを参照いただければと思います。[日本語マニュアル](https://docs.splunk.com/Documentation/Splunk/8.2.3/Translated/Japanesemanuals)も充実しています。

# やってみること

SplunkのBlog [Manage Your Splunk Infrastructure as Code Using Terraform](https://www.splunk.com/en_us/blog/partners/manage-your-splunk-infrastructure-as-code-using-terraform.html)を参考にローカル環境Splunkのリソースを[Terraform](https://registry.terraform.io/)で管理してみます。
具体的に作成するリソースは以下です。
- ロール
- ユーザー
- インデックス
- ダッシュボード

ダッシュボード以外はほぼSplunkのBlogと同じ手順を辿っています。

# 利用した環境
今回ローカル環境にSplunkの[無料トライアル版](https://www.splunk.com/ja_jp/download.html)をインストールし、その環境で遊んでみました。
無料トライアル版はデータの取り込み量の制限は1日500MBまでとなりますが、60日間無償でSplunkの各種機能を利用可能です。
60日経過後は有償版のライセンスを適用するか、出来ることはかなり減りますがフリー版のライセンスに移行することが可能です。

# 事前準備

- ローカル環境にSplunkをインストール（こちらの手順は割愛）
  - ブラウザから`http://localhost:8000/`でインストール時に作成したadminアカウントでローカルのSplunkに接続できることを確認
- TerraformのSplunk Providerの[Requirements](https://github.com/splunk/terraform-provider-splunk#requirements)がv0.12のため手元の環境を[tfenv](https://github.com/tfutils/tfenv)を利用して手元のTerraformをv0.12以上に設定
``` bash
# terraformのVersion管理の補助ツールであるtfenvをインストール
$ brew install tfenv

# インストール可能なversionを確認
$ tfenv list-remote

# 任意のversionをインストール
$ tfenv install <任意のVersion>

# 利用するTerraformのversionを設定
$ tfenv use <任意のVersion>

```
- 適当なSampleデータが欲しいのでこれもSplunkの[チュートリアル](https://docs.splunk.com/Documentation/Splunk/8.0.4/SearchTutorial/Systemrequirements?_gl=1*1qicpgh*_ga*NzExODE4MjM2LjE2MTA4MDA2MzI.*_gid*NTM0NjUyNzQ2LjE2NjM0NjQ3OTY.*_gac*RUFJYUlRb2JDaE1JaEpfQW41bWQtZ0lWaTdhV0NoMXUwQWUzRUFBWUFTQUFFZ0lsTlBEX0J3RS4xNjYzNDY0ODAz&_ga=2.48824546.534652746.1663464796-711818236.1610800632&_gac=1.220327212.1663464803.EAIaIQobChMIhJ_An5md-gIVi7aWCh1u0Ae3EAAYASAAEgIlNPD_BwE#Download_the_tutorial_data_files)からzipを手元にダウンロード

# TerraformでSplunkにリソース作成

事前準備が出来たら実際にTerraformを使ってSplunkのリソースを管理してみます。

## TerraformでSplunkへ接続
Terraform作業用のディレクトリ（今回はsplunk）を作成し、作業用ディレクトリ配下に移動しmain.tfを作成します。
```bash
$ mkdir ./splunk
$ cd ./splunk
$ touch main.tf
```

作成したmain.tfにprovider情報を記述します。

```tf
terraform {
  required_providers {
    splunk = {
      source = "splunk/splunk"
      version = "1.4.17"
    }
  }
}

provider "splunk" {
  url                  = "localhost:8089"
  username             = "<Splunkインストール時に設定したAdminアカウント>"
  password             = "<Splunkインストール時に設定したAdminパスワード>"
  insecure_skip_verify = true
}
```
作業ディレクトリの初期化コマンドが無事に成功することを確認します。

```bash
$ terraform init
```
`Terraform has been successfully initialized!`と表示されれば完了です。

planを実行
```bash
$ terraform fmt
$ terraform plan

No changes. Your infrastructure matches the configuration.

Terraform has compared your real infrastructure against your configuration and found no differences, so no changes are
needed.
```

この状態ではまだ何もTerraformではリソースを管理していないためNo changesと表示されます。

## ユーザーとインデックス作成

Splunkにテスト用のユーザーとロール、インデックスを作成するためmain.tfに以下を追記します。

```tf

// Role
resource "splunk_authorization_roles" "role01" {
  name           = "terraform-user01-role"
  default_app    = "search"
  imported_roles = ["power", "user"]
  capabilities   = ["accelerate_datamodel", "change_authentication", "restart_splunkd"]
}

// User
resource "splunk_authentication_users" "user01" {
  name              = "user01"
  email             = "sample@sample.sample"
  password          = "<任意のパスワード>"
  force_change_pass = false
  roles             = ["terraform-user01-role"]
  depends_on = [
    splunk_authorization_roles.role01
  ]
}

// Index
resource "splunk_indexes" "index01" {
  name                   = "index01"
  max_total_data_size_mb = 1000000
}

```

テスト用のRoleとユーザー、インデックスを定義するリソースを記述しました。この状態でplanを実行し問題なければapplyします。

```bash
$ terraform fmt

# Plan実行、Plan: 3 to add, 0 to change, 0 to destroy.と表示されればOK
$ terraform plan

# Apply実行、Apply complete! Resources: 3 added, 0 changed, 0 destroyed.と表示されればOK
$ terraform apply -auto-approve
```

Splunk上でもユーザーが作成されたこと、作成したユーザーでもログインが可能なことを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/f17ea66f-0cc1-e6f2-e6df-a48f3f9ada9c.png)

またIndexが作成されていることも確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/0077f009-ed36-4ada-bad4-ff8001b64ce1.png)

## 作成したIndexにテスト用データを投入
テスト用のデータは正直なんでも良いのですが、今回はSplunkのチュートリアルで使われるデータを利用することにしました。

- 事前準備でダウンロードしたデータを解凍し、Splunkに取り込みます
  - 設定＞データ入力＞ファイルとディレクトリを選択
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/8f41cab1-bd49-ace2-f5f3-8ea25ab28cb6.png)
  - 新しいローカルファイルとディレクトリを選択
  - 参照から先ほどダウンロードしたZipを解凍したディレクトリを選択し「次へ」を選択
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/42d826ca-e0ca-b435-77c1-3fb4e8bd9952.png)
  - 適当なホストフィールドの値（今回はtest）、インデックスは先ほど作成した`index01`を指定し「確認」を選択
    - ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/3f925ed1-f6bd-de0b-fa80-c1baacae3642.png)
  - 「確認」で内容に問題なければ「実行」を選択
  - 確認として全時間に対し以下のSPLを実行し結果が返ってくることを確認
``` 
index="index01" host="test" 
| timechart span=1h count
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/ebaf08a8-1d34-205f-484e-d6cbcc754ffe.png)

では次はこのSPLを使ったダッシュボードの作成をTerraformでしてみたいと思います。

## ダッシュボードを作成

ユーザーやインデックス作成まではほぼSplunkのBlogと同じ内容を実施してきましたが、せっかくなのでダッシュボードも作成してみます。
ダッシュボードはTerraformのsplunk providerでは「[splunk_data_ui_views](https://registry.terraform.io/providers/splunk/splunk/latest/docs/resources/data_ui_views)」で定義します。
Argument：`eai:data`の中にダッシュボードをXMLで定義する必要がありますが、さすがにダッシュボード用のXMLを０から構築するのは残念ながら自分のSplunk力だと無理です。。
なので今回は1度手動でダッシュボードを作成し、SplunkのGUI上でソースのXMLが確認できるのでそれをそのまま流用することにしました。

### 元になるダッシュボードを手動で作成しXMLをコピー
ダッシュボードの作成方法は割愛しますが、ひとまず以下のダッシュボードを「test-manually」という名前で手動で作成しました。作成したダッシュボード上で「編集」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/d701bf06-1795-251e-7667-7a20645e101e.png)

編集画面でソースを選択すると手動で作成したダッシュボードのXMLが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/bb13d40a-889f-795d-821e-6f9c1ea63f4c.png)
次はこれをコピペしてTerraformで適用してみます。

### main.tfにsplunk_data_ui_viewsを追記

```tf
resource "splunk_data_ui_views" "terraform_operations" {
  name     = "Terraform"
  eai_data = <<-EOT
<form version="1.1">
  <label>test-terraform</label>
  <fieldset submitButton="false">
    <input type="time" token="field1">
      <label></label>
      <default>
        <earliest>0</earliest>
        <latest></latest>
      </default>
    </input>
  </fieldset>
  <row>
    <panel>
      <chart>
        <search>
          <query>index=index01 host=test | timechart span=1h count</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="charting.chart">column</option>
        <option name="charting.drilldown">none</option>
        <option name="refresh.display">progressbar</option>
      </chart>
    </panel>
  </row>
  <row>
    <panel>
      <chart>
        <search>
          <query>index=index01 host=test sourcetype=access_combined_wcookie | top categoryId</query>
          <earliest>$field1.earliest$</earliest>
          <latest>$field1.latest$</latest>
        </search>
        <option name="charting.chart">pie</option>
        <option name="charting.drilldown">none</option>
      </chart>
    </panel>
  </row>
</form>
  EOT
  acl {
    app     = "search"
    owner   = "admin"
    sharing = "app"
  }
}
```

先ほどコピーしたXMLをArgument：`eai:data`の中にコピペします。labelなどは重複しないように一部変更しました。
またApp内で共有するためにaclを定義しsharing対象をappとします。ここを特に指定しないとPrivateなダッシュボードになるようです。

この状態でPlanとApplyをしていきます。

```bash
$ terraform fmt

# Plan実行、Plan: 1 to add, 0 to change, 0 to destroy.と表示されればOK
$ terraform plan

# Apply実行、Apply complete! Resources: 1 added, 0 changed, 0 destroyed.と表示されればOK
$ terraform apply -auto-approve
```

無事にApplyが完了すると、ダッシュボード上でもtest-terraformが作成されたことが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/44cae070-5bf3-4a36-2384-64f073e05dbc.png)

Terraformで作成した`user01`でSplunkにログインして、ダッシュボードで確認してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/552698/4bc55add-2a05-fb24-3afe-5c3a424af486.png)
無事に作成したユーザーでもダッシュボードを参照することができました。

# 終わりに
今回はローカル環境のSplunk Enterpriseの一部のリソースをTerraformで管理してみました。
今回作成したリソースの他にもアラートなど様々なリソースがTerraformで管理できるようです。
GitHubなどを活用し、差分を追える状態やレビューがしやすい環境の整備や、CI/CDと絡めた活用ができそうです。
なお今回はSplunk Enterpriseで検証していますが、Splunk Cloudではどうなのかということも今後検証できたらと思います。


# 参考記事

- [Manage Your Splunk Infrastructure as Code Using Terraform](https://www.splunk.com/en_us/blog/partners/manage-your-splunk-infrastructure-as-code-using-terraform.html)
- https://registry.terraform.io/providers/splunk/splunk/latest
- https://github.com/splunk/terraform-provider-splunk