Terraform(Schematics)でICOSバケットを量産する

# はじめに

TerraformあるいはそのマネージドサービスであるSchematicsを使用してIBM Cloudの環境を定義する際のTipsとして、ICOSバケットを量産する方法をまとめてみました。

# 確認した環境

+ Terraform v1.5.0 (Mac)
    + ibm-cloud/ibm v1.56.1
+ Schematics (Terraform v1.4.6)

# 用意する資材

まず、provider.tfとversions.tfを用意します。

```Terraform:provider.tf
provider "ibm" {
    ibmcloud_api_key   = var.ibmcloud_api_key
    region             = var.region
}
```

```Terraform:versions.tf
terraform {
  required_version = ">= 1.0.0, < 2.0.0"
  required_providers {
    ibm = {
      source = "IBM-Cloud/ibm"
    }
  }
}
```

次に、ICOSバケット作成時に使用するパラメータを変数として用意します。まず、variableを定義していきます。使用するICOSインスタンス、Activity Tracker及びプラットフォームメトリクス用のIBM Cloud Monitoring with Sysdigの各インスタンスは既にデプロイ済みの物を使用することにします。

```Terraform:variable.tf
# API Key
variable "ibmcloud_api_key" {
  description = "APIキー"
  type        = string
}

# デプロイ先
variable "region" {
  description = "デプロイ先リージョン（ロケーション）"
  type        = string
}

# Activity Tracker
variable "activitytracker" {
  description = "Activity Trackerインスタンス名"
  type        = string
}

# IBM Cloud Monitoring with Sysdig (Platform metrics)
variable "monitoring_platform" {
  description = "プラットフォームメトリクス用 IBM Cloud Monitoring with Sysdigインスタンス名"
  type        = string
}

# ICOSインスタンス
variable "icos_instance" {
  description = "ICOSインスタンス"
  type        = string
}

# ICOSバケット
variable "icos_buckets" {
  description = "ICOSバケット"
  type        = map(any)
}
```

そして、変数の値を定義します。activitytrackerとmonitoring_platformには、バケットを作成するロケーションを対象としたActivity Tracker及びプラットフォームメトリクスを有効にしたIBM Cloud Monitoringのインスタンス名を指定します。icos_bucketsに定義するのが、作成するICOSバケットのパラメータです。map型で定義しており、キー名がそのままバケット名になります。

```Terraform:terraform.tfvars
# バケット作成先ロケーション
region　= "jp-tok"

# Activity Tracker
activitytracker = "activitytracker-jp-tok"

# IBM Cloud Monitoring with Sysdig (Platform metrics)
monitoring_platform = "platformmetrics-jp-tok"

# ICOSインスタンス
icos_instance = "icos-instance"

# ICOSバケット
icos_buckets = {
  "hirokuda-test001" = {
    storage_class  = "standard"
    archive_enable = true
    archive_type   = "GLACIER"
    archive_days   = 3
    expire_enable  = true
    expire_days    = 7
  }
  "hirokuda-test002" = {
    storage_class  = "standard"
    archive_enable = true
    archive_type   = "GLACIER"
    archive_days   = 3
    expire_enable  = true
    expire_days    = 7
  }
}

```

APIキーはあえてファイルに記載していません。terraform plan/apply実行時に入力するか、実行前に環境変数TF_VAR_ibmcloud_api_keyに定義しておくこととします。

最後に、main.tfです。ibm_cos_bucketをfor_eachでループさせることで、変数に定義した分のICOSバケットを作成することが出来ます。

```Terraform:main.tf
# Activity Tracker
data "ibm_resource_instance" "activitytracker" {
  name = var.activitytracker
}

# IBM Cloud Monitoring with Sysdig (Platform metrics)
data "ibm_resource_instance" "monitoring_platform" {
  name = var.monitoring_platform
}

# ICOSインスタンス
data "ibm_resource_instance" "icos_instance" {
  name = var.icos_instance
}

# ICOSバケット
resource "ibm_cos_bucket" "bucket" {
  for_each = var.icos_buckets

  bucket_name          = each.key
  resource_instance_id = data.ibm_resource_instance.icos_instance.id
  region_location      = var.region
  storage_class        = each.value.storage_class
  activity_tracking {
    read_data_events     = true
    write_data_events    = true
    activity_tracker_crn = data.ibm_resource_instance.activitytracker.id
  }
  metrics_monitoring {
    usage_metrics_enabled   = true
    request_metrics_enabled = true
    metrics_monitoring_crn  = data.ibm_resource_instance.monitoring_platform.id
  }
  archive_rule {
    rule_id = "arch-rule"
    enable  = each.value.archive_enable
    days    = each.value.archive_days
    type    = each.value.archive_type
  }
  expire_rule {
    rule_id = "expire-rule"
    enable  = each.value.expire_enable
    days    = each.value.expire_days
  }
}
```

上記の例では、Activity Trackerとプラットフォームメトリクスは強制的に有効、ストレージクラス、アーカイブルール及び有効期限をカスタマイズ可能にしています。他にどのようなパラメータが指定可能なのかは、[こちら](https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/cos_bucket)を参照してみてください。

# Schematicsで実行する場合の注意点

Schematicsで実行する場合は、まずterraform.tfvars以外の資材をGitに上げたうえで、workspaceを作成します。その後、terraform.tfvarsに設定した値を画面から定義、あるいは以下の様なCLIで定義しますが、CLIで実行すると以下の様なエラーになってしまいます。

```
$ ibmcloud sch plan --id ${WORKSPACE_ID} --var-file terraform.tfvars
tfvars の形式が無効です。 これは key=value の形式でなければなりません
```

tfvarsの形式チェックが厳密？過ぎて、改行を含んだmap型の変数定義を受け付けてくれません。また、コメントもNGのようで、現状では以下の様に1行1変数の形式に直す必要がありますので、ご注意ください。

*2024/6/25追記* 上記の制約ですが、最新のSchematicsプラグインで解消されました。詳しくは[こちら](https://qiita.com/hirokuda/items/76c5a6b9a16453a5c165)を参照ください。

```Terraform:terraform.tfvars
region　= "jp-tok"
activitytracker = "activitytracker-jp-tok"
monitoring_platform = "platformmetrics-jp-tok"
icos_instance = "icos-instance"
icos_buckets = { "hirokuda-test001" = { storage_class = "standard", archive_enable = true, archive_type = "GLACIER", archive_days = 3, expire_enable = true, expire_days = 7 }, "hirokuda-test002" = { storage_class = "standard", archive_enable = true, archive_type = "GLACIER", archive_days = 3, expire_enable = true, expire_days = 7 } }

```

環境や用途ごとに、コンソールやCLIでICOSバケットをその都度作っていると、結果として結構な数になっていて、それぞれの設定が想定通りなのかどうか、把握し辛くなることがあると思います。

これらをTerraformでコード化することで、構築作業が容易になるだけでなく、定期的にplanを実行することで、想定した設定が実環境に間違いなく反映されていることを機械的にチェックできるので、安心して運用することが出来るのではと思います。