Terraform으로 알림 리소스 프로비저닝하기

Terraform으로 알림 리소스 프로비저닝하기 (Use Terraform to provision alerting resources)

Terraform의 Grafana Provider를 사용해 알림(Alerting) 리소스를 코드로 관리하고 Grafana에 프로비저닝하는 방법을 알려드릴게요. Grafana Alerting 전체 스택을 코드로서 생성·관리·유지할 수 있게 되죠. 실습 데모는 Grafana OSS와 Docker Compose를 이용한 예제를 클론해서 시도해 볼 수 있어요.

출처: 문서

본문

Terraform으로 알림 리소스를 만들고 관리하려면 다음 작업을 순서대로 진행해야 해요.

  1. Terraform provider를 구성할 API 키를 생성하세요.
  2. 기존 알림 리소스 내보내기로 리소스를 Terraform 형식으로 만들거나, Terraform Alerting 스키마를 직접 작성하세요. 기본적으로 프로비저닝된 리소스는 Grafana UI에서 편집할 수 없으니, UI에서 변경을 허용하려면 Terraform 리소스에 disable_provenance를 활성화하세요.
  3. terraform apply를 실행해 알림 리소스를 프로비저닝하세요.

시작 전에 Grafana 인스턴스와 Terraform 설치가 필요해요.

API 키 생성과 Terraform provider 구성

서비스 계정 토큰으로 Terraform을 Grafana에 인증할 수 있어요.

  1. 새 서비스 계정을 생성하세요.
  2. Alerting provisioning API에 접근할 역할이나 권한을 할당하세요.
  3. 새 서비스 계정 토큰을 생성하세요.
  4. 토큰에 이름을 붙여 Terraform에서 사용할 수 있게 저장하세요.

Terraform 구성 작업 디렉터리에서 main.tf 파일을 이렇게 만드세요.

terraform {
    required_providers {
        grafana = {
            source = "grafana/grafana"
            version = ">= 2.9.0"
        }
    }
}

provider "grafana" {
    url = <grafana-url>
    auth = <api-key>
}

다음 값을 치환하세요.

  • <grafana-url> → Grafana 인스턴스의 URL
  • <api-key> → 앞서 생성한 API 토큰

이 구성은 Grafana Terraform provider를 설치하고 API 토큰으로 인증합니다. 기본 인증 등 다른 인증 방법은 auth 옵션 문서를 참고하세요. Grafana Cloud는 Terraform으로 Grafana Cloud 스택 관리, RBAC는 Terraform으로 RBAC 프로비저닝 문서를 참고하세요.

알림 리소스 Terraform 구성 만들기

Grafana Terraform provider로 관리할 수 있는 알림 리소스는 다음과 같습니다.

알림 리소스 Terraform 리소스
Alert rules grafana_rule_group
Contact points grafana_contact_point
Notification templates grafana_message_template
Notification policy tree grafana_notification_policy
Mute timings grafana_mute_timing

알림 규칙 추가하기

알림 규칙은 Grafana 데이터 소스를 쿼리해 알림을 받게 해줘요. 먼저 데이터 소스와 규칙을 저장할 폴더를 만드세요(예제는 TestData 데이터 소스 사용).

resource "grafana_data_source" "<terraform_data_source_name>" {
    name = "TestData"
    type = "testdata"
}

resource "grafana_folder" "<terraform_folder_name>" {
    title = "My Rule Folder"
}
  • <terraform_data_source_name>은 데이터 소스의 Terraform 이름, <terraform_folder_name>은 폴더의 Terraform 이름으로 치환하세요.

그 다음 Grafana에서 가져올 알림 규칙을 만들거나 찾은 뒤, 내보내기로 규칙 그룹을 Terraform 형식(grafana_rule_group)으로 내보내고 편집하거나 새로 작성하세요.

resource "grafana_rule_group" "<terraform_rule_group_name>" {
    name = "My Alert Rules"
    folder_uid = grafana_folder.<terraform_folder_name>.uid
    interval_seconds = 60
    org_id = 1

    rule {
        name = "My Random Walk Alert"
        condition = "C"
        for = "0s"

        // Query the datasource.
        data {
            ref_id = "A"
            relative_time_range {
                from = 600
                to = 0
            }
            datasource_uid = grafana_data_source.<terraform_data_source_name>.uid
            // `model` is a JSON blob that sends datasource-specific data.
            // It's different for every datasource. The alert's query is defined here.
            model = jsonencode({
                intervalMs = 1000
                maxDataPoints = 43200
                refId = "A"
            })
        }

        // The query was configured to obtain data from the last 60 seconds. Let's alert on the average value of that series using a Reduce stage.
        data {
            datasource_uid = "__expr__"
            model = <<EOT
{"conditions":[{"evaluator":{"params":[0,0],"type":"gt"},"operator":{"type":"and"},"query":{"params":["A"]},"reducer":{"params":[],"type":"last"},"type":"avg"}],"datasource":{"name":"Expression","type":"__expr__","uid":"__expr__"},"expression":"A","hide":false,"intervalMs":1000,"maxDataPoints":43200,"reducer":"last","refId":"B","type":"reduce"}
EOT
            ref_id = "B"
            relative_time_range {
                from = 0
                to = 0
            }
        }

        // Now, let's use a math expression as our threshold.
        // We want to alert when the value of stage "B" above exceeds 70.
        data {
            datasource_uid = "__expr__"
            ref_id = "C"
            relative_time_range {
                from = 0
                to = 0
            }
            model = jsonencode({
                expression = "$B > 70"
                type = "math"
                refId = "C"
            })
        }
    }
}

서로 다른 Grafana 리소스는 Terraform 구성에서 uid 값으로 연결됩니다. uid는 프로비저닝 시 무작위로 생성돼요.

연락 지점(Contact points) 추가하기

Contact points는 알림 알림의 수신자입니다. 예제는 이메일 컨택트 포인트입니다.

resource "grafana_contact_point" "<terraform_contact_point_name>" {
    name = "My contact point email"

    email {
        addresses               = ["<email_address>"]
    }
}
  • <terraform_contact_point_name>은 컨택트 포인트의 Terraform 이름, <email_address>는 알림을 받을 이메일입니다.

알림 템플릿 추가·활성화하기

Notification templates로 여러 컨택트 포인트에 걸쳐 알림을 커스터마이즈할 수 있어요. 다음 예제는 custom_emails 그룹을 만들고 custom_email.message 템플릿을 정의합니다.

resource "grafana_message_template" "<terraform_message_template_name>" {
    name = "custom_emails"

    template = <<EOT
{{ define "custom_email.message" }}
Lorem ipsum - Custom alert!
{{ end }}
EOT
}

앞서 만든 컨택트 포인트에서 email.message 속성으로 템플릿을 활성화하세요.

resource "grafana_contact_point" "<terraform_contact_point_name>" {
    name = "My contact point email"

    email {
        addresses               = ["<email_address>"]
        message                 = "{{ template \"custom_email.message\" .}}"
    }
}

Mute timing 추가하기

Mute timings은 정해진 시간 동안 알림을 일시 중지해요. 예제는 주말에 알림을 끕니다.

resource "grafana_mute_timing" "<terraform_mute_timing_name>" {
    name = "No weekends"

    intervals {
        weekdays = ["saturday", "sunday"]
    }
}

알림 정책 트리 추가하기

Notification policies는 알림 인스턴스를 컨택트 포인트로 라우팅할 방법을 정의해요.

경고: 정책 트리는 단일 리소스이므로 프로비저닝하면 기존 정책 트리의 모든 정책이 덮어써집니다. 다만 알림 규칙이 컨택트 포인트를 직접 선택할 때 생성되는 내부 정책에는 영향이 없어요.

resource "grafana_notification_policy" "my_policy_tree" {
contact_point = grafana_contact_point.<terraform_contact_point_name>.name
...

policy {
    contact_point = grafana_contact_point.<terraform_contact_point_name>.name

    matcher {...}

    mute_timings = [grafana_mute_timing.<terraform_mute_timing_name>.name]
}
}

Grafana UI에서 리소스 편집 활성화하기

기본적으로 Terraform으로 프로비저닝된 리소스는 Grafana에서 편집할 수 없어요. 이는 알림 스택이 항상 Terraform 코드와 동기화되도록 보장합니다. UI에서 편집 가능하게 하려면 알림 리소스에 disable_provenance 속성을 활성화하세요.

resource "grafana_contact_point" "my_contact_point" {
  name = "My Contact Point"

  disable_provenance = true
}

resource "grafana_message_template" "custom_notification_template_group" {
  name     = "custom_notification_template_group"
  template = "{{define \"template1\" }}Say{{ end }}{{define \"template2\" }}Hi!{{ end }}"

  disable_provenance = true
}
...

Terraform CLI로 Grafana 리소스 프로비저닝하기

  1. Terraform 구성 파일이 있는 작업 디렉터리를 초기화하세요.
terraform init

이 명령은 Terraform 디렉터리를 초기화하고 main.tf에 구성된 Grafana Terraform provider를 설치합니다.

  1. 구성 파일을 적용해 리소스를 프로비저닝하세요.
terraform apply

Grafana에 변경을 적용하기 전에 Terraform이 실행 계획을 보여주고 승인을 요청합니다.

 Plan: 4 to add, 0 to change, 0 to destroy.

 Do you want to perform these actions?
 Terraform will perform the actions described above.
 Only 'yes' will be accepted to approve.

 Enter a value:

승인하면 Grafana에 리소스가 생성됩니다.

Apply complete! Resources: 4 added, 0 changed, 0 destroyed.

이제 Grafana에 접속해 리소스 생성 여부를 확인할 수 있어요.

더 많은 예제

더 알아보기 (Learn more)