0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon OpenSearch Service のモニターとアラートを Terraform で管理する

Posted at

はじめに

OpenSearch ではシステムの状態を監視し、問題が発生した際に通知するためのモニターとアラート機能が提供されています。
しかし、多数のモニターを手動で作成・管理していくと、以下のような課題が発生します:

  • 設定の一貫性を保つことが難しい
  • 環境間(開発・ステージング・本番)での再現が煩雑
  • 変更履歴の管理が困難
  • 大量のモニター設定の更新作業が手間

これらの課題を解決するため、Terraform を使って OpenSearch のモニターとアラートを管理するようにしてみました。

実装方法

1. プロジェクト構成

基本的なプロジェクト構成は以下の通りです:

.
├── main.tf           # OpenSearch モニターリソースの定義
├── variables.tf      # 変数の定義
├── terraform.tfvars  # 実際の変数値の設定
├── provider.tf       # AWS と OpenSearch プロバイダーの設定
├── outputs.tf        # 出力値の定義
└── versions.tf       # Terraform とプロバイダーのバージョン要件

2. プロバイダーの設定

provider.tfで、AWS と OpenSearch のプロバイダーを設定します:

provider.tf
provider "aws" {
  region = var.aws_region
}

provider "opensearch" {
  url         = var.opensearch_endpoint
  aws_region  = var.aws_region
  
  # IAM認証を使用
  sign_aws_requests = true
  
  # ヘルスチェックを無効化
  healthcheck = false
  
  # スナップショット設定
  sniff = false
  
  # TLS設定
  insecure = true  # 自己署名証明書を使用している場合はtrueに設定
}

3. 変数の定義

variables.tf で、必要な変数を定義します:

variables.tf
variable "aws_region" {
  description = "AWS region where the OpenSearch domain is located"
  type        = string
  default     = "ap-northeast-1"
}

variable "opensearch_domain_name" {
  description = "Name of the existing OpenSearch domain"
  type        = string
}

variable "opensearch_endpoint" {
  description = "OpenSearch domain endpoint URL"
  type        = string
}

# 複数のモニターとアラートを定義するための変数
variable "monitors" {
  description = "Map of monitors to create with their configurations"
  type = map(object({
    monitor_name     = string
    monitor_schedule = string
    monitor_indices  = list(string)
    aggregation_name = string
    aggregation_type = string
    aggregation_field = string
    alert_name       = string
    alert_threshold  = number
    condition        = string
    subject_template = string
    message_template = string
    destination_key  = string
  }))
  default = {}
}

4. モニターの定義

main.tf で、OpenSearch モニターリソースを定義します:

main.tf
# モニターの作成
resource "opensearch_monitor" "monitors" {
  for_each = var.monitors
  
  body = jsonencode({
    name     = each.value.monitor_name
    enabled  = true
    schedule = {
      cron = {
        expression = each.value.monitor_schedule
        timezone   = "Asia/Tokyo"
      }
    }
    inputs = [
      {
        search = {
          indices = each.value.monitor_indices
          query = {
            aggregations = {
              "${each.value.aggregation_name}" = {
                "${each.value.aggregation_type}" = {
                  field = each.value.aggregation_field
                }
              }
            }
          }
        }
      }
    ]
    triggers = [
      {
        name      = each.value.alert_name
        severity  = "1"
        condition = {
          script = {
            source = "return ${each.value.aggregation_name}.value ${each.value.condition == "GREATER_THAN" ? ">" : each.value.condition == "LESS_THAN" ? "<" : "=="} ${each.value.alert_threshold}"
            lang   = "painless"
          }
        }
        actions = [
          {
            name             = "send_notification"
            destination_id   = each.value.destination_key
            message_template = {
              source = each.value.message_template
            }
            subject_template = {
              source = each.value.subject_template
            }
          }
        ]
      }
    ]
  })
}

5. モニター設定の定義

terraform.tfvars で、実際のモニター設定を定義します:

terraform.tfvars
aws_region = "ap-northeast-1"
opensearch_domain_name = "mydomain"
opensearch_endpoint = "https://search-mydomain-xxxxxxxxxxxx.ap-northeast-1.es.amazonaws.com"

# モニターとアラートの設定
monitors = {
  monitor_001 = {
    monitor_name     = "monitor_001"
    monitor_schedule = "0 0/15 * * *"  # 15分ごと
    monitor_indices  = ["opensearch_dashboards_sample_data_logs"]
    aggregation_name = "response_503"
    aggregation_type = "value_count"
    aggregation_field = "response.keyword"
    alert_name       = "alert_001"
    alert_threshold  = 1
    condition        = "GREATER_THAN"
    subject_template = "OpenSearch Alert: alert_001"
    message_template = "This is alert_001."
    destination_key  = "channel-sns"  # OpenSearch Dashboardsで作成した送信先の名前
  },
  # 必要に応じて複数のモニターを追加できます
  monitor_002 = {
    monitor_name     = "cpu-usage-monitor"
    monitor_schedule = "0 0/5 * * *"  # 5分ごと
    monitor_indices  = ["metrics-*"]
    aggregation_name = "avg_cpu"
    aggregation_type = "avg"
    aggregation_field = "cpu.usage"
    alert_name       = "high-cpu-alert"
    alert_threshold  = 80
    condition        = "GREATER_THAN"
    subject_template = "OpenSearch Alert: High CPU Usage"
    message_template = "The average CPU usage has exceeded 80%."
    destination_key  = "channel-sns"
  }
}

6. 出力の定義

outputs.tf で、作成されたモニターの情報を出力するための設定を行います:

outputs.tf
output "monitor_ids" {
  description = "IDs of the created OpenSearch monitors"
  value       = { for k, v in opensearch_monitor.monitors : k => v.id }
}

output "monitor_count" {
  description = "Number of monitors created"
  value       = length(opensearch_monitor.monitors)
}

デプロイ手順

1. 前提条件

  • Terraform がインストールされていること
  • AWS CLI が設定されていること
  • OpenSearch ドメインへのアクセス権限があること
  • OpenSearch Dashboards でアラート送信先が作成されていること

2. 初期化

terraform init

3. 実行計画の確認

terraform plan

4. デプロイ

terraform apply

5. 確認

OpenSearch Dashboards にアクセスして、モニターが正常に作成されていることを確認します。

スクリーンショット 2025-05-31 20.17.31.png

まとめ

Terraform を使用して OpenSearch のモニターとアラートを管理することで、以下のメリットが得られます:

  • 設定の一貫性と再現性の確保
  • バージョン管理による変更履歴の追跡
  • 複数環境への簡単なデプロイ
  • 大量のモニター設定の効率的な管理

今回の実装では、OpenSearch のモニターとアラートを Terraform で管理する基本的な方法を紹介しました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?