前回
はじめに
New Relic記事第2弾。
前回は、AWSのメトリクスを、CloudWatchメトリクスストリームを使ってNew Relicに転送してサマリを監視するところまでをTerraformで自動化した。
今回は、メトリクスを監視してアラートを作成する部分を構築する。もちろん、Terraformでの自動化方法についても紹介する。
アラート作成
前回作ったLambda関数は一定確率でエラー終了して、Lambda Function URLsで500応答を返すようにしている。
import json
import random
def lambda_handler(event, context):
random_value = random.random()
if random_value < 0.5:
return {
'statusCode': '200',
'body': json.dumps({'message': 'OK.'}),
}
else:
return {
'statusCode': '500',
'body': json.dumps({'message': 'NG.'}),
}
今回、一定間隔でこのLambda関数を実行し、1つでもエラーがあった場合にアラートを上げるような設定を行う。
実際の運用上、これが適切な方法かはしっかりと吟味を行っていただきたい。
New Relicには3種類のアラートの発報方法がある。
- ケイデンス(Cadence)
- イベントタイマー(Evnet Timer)
- イベントフロー(Event Flow) ※現在のデフォルトはこれ
ワークロードの特性に応じて使い分ける必要があるが、公式のドキュメントが難解なので、時系列での図解がある記事へのリンクも張っておく。
リンク内でも言及があるが、CloudWatch メトリクスストリームの場合はEvent Flowを選択するのが適切なようなので、今回はEvent Flowで作成をした。
アラートの構成要素
アラートは以下の3つの構成要素からなっている(括弧内はTerraformのリソース名)。
- アラートポリシー(newrelic_alert_policy)
- アラート条件(newrelic_nrql_alert_condition)
- アラート通知
アラート通知は、さらに以下の構成要素に分解される。
- ワークフロー(newrelic_workflow)
- チャネル(newrelic_notification_channel)
- 目的地(newrelic_notification_destination)
それぞれの概要は、以下の公式ドキュメントを参照していただきたい。
アラートポリシー
アラートは一連のアラート条件をまとめて、どのように通知をするかをまとめる概念を指す。
Terraform では以下のリソース定義を行う。
resource "newrelic_alert_policy" "example" {
name = "Lambda Alert Example"
incident_preference = "PER_CONDITION_AND_TARGET"
}
incident_preference
については、以下のNew Relicの公式ドキュメントと、TerraformのNew Relic Providerの公式ドキュメントを参照。
これは、アラート通知の粒度を決定するものだ。
今回はもっとも細かい粒度で通知をする設定を行う。
アラート条件
アラート条件は、NRQLというNew Relic用のクエリ言語で取得できる情報に対してどのような閾値を設定するかを設定する。
また、policy_id
でアラートポリシーとの紐付けも行う。
前述した通り、今回はLambda関数の実行で一つでもエラーがあったらアラートを上げる設定を行う。
メトリクスストリームからaws.lambda.Url5xxCount
のメトリクスを拾って閾値を設定しよう。
他のLambda関数の情報を拾って誤検知しないように、WHERE句で `aws.lambda.functionName` = '${aws_lambda_function.example1.function_name}'
で絞り込みを行うのも忘れないように。
resource "newrelic_nrql_alert_condition" "example" {
enabled = true
name = "P1 | 5xx HTTP Response | Lambda Function Example"
description = "Alert when AWS Lambda Functions returned 5xx HTTP Response."
type = "static"
policy_id = newrelic_alert_policy.example.id
title_template = "New Relic Alert Example: {{conditionName}}"
fill_option = "static"
fill_value = 0
aggregation_method = "event_flow"
aggregation_window = 60
aggregation_delay = 120
open_violation_on_expiration = false
close_violations_on_expiration = false
ignore_on_expected_termination = true
nrql {
query = <<EOQ
SELECT
count(`aws.lambda.Url5xxCount`)
FROM
Metric
WHERE
`collector.name` = 'cloudwatch-metric-streams' AND
`aws.accountId` = '${data.aws_caller_identity.self.account_id}' AND
`aws.lambda.functionName` = '${aws_lambda_function.example1.function_name}'
EOQ
}
critical {
operator = "above"
threshold = 1
threshold_duration = 60
threshold_occurrences = "at_least_once"
}
}
title_template
では、通知のタイトルを設定する。
ここには、HandleBarsの記法で変数置換が可能になっている。通知の視認性を上げるためにも分かりやすいタイトルの設定をしておこう。今回の例で言えば、{{conditionName}}
は、このアラートの名前(name
プロパティ)と同じ値が設定される。
詳細はNew Relicの以下の公式ドキュメントを参照。
その他、様々な設定が行えるが、詳細は以下の公式ドキュメントを参照。
NRQLを使用しないnewrelic_alert_condition
というリソースも存在するが、TerraformのNew Relic Providerの公式ドキュメントでdeprecatedである旨が記載されているため、本記事では取り扱わない。
アラート通知
アラート通知は以下の通り3つのリソースを設定する。
ワークフロー
ワークフローでは、通知チャネルの設定と、通知のフィルタ条件を設定する。
今回はnewrelic_alert_policy.example.id
に合致するもののみ通知する設定だ。
resource "newrelic_workflow" "example" {
name = "example"
muting_rules_handling = "NOTIFY_ALL_ISSUES"
issues_filter {
name = "Issue Filter"
type = "FILTER"
predicate {
attribute = "labels.policyIds"
operator = "EXACTLY_MATCHES"
values = [newrelic_alert_policy.example.id]
}
}
destination {
channel_id = newrelic_notification_channel.example.id
}
}
チャネル
チャネルでは、何のチャネルを使用するかを選択する。
EMAIL
以外にも、SERVICE_NOW_APP
, WEBHOOK
, JIRA_CLASSIC
, MOBILE_PUSH
, EVENT_BRIDGE
, SLACK
, SLACK_COLLABORATION
, PAGERDUTY_ACCOUNT_INTEGRATION
, PAGERDUTY_SERVICE_INTEGRATION
と様々な通知先を設定可能だ。
property
項目は通知先によって異なるため、詳細はTerraformのNew Relic Providerの公式ドキュメントを参照。
resource "newrelic_notification_channel" "example" {
name = "Email Example"
type = "EMAIL"
destination_id = newrelic_notification_destination.example.id
product = "IINT"
property {
key = "subject"
value = "NewRelic Nortification Test"
}
property {
key = "customDetailsEmail"
value = "issue id - {{issueId}}"
}
}
目的地(デスティネーション)
デスティネーションでは、実際の通知先を設定する。
要は、Emailの場合はメールアドレスだ。
これも、type
によって設定する値が異なるため、詳細はTerraformのNew Relic Providerの公式ドキュメントを参照。
resource "newrelic_notification_destination" "example" {
name = "Email Example"
type = "EMAIL"
property {
key = "email"
value = local.newrelic_nortice_email_address
}
}
ここまで設定したら、terraform apply
で設定を反映しよう。
いざ、動かす!
メール内容の確認
前回作ったLambda Function URLsのエンドポイントに向けてcurlでリクエストを送り続けてみよう。
すると、local.newrelic_nortice_email_address
で通知先に設定したメールアドレスに対して、以下のようなメールが届くはずだ。
この通り、newrelic_nrql_alert_condition.example.title_template
で設定した{{conditionName}}}
が正しく置換されていることが確認できる。
コンソールの確認
コンソールの左メニューから、「Alerts」→「Issues & Activity」を選択すると、上記のメールで送信されたIssueの情報が表示される。
この行をクリックすると、メールで通知されたのと同等の情報が参照可能だ。
これで、AWSのメトリクスの自動監視が可能になった!
次回