My Note

自己理解のためのブログ

Terraform ( terraform-cloud )でMackerelをコード管理する

はじめに

2022年の一本目の記事になります。Mackerelに関する記事は最近書けていなかったので久々の投稿になります。 以前の記事でMackerel監視設定の管理をServerlessで自動化しました。

yhidetoshi.hatenablog.com

当時は Mackerel公式からterraformプロバイダーが提供されていませんでしたが、昨年リリースされたので 監視設定に限らずMackerelの設定をコード化できるので試してみました。

mackerel.io

環境

  • terraform-clolud(無料プラン)
  • GitHub
  • Mackerel
  • Terraform: v1.0.11

f:id:yhidetoshi:20220111145022p:plain

やること

  • terraform-cloudの設定
  • terraformの構成
  • serviceを作成
  • terraform import (既存のservice)
  • roleを作成
  • monitorを作成
  • notificationを作成
  • alertを作成

terraformのコードと構成

terraform-cloudの設定

  • GitHubとterraform-cloudの連携
  • terraform-cloudの organizationとworkspaceの作成

の詳細な説明については省略します。

terraform-cloud の "workspace" の設定する部分を一部抜粋しました。

Variables

  • 環境変数として、mackerelのAPI-KEYを設定しています。Mackerelに設定を反映するときに必要になります。

f:id:yhidetoshi:20220111151038p:plain

Setting (General Settings)

  • 実行環境を "Remote" にして Terraformのバージョンを設定。

f:id:yhidetoshi:20220111151207p:plain

Setting (Version Control)

  • fileが変更されたら実行するトリガーのパスを設定。

f:id:yhidetoshi:20220111151258p:plain

terraform-registry

利用する Mackerelのterraform registryとGitHubは下記。

terraformの構成

  • 構成は複数のOrganizationを運用するという設定で org_a, org_bのようにorg毎にworkspaceを分離
  • 役割毎にtfファイルを分離

ディレクトリ構造

└── terraform
    ├── org_a
    │   ├── alerts.tf
    │   ├── monitors.tf
    │   ├── notifications.tf
    │   ├── providers.tf
    │   ├── roles.tf
    │   ├── services.tf
    │   └── variables.tf
    └── org_b
        ├── providers.tf
        └── variables.tf
terraform {
  required_version = ">=1.0"
  required_providers {
    mackerel = {
      source  = "mackerelio-labs/mackerel"
      version = "~> 0.0.8"
    }
  }
  backend "remote" {
    hostname     = "app.terraform.io"
    organization = "my-org"
    workspaces {
      name = "mackerel-org-a"
    }
  }
}
  • terraform/org_a/variables.tf
variable "MACKEREL_API_KEY" {
  type = string
}
  • ローカルmoduleは hashicorp/mackerel のプロバイダーがなくエラーになるため利用していません。
> tree .
 ├── modules
    │   └── service
    │       ├── main.tf
    │       └── variables.tf
   └── org_a
        ├── providers.tf
        ├── services.tf
        └── variables.tf


> terraform init

│ Error: Failed to query available provider packages
│
│ Could not retrieve the list of available versions for provider hashicorp/mackerel: provider registry
│ registry.terraform.io does not have a provider named registry.terraform.io/hashicorp/mackerel


> terraform providers
Providers required by configuration:
.
├── provider[registry.terraform.io/mackerelio-labs/mackerel] ~> 0.0.8
└── module.service_name_org_a
    └── provider[registry.terraform.io/hashicorp/mackerel]

serviceを作成

resource "mackerel_service" "aws" {
  name = "AWS"
  memo = "aws billing"
}

resource "mackerel_service" "dev" {
  name = "dev"

■ 確認

❯ mkr services | jq '.[].name' -r | grep -e dev -e AWS
AWS
dev

→ "dev" のサービスが作成されています。

terraform import

新規でmackerelを利用する場合は困らないですが、すでに運用を始めていると既存の設定を terraformに取り込む必要があるので terraform import を利用します。

  • terraform importするために開発端末からmackerelに対してAPIを発行するので環境変数をセットします。
export MACKEREL_API_KEY=XXXX

すでに作成してあるサービスの "AWS" とimportします。

resource "mackerel_service" "aws" {
  name = "AWS"
  memo = "aws billing"
}
  • importする
❯ terraform import mackerel_service.aws AWS


Acquiring state lock. This may take a few moments...

Import successful!

The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.

Releasing state lock. This may take a few moments...
  • stateファイルを確認
❯ terraform state list mackerel_service.aws
mackerel_service.aws

→ statefileに追加されています。

roleを作成

resource "mackerel_role" "web" {
  name    = "web"
  service = mackerel_service.dev.name
  depends_on = [
    mackerel_service.dev
  ]
}

resource "mackerel_role" "db" {
  name    = "db"
  service = mackerel_service.dev.name
  depends_on = [
    mackerel_service.dev
  ]
}

f:id:yhidetoshi:20220112133255p:plain

→ "dev" のサービスに "web" と "db" のロールが作成されています。

monitorを作成

resource "mackerel_monitor" "cpu_high" {
  name    = "VM CPU %"
  is_mute = false

  host_metric {
    metric   = "cpu%"
    operator = ">"
    warning  = 80
    critical = 90
    duration = 3

    scopes = ["dev:web"]
  }
}

作成されたmonitor

f:id:yhidetoshi:20220114110313p:plain

notificationを作成

resource "mackerel_channel" "email" {
  name = "Email"

  email {
    emails = ["sample1@example.com", "sample2@example.com"]
    events = ["alert", "alertGroup"]
  }
}

resource "mackerel_channel" "slack" {
  name = "Slack"

  slack {
    url                 = "https://hooks.slack.com/services/xxx/yyy/zzz"
    enabled_graph_image = true
    events              = ["alert", "alertGroup"]
    mentions = {
      critical = "@here"
    }
  }
}

Emailのchannel

f:id:yhidetoshi:20220114104823p:plain

Slackのchannel

f:id:yhidetoshi:20220114110154p:plain

alertsを作成

resource "mackerel_alert_group_setting" "admin" {
  name = "admin"
  memo = "For Admin members"
  service_scopes = [
    mackerel_service.dev.name,
  ]
  depends_on = [
    mackerel_service.dev
  ]
}

おわり

Mackerelの公式からTerraformのregistryがリリースされたので利用して設定を管理してみました。 これを使えばコードベースでMackerelの管理ができそうですね。

ソースコードは以下のGitHubに配置しています。

github.com